I am a newbie in Ruby on rails, please help me solve my problem.
I already use gem searchkick, and in console I can get the result.
this is my code
route.rb
resources :m_customers
resource :patient, except: [:index, :show] do
collection do
get 'autocomplete'
end
end
root :to => 'home#index'
get 'patient/PatientList', to:'patient#PatientList'
get 'patient/PatientList/autocomplete', to:'patient#autocomplete'
get 'patient/PatientHistory/:kode/:histid', to:'patient#PatientHistory', as: 'patient/PatientHistory'
get 'patient/PatientSub/:id', to:'patient#PatientSub', as: 'patient/PatientSub'
get 'patient/PatientObj/:objid', to:'patient#PatientObj', as: 'patient/PatientObj'
get 'patient/PatientAsses/:assid', to:'patient#PatientAsses', as: 'patient/PatientAsses'
get 'patient/PatientPlan/:planid', to:'patient#PatientPlan', as: 'patient/PatientPlan'
m_customer.rb => model
class MCustomer < ActiveRecord::Base
self.primary_key = :Cust_ID
searchkick match: :word_start, searchable: [:Cust_Name, :Cust_ID]
MCustomer.search "tipping poi"
end
patient_controller.rb
class PatientController < ApplicationController
require 'will_paginate/array'
def PatientList
#date_now = Time.now
#patients = TRegistration.paginate(:page => params[:page], :per_page => 7).where(:Reg_status => 'N')
#patient2s = TRegistration.paginate(:page => params[:page], :per_page => 7).where(:Reg_status => 'P')
if params[:query].present?
#MCustomers = MCustomer.search(params[:query])
else
#MCustomers = []
end
end
def autocomplete
render json: MCustomer.search(params[:query], autocomplete:true, limit: 10).map do |customer| {name: customer.Cust_Name, value: customer.Cust_ID}
end
end
end
when I go to the page below, I can find the result from searchkick :
//localhost:3000/patient/PatientList/autocomplete?query=s
but when I inserted serch input, nothing could be shown
PatientList.html.erb
<div class="cust-search">
<%= form_tag patient_PatientList_path, method: :get do %>
<div class="form-group">
<%= text_field_tag :query, params[:query], class: 'form-control twitter-typeahead' %>
<%= submit_tag 'Search', class: 'btn btn-default' %>
</div>
<% end %>
</div>
java script patient.js
var ready;
ready = function() {
var engine = new Bloodhound({
datumTokenizer: function(d) {
return Bloodhound.tokenizers.whitespace(d.name); },
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: { url: '../patient/PatientList/autocomplete?query=%QUERY' }
});
// initialize the bloodhound suggestion engine
var promise = engine.initialize();
promise
.done(function() { console.log('success!'); })
.fail(function() { console.log('err!'); });
// instantiate the typeahead UI
$( '.twitter-typeahead').typeahead(null, {
displayKey: 'Cust_Name',
source: engine.ttAdapter()
});
}
$(document).ready(ready);
$(document).on('page:load', ready);
please help. thanks anyway.
This is what your code should look like if you want a working autocomplete (only the relevant parts)
m_customer.rb (you should really consider naming it just customer)
class MCustomer < ActiveRecord::Base
searchkick autocomplete: ['Cust_Name']
end
you should use the autocomplete option and provide the column you want to autocomplete, e.g: cust_name
patient_controller.rb ( you should really consider naming it customer_controller )
class PatientController < ApplicationController
def autocomplete
render json: MCustomer.search(params[:query], autocomplete:true, limit: 10).map do |customer| { name: customer.Cust_Name }
end
end
end
here you are formatting your json response
patient.js (read this carefully and see the modifications)
var engine = new Bloodhound({
datumTokenizer: function(d) {
return Bloodhound.tokenizers.whitespace(d.name); },
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: { url: '/patient/autocomplete?query=%QUERY' }
});
var promise = engine.initialize();
$( '.twitter-typeahead').typeahead(null, {
name: "customer",
displayKey: "name",
limit: 20,
source: engine.ttAdapter()
});
}
I think this is where you made your mistake, you should provide the right key so the method will read your json as it should and retrieve the names you want.
you should check out this wonderful guide, you can read and just copy-paste with the modifications that suit your code:
https://rubyplus.com/articles/4031-Autocomplete-using-Typeahead-and-Searchkick-in-Rails-5
hope it helps anyone
Related
I am building an application where i try to suggest "Similar topics" in rails, as the user put the title of his/her new story.
I have 2 problems:
The controller with the custom action does not work at all. it seems that the server simply retrieves the view. Without running any of the code in the action
To go around the issue of the controller, i created a service.rb with a function to retrieve the records based on the params[:title], but from here I do NOT know how to make small popup window with suggestions (and weblinks) as the user write the title of the topic.
I have done so far :
View
<div class="col-md-12">
<%= simple_form_for #message do |f| %>
<div style="font-size: xx-small; font-style: italic; color: #44B5EB">
<%= f.input :title, label: "#{t :Title}", placeholder: "#{t :Search}", id: "title" , data: {behavior: "autocomplete_message"}%>
<%= f.cktext_area :description, label: "#{t :Message_body}", :input_html => {:rows => 25} %>
<br> <br>
<%= f.submit "#{t :Create_story}", class: "btn btn-primary"%>
<% end %>
</div>
</div>
<script>
$("#title").addEventListener("turbolinks:load", function () {
$input = $("[data-behavior = 'autocomplete_message']");
var options = {
getValue: "name",
url: function (phrase) {
return "messages/search.json?title=" + phrase;
},
categories: [
{
listLocation: "qandas",
header: "<p class='Search_drop_separate'>Q&A </p>",
}
],
list: {
onChooseEvent: function(){
var url = $input.getSelectedItemData().url;
$input.val("");
Turbolinks.visit(url)
}
}
};
$input.easyAutocomplete(options)
});
</script>
Controller
class StorytController < ApplicationController
before_action :authenticate_user!
before_action :find_message, only: [:show, :edit, :update, :destroy]
respond_to :html, :js
...
def search
##qandasquestions = Qandasquestion.ransack(question_or_answer_cont: params[:q]).result(distinct: true)
respond_to do |format|
format.html {
#qandasquestions = #qandasquestions
redirect_to stories_search_path
}
format.json {
#qandasquestions = #qandasquestions.limit(5)
}
end
end
def full_name
"#{first_name} #{last_name}"
end
private
def force_json
request.format = :json
end
end
Search.jason.builder
json.qandas do
json.array!(#qandasquestions) do |qandasquestion|
json.name "#{qandasquestion.question}"
json.url qanda_path(qandasquestion.qanda_id)
end
end
routes:
get 'stories/search'
What I am looking to build is actually very similar to what we have on Stackoverflow on the principle.
Anybody did something similar and can help me please?
I don't mean to sidetrack you but if you have a couple minutes to check this out, have you seen select2? It works nice with Rails and there's also a gem to make it work nice with simple_form
https://github.com/lndl/select2_simple_form
I'm new at RoR and I'm having a trouble in my app. The problem consists on filter a select field named "Solution", based on the others select fields above it.
Now, what the app do is to retrieve all information from BD about Area, Region, Associated, Solution and populate the select fields with these data. But the user wants that, when an area, a region and an associated is selected by the user, only the solutions about that associated in that region on that area should be shown.
Edit:
I'm almost there! I've made many changes in my app. The select fields are populated by controller action new and the function "populate_selects", which is called by the parameter before_action :popula_selects, only: [:new, :edit]. A new function was created in order to be called by AJAX and upgrade the "Solution" field:
Atendments_Controller < ApplicationController
before_action :populate_selects, only: [:new, :edit]
def new
#atend = atendment.new
end
def update_solution #AJAX
#solutions = atendment.joins(:solution).where("atendment_area_id = ? and atendment_region_id = ? and atendment_assoc_id = ?", params[:atendment_area_id], params[:atendment_region_id], params[:atendment_assoc_id])
respond_to do |format|
format.js
end
end
private
def populate_selects
#atendment_area = atendmentArea.where(status: true, user_id: current_user.id)
#atendment_region = atendmentRegion.where(status: true, user_id: current_user.id)
#atendment_assoc = atendmentRegionAssoc.where(status: true, assoc_id: current_user.entidade_id).where(atendment_region_id: #atendment_region.map(&:atendment_region_id))
#solutions = atendment.joins(:solution).where("atendment_area_id = ? and atendment_region_id = ? and atendment_assoc_id = ?", params[:atendment_area_id], params[:atendment_region_id], params[:atendment_region_assoc_id])
end
end
Below, the _form.html.erb code from view:
<div class="atendment-form">
<%= form_for :atendment, url: {action: "new"}, html: {method: "get"} do |f| %>
<div class="col-xs-6">
<%= f.select :atendment_area_id, options_for_select(#atendment_area.collect { |c| [ c.atendment_area.name, c.id ] }, 1), {:prompt=>"Área"}, { :class => 'form-control', :required => true, id: 'atendment_atendment_area_id' } %>
</div>
<div class="col-xs-6">
<%= f.select :atendment_region_id, options_for_select(#atendment_region.collect { |c| [ c.atendment_region.name, c.id ] }, 1), {:prompt=>"Região"}, { :class => 'form-control', :required => true, id: 'atendment_atendment_region_id' } %>
</div>
</div>
</div>
<div class="field">
<%= f.select :atendment_assoc_id, options_for_select(#atendment_assoc.collect { |c| [ c.atendment_region.name, c.id ] }, 1), {:prompt=>"Associado"}, { :class => 'form-control', :required => true, id: 'atendment_atendment_assoc_id' } %>
</div>
<div class="field">
<%= f.select :solution_id, options_for_select(#solutions.collect { |solution| [solution.name, solution.id] }, 0), {:prompt=>"Solução"}, { :class => 'form-control', :required => true, id: 'atendment_solution_id' } %>
</div>
</div>
Route to the new function:
resources :atendments do
collection do
get :update_solution
end
end
AJAX function which calls the "update_solution" and reset solution field's value (app/assets/javascript/atendment.js.coffee):
show_solutions = ->
$.ajax 'update_solution',
type: 'GET'
dataType: 'script'
data: {
atendment_area_id: $("#atendment_atendment_area_id").val()
atendment_region_id: $("#atendment_atendment_region_id").val()
atendment_assoc_id: $("#atendment_atendment_assoc_id").val()
}
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{textStatus}")
success: (data, textStatus, jqXHR) ->
console.log("OK!")
$(document).ready ->
$('#atendment_atendment_assoc_id').on 'change', ->
show_solutions()
So, I've created a .coffee file to render the partial that will return a new value to the "solution" field "option" tag
(app/views/atendment/update_solution.coffee):
$("#atendment_solution_id").empty()
.append("<%= escape_javascript(render :partial => 'solution') %>")
And, the last but not least, the partial containing the html code for the "option" tag mentioned above (app/views/atendments/_solution.html.erb):
<option value="<%= solution.id %>" selected="selected"><%= solution.nome %></option>
For any reason, the AJAX function doesn't print nothing on console (nor error neither success), but it calls the update_solution.coffee file. The point is, it doesn't update the option value due an error (500 internal server error). I don't know what am I doing wrong. If anybody could help me, I appreciate it.
I would do this with JS, can think any other way.
A function called by onchange that change the display attribute from each field that you need to hide or show.
I solved this with the following code:
assets/js/atendments.js
I changed the code because the last one had many bugs.
function getAssociated(){
var aau_id = $("#atendment_area_user_id").val()
var aru_id = $("#atendment_region_user_id").val();
$.getJSON("/controllers/atendments_controller/getAssociated/"+aru_id,
function ( callback ) {
if (callback != "error"){
var assoc = document.getElementById("atendment_region_associated_id");
while (assoc.firstChild) {
assoc.removeChild(assoc.firstChild);
}
var i = Object.keys(callback).length -1;
$("#atendment_region_associated_id").append("<option value=''>Associated</option>");
while (i >= 0) {
$("#atendment_region_associated_id").append("<option value='"+callback[Object.keys(callback)[i]]+"'>"+Object.keys(callback)[i]+"</option>");
i--;
}
}
});
get_solution_type();
}
function get_solution_type() {
var ara_id = $("#atendment_region_associated_id").val();
$.getJSON("/controllers/atendments_controller/getSolution/"+ara_id,
function ( callback ) {
if (callback != "error"){
var sol = document.getElementById("atendment_solution_id");
while (sol.firstChild) {
sol.removeChild(sol.firstChild);
}
var i = Object.keys(callback).length-1;
while (i >= 0) {
$("#atendment_solution_id").append("<option value='"+callback[Object.keys(callback)[i]]+"'>"+Object.keys(callback)[i]+"</option>");
i--;
}
}
});
var aau_id = $("#atendment_area_user_id").val();
$.getJSON("/controllers/atendments_controller/getType/"+aau_id,
function ( callback ) {
if (callback != "erro"){
var type = document.getElementById("atendment_type_id");
while (type.firstChild) {
type.removeChild(type.firstChild);
}
var i = 0;
while (i < (Object.keys(callback).length)) {
$("#atendment_type_id").append("<option value='"+callback[Object.keys(callback)[i]]+"'>"+Object.keys(callback)[i]+"</option>");
i++;
}
}
});
}
The $.getJSON performs ajax request to the controller that responds with JSON and update the select fields option tags.
controllers/atendments_controller
I just retrieve the data from DB and return as JSON
def getAssociated
aru_id = params[:atendment_region_user_id]
aras = AtendmentRegionAssociated.where("SQL here")
if aras.present?
render :json => aras.to_json
else
render :json => "error".to_json
end
end
def getSolution
ara_id = params[:atendment_region_associated_id]
sol = Solution.where("SQL here")
if sol.present?
render :json => sol.to_json
else
render :json => "error".to_json
end
end
def getType
aau_id = params[:atendment_area_user_id]
type = AtendmentType.where("SQL here")
if type.present?
render :json => type.to_json
else
render :json => "error".to_json
end
end
Update the routes and put the javascript functions in select fields onchange property. Now everything is working fine :D
I have a form partial inside which I select associated users through a multiple: true collection select:
= f.collection_select(:user_ids, User.all, :id, :email, {selected: #limit_group.user_ids, include_blank: true}, {multiple: true, "data-placeholder" => "Add users to group"})
But how can I do this more efficiently to avoid big load times when the database has like thousands of users?
You'll be better using something called AutoComplete / LiveSearch with a text box (like Pardeep Saini mentioned).
We've done this before:
You could achieve this relatively simply:
= f.text_field :user_ids, placeholder: "Search for users"
You'd then have to use javascript:
#app/assets/javascripts/application.js
$(document).on("keyup", "input[type=text]#user_ids", function(){
$.getJSON("users/search", {name: $(this).val()}).done(function(json){
var users = [];
$.each(json.users, function(user) {
users.push("" + user.name + "");
});
$(".search").html(users).show();
});
});
$(document).on("click", ".search a", function(e) {
e.preventDefault();
// add hidden field with user name to form
});
You'd have to back it up with the relevant controller action:
#config/routes.rb
resources :users do
get :search, on: :collection
end
#app/controllers/users_controller.rb
class UsersController < ApplicationController
def search
#users = User.where("name LIKE ?", "%" + params[:name] + "%")
respond_to do |format|
format.json (render json: #users.to_json)
end
end
end
The above code should be refactored.
--
To get this working with multiple values would be a little bit more involved. It could be done, but you'd have to do it like the tags setup in StackOverflow...
The way they do that is to basically use a similar principle to the above (each tag will be a returned piece of data from the search).
Here's the actual code we used in the cosmetics example above:
#app/assets/javascripts/extra/jquery.livesearch.js
(function($) {
$.searchbox = {}
$.extend(true, $.searchbox, {
settings: {
url: 'search',
param: 'search',
dom_id: '#livesearch',
minChars: 2,
loading_css: '#livesearch_loading',
del_id: '#livesearch_del'
},
loading: function() {
$($.searchbox.settings.loading_css).show()
},
idle: function() {
$($.searchbox.settings.loading_css).hide()
},
start: function() {
$.searchbox.loading()
$(document).trigger('before.searchbox')
},
stop: function() {
$.searchbox.idle()
$(document).trigger('after.searchbox')
},
kill: function() {
$($.searchbox.settings.dom_id).fadeOut(50)
$($.searchbox.settings.dom_id).html('')
$($.searchbox.settings.del_id).fadeOut(100)
},
reset: function() {
$($.searchbox.settings.dom_id).html('')
$($.searchbox.settings.dom_id).fadeOut(50)
$('#SearchSearch').val('')
$($.searchbox.settings.del_id).fadeOut(100)
},
process: function(terms) {
if(/\S/.test(terms)) {
$.ajax({
type: 'GET',
url: $.searchbox.settings.url,
data: {search: terms.trim()},
complete: function(data) {
$($.searchbox.settings.del_id).fadeIn(50)
$($.searchbox.settings.dom_id).html(data.responseText)
if (!$($.searchbox.settings.dom_id).is(':empty')) {
$($.searchbox.settings.dom_id).fadeIn(100)
}
$.searchbox.stop();
}
});
return false;
}else{
$.searchbox.kill();
}
}
});
$.fn.searchbox = function(config) {
var settings = $.extend(true, $.searchbox.settings, config || {})
$(document).trigger('init.searchbox')
$.searchbox.idle()
return this.each(function() {
var $input = $(this)
$input
.keyup(function() {
if ($input.val() != this.previousValue) {
if(/\S/.test($input.val().trim()) && $input.val().trim().length > $.searchbox.settings.minChars){
$.searchbox.start()
$.searchbox.process($input.val())
}else{
$.searchbox.kill()
}
this.previousValue = $input.val()
}
})
})
}
})(jQuery);
... and ...
#app/assets/javascripts/application.js
$(document).ready( function() {
var base_url = window.location.protocol + "//" + window.location.host;
$('#SearchSearch').searchbox({
url: base_url + '/search/',
param: 'search',
dom_id: '#livesearch',
loading_css: '#livesearch_loading'
})
});
$(document).on('click', '#livesearch_del', function() { $.searchbox.reset(); })
$(document).on('submit', '#SearchForm', function() { $.searchbox.kill(); });
$(document).on('click', '.livesearch_results tr', function() { window.location = $('a:first', this).attr('href'); });
The routes & controller:
#config/routes.rb
match 'search(/:search)', :to => 'products#search', :as => :search, via: [:get, :post]
#app/models/product.rb
class Product < ActiveRecord::Base
def self.search(search)
where("name LIKE ? OR description LIKE ?", "%#{search}%", "%#{search}%").take(5)
end
end
#app/controllers/product_controller.rb
class ProductsController < ApplicationController
def search
#products = Product.search params[:search]
respond_to do |format|
format.js { render :partial => "elements/livesearch", :locals => {:search => #products, :query => params[:search]} }
format.html {
render :index
}
end
end
end
The views:
#app/views/elements/_livesearch.html.erb
<div class="livesearch_container">
<table class="livesearch_results">
<% unless search.blank? %>
<% search.each_with_index do |item,i| %>
<% pos ||= '' %>
<% if (i == 0) then pos = 'first' end %>
<% if (i == search.size - 1) then pos += ' last' end %>
<tr data-link="<%= "/#{item.slug}" %>" class="<%= "#{pos}" %>">
<td class="image">
<% model = item.images.first || item.images.build %>
<%= image_tag(model.image.url(:thumb), :title => item.name, data: {"placement" => "left"}, :height => "85") %><br/>
</td>
<td class="information">
<%= link_to image_tag(item.brand.images.first.image.url(:thumb), :width => "55", :title => "View #{item.brand.name}"), "/#{item.brand.slug}", :class => "brand" if defined?(item.brand.images.first) %>
<div class="name"><%= link_to item.name, "/#{item.slug}" %></div>
</td>
<td class="price">
<%= number_to_currency(item.price, unit: "£") %>
</td>
</tr>
<% end %>
<tr class="results"><td colspan="3"><%= link_to "See all #{search.size} results here »", search_path(query) %></td></tr>
<% else %>
<tr class="results"><td colspan="3"><%= link_to 'No results found', search_path(query) %></td></tr>
<% end %>
</table>
</div>
I also made a gist here: https://gist.github.com/richpeck/2310ff3ab1ffcd6a9138
Im trying to implement a multiple level drop down list in Rails
I have three Tables in my DB.
vehicle_make.rb
class VehicleMake < ActiveRecord::Base
validates_uniqueness_of :make
has_many :appointments
end
vehicle_model.rb
class VehicleModel < ActiveRecord::Base
validates_uniqueness_of :model
has_many :appointments
end
vehicle_make_model.rb
class VehicleMakeModel < ActiveRecord::Base
validates_uniqueness_of :vehicle_make_id, :scope => :vehicle_model_id
end
and im trying to implement a multiple dropdown list in appointments.html.rb
on selecting the vehicle model only corresponding make should load..
<%= f.select :vehicle_make_id, options_for_select(vehicle_make.map {|s| [s.make, s.id]}, appointment.vehicle_make_id), {}, {class: "form-control"} %>
and in my js i have..
$('#appointment_vehicle_make_id').on('change', function() {
var vehicle_make_id = this.value;
$.ajax({
url : '/appointments/update_models',
type : 'GET',
data : {
make_id : vehicle_make_id
},
success : function(response) {
console.log(response);
}
});
});
and this is my controller method.
def update_models
#vehicle_models = VehicleModel.all
#model_ids = []
#selected_vehicle_models = VehicleMakeModel.where(vehicle_make_id: params[:make_id]).order(:vehicle_model_id) unless params[:make_id].blank?
#selected_vehicle_models.each do |t|
#model_ids << t.vehicle_model_id
end
respond_to do |format|
format.html { render layout: false }
format.js
end
end
I have html page named update_models.html.erb associated to the above action.
<%= select_tag :vehicle_model_id, options_for_select(#model_ids.map {|s| [s.model, s.first.id]}, nil), {}, {class: "form-control"} %>
I get an error in terminal saying
ActionView::Template::Error (wrong number of arguments (4 for 1..3)):
1: <%= select_tag :vehicle_model_id, options_for_select(#model_ids.map {|s| [s.model, s.first.id]}, nil), {}, {class: "form-control"} %>
Im stuck here. I dont know how to proceed from here.. please help
In your controller action update_models, you are trying to render js, so it's trying to find template named as update_models.js.erb.
You can try replacing your respond_to block with:
respond_to do |format|
format.json { render :json => #model_ids }
end
Afterwards, you will need to parse this data in your ajax success callback
I have two drop down boxes in my application.
Based on the value selected in 1st combobox, the values in 2nd drop down box should be populated.And these values should come from Database.
Please help me.
here's a clean approach using jquery-ujs (https://github.com/rails/jquery-ujs)
In your view:
<%=
select_tag
:first_select, # name of selectbox
options_from_collection_for_select(#myrecords, "id", "name"), # your options for this select box
:'data-remote' => 'true', # important for UJS
:'data-url' => url_for(:controller => 'MyController', :action => 'getdata'), # we get the data from here!
:'data-type' => 'json' # tell jQuery to parse the response as JSON!
%>
<%=
select_tag
:second_select, # name of selectbox
"<option>Please select something from first select!</option>"
%>
Your Controller:
class MyController < ApplicationController
def getdata
# this contains what has been selected in the first select box
#data_from_select1 = params[:first_select]
# we get the data for selectbox 2
#data_for_select2 = MyModel.where(:some_id => #data_from_select1).all
# render an array in JSON containing arrays like:
# [[:id1, :name1], [:id2, :name2]]
render :json => #data_for_select2.map{|c| [c.id, c.name]}
end
end
In your application.js:
$(document).ready(function() {
// #first_select is the id of our first select box, if the ajax request has been successful,
// an ajax:success event is triggered.
$('#first_select').live('ajax:success', function(evt, data, status, xhr) {
// get second selectbox by its id
var selectbox2 = $('#second_select');
// empty it
selectbox2.empty();
// we got a JSON array in data, iterate through it
$.each(data, function(index, value) {
// append an option
var opt = $('<option/>');
// value is an array: [:id, :name]
opt.attr('value', value[0]);
// set text
opt.text(value[1]);
// append to select
opt.appendTo(selectbox2);
});
});
});
You could take inspiration from what I have in a project of mine. It updates the state given the country selected.
It makes use of Carmen a great gem listing countries, states etc...
View:
<p>
<label>Country <span>*</span></label>
<%= profile_form.select(:country,Carmen.countries, {:include_blank => 'Select a Country'}, :id => "profile_country") %>
</p>
<p>
<label>State <span>*</span></label>
<%= profile_form.select(:state, "" , {:include_blank => 'Select a Country first'}, :id => "profile_state") %>
</p>
Jquery code:
$('#profile_country').change(function() {
if ($(this).val() == '')
{
$('#profile_state').html( $('<option>No state provided for your country</option>'));
}
else {
$.ajax({
type: "GET",
url: "/remote/get_states/" + encodeURIComponent($(this).attr('value')),
success: function(data){
if (data.content == 'None') //handle the case where no state related to country selected
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>No state provided for your country</option>'));
}
else
{
$('#profile_state').empty();
$('#profile_state').append( $('<option>Select your State</option>'));
jQuery.each(data,function(i, v) {
$('#profile_state').append( $('<option value="'+ data[i][1] +'">'+data[i][0] +'</option>'));
});
}
}
});
}
});
Controller:
def states
begin
render :json => Carmen::states(CGI::unescape(params[:country]))
rescue
render :json => {"content" => "None"}.to_json
end
end
This is how I did it. Works in Rails 3.2
View:
<%= select_tag :major_category_select_id, options_from_collection_for_select(#majorcategories, 'id', 'name'), :'data-remote' => 'true', :'data-url' => url_for(:controller => 'listings', :action => 'submit_major_category', format: 'js') %>
Controller method:
def submit_major_category
#major_category = MajorCategory.find(params[:major_category_select_id])
#minor_categories = #major_category.minor_categories
respond_to do |format|
# format.html { render partial: 'minor_categories_select' }
format.js
end
end
Routes:
get "listings/submit_major_category"
Then create a submit_major_category.js.erb file that gets responded to.