formex v0.3.3 Formex.Type behaviour
In order to create a form, you need to create the Type file. It’s similar to Symfony’s way of creating forms.
Example:
defmodule App.ArticleType do
use Formex.Type
alias Formex.CustomField.SelectAssoc
def build_form(form) do
form
|> add(:text_input, :title, label: "Title")
|> add(:textarea, :content, label: "Content", phoenix_opts: [
rows: 4
])
|> add(:checkbox, :hidden, label: "Is hidden", required: false)
|> add(SelectAssoc, :category_id, label: "Category", phoenix_opts: [
prompt: "Choose category"
])
|> add_button(:reset, "Reset form", phoenix_opts: [
class: "btn-default"
])
|> add_button(:submit, if(form.struct.id, do: "Edit", else: "Add"), phoenix_opts: [
class: "btn-primary"
])
end
# optional
def changeset_after_create_callback(changeset) do
# do an extra validation
changeset
end
end
Nested forms
*_to_one
We have models User
, and UserInfo
. The UserInfo
contains extra information that we don’t
want, for some reason, store in the User
model.
schema "users" do
field :first_name, :string
field :last_name, :string
belongs_to :user_info, App.UserInfo
end
schema "user_infos" do
field :section, :string
field :organisation_cell, :string
has_one :user, App.User
end
Note: belongs_to
can also be placed in UserInfo
and so on, it doesn’t matter in this example.
Our form will consist of two modules:
user_type.ex
defmodule App.UserType do
use Formex.Type
def build_form(form) do
form
|> add(:text_input, :first_name)
|> add(:text_input, :last_name)
|> add_form(App.UserInfoType, :user_info)
end
end
user_info_type.ex
defmodule App.UserInfoType do
use Formex.Type
def build_form( form ) do
form
|> add(:text_input, :section)
|> add(:text_input, :organisation_cell)
end
end
Our form can be displayed in various ways:
Print whole form, with nested form, at once
<%= formex_rows f %>
Standard
<%= formex_row f, :first_name %> <%= formex_row f, :last_name %> <%= formex_row f, :user_info %>
Set a form template for nested form
<%= formex_row f, :first_name %> <%= formex_row f, :last_name %> <div class="form-horizontal"> <%= formex_row f, :user_info, template: Formex.Template.BootstrapHorizontal %> </div>
At the moment it is not possible to write more sophisticated template for subform.
*_to_many
Work in progress
Summary
Functions
Adds a field to the form
Adds a button to the form
Embeds a form of assoc to the main form
Callbacks
In this callback you have to add fields to the form
Callback that will be called after changeset creation. In this function you can for example add an extra validation to your changeset
Functions
Adds a field to the form.
If the type_or_module
is an atom, then this function invokes Formex.Field.create_field/4
.
Otherwise, the Formex.CustomField.create_field/3
is called.
Adds a button to the form.
The type
may be either :submit
or :reset
.
This function invokes Formex.Button.create_button/3
.
Embeds a form of assoc to the main form.
If a struct of this form is not already preloaded, it will be loaded.
Options
required
- is the subform required.Defaults to
true
. This option will be passed toEcto.Changeset.cast_assoc/3
Callbacks
In this callback you have to add fields to the form.
changeset_after_create_callback(changeset :: Ecto.Changeset.t) :: Ecto.Changeset.t
Callback that will be called after changeset creation. In this function you can for example add an extra validation to your changeset.