#234 SimpleForm
- Download:
- source codeProject Files in Zip (108 KB)
- mp4Full Size H.264 Video (14.9 MB)
- m4vSmaller H.264 Video (9.32 MB)
- webmFull Size VP8 Video (22.4 MB)
- ogvFull Size Theora Video (20.5 MB)
Há alguns meses, dois episódios falaram sobre a gem Formtastic [assistir, ler]. Ela oferece uma maneira prática de gerar o código para exibir formulários em Rails. Nesse episódio vamos dar uma olhada em uma outra gem chamada SimpleForm. Assim como Formtastic, SimpleForm fornece uma maneira simples de gerar o código dos formulários nas views, se comparado com a maneira padrão do Rails. Se você conhece o Formtastic, então o SimpleForm vai parecer bem familiar, pois eles são realmente muito semelhantes.
A grande pergunta aqui é: dado que as gems são similares, porque você deveria escolher usar SimpleForm em vez de Formtastic? Um motivo é que o SimpleForm é mais leve. Ela é também mais customizável e extensível que o Formtastic. Se você usou o Formtastic e sente que ele se mete no seu caminho, então é bom dar uma olhada no SimpleForm.
Integrando SimpleForm em uma Aplicação
Para demonstrar o SimpleForm, vamos atualizar um formulário escrito usando o código padrão de views do Rails para usar o SimpleForm. A aplicação é um simples comércio eletrônico com um número de produtos, cada qual pertence a uma categora e o formulário que vamos modificar é o formulário de criação de um novo produto. Esse formulário tem diferentes tipos de campos e será um bom exemplo para usar o SimpleForm.
Para usar o SimpleForm, temos primeiro que adicionar a gem no Gemfile
da aplicação.
gem "simple_form"
E para termos certeza de que está instalada, precisamos executar:
$ bundle install
Agora que a gem está instalada, precisamos executar um generator
que adicionará uns poucos arquivos que o SimpleForm precisa dentro da nossa aplicação.
$ rails g simple_form:install <span class="passed">create</span> config/initializers/simple_form.rb <span class="passed">create</span> config/locales/simple_form.en.yml <span class="passed">create</span> lib/templates/erb/scaffold/_form.html.erb
Esses arquivos gerados são usados principalmente para customização e iremos dar uma olhada neles rapidamente. Antes, vamos atualizar o código do nosso formulário de cadastro de produtos que está assim:
<%= form_for @product do |f| %> <%= f.error_messages %> <p> <%= f.label :name %> <%= f.text_field :name %> </p> <p> <%= f.label :price %> <%= f.text_field :price %> </p> <p> <%= f.label :released_on %> <%= f.date_select :released_on %> </p> <p> <%= f.label :category_id %> <%= f.collection_select :category_id, Category.all, :id, :name %> </p> <p> <%= f.label :rating %> <%= f.select :rating, 1..5 %> </p> <p> <%= f.label :discontinued %> <%= f.check_box :discontinued %> </p> <p><%= f.submit %></p> <% end %>
As duas principais mudanças que precisamos fazer são substituir o form_for
pelo simple_form_for
e substituir cada par de labels e inputs com um dos métodos do SimpleForm.
<%= simple_form_for @product do |f| %> <%= f.error_messages %> <%= f.input :name %> <%= f.input :price %> <%= f.input :released_on %> <%= f.association :category %> <%= f.input :rating %> <%= f.input :discontinued %> <%= f.button :submit %> <% end %>
Para a maior parte dos controles no formulário, podemos usar o métodof.input
. Um campo onde precisamos usar algo diferente é o category
. No formulário original, esse campo usava collection_select
para renderizar um menu drop down contendo todas as categorias.
<%= f.collection_select :category_id, Category.all, :id, :name %>
Com o SimpleForm, podemos substituir por f.association
, que faz a mesma coisa.
Podemos recarregar o formulário e ver como ele está sendo renderizado pelo SimpleForm.
O formulário parece um pouco diferente agora pois não tem mais o estilo que tinha anteriormente. Mas é fácil alterar nosso css para adicionar alguns estilos e classes que o SimpleForm usa em seus formulários.
.simple_form label { float: left; width: 100px; text-align: right; margin: 2px 10px; } .simple_form div.input { margin-bottom: 10px; } .simple_form div.boolean, .simple_form input[type='submit'] { margin-left: 120px; } .simple_form div.boolean label { float: none; margin: 0; }
Quando você usar o SimpleForm em sua própria aplicação, vai querer customizar o estilo de acordo com o design da sua aplicação. O CSS acima vai te dar uma ideia de quais os nomes das classes usados nos elementos HTML que o SimpleForm gera. Com o estilo acima aplicado, nosso formulário parece um pouco melhor.
Personalizando Campos
Para os campos que usamos f.input
, o SimpleForm automaticamente detectou cada tipo de coluna, de modo que o campo "Released on" está renderizado como data e "Discontinued" está renderizado com um checkbox, pois ele representa uma coluna boolean
. Sendo uma associação, o campo "Category" foi renderizado como um menu drop down com uma opção em branco. Se você quiser customizar esse campo, pode fazer isso adicionando algumas opções. Por exemplo, podemos remover a opção em branco do "Category" adicionando a opção :include_blank
.
<%= f.association :category, :include_blank => false %>
O formulário original tem uma lista drop down para o campo rating, mas isso agora foi substituído por um campo texto. Podemos restaurar esse drop down usando a opção :collection
passando um range pra ela.
<%= f.input :rating, :collection => 1..5 %>
Se queremos a lista renderizada como radio buttons, podemos usar a opção :as
.
<%= f.input :rating, :collection => 1..5, :as => :radio %>
Quando recarregamos o formulário, vemos que a opção em branco não existe mais no menu drop down e que o campo rating foi renderizado como radio buttons.
Outra grande característica do SimpleForm é detectar automaticamente os campos obrigatórios. Podemos demonstrar isso fazendo os campos name
e price
obrigatórios no modelo Product
.
class Product < ActiveRecord::Base attr_accessible :name, :price, :released_on, :category_id, :rating, :discontinued belongs_to :category validates_presence_of :name, :price end
Isso é tudo que precisamos fazer. Quando recarregarmos o formulário, vamos ver esses campos marcados com asteríscos e se tentarmos submeter o formulário sem preencher esses campos, vamos ver uma mensagem de erro.
Podemos também adicionar um aviso para cada campo. Vamos supor que queremos informar que o preço deve ser dado em libras esterlinas. Só precisamos adicionar uma opção :hint
a esse campo.
<%= f.input :price, :hint => "prices should be in UKP." %>
Isso adicionará uma mensagem informativa depois do campo no formulário.
Há mais informações sobre as opções que podem ser usadas no README do SimpleForm. Vale a pena dar uma olhada no README do Formtastic também, pois muitas opções que ele usa também podem ser usadas pelo SimpleForm.
Personalizando o SimpleForm
Quando executamos o gerador do SimpleForm, ele criou três arquivos.
$ rails g simple_form:install <span class="passed">create</span> config/initializers/simple_form.rb <span class="passed">create</span> config/locales/simple_form.en.yml <span class="passed">create</span> lib/templates/erb/scaffold/_form.html.erb
Se quisermos customizar o SimpleForm em toda a aplicação, podemos modificar esses arquivos. O primeiro contém algumas opções comentadas e muitas configurações podem ser feitas aqui. Por exemplo, podemos alterar a ordem que cada campo é renderizado; podemos alterar a tag html que envolve cada campo e podemos alterar o tamanho padrão de cada campo de texto. Queremos campos de texto mais estreitos na nossa aplicação, então vamos alterar o valor padrão de 50
para 30
.
# Use this setup block to configure all options available in SimpleForm. SimpleForm.setup do |config| # Other options removed... # Default size for text inputs. config.default_input_size = 30 end
Outro arquivo que foi gerado, foi de idiomas e é onde podemos internacionalizar os formulários.
en: simple_form: "yes": 'Yes' "no": 'No' required: text: 'required' mark: '*' # You can uncomment the line below if you need to overwrite the whole required html. # When using html, text and mark won't be used. # html: '<abbr title="required">*</abbr>' error_notification: default_message: "Some errors were found, please take a look:" # Labels and hints examples # labels: # password: 'Password' # user: # new: # email: 'E-mail para efetuar o sign in.' # edit: # email: 'E-mail.' # hints: # username: 'User name to sign in.' # password: 'No special characters, please.'
Mesmo se a aplicação não precisa mostrar múltiplos idiomas esse arquivo ainda é útil para alterar alguns textos do SimpleForm, como o texto que é apresentado nos campos obrigatórios.
O último arquivo gerado sobrescreve o partial de formulários do gerador do scaffold.
<%%= simple_form_for(@<%= singular_name %>) do |f| %> <%% if @<%= singular_name %>.errors.any? %> <div id="error_explanation"> <h2><%%= pluralize(@<%= singular_name %>.errors.count, "error") %> prohibited this <%= singular_name %> from being saved:</h2> <ul> <%% @<%= singular_name %>.errors.full_messages.each do |msg| %> <li><%%= msg %></li> <%% end %> </ul> </div> <%% end %> <div class="inputs"> <%- attributes.each do |attribute| -%> <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %> <%- end -%> </div> <div class="actions"> <%%= f.button :submit %> </div> <%% end %>
No Rails 3, podemos sobrescrever qualquer arquivo template de um generator
adicionando em nossa aplicação. Então se quisermos customizar o jeito que um generator funciona, para atender a nossa forma de trabalho, podemos simplesmente criar um novo arquivo template.
Por esse episódio é só. O SimpleForm torna fácil criar formulários em suas aplicações Rails e vale muito a pena dar uma olhada nele.