PhxAdmin v0.9.1 PhxAdmin.Form

Override the default new and edit form pages for an PhxAdmin resource.

By default, PhxAdmin renders the form page without any additional configuration. It renders each column in the model, except the id, inserted_at, and updated_at columns in an attributes table.

To customize the new and edit pages, use the form macro.

For example, the following will show on the id an name fields, as well place a selection column and batch actions row on the page:

defmodule MyProject.PhxAdmin.Contact do
  use PhxAdmin.Register

  register_resource MyProject.Contact do

    form contact do
      inputs do
        input contact, :first_name
        input contact, :last_name
        input contact, :email
        input contact, :category, collection: MyProject.Category.all
      end

      inputs "Groups" do
        inputs :groups, as: :check_boxes, collection: MyProject.Group.all
      end
    end
  end
end

The form command

Call form with a name for your resource and a do block.

The inputs command

Calling inputs with a do block displays a field set with the specified inputs from the block.

Adding a label to inputs, labels the field set.

The input command

The first argument is input is alway the resource name give to the form command. The second argument is the the field name expressed as an atom. Optionally, a third argument can be a keyword list.

Override the default label

input resource, :name, label: "Customer Name"

Specify a collection

input resource, :category, collection: Repo.all(Category)

Specify the field names for a collection

input resource, :user, fields: [:first_name, :email]

Specifying type of control

input user, :password, type: :password

Array field support

# default  tag style
input user, :nicknames

# multi select restricted to the provided collection
input user, :groups, select2: [collection: ~w(Sales Marketing Dev)]

# tags style with the extra collection options
input user, :groups, select2: [collection: ~w(Sales Marketing Dev)]

Customizing DateTime fields

input user, :start_at, options: [sec: []]

Most of the options from the datetime_select control from phoenix_html should work.

Map field support

Since maps don’t have a defined schema, you can define the schema as an option to the input macro. For example:

form user do
  inputs "User Details" do
    input user, :name
  end
  inputs "Statistics" do
    input user, :stats, schema: [age: :integer, height: :string, birthday: :string]
  end
end

Array of maps field support

Like maps, you must provided the schema for an array of maps. For example:

form user do
  inputs "User Details" do
    input user, :name
  end
  inputs "Addresses" do
    input user, :addresses, schema: [street: :string, city: :string]
  end
end

Rendering a has_many :through (many-to-many) relationship

The example at the beginning of the chapter illustrates how to add a list of groups, displaying them as check boxes.

inputs "Groups" do
  inputs :groups, as: :check_boxes, collection: MyProject.Group.all
end

Nested attributes

PhxAdmin supports in-line creation of a has_many, through: (many-to-many) relationship. The example below allows the user to add/delete phone numbers on the contact form using the has_many command.

form contact do
  inputs do
    input contact, :first_name
    input contact, :last_name
    input contact, :email
    input contact, :category, collection: UcxNotifier.Category.all
  end

  inputs "Phone Numbers" do
    has_many contact, :phone_numbers, fn(p) ->
      input p, :label, collection: PhoneNumber.labels
      input p, :number
    end
  end
end

Note: has_many does not yet work with simple one-to-many relationships.

Adding conditional fields

The following complicated example illustrates a number of concepts possible in a form definition. The example allows management of an authentication token for a user while on the edit page.

First, the if params[:id] do condition ensures that the code block only executes for an edit form, and not a new form.

Next, the actions command adds in-line content to an inputs block.

form user do
  inputs "User Details" do
    input user, :name
    # ...
  end

  if params[:id] do
    inputs "Authentication Token" do
      actions do
        user = Repo.get User, params[:id]
        if user.authentication_token do
          content content_tag(:li, user.authentication_token, style: "padding: 5px 10px")
          content content_tag(:li, token_link("Reset Token", :reset, params[:id]), class: "cancel")
          content content_tag(:li, token_link("Delete Token", :delete, params[:id]), class: "cancel")
        else
          content content_tag(:li, token_link("Create Token", :create, params[:id]),
            class: "cancel", style: "padding-left: 20px")
        end
      end
    end
  end

end

The javascript command

Use the javascript command to add javascript to the form page.

For example, the following adds a change handler to get a list of assets using an ajax call:

javascript do
  """
  $(document).ready(function() {
    $('#asset_assetable_type_id').change(function() {
      $.get('/assets/'+$(this).val()+'/assetables?format=js');
    });
  });
  """
end

Summary

Macros

Add an action block to a form

Add a HTML content block to a form

Add HTML content to a form

Customize the form page

Display a nested resource on the form

Display an input field on the form

Add an fieldset to the form

Add a has_many field to a form

Add a has_many field to a form

Add javascript to the form

Functions

build_array_control_select2_script(arg, name)
build_array_control_select2_script_opts(arg)
build_hidden_block(conn, mode)
build_input(conn, type, field, field_name, data, model_name, errors \\ nil, index \\ nil)
build_item(conn, item, resource, model_name, error)

Handle building the items for an input block.

This is where each of the fields will be build

build_main_block(conn, resource, model_name, schema)
build_script(arg1)
build_scripts(list)
date_select(form, field_name, opts \\ [])
datetime_select(form, field_name, opts \\ [])
escape_value(value)
get_action(resource, mode)
get_required(field_name, arg2)
global_script()
put_script_block(script_block)
required_abbr(arg1)
setup_resource(resource, params, model_name)
time_select(form, field, opts \\ [])
wrap_item_type(type, label, ext_name, contents, error, required)

Macros

actions(list)

Add an action block to a form

TBD: Add more description here

content(list)

Add a HTML content block to a form

For example:

content do
  """
  <div>Something here</div>
  <div>More stuff here</div>
  """
end
content(items, opts \\ quote() do [] end)

Add HTML content to a form.

Can be called multiple times to append HTML content for a page

For example:

content content_tag(:li, user.authentication_token, style: "padding: 5px 10px")
content content_tag(:li, token_link("Reset Token", :reset, params[:id]), class: "cancel")
content content_tag(:li, token_link("Delete Token", :delete, params[:id]), class: "cancel")
form(resource, list)

Customize the form page.

Use the form command to customize the new and edit page forms. Pass a name for the resource to be created or modified.

has_many(resource, name, opts \\ [], fun \\ nil)

Display a nested resource on the form.

Adds management of a has_many resource to the page, allowing in-line addition, editing, and deletion of the nested resource.

input(resource, name, opts \\ [])

Display an input field on the form.

Display all types of form inputs.

Options

  • :type - Sets the type of the control (:password, :hidden, etc)

  • :label - Sets a custom label

  • :collection - Sets the collection to render for a belongs_to relationship

  • :fields - Sets a list of fields to be used in a select control. For example input post :user, fields: [:first_name, :last_name] would render a control like:

    `<select>`
      `<option id="1">José Valim</option>`
      `<option id="2">Chris McCord</option>
        `</select>`
    • :prompt - Sets a HTML placeholder

    • :change - Sets change handler to a control. When set to a string, the string is assumed to be javascript and added with the control. When a keyword list, the list is used to define what should happen when the input changes. See the section below on valid keywords.

    • :ajax - Used for ajax controls. See ajax below

    • :display - When set to false, the control and its label are hidden with style="display: none". Use this to hide inputs that will later be displayed with javascript or an ajax request

    • :as - Sets the type of collection. Valid options are:

      • :check_boxes - Use check boxes
      • :radio - Use radio buttons

    Ajax controls

    Use the ajax: true, change: [...] do allow dynamic updating of nested collection inputs.

    For example, assume a page for purchasing a product, where the product has a number of options and each option has different possible color selections.

    When option 1 is selected, they have the choice of red or black. If option 2 is selected, they have the choice of red or green. So, based on the option selected, the color select needs to be dynamically reloaded.

    TBD: Complete this

inputs(opts)

Add an fieldset to the form

inputs(name, opts)

Add a has_many field to a form.

inputs(name, opts, list)

Add a has_many field to a form.

javascript(list)

Add javascript to the form

Adds a block of javascript code to the form. Typically used to add change or click handlers to elements on the page