Then require one of the jQuery UI theme into app/assets/stylesheets/application.css
*= require_self *= require_tree . *= require_style *= require jquery-ui/ui-lightness */
app/assets/javascripts/application.js
//= require jquery //= require jquery_ujs //= require jquery-ui //= require_tree .
Our controller responds json object in apps/controllers/accounts_controller.rb
def search_account
@accounts=Account.where("LOWER(name) LIKE ?", "%#{params[:name].downcase}%").limit(params[:maxRows]).order(:name)
respond_to do |format|
format.json {render :json => @accounts}
end
end
I've created a helper for input element app/helpers/application_helper.rb
(Take care of heredoc strings.)
def autocomplete_input(attributes={})
#*need* object: this form's object : "person"
#*need* instance: searcheable object : 'account'
# instance_key: primary key of this instance : 'account_id'
# value: original or default value for instance : 'Yahoo Corp.'
# value_key: original or default value for instance_key: 252
#*need* ajax_url: remote url for ajax call without format: url_for(:controller=> :accounts, :action=> :search, :id=>'all')
# ajax_query_additional_params (Array): ["maxRows: 7", "anything :20"]
#*need* ajax_query_searchable_param Object's string (String): "name" (@person.account.name)
#*need* ajax_query_searchable_param_key Object's foreign key (String): "id" (@person.account.id)
# min_length minimal chars to start searching: 2
if attributes.nil? then return false end
if attributes.empty? then return false end
object=attributes[:object]
instance=attributes[:instance]
if object.nil? or instance.nil? then return false end
object=object.to_s.downcase
instance=instance.to_s.downcase
instance_key=attributes[:instance_key] || instance + "_id"
value=attributes[:value] || ""
value_key=attributes[:value_key] || ""
value_key_html=""
unless value_key.to_s.empty? then
value_key_html=" value=\""+value_key.to_s+"\""
end
ajax_url=attributes[:ajax_url]
ajax_query_additional_params=attributes[:ajax_query_additional_params] || ""
ajax_query_searchable_param=attributes[:ajax_query_searchable_param] || "name"
ajax_query_searchable_param_key=attributes[:ajax_query_searchable_param_key] || "id"
min_length=attributes[:min_length] || 2
ajax_query_additional_params_formatted=""
unless ajax_query_additional_params.nil? then
case ajax_query_additional_params
when Array then
i=0
ajax_query_additional_params.each do |aqap|
if i==0 then
ajax_query_additional_params_formatted=ajax_query_additional_params_formatted + aqap.to_s
else
ajax_query_additional_params_formatted=ajax_query_additional_params_formatted + ",\n" + aqap.to_s
end
i=i.next
end
when String then
ajax_query_additional_params_formatted=ajax_query_additional_params
when Hash then
i=0
ajax_query_additional_params.each do |aqap_key,aqap_value|
if i==0 then
ajax_query_additional_params_formatted=ajax_query_additional_params_formatted + aqap_key.to_s + ": " + aqap_value.to_s
else
ajax_query_additional_params_formatted=ajax_query_additional_params_formatted + ",\n" + aqap_key.to_s + ": " + aqap_value.to_s
end
i=i.next
end
end
end
jquery_request_data_params="data: {\n"
unless ajax_query_additional_params_formatted.empty? then
jquery_request_data_params=jquery_request_data_params + ajax_query_additional_params_formatted + ",\n"
end
jquery_request_data_params=jquery_request_data_params + "#{ajax_query_searchable_param}: request.term\n},"
search_field_id="search_#{object}_#{instance}"
value_div_id="#{object}_#{instance}_log"
hidden_field_id="#{object}_#{instance_key}"
hidden_field_name="#{object}[#{instance_key}]"
function_log_name="log_#{object}_#{instance}"
html_text = <<HTML1
<table><tbody><tr>
<td><input id="#{search_field_id}" class="ui-autocomplete-input"/></td>
<td><div id="#{value_div_id}" class="ui-widget-content">#{value}</div></td>
</tr></tbody></table>
<input type="hidden" id="#{hidden_field_id}" name="#{hidden_field_name}" #{value_key_html} >
HTML1
js_text = <<JS1
$(function() {
function #{function_log_name}( label, id ) {
$( "##{value_div_id}" ).html(label);
$( "##{hidden_field_id}").val(id);
}
$( "##{search_field_id}" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "#{ajax_url}.json",
dataType: "json",
#{jquery_request_data_params}
success: function( data ) {
response( $.map( data, function( item ) {
return {
label: item.#{ajax_query_searchable_param},
value: item.#{ajax_query_searchable_param},
id: item.#{ajax_query_searchable_param_key}
}
}));
}
});
},
minLength: #{min_length},
select: function( event, ui ) {
if (ui.item) {
#{function_log_name}( ui.item.value, ui.item.id );
} else {
#{function_log_name}( this.value, this.value );
}
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
});
JS1
concat(raw(javascript_tag(js_text)))
concat(raw(html_text))
end
Finally insert autocomplete element in _form.htm.erb
<div class="ui-widget">
<label for="search_account">Account:</label><br />
<% autocomplete_input(:object => "person",
:instance => "account",
:instance_key => "account_id",
:value => (@person.account.name unless @person.account.nil?),
:value_key => @person.account_id,
:ajax_url => url_for(:controller => 'accounts',
:action => 'search_account',
:id => 'all'),
:ajax_query_additional_params => {:maxRows => 7},
:ajax_query_searchable_param => "name",
:ajax_query_searchable_param_key => "id",
:min_length => 2
)%>
</div>
</div>
Works with Rails 3.2 and jQuery JavaScript Library v1.7.1. Good luck! Questions?
Great Article! Thanks for sharing this information.
ReplyDeleteRuby on Rails Development | Asp.net Development
This comment has been removed by the author.
ReplyDelete