Packages
formex
0.2.0
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/custom_fields/select_assoc.ex
defmodule Formex.CustomField.SelectAssoc do
@behaviour Formex.CustomField
import Ecto.Query
alias Formex.Field
@repo Application.get_env(:formex, :repo)
@moduledoc """
This module generates a `:select` field with options downloaded from Repo.
Example of use for Article with one Category:
```
schema "articles" do
belongs_to :category, App.Category
end
```
```
form
|> add(Formex.CustomField.SelectAssoc, :category_id, label: "Category")
```
Formex will find out that `:category_id` refers to App.Category schema and download all rows
from Repo ordered by name.
## Options
* `choice_name` - controls the content of `<option>`. May be the name of field or function.
Example of use:
```
form
|> add(SelectAssoc, :article_id, label: "Article", choice_name: :title)
```
```
form
|> add(SelectAssoc, :article_id, label: "Article", choice_name: fn article ->
article.title
end)
```
"""
def create_field(form, name_id, opts) do
name = Regex.replace(~r/_id$/, Atom.to_string(name_id), "") |> String.to_atom
# option_name
module = form.model.__schema__(:association, name).queryable
choices = get_choices(module, opts[:choice_name])
%Field{
name: name_id,
type: :select,
value: Map.get(form.struct, name),
label: Field.get_label(name, opts),
required: Keyword.get(opts, :required, true),
data: [
choices: choices
],
opts: opts
}
end
defp get_choices(module, choice_name) when is_function(choice_name) do
module
|> @repo.all
|> Enum.map(fn row ->
name = choice_name.(row)
{name, row.id}
end)
|> Enum.sort(fn {name1, _}, {name2, _} ->
name1 < name2
end)
end
defp get_choices(module, choice_name) do
choice_name = if choice_name, do: choice_name, else: :name
query = from e in module,
select: {field(e, ^choice_name), e.id},
order_by: field(e, ^choice_name)
@repo.all(query)
end
end