I have a Rails application that in the erb code, I use a select box. What I would like to do is reload the page passing the sort parameter. My controller already handles it, but I don't know how to reload the page with the selected value from my select box. Here is my code:
<% #options = {:latest => 'lastest' , :alphabetical => 'alphabetical', :pricelow => 'price-low', :pricehigh =>'pricehigh'} %>
<%= select_tag 'sort[]', options_for_select(#options), :include_blank => true,:onchange => "location.reload('location?sort='+this.value)"%>
Have you considered using an ajax call on your list box? If you have a method on your controller that returns just the sorted list, based on sort parameter, then you could do:
<% #options = {:latest => 'lastest' , :alphabetical => 'alphabetical', :pricelow => 'price-low', :pricehigh =>'pricehigh'} %>
<%= select_tag 'sort[]', options_for_select(#options), :include_blank => true,:onchange => remote_function(:url => {:controller => 'your_controller', :action => 'list_sort_method'}, :with => "'sort='+this.value", :update => "div_containing_list") %>
If you don't want to use AJAX, then put a form_tag around your code.
Take a look at the Redmine source code on http://redmine.rubyforge.org/svn/trunk. The UsersController does something similar - there's a combo box that allows a filter. Selecting the combo reloads the page.
Related
According https://github.com/nathanvda/cocoon#link_to_add_association you should be able to pass a function to data-association-insertion-node
I have tried this:
<%= link_to_add_association 'Add Timeslot', f, :timeslots, :data => {'association-insertion-node' => 'get_row()'} %>
And this:
<%= link_to_add_association 'Add Timeslot', f, :timeslots, :data => {'association-insertion-node' => 'get_row'} %>
And this (getting desperate):
<%= link_to_add_association 'Add Timeslot', f, :timeslots, :data => {'association-insertion-node' => 'function get_row(node){var row = "<tr></tr>";$("#table_body").append(row);return row;}'} %>
But none of them work.
Javascript:
function get_row(node){
var row = "<tr></tr>"
$("#table_body").append(row);
return row
}
I am trying to add a tr to a table and then append the nested timeslot form to the tr.
At the moment this is not possible what you are trying to do. When setting the data-association-insertion-method like this, it will just be a string in javascript, and not a reference to a method.
As documented in the README, you have to do the following (assuming you gave your links a class .add-timeslot):
$(document).on('turbolinks:load', function() {
$(".add-timeslot a").
data("association-insertion-method", 'append').
data("association-insertion-node", function(link){
return link.closest('.row').next('.row').find('.sub_tasks_form')
});
});
(the example is almost verbatim copied from documention for demonstration purposes only --you will have to fill in your get_row function)
I have the following select drop down in my rails. I'm following the syntax from the API( http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select):
collection_select(object, method, collection, value_method, text_method, options = {}, html_options = {})
<%= collection_select(:sources, :source_id, Source.all, :id, :name, :include_blank => "Please select a source...", html_options = {:onchange => "updateTextArea()"} ) %>
function updateTextArea(){
alert('source changed')
}
I'm able to get the drop down to display just fine with the values from the DB when I don't include html_options. However, I'm stuck trying to get an onchange action to occur.
I think options needs to be in a hash (the part you have include_blank in currently). Try changing this
<%= collection_select(:sources, :source_id, Source.all, :id, :name, :include_blank => "Please select a source...", html_options = {:onchange => "updateTextArea()"} ) %>
to this
<%= collection_select(:sources, :source_id, Source.all, :id, :name, options = {include_blank: "Please select a source..."}, html_options = {:onchange => "updateTextArea()"} ) %>
I believe that in place of options = or html_options = you need to pass actual hash itself (like you actually did with include_blank => true). I would only explicitly mark those hashes with curly braces to separate them:
<%= collection_select(:sources, :source_id, Source.all, :id, :name, { :include_blank => "Please select a source..."}, {:onchange => "updateTextArea()"} ) %>
Hope this helps.
EDIT:
I forgot to add that if updateTextArea() JS function is not bind to a window there might be a problem with picking it up (I had similar problems in the past). For safety I would also do (if you are not using CoffeScript):
window.updateTextArea = function() { /* Your code */ }
I'm trying to build a RoR app, with three models:
Games that can be classified in a Sector(called GameSector) and in a subsector (called GameSubsector)
A sector is made up of many subsectors.
a Subsector.
Here are my basic models relationships:
models/game.rb
belongs_to :game_sector, :foreign_key => 'game_sector_id', :counter_cache => true
belongs_to :game_subsector, :foreign_key => 'game_subsector_id',:counter_cache => true
I use Active Admin to input the Games, Sectors or subsectors information.
I have a very basic form when I create a game and I'd just like to make the second select drop down (game_subsector) adjust on the choice of the first select (gamesector) so that I don't the the whole (very long) list of game_subsectors but only those that belong to the game_sector I choose.
After dozens of tests and techniques tried but failing, I've finally used this dev's advice that appeared relevant to me: http://samuelmullen.com/2011/02/dynamic-dropdowns-with-rails-jquery-and-ajax/.
But it still does not work.
Here is the form on Active Admin which is located on admin/game.rb
ActiveAdmin.register Game do
menu :parent => "Campaigns", :priority => 1
controller do
with_role :admin_user
def game_subsectors_by_game_sector
if params[:id].present?
#game_subsectors = GameSector.find(params[:id]).game_subsectors
else
#game_subsectors = []
end
respond_to do |format|
format.js
end
end
end
form do |f|
f.inputs "Details" do
f.input :name
f.input :game_sector_id,
:label => "Select industry:",
:as => :select, :collection => GameSector.all(:order => :name),
:input_html => { :rel => "/game_sectors/game_subsectors_by_game_sector" }
f.input :game_subsector_id, :as => :select, :collection => GameSubsector.all(:order => :name)
f.actions
end
I feel the javascript is even maybe not fired.
The jquery I use is located on app/assets/javascript/admin/active_admin.js (I changed config so it loads this javascript when loading active admin pages)
jQuery.ajaxSetup({
'beforeSend': function(xhr) { xhr.setRequestHeader("Accept", "text/javascript"); }
});
$.fn.subSelectWithAjax = function() {
var that = this;
this.change(function() {
$.post(that.attr('rel'), {id: that.val()}, null, "script");
});
};
$("#game_game_sector_id").subSelectWithAjax(); //it it found in my view???
Finally I created a view as this expert adviced: in app/views/layout/ game_subsectors_by_game_sector.js.erb
$("#game_game_subsector_id").html('<%= options_for_select(#game_subsectors.map {|sc| [sc.name, sc.id]}).gsub(/n/, '') %>');
I'm not sure I have out it in the right place though...
What you need is:
Inspect with your web browser console your selects, and use a CSS selector to create a jQuery object for the sector select, something like:
$('#sector_select')
Append to this object a handler, so when it changes AJAX request is fired:
$('#sector_select').change(function(){
$.ajax('/subsectors/for_select', {sector_id: $(this).val()})
.done(function(response){ // 3. populate subsector select
$('#subsector_select').html(response);
});
});
See 3 in code, you need to inspect to get the right CSS selector. Be sure you are getting the expected response in the Network tab of your web browser inspector(if using Chrome).
You need a controller that answers in /subsectors/for_select, in the file app/controllers/subsectors_controller.rb:
class SubsectorsController < ApplicationController
def for_select
#subsectors = Subsector.where sector_id: params[:sector_id]
end
end
You need a view that returns the options to be populated app/views/subsectors/for_select.html.erb:
<% #subsectors.each do |ss| %>
<option value="<%= ss.id %>"><%= ss.name %></option>
<% end %>
You need a route:
get '/subsectors/for_select', to: 'subsectors#for_select'
I have a select tag which populates list of department names, When I select a value from drop down, I need to display an edit link below (link_to) and append the selected value of dropdown as id params.(I am not using form for this single select tag since I dont need to save value in my databse). How this could be possible. Please help. I am using rails2.3
I tried like the below but it didn't work.
Select A Dept
<%=select :select_dept, :dept, #dept.map{|dept| [dept.full_name, dept.id]},{:prompt => "#{t('select_a_batch')}"} %>
<%= link_to "Display", {:controller => "user", :action => "display_value", :id => $('#select_dept').val() } ,:class => "button" %>
Gopal is on the right track.
Give the link an id so you can pick it out
<%= link_to 'Display", {:controller ...}, :class => 'button', :id => 'display_link' %>
Hide it with CSS by default
#display_link { display:none; }
#display_link.showing { display:block; }
Then in javascript, do something like
$('#select_dept').on('change', function(ev) {
var deptId = $(this).find(':selected').val();
var newPath = '/users/' + deptId + '/display_value';
$('#display_link').attr('href', newPath);
$('#display_link').addClass('showing');
});
This will not set things up on page load, but you could run the same function you've passed as the change callback on page load to set things up (assuming one of the items might be selected on load).
I want to have form which shown fields based on the Type of Publications you select. I have used Single Table Inheritance (according to this [link] http://blog.thirst.co/post/14885390861/rails-single-table-inheritance) to create Publication model (base model), and subclasses (book_chapter, book_whole, conference_article, journal_article). Fields of Publications model are as follows: type, author, title, year, publication, volume, issue, page, keywords, abstract, publisher, placeofpublication, editor, seriestitle, seriesvolume, seriesissue, issn, isbn, area, url, doi.
So, based on the Type that will be chosen (for instance book_chapter), I want to have particular fields of Publications.
I handled to create dropdown list with types, but when select the type and create publications the Type record do not saved on database. This is the code for type dropdown
list
<%= f.label :type, :class => 'control-label' %>
<div class="controls">
<%= f.collection_select :type, Publication.order(:type), :id, :type, include_blank: true, :class => 'text_field' %>
</div>
</div>
Are you sure type is permited as an accessible param in your controller
def publication_params
params.require(:publication).permit(:type)
end
Are you sure the values for your options in the select are the right ones ?
Why is your collection_select containing :id
<%= f.collection_select :type, Publication.order(:type), :id, :type, include_blank: true, :class => 'text_field' %>
instead of :type
<%= f.collection_select :type, Publication.order(:type), :type, :type, include_blank: true, :class => 'text_field' %>
Regarding your second question, the answer will rely on a javascript / client side implementation.
Using jQuery you would implement something like this
# JS ($=jQuery)
# assuming your type select has id='type_select'
# assuming your fields inside your form have class 'field'
$('#type_select').change(function(event){
current_type = $(e.target).val();
$(e.target).parents('form').children('.field').each(function(el,i){
if($.inArray($(el).attr('id'), form_fields_for(current_type)){
$(el).show();
}else{
$(el).hide();
}
});
});
var form_fields_for= function(type){
{ book_chapter: [field1_id, field2_id, field3_id, field4_id],
book_whole: [field1_id, field2_id],
conference_article: [field1_id],
journal_article: [field1_id, field2_id, field3_id, field4_id, field5_id]
}[type];
};
Another solution would be to set specific classes for each fields for each of your types:
If we take the same assumptions as above, you would have rails to show a form like this:
# pseudocode (html form)
form
field1 class='book_chapter book_whole conference_article journal_article'
field2 class='book_chapter book_whole journal_article'
field3 class='book_chapter journal_article'
...
And then you would hide or show these specific classes
# JS ($=jQuery)
$('#type_select').change(function(event){
current_type = $(e.target).val();
$('.' + current_type).show();
$(e.target).parents('form').children('.field').each(function(el,i){
if(!$(el).hasClass(current_type)){
$(el).hide();
}
});
});