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.
Related
I have a City Model:
class Geo::City < Smth
self.table_name = 'cities_table'
has_many :streets, class_name: "Geo::Street", primary_key: :geo_code, foreign_key: :geo_code
The aim is, to search all streets in the city and print them as a search result. In my controller I have a filter method as follows:
def filter
#city_list = city_list
params[:q] ||= {}
params[:q][:ags8_id_eq] = #city_list[0][1]
if params[:q].present? && params[:q][:geo_code_eq].present?
#city = Geo::City.find_by(geo_code: params[:q][:geo_code_eq])
#collection = [["#{#city}", "#{params[:q][:geo_code_eq]}"]]
end
#streets = #city.streets.limit(15)
#q = #streets.ransack(params[:q])
end
I also have a search_city method as follows:
def search_city
render json: city_list.select {|city| city.first.include?(params[:q][:geo_code_eq])}
end
And a private method city_list which I am calling in methods above:
def city_list
all_cities = Geo::City.order('city_name').reduce([]) {|cities, c| cities << [c.name, c.geo_code]}
I had to change all the method names,cause it's for work, so the_city list is kind of an example and it also works fine, I assume, this is not the problem. I also have a js-file for select 2.
(function() {
$(function() {
return $('.city-select2').select2({
ajax: {
url: "/filter/search_city",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: {
geo_code_eq: params.term
}
};
},
processResults: function(data) {
return {
results: $.map(data, function(obj) {
return {
id: obj[1],
text: obj[0]
};
})
};
},
cache: true
},
minimumInputLength: 2,
placeholder: "City",
tags: false,
tokenSeparators: [","],
selectOnClose: true,
allowClear: true
});
});
}).call(this);
It seems to be working, cause when I type city name it finds the city with the letters I typed. What happens after I submit select form is that I just get an empty array, so basically like this:
The url looks the following:
http://localhost:3000/filter/search_city?q%5Bgeo_code_eq%5D=16071003&commit=Search
My view does this:
= search_form_for #q, url: search_city_path do |f|
.columns.is-centered{style: 'padding-top: 100px;'}
.column.is-half
= f.select(:geo_code_eq, options_for_select(collection: #collection.present? ? #collection : [], input_html: { class: "city-select2 select-input" })
= f.submit "Search"
What is wrong? How do I get streets in the cities printed? There might be some spelling mistakes in the code, as I had to replace names, this won't be the reason for my empty array. Also, in the url there is only B selected, maybe that the reason? But it also finds the geo_code, so it should be capable of giving the streets back linked to geo_code, as geo_code is also the part of streets_table..
Main reason for the array was the path in the view. Should have been filter_path ans not the search_city_path, as it was the same path my select2 was getting data from, redirection there on submit made no sence.
I use select2 and want to create new tags and then save them.
i have form for #cost and for select2 this
<%= f.collection_select :product_ids, Product.all,:id, :name ,{include_hidden: false},{ multiple: true} %>
for creation new product i have this js code
$(document).ready(function () {
$('#cost_product_ids').select2({
tags: true,
tokenSeparators: [",", " "],
createProduct: function (product) {
return {
id: product.term,
text: product.term,
isNew: true
};
}
}).on("change", function (e) {
var isNew = $(this).find('[data-select2-tag="true"]');
if (isNew.length) {
$.ajax({
type: "POST",
url: "/product_new",
data: {product: isNew.val()}
});
}
});
});
and controller method for save new product
def product_new
product = Product.find_by(name:params[:product])
Product.create(name:params[:product]) if !product
render json: :ok
end
cost create action
def create
#cost = Cost.new(costs_params)
if #cost.save
flash[:notice] = t('added')
if params[:add_more].present?
redirect_back(fallback_location: root_path)
else
redirect_to #cost
end
else
render action: 'edit'
end
end
def costs_params
params.require(:cost).permit(:day, :amount, :description, :source,:tag_list,:product_ids=>[])
end
it works ok, but when i want to save my #cost record with this newly created product i have received only name of my tag without id.
For example i have products water=>id:1,beer=>id:2,and create new juice tag in db it has id:3
on create in have params "product_ids"=>["1", "2", "juice"]
How to fix it?
you shouldn't use id: product.term,
but id: product.id,
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;
});
}
});
Models:
User create Event, and each Event need a Court location, then a House location, the value of House depends on the value of Court, for example:
select Court A, returns House as A1, A2, A3
select Court B, returns House as B1, B2, B3
In Event Controller form:
def new
#event = current_user.events.build(event_params)
#courts = Court.all
#houses = House.where("court_id = ?", Court.first.id)
end
def edit
#event = Event.find(params[:id])
#courts = Court.where(:id => #event.court_id)
#houses = House.where(:id => #event.house_id)
end
In View form:
<%= f.label 'Event Location' %>
<%= f.select :court_id, options_for_select(#courts.collect { |court| [court.name, court.id] }, 1), {}, { id: 'courts_select' } %>
<%= f.select :house_id, options_for_select(#houses.collect { |house| [house.name, house.id] }, 0), {}, { id: 'houses_select' } %>
Javascript:
$(function() {
return $(document).on('change', '#courts_select', function(evt) {
return $.ajax('/events/update_houses', {
type: 'GET',
dataType: 'script',
data: {
court_id: $("#courts_select option:selected").val()
},
error: function(jqXHR, textStatus, errorThrown) {
return console.log("AJAX Error: " + textStatus);
},
success: function(data, textStatus, jqXHR) {
return console.log("Dynamic court select OK!");
}
});
});
});
Now this works fine when the user create the event, but when they want to edit, the Court and House Select only shows 1 value. It's because in the edit controller the where() only returns 1 value. How can I change my edit controller code so that at edit form, it returns the a list of choices and remembers the user's choice
For starters, you want to supply all Courts and the corresponding Houses for the currently-selected Court.
def edit
#event = Event.find(params[:id])
#courts = Court.all
#houses = House.where(:court_id => #event.court_id)
end
Then you want your selects to select the proper value from the dropdown. Instead of:
<%= f.select :court_id, options_for_select(#courts.collect { |court| [court.name, court.id] }, 1), {}, { id: 'courts_select' } %>
Something like:
<%= f.select :court_id, options_for_select(#courts.collect { |court| [court.name, court.id] }, #event.court_id), {}, { id: 'courts_select' } %>
... rinse and repeat for the House select
Hope that helps!
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