Ror lab. season 2
   - the 14th round -



  Action View
Form Helpers -2
    January 12th, 2013

     Hyoseong Choi
Special Select
• time_zone_select
  : time_zone_options_for_select
• country_select
  : isolated to country_select plugin
• select_date : barebones helper
• date_select : model object helper
Time Zones
time_zone_select
                                                      model select
                                          attribute
                 <%= f.time_zone_select :time_zone,
priority_zones




                 [ ActiveSupport::TimeZone['Seoul'],
                 ActiveSupport::TimeZone['Tokyo'],ActiveSupport::TimeZ
                 one['Beijing'] ], :default => "Seoul" %>
time_zone_options_for_select
                                      bare-bones select

                      attribute
  <%= form_tag do %>                  selected
    <%= select_tag :time_zone,
          time_zone_options_for_select(nil,
              [




                                                     priority_zones
                ActiveSupport::TimeZone['Seoul'],
                ActiveSupport::TimeZone['Tokyo'],
                ActiveSupport::TimeZone['Beijing']
              ]
         ),
         :default => "Seoul" %>
  <% end %>
country_select
   • gem ‘country_select’
 <%= form_for(@person) do |f| %>
   <div class="field">
     <%= f.label :country %><br />
     <%= f.country_select :country,
             ["Korea, Republic of"] %>
   </div>
                           priority_countries
   <div class="actions">
     <%= f.submit %>
   </div>
 <% end %>




https://github.com/rails/country_select/blob/master/
lib/country_select.rb
select_date
<%= select_date Date.today, :prefix => :start_date %>




<select id="start_date_year"
        name="start_date[year]"> ... </select>
<select id="start_date_month"
        name="start_date[month]"> ... </select>
<select id="start_date_day"
        name="start_date[day]"> ... </select>




Date.civil(params[:start_date][:year].to_i,
params[:start_date][:month].to_i, params[:start_date]
[:day].to_i)
Individual Selects
• select_year
• select_month
• select_day      :prefix defaults to “date”
• select_hour
• select_minute
• select_second
cf. select_date
date_select
<%= date_select :person, :birth_date %>




<select id="person_birth_date_1i"
        name="person[birth_date(1i)]"> ... </select>
<select id="person_birth_date_2i"
        name="person[birth_date(2i)]"> ... </select>
<select id="person_birth_date_3i"
        name="person[birth_date(3i)]"> ... </select>




{:person => {'birth_date(1i)' => '2008',
'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}
Uploading Files
params[:picture]
 <%= form_tag({:action => :upload}, :multipart =>
 true) do %>
   <%= file_field_tag 'picture' %>
 <% end %>
  
 <%= form_for @person, :multipart => true do |f| %>
   <%= f.file_field :picture %>
 <% end %>

params[:person][:picture]
Since Rails 3.1, it automatically sets the multipart/
form-data with file_field in the form_for
What gets
           uploaded
def upload
  uploaded_io = params[:person][:picture]
  uploaded_io
  File.open(Rails.root.join('public', 'uploads',
uploaded_io.original_filename), 'w') do |file|
    file.write(uploaded_io.read)
  end                             wb
end




an instance of a subclass of IO
   • original_filename
   • content_type : MIME type
UploadedFile
               CLASS ActionDispatch::Http::UploadedFile




"uploaded_file"=>
#<ActionDispatch::Http::UploadedFile:0x007fd288c8fed0
  @original_filename="korean_flag.png",
  @content_type="image/png",
  @headers="Content-Disposition: form-data; name="person[uploaded]";
filename="korean_flag.png"rnContent-Type: image/pngrn",
  @tempfile=
    #<File:/var/folders/rv/q26ztr693k5_58wbggd_jl300000gn/T/
RackMultipart20130107-90570-18x3nfy>
>
Upload Gems
• System Requirement : ImageMagick
• CarrierWave,
 • more flexiable than Paperclip
 • Rmagick gem, required!
• Paperclip
Ajaxing Upload

• “remotipart” gem
  : AJAX style file uploads with jQuery

  https://github.com/leppert/remotipart
Customizing Form
            Builders                                                                   Pro



  using
 helper       <%= form_for @person do |f| %>
 method         <%= text_field_with_label f, :first_name %>
              <% end %>

    or
                <%= form_for @person, :builder => LabellingFormBuilder do |
                f| %>
   using
                  <%= f.text_field :first_name %>
subclassing     <% end %>



                class LabellingFormBuilder <
                ActionView::Helpers::FormBuilder
                  def text_field(attribute, options={})
                    label(attribute) + super
                  end
                end
                                         app/form_builders/labelling_form_builder.rb
Simple_form



•   https://github.com/plataformatec/simple_form
•   with Twitter Boostrap
•   with Foundation 3
Params Naming
  Client           Server

    Form
for model obj
                params[:person]
 “@person”

   submit
Basic Structures
               Arrays & Hashes

<input id="person_name" name="person[name]"

      type="text" value="Henry"/>


params hash
      {‘person’ => {‘name’ => ‘Henry’}}

params[:person]
       {‘name’ => ‘Henry’}

params[:person][:name]
       ‘Henry’
Nested Hashes
<input id="person_address_city"
      name="person[address][city]"
      type="text" value="New York"/>



params hash
      {'person' => {'address' => {'city' => 'New York'}}}
Duplicated Params
                                 array


 <input name="person[phone_number][]" type="text"/>
 <input name="person[phone_number][]" type="text"/>
 <input name="person[phone_number][]" type="text"/>




params[:person][:phone_number]
array        [
                    ’02-333-1234’,
                    ‘031-323-9898’,
                    ‘062-546-2323’
                ]
hash & array


   Mixed Params
   hash nth-nested but array only one-level

<input name="addresses[][line1]" type="text"/>
<input name="addresses[][line2]" type="text"/>
<input name="addresses[][city]" type="text"/>




params[:addresses]             array

                                       hash
      [
          {
              ‘line1’ => ’02-333-1234’,
              ‘line2’ => ‘031-323-9898’,
              ‘city’ => ‘seoul’
          }
      ]
Using Form
             Helpers
<%= form_for @person do |person_form| %>
  <%= person_form.text_field :name %>             address.id
  <% @person.addresses.each do |address| %>
    <%= person_form.fields_for address, :index => address do
|address_form|%>
      <%= address_form.text_field :city %>
    <% end %>
  <% end %>
<% end %>



<form accept-charset="UTF-8" action="/people/1" class="edit_person"
id="edit_person_1" method="post">
  <input id="person_name" name="person[name]" size="30" type="text" />
  <input id="person_address_23_city" name="person[address][23][city]" size="30"
type="text" />
  <input id="person_address_45_city" name="person[address][45][city]" size="30"
type="text" />
</form>
Using Form
         Helpers
params

{
    'person' =>
    {
       'name' =>   'Bob',
       'address'   =>
       {
         '23' =>   {'city' => 'Paris'},
         '45' =>   {'city' => 'London'}
       }
    }
}
Using :index
     <%= fields_for 'person[address][primary]',
     address, :index => address do |address_form| %>
       <%= address_form.text_field :city %>
     <% end %>
or
     <%= fields_for 'person[address][primary][]', address
     do |address_form| %>
       <%= address_form.text_field :city %>
     <% end %>



     <input id="person_address_primary_1_city"
     name="person[address][primary][1][city]" type="text"
     value="bologna" />
Form to External
  Resources - 1
form_tag

 <%= form_tag 'http://farfar.away/
 form', :authenticity_token => 'external_token') do %>
   Form contents
 <% end %>



 <%= form_tag 'http://farfar.away/
                               false
 form', :authenticity_token => false) do %>
   Form contents
 <% end %>                 payment gateway
Form to External
  Resources - 2
form_for

 <%= form_for @invoice, :url =>
 external_url, :authenticity_token => 'external_token'
 do |f|
   Form contents
 <% end %>



 <%= form_for @invoice, :url =>
 external_url, :authenticity_token => false do |f|
   Form contents
 <% end %>
Complex forms
ROR Lab. screencasts
Railscasts by Ryan Bates
•   Complex Forms Part 1 - Episode #73

•   Complex Forms Part II - Episode #74

•   Complex Forms Part III - Episode #75

•   Nested Model Form (revised) - Episode #196
감사합니다.

Action View Form Helpers - 2, Season 2

  • 1.
    Ror lab. season2 - the 14th round - Action View Form Helpers -2 January 12th, 2013 Hyoseong Choi
  • 2.
    Special Select • time_zone_select : time_zone_options_for_select • country_select : isolated to country_select plugin • select_date : barebones helper • date_select : model object helper
  • 3.
  • 4.
    time_zone_select model select attribute <%= f.time_zone_select :time_zone, priority_zones [ ActiveSupport::TimeZone['Seoul'], ActiveSupport::TimeZone['Tokyo'],ActiveSupport::TimeZ one['Beijing'] ], :default => "Seoul" %>
  • 5.
    time_zone_options_for_select bare-bones select attribute <%= form_tag do %> selected <%= select_tag :time_zone, time_zone_options_for_select(nil, [ priority_zones ActiveSupport::TimeZone['Seoul'], ActiveSupport::TimeZone['Tokyo'], ActiveSupport::TimeZone['Beijing'] ] ), :default => "Seoul" %> <% end %>
  • 6.
    country_select • gem ‘country_select’ <%= form_for(@person) do |f| %> <div class="field"> <%= f.label :country %><br /> <%= f.country_select :country, ["Korea, Republic of"] %> </div> priority_countries <div class="actions"> <%= f.submit %> </div> <% end %> https://github.com/rails/country_select/blob/master/ lib/country_select.rb
  • 7.
    select_date <%= select_date Date.today,:prefix => :start_date %> <select id="start_date_year" name="start_date[year]"> ... </select> <select id="start_date_month" name="start_date[month]"> ... </select> <select id="start_date_day" name="start_date[day]"> ... </select> Date.civil(params[:start_date][:year].to_i, params[:start_date][:month].to_i, params[:start_date] [:day].to_i)
  • 8.
    Individual Selects • select_year •select_month • select_day :prefix defaults to “date” • select_hour • select_minute • select_second cf. select_date
  • 9.
    date_select <%= date_select :person,:birth_date %> <select id="person_birth_date_1i" name="person[birth_date(1i)]"> ... </select> <select id="person_birth_date_2i" name="person[birth_date(2i)]"> ... </select> <select id="person_birth_date_3i" name="person[birth_date(3i)]"> ... </select> {:person => {'birth_date(1i)' => '2008', 'birth_date(2i)' => '11', 'birth_date(3i)' => '22'}}
  • 10.
    Uploading Files params[:picture] <%=form_tag({:action => :upload}, :multipart => true) do %>   <%= file_field_tag 'picture' %> <% end %>   <%= form_for @person, :multipart => true do |f| %>   <%= f.file_field :picture %> <% end %> params[:person][:picture] Since Rails 3.1, it automatically sets the multipart/ form-data with file_field in the form_for
  • 11.
    What gets uploaded def upload   uploaded_io = params[:person][:picture] uploaded_io   File.open(Rails.root.join('public', 'uploads', uploaded_io.original_filename), 'w') do |file|     file.write(uploaded_io.read)   end wb end an instance of a subclass of IO • original_filename • content_type : MIME type
  • 12.
    UploadedFile CLASS ActionDispatch::Http::UploadedFile "uploaded_file"=> #<ActionDispatch::Http::UploadedFile:0x007fd288c8fed0 @original_filename="korean_flag.png", @content_type="image/png", @headers="Content-Disposition: form-data; name="person[uploaded]"; filename="korean_flag.png"rnContent-Type: image/pngrn", @tempfile= #<File:/var/folders/rv/q26ztr693k5_58wbggd_jl300000gn/T/ RackMultipart20130107-90570-18x3nfy> >
  • 13.
    Upload Gems • SystemRequirement : ImageMagick • CarrierWave, • more flexiable than Paperclip • Rmagick gem, required! • Paperclip
  • 14.
    Ajaxing Upload • “remotipart”gem : AJAX style file uploads with jQuery https://github.com/leppert/remotipart
  • 15.
    Customizing Form Builders Pro using helper <%= form_for @person do |f| %> method   <%= text_field_with_label f, :first_name %> <% end %> or <%= form_for @person, :builder => LabellingFormBuilder do | f| %> using   <%= f.text_field :first_name %> subclassing <% end %> class LabellingFormBuilder < ActionView::Helpers::FormBuilder   def text_field(attribute, options={})     label(attribute) + super   end end app/form_builders/labelling_form_builder.rb
  • 16.
    Simple_form • https://github.com/plataformatec/simple_form • with Twitter Boostrap • with Foundation 3
  • 17.
    Params Naming Client Server Form for model obj params[:person] “@person” submit
  • 18.
    Basic Structures Arrays & Hashes <input id="person_name" name="person[name]" type="text" value="Henry"/> params hash {‘person’ => {‘name’ => ‘Henry’}} params[:person] {‘name’ => ‘Henry’} params[:person][:name] ‘Henry’
  • 19.
    Nested Hashes <input id="person_address_city" name="person[address][city]" type="text" value="New York"/> params hash {'person' => {'address' => {'city' => 'New York'}}}
  • 20.
    Duplicated Params array <input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/> <input name="person[phone_number][]" type="text"/> params[:person][:phone_number] array [ ’02-333-1234’, ‘031-323-9898’, ‘062-546-2323’ ]
  • 21.
    hash & array Mixed Params hash nth-nested but array only one-level <input name="addresses[][line1]" type="text"/> <input name="addresses[][line2]" type="text"/> <input name="addresses[][city]" type="text"/> params[:addresses] array hash [ { ‘line1’ => ’02-333-1234’, ‘line2’ => ‘031-323-9898’, ‘city’ => ‘seoul’ } ]
  • 22.
    Using Form Helpers <%= form_for @person do |person_form| %>   <%= person_form.text_field :name %> address.id   <% @person.addresses.each do |address| %>     <%= person_form.fields_for address, :index => address do |address_form|%>       <%= address_form.text_field :city %>     <% end %>   <% end %> <% end %> <form accept-charset="UTF-8" action="/people/1" class="edit_person" id="edit_person_1" method="post">   <input id="person_name" name="person[name]" size="30" type="text" />   <input id="person_address_23_city" name="person[address][23][city]" size="30" type="text" />   <input id="person_address_45_city" name="person[address][45][city]" size="30" type="text" /> </form>
  • 23.
    Using Form Helpers params { 'person' => { 'name' => 'Bob', 'address' => { '23' => {'city' => 'Paris'}, '45' => {'city' => 'London'} } } }
  • 24.
    Using :index <%= fields_for 'person[address][primary]', address, :index => address do |address_form| %>   <%= address_form.text_field :city %> <% end %> or <%= fields_for 'person[address][primary][]', address do |address_form| %>   <%= address_form.text_field :city %> <% end %> <input id="person_address_primary_1_city" name="person[address][primary][1][city]" type="text" value="bologna" />
  • 25.
    Form to External Resources - 1 form_tag <%= form_tag 'http://farfar.away/ form', :authenticity_token => 'external_token') do %>   Form contents <% end %> <%= form_tag 'http://farfar.away/ false form', :authenticity_token => false) do %>   Form contents <% end %> payment gateway
  • 26.
    Form to External Resources - 2 form_for <%= form_for @invoice, :url => external_url, :authenticity_token => 'external_token' do |f|   Form contents <% end %> <%= form_for @invoice, :url => external_url, :authenticity_token => false do |f|   Form contents <% end %>
  • 27.
    Complex forms ROR Lab.screencasts Railscasts by Ryan Bates • Complex Forms Part 1 - Episode #73 • Complex Forms Part II - Episode #74 • Complex Forms Part III - Episode #75 • Nested Model Form (revised) - Episode #196
  • 28.
  • 29.
      ROR Lab.