I've been working on a simple project for a greeting card application and I came up with a little something that might be interesting. The cards have a recipient and can have multiple signers. I added autocomplete for the recipient, but it was a bit harder for the comma separated list of signers. What I ended up doing was was simply grabbing the last piece of the list in the controller and passing that back to the view.
Here's the view code ...
Create a Card
<%= image_tag "card_images/#{@template.image_name}", :size => "200x200" %>
<%= form_tag ("create_from_image") do %>
<%= label_tag("Add the recipient's email: ") %>
<%= text_field_tag(:recipient_email, "#{@recipient_email}")%>
<%= label_tag("Add A Greeting: ") %>
<%= text_field_tag(:greeting, "#{@greeting}")%>
<%= label_tag("Add the signers' emails (comma separated): ") %>
<%= text_field_tag(:signers_email, "#{@signers}")%>
<%= hidden_field_tag :template_id, @template.id %>
<%= submit_tag("Preview the card!") %>
<%= submit_tag("Send the card!") %>
<% end %>
There's nothing very interesting in here, but the main field we're interested in is the :signers_email text field.
Here's the javascript code for it ...
$(document).ready(function(){
// Below is the name of the textfield that will be autocomplete
$('#recipient_email, #signers_email').autocomplete({
// This shows the min length of charcters that must be
// typed before the autocomplete looks for a match.
minLength: 2,
// This is the source of the auocomplete suggestions. In this case a
// list of emails from the users controller, in JSON format.
source: '/users/index.json'
})
});
What this says is that for both the recipient_email and signers_email fields, use autocomplete, send when we have two characters, and use the /users/index.json function to get the data we need.
Finally, we have the controller code ...
def index
@title = "All users"
@suggestion = "Pick someone and send them a card!"
if params[:term]
search_term = params[:term].split(",").last.strip
@users = User.find(:all, :conditions => ['email LIKE ?', "#{search_term}%"])
@users_hash = []
@users.each do |user|
@users_hash << { "label" => user.email }
end
else
@users = User.where(:active => true).paginate(:page => params[:page])
end
respond_to do |format|
format.html
# Here is where you can specify how to handle the request for "/people.json"
format.json { render :json => @users_hash }
end
end
Here, we have a couple of things going on ... for the Ajax side, we'll get the params[:term] field so we know that we need to get the constrained list. First, we're going to grab the params[:term] value, which should look something like "abc@test.com, def". Here we'd like to look for emails that start with the "def" and ignore the "abc@test.com" piece. So ... we split on the comma, grab the final element in the array, and then remove any leftover spaces at the end or beginning of the string. Next, we'll create an array where each element is a hash of the form { "label" => "defghi@test.com" }. This is the form that the jquery autocomplete needs. Finally, we use the respond_to section to send this back as json.
As always, let me know if you have questions.
No comments:
Post a Comment