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!
SimpleForm inputs
From the README:
Forms made easy (for Rails)!
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.
As the README says, SimpleForm is a tool to help you build forms easily in Rails. Let’s see some examples:
<%= simple_form_for @user do |f| %>
<%= f.input :username, :label => 'Your username please' %>
<%= f.input :password, :hint => 'No special characters.' %>
<%= f.input :remember_me, :as => :boolean %>
<%= f.button :submit %>
<% end -%>
There are plenty of things going on here: we create a form using simple_form_for
helper, then we use the :input
method to create input elements based on column type. For instance, :username
will create a default text input, while :password
attribute will render an input type password. For the :username
attribute, we are specifying a label manually. For :password
, the label will be taken from I18n, and we are adding a hint message to the field. For :remember_me
, we are explicitly saying to render it as a checkbox, using the :as => :boolean
option (that is the default for boolean attributes). Also, there is a button
helper that simply delegates to Rails helpers, in this case submit
.
The output for a new @user
would be:
<form action="/users" class="simple_form user" id="new_user" method="post">
<div class="input string required">
<label class="string required" for="user_username"><abbr title="required">*</abbr> Your username please</label>
<input class="string required" id="user_username" maxlength="255" name="user[username]" size="50" type="text" />
</div>
<div class="input password required">
<label class="password required" for="user_password"><abbr title="required">*</abbr> Password</label>
<input class="password required" id="user_password" name="user[password]" size="30" type="password" />
<span class="hint">No special characters.</span>
</div>
<div class="input boolean optional">
<label class="boolean optional" for="user_remember_me"> Remember me</label>
<input name="user[remember_me]" type="hidden" value="0" />
<input class="boolean optional" id="user_remember_me" name="user[remember_me]" type="checkbox" value="1" />
</div>
<input id="user_submit" name="commit" type="submit" value="Create User" />
</form>
You may have noticed there is some additional css classes added to the markup, like string
and required
. 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
: inside it there is an abbr
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
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
.
Furthermore, there is the hint
tag for the :password
attribute that SimpleForm creates based on the :hint
option we have defined. Also notice that the gem has automatically added a div
wrapper to each input, with the same css classes. SimpleForm allows us to configure this wrapper as well, using for instance p
instead of div
. We are going to see more about configuration later.
SimpleForm is already prepared to generate some of the new HTML 5 input tags, such as email
, url
and number
inputs:
<%= simple_form_for @user do |f| %>
<%= f.input :website, :as => :url %>
<%= f.input :email %>
<%= f.input :age, :hint => "This defaults to 'number' input based on field type" %>
<%= f.button :submit %>
<% end -%>
Based on the attribute name, SimpleForm will generate url
or email
input types, and we can always set a specific type with the :as
option. Numeric attributes will always be rendered as input type number.
Working with associations
SimpleForm adds a custom and straightforward method to render select tags for associations, called association
. For now, consider our User
belongs to a Company
, and has and belongs to many Roles
. Let’s go straight to the example:
<%= simple_form_for @user do |f| %>
<%= f.input :name %>
<%= f.association :company %>
<%= f.association :roles %>
<%= f.button :submit %>
<% end -%>
It will detect the association type and render a select
tag for choosing the company, listing all companies in the database, and another select
for roles, with multiple
option enabled.
SimpleForm also has some add-ons, letting us render associations as a collection of radios or check boxes. Using the same example:
f.association :company, :as => :radio
f.association :roles, :as => :check_boxes
Now we are rendering a collection of radios for choosing the Company
, and another collection of check boxes for choosing Roles
.
Configuration
SimpleForm lets us do some customizations by running its install generator:
rails generate simple_form:install
# Output
create config/initializers/simple_form.rb
create config/locales/simple_form.en.yml
create lib/templates/erb/scaffold/_form.html.erb
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?
Let’s take a look at some configuration options:
-
components: defines the components used by the form builder. We can remove any of them, change the order, or add new ones. Defaults to
[ :label, :input, :hint, :error ]
. -
hint_tag: tag used for hints, defaults to
span
. -
error_tag: tag used for errors, defaults to
span
. -
wrapper_tag: tag used as wrapper to all inputs, defaults to
div
-
label_text: determines how the label text should be generated altogether with the required text. It must be a lambda/proc that receives both label and required texts. Defaults to
"required label"
.
There are a lot more options available in the initializer file, such as default input size and priority countries for generating country selects. Also, the locale file lets us determine the required text and mark, or even the entire required html tag.
Internationalization
SimpleForm is ready for I18n, supporting labels
and hints
. In addition, it lets us set different content for each action, new
and edit
. Here is an example locale file:
en:
simple_form:
labels:
user:
username: 'User name'
password: 'Password'
edit:
username: 'Change user name'
password: 'Change password'
hints:
user:
username: 'User name to sign in.'
password: 'No special characters, please.'
Simple, right? If it does not find any specific translation using I18n for the label
, it will fallback to human_attribute_name
.
Here we go!
SimpleForm has much more to offer. We would like to invite you to take a better look at the examples and possibilities. Remember, SimpleForm aims to be flexible and powerful to help you easily build forms, without saying how you should create your markup.
Also, feel free to explore the source code and extend SimpleForm even further. Since it’s based on components, creating a new component which moves the current hints to inside the input (using javascript or the new placehoder attribute in HTML 5), should be easy!
It’s worth saying SimpleForm is Rails 3 compatible in the master branch. If you are using Rails 2.3.x, there is a v1.0 branch and version that you might want to take a look.
SimpleForm has been helping us a lot so far, we hope you enjoy it. Moreover, we would like to enjoy other tools that help your productivity day by day, please leave a comment and let us know, we would appreciate a lot!
ok..nice… but why use this instead of formtastic?
ok..nice… but why use this instead of formtastic?
Great work guys! I’m using this on project already and love it.
Great work guys! I’m using this on project already and love it.
@adam, one of the most important features in Formtastic is that it’s quite opinionated about your markup. Sometimes, we get the design straight from our client and we are not supposed to redesign the form markup, meaning we cannot use Formtastic (as said in the beginning of the text). So, if you need a more flexible solution, not opinionated on markup, I recommend you to use SimpleForm. But, if you are free to choose your markup and love Formtastic one, stick with it!
@adam, one of the most important features in Formtastic is that it’s quite opinionated about your markup. Sometimes, we get the design straight from our client and we are not supposed to redesign the form markup, meaning we cannot use Formtastic (as said in the beginning of the text). So, if you need a more flexible solution, not opinionated on markup, I recommend you to use SimpleForm. But, if you are free to choose your markup and love Formtastic one, stick with it!
Nice Plugin… good bye formtastic…
Nice Plugin… good bye formtastic…
@adam, I switched from Formtastic to SImpleForm for the markup reason that José said. But also because you can extend easily SimpleForm, it was rails 3 compatible a long time ago and I prefer the code. Reading the code is always a good thing to do before using a gem/plugin.
Opinionated response of course 🙂
@adam, I switched from Formtastic to SImpleForm for the markup reason that José said. But also because you can extend easily SimpleForm, it was rails 3 compatible a long time ago and I prefer the code. Reading the code is always a good thing to do before using a gem/plugin.
Opinionated response of course 🙂
Nice work! If you want to make it distinct from Formtastic though, I suggest you integrate show_form_for so the same partial could be used for both show and edit actions. Two obvious places to add it to the DSL would be either “” or “”, but I’m sure you’d come up with a better solution.
Nice work! If you want to make it distinct from Formtastic though, I suggest you integrate show_form_for so the same partial could be used for both show and edit actions. Two obvious places to add it to the DSL would be either “” or “”, but I’m sure you’d come up with a better solution.
Oops, the ERB got stripped, here’s the content of the empty “” above: “simple_form_for @user, false do |f|” or “f.show true”.
Oops, the ERB got stripped, here’s the content of the empty “” above: “simple_form_for @user, false do |f|” or “f.show true”.
@svoop if I remember this was already requested, but is not an easy deal. Actually I’m not sure how good it’d be, to put SimpleForm and ShowFor talking together, mostly because they have different options in the majority of their components.
If we integrate both libs, chances are people will need some sort of configuration to setup a specific option just for ShowFor or SimpleForm in that specific case, and it might turn them a bit harder to maintain.
Anyway, I haven’t tried that but if you have a small forms that are just :inputs or :associations, without any specific option, you could easily separate into a partial, as SimpleForm uses :attribute as an alias for :input, making the DSL pretty similar to ShowFor.
@svoop if I remember this was already requested, but is not an easy deal. Actually I’m not sure how good it’d be, to put SimpleForm and ShowFor talking together, mostly because they have different options in the majority of their components.
If we integrate both libs, chances are people will need some sort of configuration to setup a specific option just for ShowFor or SimpleForm in that specific case, and it might turn them a bit harder to maintain.
Anyway, I haven’t tried that but if you have a small forms that are just :inputs or :associations, without any specific option, you could easily separate into a partial, as SimpleForm uses :attribute as an alias for :input, making the DSL pretty similar to ShowFor.
Great work! Its nice to have flexible markup.
One question:
How SimpleForm deals with nested forms and ‘has many’ associations?
Great work! Its nice to have flexible markup.
One question:
How SimpleForm deals with nested forms and ‘has many’ associations?
Great work guys!
I wish I had a google group for discussing and learning to use this plugin.
I have a question, that I have tried to resolve with no luck:
How can I inject a “” tag after the label as the rails scaffold do.
I would like to have the same markup.
Great work guys!
I wish I had a google group for discussing and learning to use this plugin.
I have a question, that I have tried to resolve with no luck:
How can I inject a “” tag after the label as the rails scaffold do.
I would like to have the same markup.
…
How can I inject a “br” tag after the label as the rails scaffold do?
…
Sorry, The html tag was stripped in the prior message.
…
How can I inject a “br” tag after the label as the rails scaffold do?
…
Sorry, The html tag was stripped in the prior message.
Juanma, this is documented in the generated file. Just check this file.
You just need to give a proc with the behavior you wish. 🙂
Juanma, this is documented in the generated file. Just check this file.
You just need to give a proc with the behavior you wish. 🙂
Dudes… this is awesome. I tried Formtastic for a while and really didn’t like it ’cause it was so restricting. This makes a lot more sense. Definitely have to give this a try in my next app.
Dudes… this is awesome. I tried Formtastic for a while and really didn’t like it ’cause it was so restricting. This makes a lot more sense. Definitely have to give this a try in my next app.
Why do you use inline hints instead of “placeholder” attribute? Formtastic uses the same approach, so I guess there must be some reasoning behind this… 🙂
Why do you use inline hints instead of “placeholder” attribute? Formtastic uses the same approach, so I guess there must be some reasoning behind this… 🙂
Szymon, unfortunately not all browsers support placeholder yet, so we would need to depend on Javascript which I think is something we don’t want to do by default. In any case, changing SimpleForm to use placeholder instead of hint in your app should be piece of cake! 🙂
Szymon, unfortunately not all browsers support placeholder yet, so we would need to depend on Javascript which I think is something we don’t want to do by default. In any case, changing SimpleForm to use placeholder instead of hint in your app should be piece of cake! 🙂
I’m gonna try to use SimpleForm in my next project. How do I declare nested forms to deal with ‘has many’ associations with multiple fields?
Formtastic uses ‘semantic_fields_for’. Is there a similar option?
I’m gonna try to use SimpleForm in my next project. How do I declare nested forms to deal with ‘has many’ associations with multiple fields?
Formtastic uses ‘semantic_fields_for’. Is there a similar option?
@cncardoso yes, you can use simple_fields_for as well.
@cncardoso yes, you can use simple_fields_for as well.
How to translate submit label in simple_form yml?
How to translate submit label in simple_form yml?
@mican if you’re using SimpleForm in a Rails 3 app, the submit button has already been internationalized, so you can take a look there. For Rails 2.3.x apps, you can use the keys :create, :update and :submit under simple_form.buttons.
@mican if you’re using SimpleForm in a Rails 3 app, the submit button has already been internationalized, so you can take a look there. For Rails 2.3.x apps, you can use the keys :create, :update and :submit under simple_form.buttons.
testando disqus
Juanma, this is documented in the generated file. Just check this file.
You just need to give a proc with the behavior you wish. 🙂
Szymon, unfortunately not all browsers support placeholder yet, so we would need to depend on Javascript which I think is something we don't want to do by default. In any case, changing SimpleForm to use placeholder instead of hint in your app should be piece of cake! 🙂
@adam, one of the most important features in Formtastic is that it's quite opinionated about your markup. Sometimes, we get the design straight from our client and we are not supposed to redesign the form markup, meaning we cannot use Formtastic (as said in the beginning of the text). So, if you need a more flexible solution, not opinionated on markup, I recommend you to use SimpleForm. But, if you are free to choose your markup and love Formtastic one, stick with it!
How to use it with Haml?
This gem is really a gem! Thank you and keep up the good work 🙂
ok a newbe question – How do I create the controller for something like a simple website contact form?
In text_area how do I change cols = “40” –