#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)
Pochi mesi fa abbiamo trattato in un paio di episodi il gem Formtastic [guarda, leggi]. Questo plugin offre la possibilità di generare rapidamente il codice delle viste per le form in Rails. In questo episodio daremo un’occhiata ad un gem alternativo, chiamato SimpleForm. Come Formtastic, SimpleForm fornisce un modo più semplice per generare il codice delle viste rispetto allo standard Rails. Se conoscete già Formtastic, le chiamate ai metodi SimpleForm vi sembreranno familiari, dal momento che in effetti lo sono.
La domanda da un milione di dollari è, viste tutte queste analogie fra i due gem, perchè preferire SimpleForm a Formtastic? Una delle ragioni è che SimpleForm è più leggero. Non include un foglio di stile che si aspetta essere usato, ma si concentra esclusivamente sulla generazione del markup HTML. E’ anche più personalizzabile ed estendibile di Formtastic. Se avete usato Formtastic e vi è sembrato che vi condizionasse un po’ troppo a fare a modo suo e che vi forzasse ad usare del markup che non avreste voluto, allora vale la pena che esploriate anche SimpleForm.
Integrare SimpleForm in un’applicazione
Per dimostrare SimpleForm, aggiornaremo una form già scritta usando codice di vista standard di Rails. L’applicazione è una semplice applicazione di e-commerce con una serie di prodotti, ciascuno dei quali appartiene ad una categoria e la form che abbiamo intenzione di modificare è quella di creazione di un nuovo prodotto. Questa form ha una serie di diversi tipi di campo, per cui fungerà molto bene da esempio per convertire all’uso di SimpleForm.
Per usare SimpleForm dobbiamo per prima cosa aggiungere il gem al Gemfile
dell’applicazione:
gem "simple_form"
Poi, per assicurarci che venga installato tutto, dobbiamo lanciare:
$ bundle install
Ora che il gem è installato, dobbiamo lanciare un generatore che aggiunga all’applicazione un paio di file di cui ha bisogno SimpleForm:
$ 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
Questi file generati sono usati principalmente per la personalizzazione delle form e li esamineremo in dettaglio fra poco. Prima, però, aggiorneremo la form dei prodotti che attualmente appare così:
<%= 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 %>
Le due principali modifiche che dobbiamo fare alla form sono di sostituire form_for
con simple_form_for
e tutte le coppie label ed input con un unico metodo di 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 %>
Per la maggior parte dei control della form possiamo usare il metodo f.input
. Uno dei campi per il quale dobbiamo utilizzare qualcosa di diverso è il category
. Nella form originale questo campo usava collection_select
per renderizzare una tendina contenente tutte le categorie.
<%= f.collection_select :category_id, Category.all, :id, :name %>
Con SimpleForm possiamo sostituire tutto ciò con f.association
che fa la stessa cosa.
Possiamo ora ricaricare la form e vedere come viene mostrata da SimpleForm:
La form appare piuttosto diversa ora rispetto a prima, perchè non ha più lo stile che aveva in precedenza, ma è semplice rimediare adattando i nostri fogli di stile ai nomi delle classi usate da SimpleForm nelle sue form:
.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 usate SimpleForm nelle vostre applicazioni, dovrete personalizzare questi stili per adattarli all’aspetto della vostra applicazione, ma il CSS riportato qui sopra vi dà già un’idea circa i nomi delle classi usati dagli elementi HTML generati da SimpleForm. Sistemati gli stili, la nostra form ora appare migliore:
Campi personalizzati
Per i campi per i quali abbiamo usato f.input
, SimpleForm ha automaticamente capito il tipo della colonna e per questo vediamo che “Released on” è stato renderizzato come una colonna di tipo data mentre invece “Discontinued” come checkbox, dal momento che rappresenta una colonna booleana. In quanto associazione, il campo “Category” è stato renderizzato come tendina con l’opzione vuota. Se volessimo personalizzare questi campi, facendoli apparire in modo diverso, dovremmo aggiungere alcune option. Per esempio, possiamo rimuovere l’opzione vuota dalla tendina “Category”, aggiungendo l’opzione :include_blank
:
<%= f.association :category, :include_blank => false %>
La form originale aveva una tendina per il campo rating, ma ora ci troviamo un campo di testo. Possiamo ripristinare la tendina, usando l’opzione :collection
e passando ad essa un intervallo:
<%= f.input :rating, :collection => 1..5 %>
Se invece volessimo visualizzare la lista come radio button, potremmo usare l’opzione :as
:
<%= f.input :rating, :collection => 1..5, :as => :radio %>
Al ricaricamento della form, ora vedremo che l’opzione vuota è scomparsa dalla tendina e che il campo rating è mostrato come radio button.
Un’altra bella funzionalità di SimpleForm è il riconoscimento automatico dei campi obbligatori. Possiamo illustrarvi la cosa, rendendo obbligatori i campi name
e price
nel modello Product
:
class Product < ActiveRecord::Base attr_accessible :name, :price, :released_on, :category_id, :rating, :discontinued belongs_to :category validates_presence_of :name, :price end
E’ tutto ciò che dobbiamo fare. Al ricaricamento della form vedremo questi due campi contrassegnati da un asterisco e se provassimo a fare il submit della form senza averli compilati, vedremmo i messaggi di errore relativi:
Possiamo anche facilmente aggiungere un messaggio di suggerimento per ogni campo. Poniamo di voler dare un suggerimento che indichi che i prezzi si intendono in sterline. Dobbiamo solo aggiungere un’opzione :hint
al campo:
<%= f.input :price, :hint => "prices should be in UKP." %>
Ciò aggiungerà un suggerimento subito dopo il campo della form:
Ci sono ulteriori informazioni su tutte queste opzioni di campo nella documentazione di README di SimpleForm. Vale la pena dare un’occhiata anche alla documentazione di Formtastic, visto che molte delle opzione usate da quest’ultimo plugin possono essere usate anche da SimpleForm.
Personalizzazione di SimpleForm
Quando prima abbiamo lanciato il generatore di SimpleForm, sono stati creati tre file:
$ 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 volessimo personalizzare SimpleForm per tutta un’applicazione (non solo per una singola form), potremmo farlo cambiando uno o più di questi tre file. Il primo contiene una serie di opzioni di configurazione commentate che si possono sfruttare per le personalizzazioni. Per esempio, potremmo cambiare l’ordine in cui ciascun campo viene mostrato; potremmo modificare componente container per ogni campo di form, così come la dimensione di default del campo di testo. Vogliamo che i campi di testo della nostra applicazione siano più stretti, perciò cambiamo il valore di default da 50
a 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
Il secondo file generato è quello di I18n:
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.'
Anche se la vostra applicazione non ha bisogno di mostrarsi in più di una lingua, questo file resta comunque un punto pratico in cui modificare alcune delle opzioni di SimpleForm, come ad esempio il testo da mostrare in caso di errore su campi obbligatori.
L’ultimo file generato ridefinisce il partial della form per il generatore di 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 %>
In Rails 3 possiamo fare l’override di un qualunque template in un generatore, aggiungendolo alla nostra applicazione, per cui se volessimo personalizzare il modo in cui un generatore funziona per adeguarlo al modo in cui noi vogliamo che funzioni, potremmo farlo semplicemente creando un nuovo file di template.
E’ tutto per questo episodio. SimpleForm rende ancor più semplice la creazione di form nelle vostre applicazioni Rails e vale la pena esaminarlo.