active_element

0.0.13
Light Mode Dark Mode

Form Fields

ActiveElement provides a selection of fields, most of which delegate to Rails’ own form helpers.

Extra field types provided by ActiveElement include:

  • json_field: A rich JSON schema-based form generator that recursively creates form elements for your JSON objects.
  • text_search_field: A full text search/auto-suggest component that provides a secure implementation with minimal configuration.
  • check_boxes: A set of checkboxes that can optionally be provided as option groups.

Other field types are inferred from the data type and/or column name for each attribute passed to the fields array and leverage the existing form helpers provided by Rails. e.g. if you have an ActiveRecord instance with an attribute whose database column type is date, a date field will be automatically rendered. Similarly, a column named email will render an email_field.

subject do
  active_element.component.form model: User.new,
                                fields: [:email, :name, :date_of_birth]
end

it { is_expected.to include 'type="date"' }
<div class="form pb-3" id="form-wrapper-active-element-6874f5cb-1702-4cc2-9fd1-2caddc6c6a2d">
  <form id="active-element-6874f5cb-1702-4cc2-9fd1-2caddc6c6a2d" class="user m-3" action="/_users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="fGAjpf7MHeGHTHdHll7xg9bpwmOXjnAPzto2YBB2FuFLCQPpOx8rlFO7khOjOXlmRot3s5xnid8FA_A4H5fgDw" autocomplete="off" />
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_email">
          Email
          <button type="button"
            style="background: none; border: none; outline: 0; position: absolute;  margin-top: 0.3rem"
            data-bs-toggle="popover"
            data-bs-trigger="focus"
            title="Email"
            data-bs-content="We will use your email address to send your account details.">
            <i class="text-secondary fa-solid fa-circle-info"></i>
          </button>
        </label>
      </div>
      <div class="col">
        <input class="form-control my-email-field-class" tabindex="2" label="Email" description="We will use your email address to send your account details." placeholder="Enter your email address, e.g. user@example.com" type="email" name="user[email]" id="user_email" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_name">
          Name
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="3" label="Name" type="text" name="user[name]" id="user_name" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_date_of_birth">
          Date Of Birth
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="4" label="Date Of Birth" type="date" name="user[date_of_birth]" id="user_date_of_birth" />
      </div>
    </div>
    <div class="form-group">
      <input type="submit" name="" value="Create User" class="btn btn-success" data-disable-with="Create User" />
      <a data-form-input-type="clear" class="btn btn-primary  btn-secondary ms-2" title="Clear Form" href="#">
        <span class="text-nowrap">
          <span class="button-title">Clear Form</span>
        </span>
      </a>
    </div>
  </form>
</div>

If you need to override these field types, use a two-element array of [field_name, field_type]:

subject do
  active_element.component.form model: User.new,
                                fields: [:email, :name, [:date_of_birth, :text_field]]
end

it { is_expected.not_to include 'type="date"' }
<div class="form pb-3" id="form-wrapper-active-element-4b3893de-31c8-4704-829e-75e9d5049f80">
  <form id="active-element-4b3893de-31c8-4704-829e-75e9d5049f80" class="user m-3" action="/_users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="_bz-8xvbfptXe4wAuqSdL_oxRNte6oujRk9kxOZa3iIaadHlPcN47GLiUzCcmA6fRIJC-yT-r3nuWHsajA9z4A" autocomplete="off" />
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_email">
          Email
          <button type="button"
            style="background: none; border: none; outline: 0; position: absolute;  margin-top: 0.3rem"
            data-bs-toggle="popover"
            data-bs-trigger="focus"
            title="Email"
            data-bs-content="We will use your email address to send your account details.">
            <i class="text-secondary fa-solid fa-circle-info"></i>
          </button>
        </label>
      </div>
      <div class="col">
        <input class="form-control my-email-field-class" tabindex="2" label="Email" description="We will use your email address to send your account details." placeholder="Enter your email address, e.g. user@example.com" type="email" name="user[email]" id="user_email" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_name">
          Name
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="3" label="Name" type="text" name="user[name]" id="user_name" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_date_of_birth">
          Date Of Birth
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="4" label="Date Of Birth" type="text" name="user[date_of_birth]" id="user_date_of_birth" />
      </div>
    </div>
    <div class="form-group">
      <input type="submit" name="" value="Create User" class="btn btn-success" data-disable-with="Create User" />
      <a data-form-input-type="clear" class="btn btn-primary  btn-secondary ms-2" title="Clear Form" href="#">
        <span class="text-nowrap">
          <span class="button-title">Clear Form</span>
        </span>
      </a>
    </div>
  </form>
</div>

You can also pass a third element to the array to specify any options you want to pass to the field:

subject do
  active_element.component.form model: User.new,
                                fields: [
                                  :email,
                                  :name,
                                  [:date_of_birth, :text_field, { class: 'form-control my-class' }]
                                ]
end

it { is_expected.to include 'class="form-control my-class"' }
<div class="form pb-3" id="form-wrapper-active-element-6b973fc9-4d15-4ded-9297-90175cc85c83">
  <form id="active-element-6b973fc9-4d15-4ded-9297-90175cc85c83" class="user m-3" action="/_users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="Z6akLE54SJczvRnQId59eEv570e2NY5zRuq-iS5IOVsgW_mzcpTlj3lxWvAe3J85zkhHKTZouhue15koKUuHCA" autocomplete="off" />
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_email">
          Email
          <button type="button"
            style="background: none; border: none; outline: 0; position: absolute;  margin-top: 0.3rem"
            data-bs-toggle="popover"
            data-bs-trigger="focus"
            title="Email"
            data-bs-content="We will use your email address to send your account details.">
            <i class="text-secondary fa-solid fa-circle-info"></i>
          </button>
        </label>
      </div>
      <div class="col">
        <input class="form-control my-email-field-class" tabindex="2" label="Email" description="We will use your email address to send your account details." placeholder="Enter your email address, e.g. user@example.com" type="email" name="user[email]" id="user_email" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_name">
          Name
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="3" label="Name" type="text" name="user[name]" id="user_name" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_date_of_birth">
          Date Of Birth
        </label>
      </div>
      <div class="col">
        <input class="form-control my-class" tabindex="4" label="Date Of Birth" type="text" name="user[date_of_birth]" id="user_date_of_birth" />
      </div>
    </div>
    <div class="form-group">
      <input type="submit" name="" value="Create User" class="btn btn-success" data-disable-with="Create User" />
      <a data-form-input-type="clear" class="btn btn-primary  btn-secondary ms-2" title="Clear Form" href="#">
        <span class="text-nowrap">
          <span class="button-title">Clear Form</span>
        </span>
      </a>
    </div>
  </form>
</div>

Custom Fields

If you’re using the Default Controller or you simply want to separate your configuration from your views, you can customize each form field by creating a file named config/forms/<model>/<field>.yml.

The User email field can be configured by creating config/forms/user/email.yml:

# config/forms/user/email.yml

type: email_field
options:
  class: 'form-control my-email-field-class'
  description: 'We will use your email address to send your account details.'
  placeholder: 'Enter your email address, e.g. user@example.com'
subject do
  active_element.component.form model: User.new,
                                fields: [:email, :name, :date_of_birth]
end

it { is_expected.to include 'class="form-control my-email-field-class"' }
<div class="form pb-3" id="form-wrapper-active-element-43cfb115-fde6-480e-a7a5-fa58722ee8dd">
  <form id="active-element-43cfb115-fde6-480e-a7a5-fa58722ee8dd" class="user m-3" action="/_users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="8pcTHvJT5CkiDujkATs4OHlqmypHpuFrOAUErcM_XjBIVbewbsBC_zprN79EnDfIFYnZyahnv6smGdA1RqQ8TQ" autocomplete="off" />
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_email">
          Email
          <button type="button"
            style="background: none; border: none; outline: 0; position: absolute;  margin-top: 0.3rem"
            data-bs-toggle="popover"
            data-bs-trigger="focus"
            title="Email"
            data-bs-content="We will use your email address to send your account details.">
            <i class="text-secondary fa-solid fa-circle-info"></i>
          </button>
        </label>
      </div>
      <div class="col">
        <input class="form-control my-email-field-class" tabindex="2" label="Email" description="We will use your email address to send your account details." placeholder="Enter your email address, e.g. user@example.com" type="email" name="user[email]" id="user_email" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_name">
          Name
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="3" label="Name" type="text" name="user[name]" id="user_name" />
      </div>
    </div>
    <div class="row form-fields mb-3">
      <div class="col-sm-3">
        <label for="user_date_of_birth">
          Date Of Birth
        </label>
      </div>
      <div class="col">
        <input class="form-control " tabindex="4" label="Date Of Birth" type="date" name="user[date_of_birth]" id="user_date_of_birth" />
      </div>
    </div>
    <div class="form-group">
      <input type="submit" name="" value="Create User" class="btn btn-success" data-disable-with="Create User" />
      <a data-form-input-type="clear" class="btn btn-primary  btn-secondary ms-2" title="Clear Form" href="#">
        <span class="text-nowrap">
          <span class="button-title">Clear Form</span>
        </span>
      </a>
    </div>
  </form>
</div>

The options configuration receives a small number of options specific to ActiveElement such as description and Text Search configuration, otherwise they are passed directly to the underlying Rails form helper.

The type configuration corresponds to either a Rails form helper ActiveElement extension field, i.e. email_field will call some variation of:

form_with do |form|
  form.email_field :email
end

Documentation generated by rspec-documentation