simple_form select collection populated by AJAX call - ruby-on-rails

In my view I have a simple form with two select lists:
<%= simple_form_for #job, url: jobs_path do |f| %>
<%= f.input_field :types, as: :select, collection: #types, id 'types-select' %>
<%= f.input_field :subtypes, as: :select, collection: #subtypes %>
<% end %>
When a user selects an option from the first list, the second list below should be populated with values from the database based on the above selection.
For this reason, I am making ajax request when a user selects an option from the first list:
$('#types-select').change(function(){
$.ajax({
url: '/subtypes',
dataType: 'json',
type: 'GET',
data: {
type_id: this.value
},
success: function(data) {
console.log(data);
}
});
});
Controller looks like this:
class SubtypesController < ApplicationController
respond_to :json
def index
#subtypes = Type.find(params[:type_id]).subtypes
render json: #subtypes
end
end
At this point how can I fill up the second select with options from #subtypes?

You can populate second dropdown within success callback. Make sure #subtypes is returned in proper json format too.
Controller:
def index
#subtypes = Type.find(params[:type_id]).subtypes
render json: #subtypes.map { |item| { value: item.value } }
end
JS:
$.ajax({
url: '/subtypes',
dataType: 'json',
type: 'GET',
data: {
type_id: this.value
},
success: function(data) {
// Populate second dropdown here
var output = '';
$subtypes.empty().append(function() {
data.forEach(function(item) {
output += "<option>" + item.value + "</option>"
});
return ouput;
});
}
});

Related

select2 initSelection for redisplayed the form

I'm Using Select2-rails '3.5.3, I can do search with remote data and save it, the problem is how I can restore the selected text (for example if user press edit), problem: initSelection is not fired when form loaded with edit
below is my code
hotelcheck.coffee
$('.select2-autocomplete').each (i, e) ->
select = $(e)
options = {
multiple: false
width: "98%"
placeholder: "Type Hotel name"
minimumInputLength: 3
}
options.ajax =
url: select.data('source')
dataType: 'json'
type: "GET"
quietMillis: 250
# input untuk program
data: (term, page) ->
{ q: term,
page: page,
per: 25 }
results: (data) ->
{ results: $.map(data, (item) ->
{
text: item.name
id: item.id
}
) }
initSelection: (element, callback) ->
id = $(element).val()
if id != ''
$.ajax('/hotels/' + id + '.json', dataType: 'json').done (data) ->
selected =
id: element.val()
text: data.name
callback selected
return
return
options.dropdownCssClass = 'bigdrop'
select.select2 options
form to show hidden field, I save the content to hotel_id
<%= f.hidden_field :hotel_id, data: { source: search_name_hotels_path }, class: "select2-autocomplete", :value => "#{f.object.hotel_id unless f.object.new_record? || f.object.hotel_id.nil? }" %>
hotel controller for ajax send the value
def show
#hotel = Hotel.find(params[:id])
puts "running fill name"
respond_to do |format|
format.json { render json: #hotel }
end
end
source data = hotel table with field id, name
client table = order with field hotel_id
From this page, it looks like initSelection should NOT be in options.ajax, but just in options. I would try to copy the example they have and edit it to your needs. OR update to 4.0.0, which seems to be much easier.

Ajax call on a <select> in a formtastic form

I need in my app to select from a list of provider a provider, and then, via ajax, I could see below a list of categories, that belongs to a specific provider. I have a form in activeadmin:
<%= semantic_form_for [:admin, #game], builder: ActiveAdmin::FormBuilder do |f| %>
<%= f.semantic_errors :state %>
<%= f.inputs do %>
<%= f.input :categorization_id, label: 'Provider', as: :select,
collection: Provider.all.map { |provider| ["#{provider.name}", provider.id] },
input_html: { class: (:provider_select), 'data-url': category_select_path(provider: 4) } %>
<%= f.input :categorization_id, label: 'Category',input_html: { class: ('category_dropdown') }, as: :select,
collection: Category.all.map { |category| ["#{category.name}", category.id]}%>
...
<% end %>
<%= f.actions %>
<% end %>
In activeadmin controller I have:
controller do
def ajax_call
#provider = Provider.find(params[:provider])
#categories = #provider.categories
respond_to do |format|
format.json { render json: #categories }
end
end
end
JS:
$(document).on('ready page:load', function () {
$('.select.input.optional').last().addClass('hidden_row');
$('#game_categorization_id').change(function () {
var id_value = this.value;
$('.hidden_row').removeClass('hidden_row');
$.ajax({
type: 'GET',
url: '/admin/games/category_select'
// data: id_value
})
});
});
And the routes: match '/admin/games/category_select' => 'admin/games#ajax_call', via: :get, as: 'category_select'
I don't have an idea, how can I pass providers id from collection into url. Currently, I have there category_select_path(provider: 4), but actually it has to be smth. like this - category_select_path(provider: provider.id) In the browser, in a Network tab of devtools I can see my category_select, but there is an error: Couldn't find Game with 'id'=category_select. I can't figure out from where does it come. Any suggestions? Thanks.
The problem was in routes: match '/admin/games/category_select' => 'admin/games#ajax_call', via: :get, as: 'category_select'. It is reserved by a show action of Activeadmin controller. So I changed my routes to: get '/admin/select_category' => 'admin/games#get_providers_categories', as: 'select_category', and added to ajax call data: {provider: provider}, so I could fire in params id of provider:
$.ajax({
type: 'GET',
url: '/admin/select_category',
data: {
provider: provider
},
success: (function (data) {
$('#select_category').children('option').remove();
$('#select_category').prepend('<option value=""></option>');
$.each(data.categories, function () {
$('#select_category').append('<option value="' + this.id + '">' + this.name + '</option>')
})
})
})

How to Use Ajax in ruby on rails

I want send selected drop down menu value to controller by ajax
panel_controller.rb
class PanelController < ApplicationController
def insert
#city_ids = params[:city]
end
end
panel.js.erb
$(document).ready(function() {
$('#f_city_id').change(function() {
var city_js_id = this.value
$.ajax({
url: '/panel/insert',
type: 'GET',
data: {"city": city_js_id},
success: function (data,status)
{
alert(this.url);
}
});
return false;
});
});
routes.rb
get '/panel/insert' => 'panel#insert'
views/panel/insert.html.erb
<%= #city_ids %>
but #city_ids dont respond value after chenge drop down menu
You need to respond back from your insert method.
Try doing this
class PanelController < ApplicationController
def insert
#city_ids = params[:city]
respond_to do |format|
format.html { render partial: 'insert.html.erb' }
end
end
end
Create a partial file with the new content _insert.html.erb
<%= #city_ids %>
In you panel.js.erb try catching the response and append it in your DOM wherever necessary. Your updated value will be on the page.
$(document).ready(function() {
$('#f_city_id').change(function() {
var city_js_id = this.value
$.ajax({
url: '/panel/insert',
type: 'GET',
data: {"city": city_js_id},
success: function (res){
$("#somediv").html(res);
//You will get the partial's content with the new data and you'll only need to append it to your page.
}
});
return false;
});
});

acts_as_taggable_on and select2 returning weird results in Active Admin

So I have been playing around with acts_as_taggable_on in active admin, and for the most part everything is working as expected.
However, whenever I search for tags, and add an existing tag to a model, it seems to save it as the ID, rather than as the name. Creation of new tags returns the name fine, and when I go to edit the object again the tags remain tagged by the name. But when I try and add another tag, one that already exists in the database, it returns the name in the form, and seems to save OK, but when I go back to edit the onject again the tag shows up as an ID, rather than the name.
In admin/gift.rb:
controller do
def autocomplete_gift_tags
#tags = ActsAsTaggableOn::Tag
.where("name LIKE ?", "#{params[:q]}%")
.order(:name)
respond_to do |format|
format.json { render json: #tags , only: [:id, :name], root: false }
end
end
end
In tag-autocomlete.js:
$(document).ready(function() {
$('.tagselect').each(function() {
var placeholder = $(this).data('placeholder');
var url = $(this).data('url');
var saved = $(this).data('saved');
$(this).select2({
tags: true,
placeholder: placeholder,
minimumInputLength: 1,
initSelection: function(element, callback) {
saved && callback(saved);
},
ajax: {
url: url,
dataType: 'json',
data: function(term) {
return {
q: term
};
},
results: function(data) {
return {
results: data
};
}
},
createSearchChoice: function(term, data) {
if ($(data).filter(function() {
return this.name.localeCompare(term) === 0;
}).length === 0) {
return {
id: term,
name: term
};
}
},
formatResult: function(item, page) {
return item.name;
},
formatSelection: function(item, page) {
return item.name;
}
});
});
});
And in my _gift_form.html.erb:
<%= f.input :tag_list, label: "Tags", input_html: { data: { placeholder: "Enter tags", saved: f.object.tags.map{|t| {id: t.name, name: t.name}}.to_json, url: autocomplete_gift_tags_path }, class: 'tagselect' } %>
Can't work out why the new ones are working, but the existing tags are not.
change this:
respond_to do |format|
format.json { render json: #tags , only: [:id, :name], root: false }
end
to this:
respond_to do |format|
format.json { render :json => #tags.collect{|t| {:id => t.name, :name => t.name }}}
end

Getting 2 variables from 1 ajax call in ruby on rails

I was wondering how you can get 2 variables to update a div tag using an ajax call instead of just 1. My current .js file:
$(document).ready(function() {
$("select").change(function() {
var selected_product_id;
selected_product_id = $(this).val();
$.ajax({
url: "/products/" + selected_product_id,
type: "GET",
success: function(data) {
$("#description").empty().append(data);
}
});
});
});
show.html.erb where i get the data:
<%= #product.item %>
I would like something like this
$.ajax({
url: "/products/" + selected_product_id,
type: "GET",
success: function(data) {
$("#description").empty().append(data[1]);
$("#price").empty().append(data[2]);
}
});
with
<%= #product.item %>
<%= #product.price %>
where my description div gets updated with #product.item and my price div gets updated with #product.price. How could I achieve this?
EDIT
updated .js file
$(document).ready(function() {
$("select").change(function() {
var selected_product_id;
selected_product_id = $(this).val();
$.ajax({
url: "/products/" + selected_product_id,
type: "json",
success: function(data) {
$("#description").empty().append(product.item);
$("#price").empty().append(product.price)
}
});
});
});
show.html.erb:
<%= #product.item %>
<%= #product.price %>
controller:
class ProductsController < ApplicationController
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #product.to_json }
end
def index
end
def show
#product = Product.find(params[:id])
end
end
I'm pretty sure that controller isn't correct. I placed #product before respond_to and it didn't work so I just put respond_to without really knowing where it goes. Sorry for being such a noob. Thanks for all your help.
FINAL EDIT:
working javascript file:
$(document).ready(function() {
$("select").change(function() {
var selected_product_id;
selected_product_id = $(this).val();
$.getJSON("/products/"+selected_product_id,function(data){
$("#description").empty().append(data.item);
$("#price").empty().append(data.price);
});
});
});
Ah, This remembers me a piece of code I wrote for you a week ago!
You can use JSON to render your Product:
#controller
def show
#product = Product.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render :json => #product.to_json }
end
end
And handle the response from the server like this:
$.ajax({
url: "/products/" + selected_product_id,
dataType: 'JSON',
success: function(data) {
var product = JSON.parse(data);
$("#description").empty().append(product.item);
$("#price").empty().append(product.price);
}
});
Edit #1: I found this method: jQuery.getJSON : http://api.jquery.com/jQuery.getJSON/
You could use JSON, return
{"item": "<%=j #product.item %>", "price": <%= #produce.price %>}
then type: 'json' in the ajax call

Resources