<commit_before># FormForms

[![Gem Version](https://badge.fury.io/rb/form_forms.png)](https://rubygems.org/gems/form_forms)
[![Build Status](https://secure.travis-ci.org/meineerde/form_forms.png)](http://travis-ci.org/meineerde/form_forms)
[![Code Climate](https://codeclimate.com/github/meineerde/form_forms.png)](https://codeclimate.com/github/meineerde/form_forms)

Configurable forms for Rails 3 and 4, based on the excellent
[simple_form](https://github.com/plataformatec/simple_form) gem.

The goal of this gem is to provide forms (as in views) which are flexible
enough to fulfill their intended usage but be able to be configured by
plugins. Thus plugins can easily add, delete and edit form fields without
having to override whole views (which are almost impossible to patch) or
having to monkey patch existing code which is hard to maintain.

FormForms is originally intended to be used with the simple_form gem and uses
its API in several of its shipped element definitions. While it is possible
to not use those and provide custom definitions, we require simple_form as
a dependency right now.

# Installation

Add this line to your application's Gemfile:

    gem 'form_forms'

and then run `bundle install`.

Or install it yourself using

    gem install form_forms

# Usage

FormForms is built around the idea that a Rails application is able to
define arbitrary forms using a simple yet powerful DSL. These form
definitions are typically contained in the `lib` directory and are loaded
during initialization. During rendering of a request, the view simply
retrieves an existing form definition and renders that form by parameterizing
it with some data object (e.g. an ActiveRecord model instance).

## Defining Forms

    FormForms::Registry[:my_form] = FormForms::Form.new() do |form|
      form.field(:subject) {|f| f.input :subject}
      form.field(:link) do |f|
        content_tag :p do
          content_tag(:a, :href => hint_path){ "This is a hint" }
        end
      end
    end

This will register a new form object under the name `:my_form` which will
render two fields: an input field for the `subject` attribute of the passed
model instance and a "static" hint. Each fields definition has a block which
defines what will actually be rendered. This block will be executed in the
context of the current view which allows you to use any helper methods you
have defined in your application.

Each of the fields is identified with a name, passed as the first parameter
to the field definition. Using this name, plugins can later change or remove
individual fields. As such, the name of each field has to be unique on each
level of the form.

## Form Registry

To handle several forms, FormForms ships with a simple registry. If you
need a more powerful system, you are of course free to handle your form
objects in any other way.

The default registry provides a hash-like interface on the
`FormForms::Registry` class. You can either directly assign form objects to
keys there as shown above or you can use the `register` method of all `Form`
classes as a shorthand:

    FormForms::Forms::Form.register(:my_name) do |form|
      # form definition
      # [...]
    end

## Adapting an existing form from plugins

Once a form is defined, it fields can be added, changed, and removed later on.

New fields can be added either before or after already existing elements:

    FormForms::Registry[:my_form].field_before(:description, :name) {|f| f.input :name}
    FormForms::Registry[:my_form].field_after(:credit_card, :ccv) {|f| f.input :ccv}

This will insert the new field `:name` before the already defined field
`:description` and insert the field `:ccv` after the existing `:credit_card`
field. You can also insert elements at the very beginning and the very end of
the elements list:

    FormForms::Registry[:my_form].field_first(:salutation) {|f| f.input :salutation}
    FormForms::Registry[:my_form].field_last(:accept_terms) {|f| f.input :accept_terms}

Each of the element types defines the five methods

* `form.<type>`
* `form.<type>_first`
* `form.<type>_before`
* `form.<type>_after`
* `form.<type>_last` (an alias to `form.<type>`)

Each of the methods accepts all parameters of the respective element type.
Only the `form.<type>_before` and `form.<type>_after` methods take the name of
the element that should act as the respective index as the first argument.

Finally, there is the `form.delete` method which simply takes the name of an
element as its parameter. It complete deletes this element from the element
list, preventing it from rendering:

    FormForms::Registry[:my_form].delete(:salutation)

# Form types

## `FormForms::Forms::Form`

The most common form of a form is the, well, the form. It creates a HTML form
for a single ActiveModel instance.

The form can be rendered in a view by using something like this:

    <%= FormForms::Registry[:my_form].render(@model, self) %>

The `render` method takes two parameters: the model object that should be used
as the base object for the form and a view instance (which can be almost
always passed as `self`). The view instance is used to render the form fields.

## `FormForms::Forms::Plain`

The plain form allows to use FormForms to define a simple block of elements.
It does not use a model instance and thus does not define a form builder. It
can be used to generate  several blocks of pre-defined views which can be
extended and adapted by plugins.

This form type can be rendered in a view by sing something like this:

    <%= FormForms::Registry[:plain_form].render(self) %>

The `render` method takes only one parameter: the view instance that is used
to render the elements. Note that as we don't have a form builder here, the
first argument to each element's generator block is `nil`.

This form type only supports a subset of elements to be used within it. It
does not support `fields` and `table_fields` as they require an actual
ActiveModel object for rendering. See below for more information about the
various element types.

# Element Types

FormForms already ships with different element types which allow you to
create most of the common form elements. These elements are used to define
the actual form body.

## `field`

The most basic element type is a `field` which is rendered to a basic form
field or a snipped of static code. Fields are the most basic form of elements
and typically made of the bulk of the form definition.

For the definition, they take a `name` which is used for identifying the
field in the form as well as a generator block to render the field. The name,
always being the first attribute is *only* used for identifying the element
later on and is not passed to the generator block during rendering and thus
can be chosen arbitrarily. It must only be unique in the current scope.
Generally, it is advisable to chose a name similar to the model field that is
actually rendered.

The block receives one argument during rendering: the form builder, i.e. the
simple_form object. Alternatively to a block, you can also directly pass a
string which will be emitted as-is. The usual HTML escape rules apply, i.e.
you have to use `html_save` correctly to avoid rendering unsafe data.

Alternativly to a block, you can also set a static content by assigning it to
the second argument. This will only be set during form initialization and will
not be evaluated during form rendering again. Use this to set value which are
always static.

The following two variants are equivalent:

    FormForms::Registry[:user] = FormForms::Forms::Form.new() do |form|
      form.field(:dynamic) {|f| "a value" }
      form.field(:statis, "a value")
    end

## `sub_form`

Almost all the other element types create a sub form. It allows to group
several sub elements into a single named element. While the `sub_form` acts
as a prototype for all other scoping elements (see below) which typically
surround child elements with HTML block tags during rendering, `sub_form`
just creates a logical scope in the form and doesn't affect rendering in any
way.

It allows you to group several sub-elements which can then handled as a
single element.

    FormForms::Registry[:user] = FormForms::Forms::Form.new() do |form|
      form.field(:street) {|f| f.input :street }
      form.field(:city) {|f| f.input :city }
      form.sub_form(:payment) do |sub_form|
        sub_form.field(:credit_card) {|f| f.input :credit_card}
        sub_form.field(:ccv) {|f| f.input :ccv}
      end
    end

During rendering, this example will generate the four forms exactly the same
as if they all would have been defined directly on the form.

## `fieldset`

A fieldset is used to group fields in a single form. During rendering, this<commit_msg>Typos<commit_after># FormForms

[![Gem Version](https://badge.fury.io/rb/form_forms.png)](https://rubygems.org/gems/form_forms)
[![Build Status](https://secure.travis-ci.org/meineerde/form_forms.png)](http://travis-ci.org/meineerde/form_forms)
[![Code Climate](https://codeclimate.com/github/meineerde/form_forms.png)](https://codeclimate.com/github/meineerde/form_forms)

Configurable forms for Rails 3 and 4, based on the excellent
[simple_form](https://github.com/plataformatec/simple_form) gem.

The goal of this gem is to provide forms (as in views) which are flexible
enough to fulfill their intended usage but be able to be configured by
plugins. Thus plugins can easily add, delete and edit form fields without
having to override whole views (which are almost impossible to patch) or
having to monkey patch existing code which is hard to maintain.

FormForms is originally intended to be used with the simple_form gem and uses
its API in several of its shipped element definitions. While it is possible
to not use those and provide custom definitions, we require simple_form as
a dependency right now.

# Installation

Add this line to your application's Gemfile:

    gem 'form_forms'

and then run `bundle install`.

Or install it yourself using

    gem install form_forms

# Usage

FormForms is built around the idea that a Rails application is able to
define arbitrary forms using a simple yet powerful DSL. These form
definitions are typically contained in the `lib` directory and are loaded
during initialization. During rendering of a request, the view simply
retrieves an existing form definition and renders that form by parameterizing
it with some data object (e.g. an ActiveRecord model instance).

## Defining Forms

    FormForms::Registry[:my_form] = FormForms::Form.new() do |form|
      form.field(:subject) {|f| f.input :subject}
      form.field(:link) do |f|
        content_tag :p do
          content_tag(:a, :href => hint_path){ "This is a hint" }
        end
      end
    end

This will register a new form object under the name `:my_form` which will
render two fields: an input field for the `subject` attribute of the passed
model instance and a "static" hint. Each fields definition has a block which
defines what will actually be rendered. This block will be executed in the
context of the current view which allows you to use any helper methods you
have defined in your application.

Each of the fields is identified with a name, passed as the first parameter
to the field definition. Using this name, plugins can later change or remove
individual fields. As such, the name of each field has to be unique on each
level of the form.

## Form Registry

To handle several forms, FormForms ships with a simple registry. If you
need a more powerful system, you are of course free to handle your form
objects in any other way.

The default registry provides a hash-like interface on the
`FormForms::Registry` class. You can either directly assign form objects to
keys there as shown above or you can use the `register` method of all `Form`
classes as a shorthand:

    FormForms::Forms::Form.register(:my_name) do |form|
      # form definition
      # [...]
    end

## Adapting an existing form from plugins

Once a form is defined, it fields can be added, changed, and removed later on.

New fields can be added either before or after already existing elements:

    FormForms::Registry[:my_form].field_before(:description, :name) {|f| f.input :name}
    FormForms::Registry[:my_form].field_after(:credit_card, :ccv) {|f| f.input :ccv}

This will insert the new field `:name` before the already defined field
`:description` and insert the field `:ccv` after the existing `:credit_card`
field. You can also insert elements at the very beginning and the very end of
the elements list:

    FormForms::Registry[:my_form].field_first(:salutation) {|f| f.input :salutation}
    FormForms::Registry[:my_form].field_last(:accept_terms) {|f| f.input :accept_terms}

Each of the element types defines the five methods

* `form.<type>`
* `form.<type>_first`
* `form.<type>_before`
* `form.<type>_after`
* `form.<type>_last` (an alias to `form.<type>`)

Each of the methods accepts all parameters of the respective element type.
Only the `form.<type>_before` and `form.<type>_after` methods take the name of
the element that should act as the respective index as the first argument.

Finally, there is the `form.delete` method which simply takes the name of an
element as its parameter. It complete deletes this element from the element
list, preventing it from rendering:

    FormForms::Registry[:my_form].delete(:salutation)

# Form types

## `FormForms::Forms::Form`

The most common form of a form is the, well, the form. It creates a HTML form
for a single ActiveModel instance.

The form can be rendered in a view by using something like this:

    <%= FormForms::Registry[:my_form].render(@model, self) %>

The `render` method takes two parameters: the model object that should be used
as the base object for the form and a view instance (which can be almost
always passed as `self`). The view instance is used to render the form fields.

## `FormForms::Forms::Plain`

The plain form allows to use FormForms to define a simple block of elements.
It does not use a model instance and thus does not define a form builder. It
can be used to generate  several blocks of pre-defined views which can be
extended and adapted by plugins.

This form type can be rendered in a view by sing something like this:

    <%= FormForms::Registry[:plain_form].render(self) %>

The `render` method takes only one parameter: the view instance that is used
to render the elements. Note that as we don't have a form builder here, the
first argument to each element's generator block is `nil`.

This form type only supports a subset of elements to be used within it. It
does not support `fields` and `table_fields` as they require an actual
ActiveModel object for rendering. See below for more information about the
various element types.

# Element Types

FormForms already ships with different element types which allow you to
create most of the common form elements. These elements are used to define
the actual form body.

## `field`

The most basic element type is a `field` which is rendered to a basic form
field or a snipped of static code. Fields are the most basic form of elements
and typically made of the bulk of the form definition.

For the definition, they take a `name` which is used for identifying the
field in the form as well as a generator block to render the field. The name,
always being the first attribute is *only* used for identifying the element
later on and is not passed to the generator block during rendering and thus
can be chosen arbitrarily. It must only be unique in the current scope.
Generally, it is advisable to chose a name similar to the model field that is
actually rendered.

The block receives one argument during rendering: the form builder, i.e. the
simple_form object. Alternatively to a block, you can also directly pass a
string which will be emitted as-is. The usual HTML escape rules apply, i.e.
you have to use `html_save` correctly to avoid rendering unsafe data.

Alternatively to a block, you can also set a static content by assigning it to
the second argument. This will only be set during form initialization and will
not be evaluated during form rendering again. Use this to set value which are
always static.

The following two variants are equivalent:

    FormForms::Registry[:user] = FormForms::Forms::Form.new() do |form|
      form.field(:dynamic) {|f| "a value" }
      form.field(:static, "a value")
    end

## `sub_form`

Almost all the other element types create a sub form. It allows to group
several sub elements into a single named element. While the `sub_form` acts
as a prototype for all other scoping elements (see below) which typically
surround child elements with HTML block tags during rendering, `sub_form`
just creates a logical scope in the form and doesn't affect rendering in any
way.

It allows you to group several sub-elements which can then handled as a
single element.

    FormForms::Registry[:user] = FormForms::Forms::Form.new() do |form|
      form.field(:street) {|f| f.input :street }
      form.field(:city) {|f| f.input :city }
      form.sub_form(:payment) do |sub_form|
        sub_form.field(:credit_card) {|f| f.input :credit_card}
        sub_form.field(:ccv) {|f| f.input :ccv}
      end
    end

During rendering, this example will generate the four forms exactly the same
as if they all would have been defined directly on the form.

## `fieldset`

A fieldset is used to group fields in a single form. During rendering, this
{'fraction_non_alphanumeric': 0.06872105654336516, 'fraction_numerical': 0.00022868904007775429, 'mean_word_length': 4.26708822643782, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 25, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1705887', 'n_tokens_mistral': 4712, 'n_tokens_neox': 4580, 'n_words': 2485}