JT Hopple LLC

List View Partial Pattern

JeremyDesign, Programming, Rails, Ruby, Tips Digg!

Most applications display lists of various things and they usually display these lists in slightly different ways. In my opinion, there isn't a one-size-fits-all solution to building these lists, but there is a pattern that seems to work pretty well. It consists of three parts: the list, the list-item, and the item. In addition to partitioning your lists into smaller pieces that are easier to deal with, it also makes it very easy to add both css styling and ajax behaviors to your lists.

The examples below use Ruby on Rails, but this pattern should work for your language/framework of choice. Also, I'm not going to show any of the CRUD controller actions since they should all be very simple and are unaffected by this pattern.

To implement the pattern for, let's say, a people controller, create three partials: _list.rhtml, _list_item.rhtml, and _item.rhtml.

_list.rhtml

  1. <%= link_to "Add new", new_person_url %>
  2. <ul class="list" id="PersonList">
  3. <%= render :partial => "people/list_item", :locals => { :person => person } %>
  4. </ul>

_list_item.rhtml

  1. <li class="list_item" id="Person_<%= person.id %>">
  2. <%= render :partial => "people/item", :locals => { :person => person } %>
  3. <ul class="controls">
  4. <li><%= link_to "edit", edit_person_url(person) %></li>
  5. <li><%= link_to "delete", person_url(person), :method => :delete %></li>
  6. </ul>
  7. </li>

_item.rhtml

  1. <div class="item">
  2. <h2><%= person.first_name %><%= person.last_name %></h2>
  3. <div class="details">...</div>
  4. </div>

Pretty simple partials, eh? You may be wondering what the big deal is. There really isn't one, but here's why I like to use this pattern. First, this pattern partitions your list display into small easy to work with semantical chunks. If you want to change something in the list you don't have to dig through a ton of code, and by using the suggested ids and class names in the markup you can easily style the list both globally for your application and specifically for a particular list id.

Though I recommend always building applications sans-ajax first, this pattern makes it easy to ajax-ify a list without having to refactor the list view. When you want to have your list items fade away when they're deleted, you can simply change the link_to to a link_to_remote (you can do this manually or unobtrusively) and then add a destroy.rjs template to update your page.

destroy.rjs

  1. page.visual_effect :fade, "Person_#{@person.id}"

Now, when you delete your items they'll gently fade from the list.

Next, lets say you want to use ajax to create new items. If you add an inline form to your list view that serializes the form fields and sends them to the server via ajax you can very easily have it respond with a chunk of javascript that inserts the newly rendered person, using the _list_item.rhtml partial, into the existing list. Ruby on Rails makes this a snap.

New person form

  1. <% remote_form_for :person, @person, :url => person_url do |f| %>
  2. <p>
  3. <label for="person_first_name">First Name</label>
  4. <%= f.text_field :first_name %>
  5. </p>
  6. <p>
  7. <label for="person_last_name">Last Name</label>
  8. <%= f.text_field :last_name %>
  9. </p>
  10. <%= submit_tag "Save Person" %>
  11. <% end %>

Once this form is submitted via ajax, your controller will add the person and then render the create.rjs template in response to the javascript ajax call.

create.rjs

  1. page.insert :bottom, "PersonList", :partial => "person/list_item", :locals => { :person => @person }
  2. page.visual_effect :highlight, "Person_#{@person.id}"

Again, without having to modify the list partials it was very easy to add an ajax behavior for inserting new items into the list. I'm not going to go into all of the details, but adding behaviors for updating and sorting items should just as easy as creating and destroying them.

Without too much extra effort up front, this pattern will help clean up your list views, make them more maintainable, and will make it easier to add css and javascript behaviors to your lists when the time comes.

0 Comments

Post a comment