team-formalist / formalist-rb

Flexible form builder
MIT License
22 stars 4 forks source link

Support for creating a list of arbitrary embedded forms #93

Closed narinda closed 2 years ago

narinda commented 3 years ago

This PR provides a new field type defined by the class ManyForms, and created in the form definition as:

many_forms :components,
    label: "Components",
    sortable: true,
    moveable: true,
    action_label: "Add component",
    embeddable_forms: general_component_forms

This field allows a arbitrary list of embeddable forms. The forms available are defined by the embeddable_forms attribute, in the same way as forms available in to embed in a rich text field are defined.

The #fill method of the many forms field builds a list of children composed of ChildForm elements. The ChildForm element provides a form and schema attribute that is used to validate and fill the data and convert to form AST. The many_forms #to_ast builds it's list of children AST from each of these elements.

As a bonus this ChildForm element also gave us the ability to easily define a singular FormField class, that can be used to embed a single embeddable form in another form. eg:

form_field :hero_block, 
   label: "Hero block", 
   form: general_component_forms[:hero_block].form,
   schema: general_component_forms[:hero_block].schema

Helper classes are also provided for validating and co-ercing the data received on form submit. The ValidityCheck class is initialized with the form container and when called provides a boolean value indicating whether the data is valid. eg:

Formalist::ChildForms::ValidityCheck.new(general_component_forms).(form_data)

The ParmsProcessor class runs the params validations over the data to co-erce the data to the correct types. eg:

Formalist::ChildForms::ParamsProcessor.new(general_component_forms).(form_data)

The ruby changes are supported by changes to the JS libraries in the following PRs: team-formalist/formalist-standard-react#178 team-formalist/formalist-compose-js#22 team-formalist/formalist-data-object-renderer#2