Packages
formex
0.4.15
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Form library for Phoenix with Ecto support
Current section
Files
Jump to
Current section
Files
lib/formex/view.ex
defmodule Formex.View do
use Phoenix.HTML
alias Formex.Form
alias Formex.Field
alias Formex.FormCollection
alias Formex.FormNested
alias Formex.Button
@moduledoc """
Helper functions for templating.
Example of use:
<%= formex_form_for @form, @action, fn f -> %>
<%= if @form.changeset.action do %>
<div class="alert alert-danger">
<p>Oops, something went wrong! Please check the errors below.</p>
</div>
<% end %>
<%= formex_rows f %>
<div class="form-group">
<%= submit "Submit", class: "btn btn-primary" %>
</div>
<% end %>
## Changing a form template
You can change the template globally or in the specific form/field.
* config
```
config :formex,
template: Formex.Template.BootstrapHorizontal
template_options: [ # options used by this template
left_column: "col-xs-2",
right_column: "col-xs-10"
]
```
* `formex_form_for/4`:
```
<%= formex_form_for @form, @action, [
class: "form-horizontal",
template: Formex.Template.BootstrapHorizontal
], fn f -> %>
...
<% end %>
```
* `formex_rows/2`:
```
<%= formex_rows f, template: Formex.Template.BootstrapHorizontal %>
```
* `formex_row/3`:
```
<%= formex_row f, :name, template: Formex.Template.BootstrapHorizontal %>
```
"""
defmacro __using__([]) do
quote do
import Formex.View
import Formex.View.Nested
import Formex.View.Collection
end
end
@doc """
Works similar to a `Phoenix.HTML.Form.form_for/4`
In the callback function the first argument is `t:Formex.Form.t/0` instead of a
`t:Phoenix.HTML.Form.t/0`.
This argument contains the `t:Phoenix.HTML.Form.t/0` under a `:phoenix_form` key
## Options
* `template` - a form template that implements `Formex.Template`, for example:
`Formex.Template.BootstrapHorizontal`
* `template_options` - additional options, supported by the template
"""
@spec formex_form_for(form :: Form.t, action :: String.t, options :: Keyword.t,
fun :: (Formex.t -> Phoenix.HTML.unsafe)) :: Phoenix.HTML.safe
def formex_form_for(form, action, options \\ [], fun) do
phoenix_options = options
|> Keyword.delete(:template)
|> Keyword.delete(:template_options)
Phoenix.HTML.Form.form_for(form.changeset, action, phoenix_options, fn f ->
form
|> Map.put(:phoenix_form, f)
|> Map.put(:template, options[:template])
|> Map.put(:template_options, options[:template_options])
|> fun.()
end)
end
@doc """
Generates all `formex_row/2`s at once
## Options
* `template` - a form template that implements `Formex.Template`, for example:
`Formex.Template.BootstrapHorizontal`
* `template_options` - additional options, supported by the template
"""
@spec formex_rows(Form.t, Keyword.t) :: Phoenix.HTML.safe
def formex_rows(form, options \\ []) do
Enum.map(form.items, fn item ->
formex_row(form, item.name, options)
end)
end
@doc """
Generates a row
Example of use:
<%= formex_row f, :title %>
<%= formex_row f, :content %>
<%= formex_row f, :category_id %>
## Options
* `template` - a form template that implements `Formex.Template`, for example:
`Formex.Template.BootstrapHorizontal`
* `template_options` - additional options, supported by the template
"""
@spec formex_row(Form.t, Atom.t, Keyword.t) :: Phoenix.HTML.safe
def formex_row(form, item_name, options \\ []) do
item = get_item(form, item_name)
template = get_template(form, options)
template_options = get_template_options(form, options)
case item do
%Field{} ->
template.generate_row(form, item, template_options)
%Button{} ->
template.generate_row(form, item, template_options)
%FormNested{} ->
Formex.View.Nested.formex_nested(form, item_name, options)
%FormCollection{} ->
Formex.View.Collection.formex_collection(form, item_name, options)
end
end
@spec formex_input(Form.t, Atom.t, Keyword.t) :: Phoenix.HTML.safe
def formex_input(form, item_name, options \\ []) do
item = get_item(form, item_name)
template = get_template(form, options)
template.generate_input(form, item)
end
@spec formex_label(Form.t, Atom.t, Keyword.t) :: Phoenix.HTML.safe
def formex_label(form, item_name, options \\ []) do
item = get_item(form, item_name)
template = get_template(form, options)
class = options[:class] && options[:class] || ""
template.generate_label(form, item, class)
end
def get_template(form, row_options) do
row_options[:template]
|| form.template
|| Application.get_env(:formex, :template)
|| Formex.Template.BootstrapVertical
end
def get_template_options(form, row_options) do
[]
|> Keyword.merge(Application.get_env(:formex, :template_options) || [])
|> Keyword.merge(form.template_options || [])
|> Keyword.merge(row_options[:template_options] || [])
end
defp get_item(form, item_name) do
item = Enum.find(form.items, &(&1.name == item_name))
if !item do
throw("Key :"<>to_string(item_name)<>" not found in form "<>to_string(form.type))
end
item
end
end