valibuk.net

A place for opinions and notes of a valibuk.

Form Helpers for Collection in One Form

Tagged with: — ondrej at 2:37 am on Sunday, August 6, 2006

Ruby on RailsA usage of form helpers for a single record is easy and straightforward. But how to use them for a collection of records in one form?

Do we need to edit a collection of records in one form? Well, there is always an option to let a user to edit records one by one, and we should use this option if the structure of a record is complex, e.g. a lot of items. If the structure is simple or we use a subset of a complex structure, we can allow a user to edit more records in one form. A good examples are labels of photos in a photo album, description and price for items in a web shop, etc.

If a form helper is used for a collection, it is necessary to add an index to its id. For example:

  • the id of a form element for a single record

    book[author]

  • the id of a form element for a collection of records

    book[1][author]

    that is a book with the primary key 1 and its field author.

Unfortunately, there is no united way how to add an index for all form helpers. In the following list I will show how a form helper is used for a single record and then how it is necessary to use it for a collection of records.
In the examples below I assume there is a Book model with fields such as label, published_on, note and one has_one author relationship to an Author model.

text_field

Single Record

  1. <%= text_field ‘book’, ‘label’ %>

Collection of Records

It is very easy to set an index value for the helper. It is necessary to add the :index attribute to the (third) options parameter:

  1. <%= text_field ‘book’, ‘label’, :index => @book.id %>

text_area

Single Record

  1. <%= text_area ‘book’, ‘note’ %>

Collection of Records

Similarly as for the text_field form helper, it is easy — just to add the :index attribute.

  1. <%= text_area ‘book’, ‘note’, :index => @book.id %>

select

Single Record

  1. <%= select ‘book’, ‘author_id’, @authors %>

with a blank value:

  1. <%= select ‘book’, ‘author_id’, @authors, :include_blank => true %>

Collection of Records

For the helper it is necessary to add the :index attribute, but it is tricky. The helper is defined as:

  1. select(object, method, choices, options = {}, html_options = {})

The :index attribute is accepted only in the (fourth) html_options parameter, so we have to explicitly say that by adding an empty or a non empty set as the (third) options parameter.

  1. <%= select ‘book’, ‘author_id’, @authors, {}, :index => @book.id %>

with a blank value:

  1. <%= select ‘book’, ‘author_id’, @authors, {:include_blank => true}, :index => @book.id %>

select_date, select_time and select_datetime

Single Record

  1. <%= select_date ‘book’, ‘published_on’ %>

with a blank value:

  1. <%= select_date ‘book’, ‘published_on’, :include_blank => true %>

Collection of Records

Well, the worst situation is with the select_date, select_time and select_datetime helpers. Basically you have to use the particular select_year, select_month and select_day helpers (for a time select also select_hour, select_minute and select_second helpers).

For each select helper two attributes have to be specified:

  • the :prefix attribute contains a value in the object_name[index] format, e.g. "book[#{@book.id}]“
  • the :field_name attribute specifies what will be written in the last square brackets. A value consists of two parts: field name and helper index in round brackets, e.g. 'published_on(1i)' for the year select. The following table show all helper indices:
    1. 1i year
    2. 2i month
    3. 3i day
    4. 4i hour
    5. 5i minute
    6. 6i second

The following example contains at the beginning a definition of the prefix variable that a little simplifies already complicated notation:

  1. <% prefix = "book[#{@book.id}]" %>
  2.  
  3. <%= select_year @book.published_on,
  4.   :prefix => prefix,
  5.   :field_name => "published_on(1i)" %>
  6. -
  7. <%= select_month @book.published_on,
  8.   :prefix => prefix,
  9.   :field_name => "published_on(2i)" %>
  10. -
  11. <%= select_day @book.published_on,
  12.   :prefix => prefix,
  13.   :field_name => "published_on(3i)" %>
  14. &nbsp;
  15. <%= select_hour @book.published_on,
  16.   :prefix => prefix,
  17.   :field_name => "published_on(4i)" %>
  18. :
  19. <%= select_minute @book.published_on,
  20.   :prefix => prefix,
  21.   :field_name => "published_on(5i)" %>
  22. :
  23. <%= select_second @book.published_on,
  24.   :prefix => prefix,
  25.   :field_name => "published_on(6i)" %>

with a blank value (a shortened example; of course, it is necessary to add the :include_blank attribute to all select helpers):

  1. <%= select_year @book.published_on,
  2.   :prefix => prefix,
  3.   :field_name => "published_on(1i)",
  4.   :include_blank => true %>

Conclusion

It was shown how to use form helpers for a collection of records in one form. Definitely the date & time select helpers should support the :index attribute.

Thanks

… to Mark Reginald James form Australia for his response on the RoR mailinglist (about the date_select in a collection).

These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • DZone
  • Digg
  • Reddit
  • Technorati
  • Furl
  • NewsVine
  • Slashdot
  • Ma.gnolia
  • StumbleUpon

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview


commercial break :)

Make an account on slicehost.com -- a really good hosting where you have your own virtual machine. I installed Gentoo there = I like it very much ;)