#184 Formtastic Part 1
- Download:
- source codeProject Files in Zip (104 KB)
- mp4Full Size H.264 Video (14.7 MB)
- m4vSmaller H.264 Video (10.3 MB)
- webmFull Size VP8 Video (24.9 MB)
- ogvFull Size Theora Video (19.1 MB)
184: Formtastic Bölüm 1 (orijinal Railscast bölümünü görüntüle)
Formların view kodunu yazmayı uzun ve sıkıcı buluyorsanız, bunu yapmak için daha kısa bir yol sağlayan Formtastic adlı bir gem’in olduğunu öğrenmek sizi sevindirecektir. Bununla, bu bölümde göstereceğimiz gibi nispeten ufak bir kodla oldukça karmaşık formlar oluşturulabiliyor.
Veteriner Uygulamasını Oluşturma
Formtastic’e başlamadan önce, kullanabileceğiniz bir TextMate paketinden bahsetmek yerinde olacaktır. Bu paket, form oluşturmayı daha da kolaylaştırabilecek birçok yararlı kod parçacığı sağlamaktadır.
Formtastic’i tanıtmak için yeni bir Rails uygulaması oluşturacağız. Bu uygulama bir veterinerin ameliyathanesindeki hasta hayvanların takibini yapacak, bu yüzden ona vet
adını veriyoruz ve normal yolla uygulamayı oluşturuyoruz.
<p>Formtastic bir gem olarak sağlanmaktadır. Uygulamamızın <code>/config/environment.rb</code> dosyasına aşağıdaki satırı ekleyerek onu uygulamamıza dahil edebiliriz. (TextMate kullanıyorsanız ve Formtastic paketini yüklediyseniz <code>ftgem</code> ve <code><TAB></code> tuşlarını kısayol olarak kullanabilirsiniz).</p> ``` ruby config.gem 'justinfrench-formtastic', :lib => 'formtastic', :source => 'http://gems.github.com'
Gem’in yüklendiğinden emin olmak için şu komutu çalıştırmamız yeterlidir:
``` terminal sudo rake gems:install<p>Böylece uygulamamızı yazmaya başlamak için hazırız.</p> <p>Uygulamamızın parçalarını yazmayı kolaylaştırmak için, Ryan Bates’in <a href="http://github.com/ryanb/nifty-generators">nifty oluşturucularının</a> bazılarından yararlanacağız. İlk önce <code>nifty_layout</code> oluşturucusunu kullanarak bir yerleşim (layout) dosyası ve bir stil sayfası oluşturacağız.</p> ``` terminal script/generate nifty_layout
Daha sonra, nifty_scaffold
oluşturucusundan yararlanarak ilk model’imizi ve ona eşlik edecek bir controller’ı ve view’ları oluşturacağız. Hayvanlarımızı kategorilere göre ayıracağız, bu nedenle model’imize Category
adını vereceğiz ve name
ile description
öğeleri ekleyeceğiz.
<p>Şimdi veritabanımızın geçişini yapabiliriz.</p> ``` terminal rake db:migrate
Yeni uygulamamızı başlatır ve yeni kategori sayfasına gidersek scaffold (iskelet oluşturma sistemi) tarafından oluşturulan view kodunu göreceğiz.
Scaffold tarafından yukarıdaki form için oluşturulan kod aşağıdaki gibidir:
``` ruby <% form_for @category do |f| %> <%= f.error_messages %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :description %>
<%= f.text_area :description, :rows => 5 %>
<%= f.submit "Submit" %>
<% end %><p>Bu normal Rails form kodudur; bir <code>form_for</code> ile başlar ve formdaki her alan kendi etiketiyle birlikte ayrı ayrı tanımlanır. En sonda, yeni bir kategori eklememizi sağlayan bir gönder düğmesi bulunmaktadır.</p> <p>Formtastic bu standart form metodlarının hiçbirini geçersiz kılmaz, böylece bunları bir Formtastic formunda da kullanabiliriz. Yukarıdaki formda bulunan <code>form_for</code> öğesini Formtastic’in <code>semantic_form_for</code> öğesiyle değiştirseydik form hala aynı şekilde çalışırdı. Ama bunu yapmak anlamsız olurdu, çünkü asıl kolaylık Formtastic’in form metodlarını kullandığımızda ortaya çıkar. Onları kullanarak, formumuzu aşağıdaki gibi yapabiliriz:</p> ``` ruby <% semantic_form_for @category do |f| %> <%= f.inputs %> <%= f.buttons %> <% end %>
inputs
metodu bir model’in tüm giriş alanlarını oluşturmak için kullanışlı bir yoldur ve aynı şekilde buttons
metodu bir gönder düğmesi oluşturur. Formu şimdi yeniden yüklersek biraz farklı görünecektir.
Bu form artık Formtastic’in metodları kullanılarak gösterilmektedir. İlk görülen farklılık; scaffold’un oluşturduğu formda alanların arasında paragraf etiketleri kullanılırken, Formtastic’in giriş alanlarını düğmeden ayırmak için sıralı listeleri ve fieldset etiketlerini kullanmasıdır.
Form şu andaki haliyle pek güzel görünmüyor, ancak biraz CSS uygulayarak bunu halledebiliriz. Formtastic, bu işi kendi kendimize yapmak zorunda kalmamak için kullanabileceğimiz bazı stil sayfalarıyla birlikte gelir. Şunu çalıştırırsak:
``` terminal script/generate formtastic_stylesheets<p>uygulamamızın <code>/public/stylesheets</code> dizininde iki yeni stil sayfası oluşturulur ve ardından bu stil sayfalarını yerleşim dosyamıza ekleyebiliriz. Yerleşimimizin "head" bölümünde zaten bir stil sayfasını eklemiş durumdayız.</p> ``` ruby <head> <title><%= h(yield(:title) || "Untitled") %></title> <%= stylesheet_link_tag 'application' %> <%= yield(:head) %> </head>
Formtastic stil sayfalarını buraya ekleyerek onları uygulamamızdaki her sayfaya dahil edebiliriz.
``` ruby <%= stylesheet_link_tag 'application', 'formtastic', 'formtastic-changes' %><p>İkinci dosya, <code>formtastic-changes</code>, diğer stil sayfasındaki varsayılan stillerde yapmak istediğimiz değişiklikleri yapmamız gereken yerdir. Artık birden çok stil sayfamız olduğu için, Rails’in önbelleğe alma seçeneğinden yararlanmalıyız. Böylece uygulama production (üretim) modunda çalıştırıldığında dosyalar tek bir dosyada birleştirilir. (Bu birden çok JavaScript dosyası için de geçerlidir.)</p> ``` ruby <%= stylesheet_link_tag 'application', 'formtastic', 'formtastic-changes', :cache => 'base' %>
Önbelleğe almayı bu şekilde kullanmak; üç stil sayfası dosyası base.css
adlı bir dosyada birleştirileceğinden, sayfa yüklenirken daha az sayıda dosyanın sunucudan isteneceği anlamına gelir.
Şimdi formu yeniden yüklersek biraz daha iyi görünecektir, ancak hala görünmesi gerektiği gibi değil.
Bu, Formtastic’in stil sayfasındaki birkaç satır nedeniyledir.
``` terminal html[xmlns] form.formtastic fieldset { display: block; } html[xmlns] form.formtastic fieldset ol li { display: block; }<p>Yukarıdaki iki CSS seçicisi (selector) sayfaların açılış <code><html></code> etiketinin bir <code>xmlns</code> özniteliğine sahip olmasını beklemektedir. nifty_layout oluşturucusu tarafından oluşturulan yerleşim dosyasındaki etikette bu yoktur, bu nedenle formun olması gerektiği gibi görünmesi için bunu eklememiz gerekecektir.</p> ``` terminal <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
Şimdi formu yeniden yüklediğimizde metin kutularının beklediğimiz gibi hizalandığını görebiliriz. Formun olması gerektiği gibi görünmesini sağladığımıza göre, köpekler için bir tane ve kediler için bir tane olmak üzere bir çift kategori ekleyebiliriz. Bunları birazdan hayvanların kendileri için formu oluştururken kullanacağız.
Daha Karmaşık Bir Örnek
Şimdi hayvanlar için olan formla devam edeceğiz. Kategorilerde yaptığımız gibi bir scaffold oluşturarak başlayacağız.
``` terminal script/generate nifty_scaffold animal name:string category_id:integer born_on:date female:boolean<p><code>Animal</code> model’inde <code>name</code>, <code>born_on</code> ve <code>female</code> öğelerinin yanısıra bir <code>category_id</code> olacak, böylece her hayvanı bir <code>Category</code> içine yerleştirebileceğiz. Scaffold’u oluşturduktan sonra, yeni tablonun veritabanında oluşturulması için veritabanımızın geçişini yapacağız.</p> ``` terminal rake db:migrate
Sonraki adım model’ler arasındaki ilişkiyi kurarak bir hayvanın bir kategoriye ait olmasını…
``` ruby class Animal < ActiveRecord::Base attr_accessible :name, :category_id, :born_on, :female belongs_to :category end<p>…ve bir kategoride birden fazla hayvan olmasını sağlamak.</p> ``` ruby class Category < ActiveRecord::Base attr_accessible :name, :description has_many :animals end
Scaffold tarafından oluşturulan form aşağıda gösteriliyor. Bunu biraz Formtastic koduyla değiştirmek istiyoruz.
Kategori formunda yaptığımız gibi varsayılan form_for
kodunu bir Formtastic semantic_form_for
formuyla değiştireceğiz.
<p>Az sonra form alanlarımızı özelleştireceğimiz için bu defa onların üzerinde biraz daha fazla kontrolümüzün olmasını istiyoruz. Bu nedenle <code>f.inputs</code> metoduna, alanları birer birer tanımlamak için <code>input</code> metodunu kullandığımız bir blok parametresi verdik. Bloğu kapattıktan sonra önceden yaptığımız gibi <code>f.buttons</code> metodunu kullanarak gönder düğmesini ekleyebiliriz.</p> <p>Formu şimdi yeniden yüklersek Formtastic tarafından oluşturulan alanları görürüz.</p> <div class="imageWrapper"> <img src="http://railscasts.com/static/episodes/asciicasts/E184I06.png" alt="Formtastic kontrolleri içeren Yeni Hayvan sayfası." height="477" width="801"/> </div> <p>Formtastic, <code>Animal</code> model’inin özelliklerinin veri türlerine bağlı olarak uygun form alanlarını oluşturdu. Burada göremiyor olsanız da, <code>category_id</code> alanının bir ilişki olduğunu anlayıp kategori açılır kutusunu önceden eklediğimiz iki kategoriyle doldurdu bile.</p> <p>Bu formda yapmak istediğimiz birkaç değişiklik var. Varsayılan olarak, tarih alanının yıl kısmı şu anki yılın 5 yıl öncesiyle 5 yıl sonrasının arasındakileri içeriyor. Bizimse bundan daha önceki yılları göstermemiz gerekiyor. Ayrıca, <code>category</code> açılır kutusundan boş seçeneği kaldırmak ve <code>female</code> alanını bir onay kutusu yerine bir çift radyo düğmesi olarak göstermek istiyoruz.</p> <p>Rails’in form yardımcı metodlarına verdiğimiz seçeneklerin aynılarını kullanarak alanları özelleştirebiliriz. Yani, <code>born_on</code> alanına <code>:start_year</code> parametresi verebilir ve kategorimizdeki boş seçeneği kaldırmak için<code>:include_blank => false</code> parametresini kullanabiliriz.</p> ``` ruby <% semantic_form_for @animal do |f| %> <% f.inputs do %> <%= f.input :name %> <%= f.input :born_on, :start_year => 1900 %> <%= f.input :category, :include_blank => false %> <%= f.input :female, :as => :radio %> <% end %> <%= f.buttons %> <% end %>
female
form öğesinin türünü değiştireceğimiz için, bu alana biraz farklı
davranmamız gerekiyor. Varsayılandan farklı bir alan türü belirtmek
için, Formtastic’in bir
:as
parametresi bulunuyor. Türü radyo düğmesine çevirmek için :as => :radio
parametresini kullanabiliriz.
Forma şimdi yeniden göz atarsak, yaptığımız değişikliklerin yansıtıldığını; tarihlerin 1900’den başladığını, kategoriden boş seçeneğin kaldırıldığını ve cinsiyet onay kutusunun iki radyo düğmesiyle değiştirildiğini göreceğiz.
Radyo
düğmeleri onay kutusuna göre daha iyi oldu, ancak “yes” (evet) ve “no”
(hayır) yazması yerine, alanın etiketinin “Gender” (Cinsiyet) olmasını
ve radyo düğmelerinin “Male” (Erkek) ve “Female” (Dişi) olarak
etiketlendirilmesini istiyoruz. Formtastic bu derecede bir
özelleştirmeye izin veriyor mu? Evet, izin veriyor. Etiketin ve radyo
düğmelerinin değerlerini belirlemek için :label
(etiket) ve :collection
(koleksiyon) seçeneklerini kullanabiliriz.
Adından anlaşılacağı gibi, :label
seçeneği etiketin adını belirlerken, :collection
seçeneği her bir radyo düğmesinin adını ve değerini belirten, dizilerden oluşan bir diziyi parametre olarak alır.
Form artık tam istediğimiz gibi görünüyor.
Formumuz artık tamamlandı ve istediğimiz kadar yeni hayvan oluşturmak için onu kullanabiliriz.
Sonraki Adımlar
Formtastic’le birlikte nispeten daha az view koduyla oldukça karmaşık bir formu başarıyla oluşturduk, özelleştirme seçeneklerini kullanarak bazı alanları ihtiyacımıza göre değiştirdik. Yine de hala işlemediğimiz Formtastic özellikleri olduğundan, bir sonraki bölümde daha ayrıntıya gireceğiz.