jQuery Basics

Apotomo’s web components are perfect for wrapping JavaScript controls. They simplify configuration and rendering, and – this is where it gets really handy – with little effort events from JavaScript can travel to your ruby widgets and trigger responses there.

Autocomplete

Since we already loaded jQuery UI, let’s use it to implement an autocomplete control which helps us searching for tweets.

Wrapping the Autocomplete control

The search box widget is called QuickSearch, a stupid name, whatever, I’m hungover.

rails g apotomo:widget quick_search display --haml

We are feeling comfortable with plugging widgets into views now.

app/controllers/dashboard_controller.rb (snippet)
 4  has_widgets do |root|
 5    root << widget("twitter/panel", 'parrot', :display_form)
 6    root << widget("twitter/trashbin_widget", 'bin', :title => "Trash tweets here!")
 7    root << widget("quick_search", "autocomplete")
 8  end

Just plug the new widget into the dashboard.

app/views/dashboard/index.html.haml (snippet)
 8  .column
 9    = render_widget 'autocomplete'

The view for our input box is mostly copied from the jQuery UI example.

app/cells/quick_search/display.html.haml
 1:javascript
 2  $().ready(function() {
 3    var input = $("##{widget_id}-field");
 4    input.autocomplete(
 5      {source: input.attr('data-load-event-url')}
 6    );
 7  });
 8
 9What are you lookin' for?
10= text_field_tag "#{widget_id}-field", "", 'data-load-event-url' => url_for_event(:typing)
11

jQuery’s autocomplete method simply gets its URL from the unobstrusive data-load-event-url attribute (line 5). Now, when typing into the field, a :typing event is triggered via AJAXwhich can be used for sending back matching items.

Let’s process the event.

app/cells/quick_search.rb
 1class QuickSearch < Apotomo::Widget
 2  responds_to_event :typing, :with => :search
 3  
 4  def display
 5    render :layout => 'portlet'
 6  end
 7  
 8  def search
 9    items = Tweet.find(:all, :conditions => "text LIKE '%#{param(:term)}%'").
10    collect do |t|
11      {:label => t.text}
12    end
13    
14    render :text => items.to_json
15  end
16end

We catch the event by calling our old friend responds_to_event (line 2). When that kind of event is encountered, the #search method gets invoked.

As jQuery per default sets the term query parameter we retrieve that value using Apotomo’s #param and then do the actual select (line 9).

In a more or less efficient way we create a JSON item list and send it back using render :text (line 14).

Isn’t that stupid simple? You don’t need to setup any AJAX route, you don’t need to fuck around with partials and helpers and – that’s the coolest – you might use that widget in another app, too!


blog comments powered by Disqus