Agile Tortoise
Greg Pierce’s blog
« MacBook Pro Java on Intel Macs »
Rails: acts_as_taggable UI option
There’s a gem for Ruby on Rails to easily implement “taggable” records, called acts_as_taggable. I’ve implemented in on Tickets in the trouble ticket handling system I’m working on.
I did some searching (limited) but didn’t find a whole of lot info on the types of UIs people were using for acts_as_taggable records, so I came up with my own version. I expect some of this might be a bit naive of the niceties of Rails, but I’m still pretty new at it. The end result is something that looks like this (HTML example, non-functional, no pretty CSS applied):
In my ticket-system, tagging will be done after a ticket is created — not by the person inputing the ticket, so this form will appear when viewing the ticket. Tags are input as strings, with a space separator and you can add as many as you want at one time. The “X” deletes an existing tag. The calls are done with AJAX, the the result just replaces the original tag block.
So, the template for rendering the block is in in a view at _show_tags.rhtml:
<div id="tags">
<h4>Tags</h4>
<% if( @ticket.tags_count > 0 ) %>
<ul>
<% @ticket.tags.sort_by{ |t| t.name }.each do |tag| %>
<li><%= tag.name %> <%= remove_tag_link( @ticket, tag ) %></li>
<% end %>
</ul>
<% else %>
<ul><li>[none]</li></ul>
<% end %>
</div>
<%= form_remote_tag( :update => 'tags',
:url => { :action => :add_tags, :id => @ticket.id } ) %>
<%= text_field_tag( 'tags', '', { :size => 10 } ) %>
<%= submit_tag "Add" %>
<%= end_form_tag %>
The following actions in the ticket_controller handle the AJAX calls:
def remove_tag @ticket = Ticket.find(params[:id]) @tag = Tag.find(params[:tag]) arr = @ticket.tag_names arr.delete( @tag.name ) @ticket.tag( arr, :clear => true ) @ticket.save render( :partial => 'show_tags' ) end def add_tags @ticket = Ticket.find(params[:id]) @ticket.tag(params[:tags]) @ticket.save render( :partial => 'show_tags' ) end
I also have a helper method to build the delete link tags:
def remove_tag_link( ticket, tag )
link_to_remote( "X", :update => 'ticket',
:url => { :action => :remove_tag, :id => ticket.id, :tag => tag.id }
)
end
I’d be interested to hear from anyone with Rails experience to tell me if I’m doing anything glaringly wrong on this, but it makes for a much nice UI to my mind than a simple textbox, much less prone to typo errors inputing tags.
January 13th, 2006 at 4:26 pm
Looks fine to me, and feels very similar to the UI Flickr uses.
Mmmm….AJAX-y.
Sean