active_element

0.0.13
Light Mode Dark Mode

JSON

A custom form field json_field is provided for editing JSON data.

The field is schema-based and expects to find a schema definition in config/forms/<model>/<attribute>.yml.

For example, to edit a JSON attribute named permissions on a User model, ActiveElement requires a file named config/forms/user/permissions.yml.

See the Schema documentation for a detailed description of how this file should be generated.

The json_field type will be automatically selected for ActiveRecord json and jsonb columns included in the fields array when used in conjunction with an ActiveRecord model.

Example Form

This example is powered by the example schema below.

The pets column on the users table is a json column so ActiveElement loads the schema and generates a dynamic, interactive form component allowing users to edit the data structure without having to manually edit JSON.

Click the Rendered Output tab to see it in action:

let(:user) do
  User.new(
    email: 'user@example.com',
    pets: [
      { animal: 'Cat', name: 'Hercules', favorite_foods: ['Plants', 'Biscuits'] },
      { animal: 'Dog', name: 'Samson' }
    ]
  )
end

subject do
  active_element.component.form model: user, title: 'New User', fields: [:email, :pets]
end

it { is_expected.to include 'Hercules' }
<span class="fs-4 align-bottom">New User</span>
<div class="form pb-3" id="form-wrapper-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1">
  <form id="active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1" class="user m-3" action="/_users" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="XF2C6VASr_29tr-UQJCE9pzOD9CxhyAjWSHdqf-2gpy4vvWG6LtOEfF4rXyy56eD8MB_7cog-_bsu8AcYXVUOA" 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 value="user@example.com" 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_pets">
          Pets
        </label>
        <div>
          <a data-modal-id="#json-modal-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-pets-json-view"
   id="json-view-modal-trigger-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-pets-json-view"
   data-json-modal-link="true"
   data-bs-toggle="modal"
   data-bs-target="#json-modal-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-pets-json-view"
   class="text-decoration-none text-nowrap"
   href="#">JSON <i class="fa-solid fa-magnifying-glass"></i></a>
          <div id="json-modal-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-pets-json-view" class="modal fade"
     tabindex="-1"
     aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered modal-xl modal-dialog-scrollable">
              <div class="modal-content">
                <div class="modal-header">
                  <h5 class="modal-title" data-field-type="modal-title">JSON Inspector</h5>
                  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
                    <i class="fa-solid fa-xmark"></i>
                  </button>
                </div>
                <div class="modal-body p-3" data-field-type="modal-body">
                  <div class='json-highlight' style='font-family: monospace;'><span class="p">[</span><span class="w"><br/>
                      &nbsp;&nbsp;</span><span class="p">{</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;</span><span class="nl">"animal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Cat"</span><span class="p">,</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Hercules"</span><span class="p">,</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;</span><span class="nl">"favorite_foods"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="s2">"Plants"</span><span class="p">,</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="s2">"Biscuits"</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;</span><span class="p">]</span><span class="w"><br/>
                      &nbsp;&nbsp;</span><span class="p">},</span><span class="w"><br/>
                      &nbsp;&nbsp;</span><span class="p">{</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;</span><span class="nl">"animal"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Dog"</span><span class="p">,</span><span class="w"><br/>
                      &nbsp;&nbsp;&nbsp;&nbsp;</span><span class="nl">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Samson"</span><span class="w"><br/>
                      &nbsp;&nbsp;</span><span class="p">}</span><span class="w"><br/>
                    </span><span class="p">]</span></div>
                </div>
                <div class="modal-footer" data-field-type="modal-footer"></div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="col">
        <div class="col-sm-10 json-field form-group"
     data-data-key="user.pets"
     data-field-name="pets"
     data-form-id="active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1"
     data-field-id="active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-json-field-pets"
     data-schema-field-id="active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-json-field-pets-schema"
     data-json-view-modal-id="json-modal-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-pets-json-view"
     data-json-view-modal-trigger-id="json-view-modal-trigger-active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-pets-json-view"
>
        </div>
        <input name="user[pets]" value="" id="active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-json-field-pets" autocomplete="off" type="hidden" />
        <input name="__json_field_schemas[user][pets]" value="" id="active-element-cfcf6540-4731-4e51-818e-9cef21bea0b1-json-field-pets-schema" autocomplete="off" type="hidden" />
        <input name="__json_fields[]" value="user.pets" autocomplete="off" type="hidden" id="user_pets" />
        <script type="text/javascript">
          window.ActiveElement = window.ActiveElement || {};
          ActiveElement.jsonData = ActiveElement.jsonData || {};

          ActiveElement.jsonData = {
            ...ActiveElement.jsonData,
            ...{"user.pets":{"data":[{"animal":"Cat","name":"Hercules","favorite_foods":["Plants","Biscuits"]},{"animal":"Dog","name":"Samson"}],"schema":{"type":"array","shape":{"type":"object","shape":{"fields":[{"name":"name","type":"string"},{"name":"age","type":"integer"},{"name":"animal","type":"string","options":["Cat","Dog","Polar Bear"]},{"name":"favorite_foods","type":"array","shape":{"type":"string","options":["Biscuits","Plants","Carpet"]}}]}}}}}
          };
        </script>
      </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>
New User
JSON

Example Schema

The example above is powered by this schema definition:

# config/forms/user/pets.yml
---
type: array
shape:
  type: object
  shape:
    fields:
    - name: name
      type: string
    - name: age
      type: integer
    - name: animal
      type: string
      options:
      - Cat
      - Dog
      - Polar Bear
    - name: favorite_foods
      type: array
      shape:
        type: string
        options:
        - Biscuits
        - Plants
        - Carpet

Documentation generated by rspec-documentation