{"id":1143,"date":"2010-06-29T17:01:53","date_gmt":"2010-06-29T20:01:53","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=1143"},"modified":"2015-02-25T15:07:27","modified_gmt":"2015-02-25T18:07:27","slug":"simpleform-forms-made-easy","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2010\/06\/simpleform-forms-made-easy\/","title":{"rendered":"SimpleForm: forms made easy"},"content":{"rendered":"

Sometime ago we were working on a project together with a designer, and that specific application was full of forms, each one having a different layout, but most of them sharing the same features: inline errors, hints, specific label markup for required fields, etc. To start prototyping the application faster, we used the markup the designer created with similar forms, duplicating the code. But we don’t like code duplication, we weren’t feeling comfortable with it. So we decided to move on and create a tool to help us, that should be flexible enough to let us define the markup that fits better for each application, or even no extra markup at all. Here is SimpleForm!<\/p>\n

SimpleForm inputs<\/h3>\n

From the README:<\/p>\n

Forms made easy (for Rails)!<\/p>\n

SimpleForm aims to be as flexible as possible while helping you with powerful components to create your forms. The basic goal of simple form is to not touch your way of defining the layout, letting you find the better design for your eyes. Good part of the DSL was inherited from Formtastic, which we are thankful for and should make you feel right at home.<\/p><\/blockquote>\n

As the README says, SimpleForm is a tool to help you build forms easily in Rails<\/a>. Let’s see some examples:<\/p>\n

<%= simple_form_for @user do |f| %>\n  <%= f.input :username, :label => 'Your username please' %>\n  <%= f.input :password, :hint => 'No special characters.' %>\n  <%= f.input :remember_me, :as => :boolean %>\n  <%= f.button :submit %>\n<% end -%>\n<\/code><\/pre>\n

There are plenty of things going on here: we create a form using simple_form_for<\/code> helper, then we use the :input<\/code> method to create input elements based on column type. For instance, :username<\/code> will create a default text input, while :password<\/code> attribute will render an input type password. For the :username<\/code> attribute, we are specifying a label manually. For :password<\/code>, the label will be taken from I18n, and we are adding a hint message to the field. For :remember_me<\/code>, we are explicitly saying to render it as a checkbox, using the :as => :boolean<\/code> option (that is the default for boolean attributes). Also, there is a button<\/code> helper that simply delegates to Rails helpers, in this case submit<\/code>.<\/p>\n

The output for a new @user<\/code> would be:<\/p>\n

<form action=\"\/users\" class=\"simple_form user\" id=\"new_user\" method=\"post\">\n  <div class=\"input string required\">\n    <label class=\"string required\" for=\"user_username\"><abbr title=\"required\">*<\/abbr> Your username please<\/label>\n    <input class=\"string required\" id=\"user_username\" maxlength=\"255\" name=\"user[username]\" size=\"50\" type=\"text\" \/>\n  <\/div> \n  <div class=\"input password required\">\n    <label class=\"password required\" for=\"user_password\"><abbr title=\"required\">*<\/abbr> Password<\/label>\n    <input class=\"password required\" id=\"user_password\" name=\"user[password]\" size=\"30\" type=\"password\" \/>\n    <span class=\"hint\">No special characters.<\/span>\n  <\/div> \n  <div class=\"input boolean optional\">\n    <label class=\"boolean optional\" for=\"user_remember_me\"> Remember me<\/label>\n    <input name=\"user[remember_me]\" type=\"hidden\" value=\"0\" \/>\n    <input class=\"boolean optional\" id=\"user_remember_me\" name=\"user[remember_me]\" type=\"checkbox\" value=\"1\" \/>\n  <\/div> \n  <input id=\"user_submit\" name=\"commit\" type=\"submit\" value=\"Create User\" \/> \n<\/form> \n<\/code><\/pre>\n

You may have noticed there is some additional css classes added to the markup, like string<\/code> and required<\/code>. They are added automatically by SimpleForm to help us style and plug some javascript in. There are specific css classes for each available input type. Also, pay some attention to the label<\/code>: inside it there is an abbr<\/code> tag with an asterisk (*) showing that the field is required. SimpleForm uses the new validations reflection API from Rails 3 to check if the attribute has the presence<\/code> validator, and mark the field as required if so. And we are able to say that a field is required or disable the required mark, by passing the option :required => true|false<\/code>.<\/p>\n

Furthermore, there is the hint<\/code> tag for the :password<\/code> attribute that SimpleForm creates based on the :hint<\/code> option we have defined. Also notice that the gem has automatically added a div<\/code> wrapper to each input, with the same css classes. SimpleForm allows us to configure this wrapper as well, using for instance p<\/code> instead of div<\/code>. We are going to see more about configuration later.<\/p>\n

SimpleForm is already prepared to generate some of the new HTML 5 input tags, such as email<\/code>, url<\/code> and number<\/code> inputs:<\/p>\n

<%= simple_form_for @user do |f| %>\n  <%= f.input :website, :as => :url %>\n  <%= f.input :email %>\n  <%= f.input :age, :hint => \"This defaults to 'number' input based on field type\" %>\n  <%= f.button :submit %>\n<% end -%>\n<\/code><\/pre>\n

Based on the attribute name, SimpleForm will generate url<\/code> or email<\/code> input types, and we can always set a specific type with the :as<\/code> option. Numeric attributes will always be rendered as input type number.<\/p>\n

Working with associations<\/h3>\n

SimpleForm adds a custom and straightforward method to render select tags for associations, called association<\/code>. For now, consider our User<\/code> belongs to a Company<\/code>, and has and belongs to many Roles<\/code>. Let’s go straight to the example:<\/p>\n

<%= simple_form_for @user do |f| %>\n  <%= f.input :name %>\n  <%= f.association :company %>\n  <%= f.association :roles %>\n  <%= f.button :submit %>\n<% end -%>\n<\/code><\/pre>\n

It will detect the association type and render a select<\/code> tag for choosing the company, listing all companies in the database, and another select<\/code> for roles, with multiple<\/code> option enabled.<\/p>\n

SimpleForm also has some add-ons, letting us render associations as a collection of radios or check boxes. Using the same example:<\/p>\n

  f.association :company, :as => :radio\n  f.association :roles, :as => :check_boxes\n<\/code><\/pre>\n

Now we are rendering a collection of radios for choosing the Company<\/code>, and another collection of check boxes for choosing Roles<\/code>.<\/p>\n

Configuration<\/h3>\n

SimpleForm lets us do some customizations by running its install generator:<\/p>\n

rails generate simple_form:install\n\n# Output\n  create  config\/initializers\/simple_form.rb\n  create  config\/locales\/simple_form.en.yml\n  create  lib\/templates\/erb\/scaffold\/_form.html.erb\n<\/code><\/pre>\n

As we can see, running this generator will copy an initializer file, responsible for configuring SimpleForm; a locale file, to let us change some I18n messages; and a form template inside our lib dir. This template will be used instead of the default Rails scaffold form template, so it will create our form already using SimpleForm. Easy, right?<\/p>\n

Let’s take a look at some configuration options:<\/p>\n