I'm trying to display the recent scores of a team from a database based on the selection from a collection_select drop down. I know that I need to listen for the change event on the drop down but I don't know how to do the AJAX request or how to display the data in the view.
Ok, I will write a example with category and subcategory models.
The first is relation between models:
class Category
has_many :subcategories
has_many :objects
end
class Subcategory
belongs_to :category
has_many :objects
end
class Object
belongs_to :category
belongs_to :subcategory
end
Now the form on view, for example with simple_form gem (you can do it with form_for):
<%= simple_form_for(#object, :html => {:multipart => true }) do |f| %>
<%= f.input :category, :collection => Category.all :prompt => "Select Category" %>
<%= f.input :subcategory, :label_html => { :class => 'subcategory_label_class' } do %>
<%= f.grouped_collection_select :subcategory_id, Category.order_by(:title), :subcategories, :title, :id, :name, include_blank: true %>
<% end %>
<%= f.button :submit %>
<% end %>
With this we grouped the subcategories with their parent category.
The next step you must add the code to your objects.js.coffee
$('#object_subcategory_id').parent().hide()
subcategories = $('#object_subcategory_id').html()
$('#object_category').change ->
category = $('#object_category :selected').text()
escaped_category = category.replace(/([ #;&,.+*~\':"!^$[\]()=>|\/#])/g, '\\$1')
options = $(subcategories).filter("optgroup[label='#{escaped_category}']").html()
if options
$('#object_subcategory_id').html(options)
$('.subcategory_label_class').show()
$('#object_subcategory_id').parent().show()
else
$('#object_subcategory_id').empty()
$('.subcategory_label_class').hide()
$('#object_subcategory_id').parent().hide()
You can adapt this example to your needs.
I hope it helps.
Regards!
you need to build a separate controller and send the ajax request when your change event is triggered, the controller sends back a js response, that you have to handle in your clients javascript... the following link should give you an example http://blog.bernatfarrero.com/jquery-and-rails-3-mini-tutorial/
Related
I am trying to set up some dynamic Dropdown Select Menus in a Search Form using form_tag. What I would like is similar functionality to the example found at Railcasts #88
Models:
class Count < ActiveRecord::Base
belongs_to :host
end
class Host < ActiveRecord::Base
belongs_to :site
has_many :counts
end
class Site < ActiveRecord::Base
belongs_to :state
has_many :hosts
end
class State < ActiveRecord::Base
has_many :sites
end
View:
<%= form_tag(counts_path, :method => "get", id: "search-form") do %>
<%= select_tag "state_id", options_from_collection_for_select(State.all.order(:name), :id, :name) %>
<%= select_tag "site_id", options_from_collection_for_select(Site.all.order(:name), :id, :name) %>
<% end %>
A State has_many Sites which has_many Hosts which has many Counts. Or conversely, Counts belong_to Host whichs belongs_to Site which belongs to State
So I would like to select a state from the States dropdown that would then "group" the Sites based on the state they associate through the Host.
I have struggled with this nested association and can't seem to figure out how build the grouped_collection_select.
I know I'm overlooking something obvious! Could sure use some pointers...
You can fire jquery-ajax request. Change event in first select box will call action on controller and called method will change the value of second dropdown through ajax call. Simple example:
In your view file:
<%= select_tag 'state_id', options_for_select(State.all.order(:name), :id, :name) %>
<%= select_tag "site_id", options_for_select(Site.all.order(:name), :id, :name) %>
In JS file of that controller:
$(document).on('ready page:load', function () {
$('#state_id').change(function(event){
$("#site_id").attr('disabled', 'disabled')
$.ajax({
type:'post',
url:'/NameOfController/NameOfMethod',
data:{ state_id: $(this).val() },
dataType:"script"
});
event.stopImmediatePropagation();
});
});
In NameOfController.rb
def NameOfMethod
##no need to write anything
end
In NameOfMethod.js.erb
<% if params[:state_id].present? %>
$("#site_id").html("<%= escape_javascript(render(partial: 'site_dropdown'))%>")
<% end %>
in _site_dropdown.html.erb file:
<% if params[:state_id].present? %>
<%= select_tag 'site_id', options_for_select(Site.where("state_id = ?", params[:state_id])) %>
<% else %>
<%= select_tag "site_id", options_for_select(Site.all.order(:name), :id, :name) %>
So it will change site dropdown based on selected state dropdown. You can go upto n number of level for searching. Good luck.
I have problem.
I want to my posts/new.html.erb join dropdown.
I have two model post and category.
I hope when new post can choose my category.
posts/new.html.erb/
<%= simple_form_for #post do |f|%>
<%= f.input :category_id, as: :select %>
<% end %>
helper/posts.helper.rb
def collect_category
#cat_arr = []
Category.all.each do |cat|
#cat_arr = cat
end
return #cat_arr
end
I can't understand simple_form collection
Please help me, thx!
On your Post model, make sure you have:
belongs_to :category, class_name: "Category"
And your Category model, put:
has_many :posts, class_name: "Post"
Now on your form, you can do:
<%= f.association :category, as: :select %>
Optional: collection: Category.all(order: 'name') or whatever you want to display it by and order if you want.
You'll probably have to add attr_accessor for category_id on your Post model as well.
I am creating a category select dropdown to add categories to an event.
I can add them and they are showing in the form for the edit area, I can see the categories added in the backend.
When I try to show them in the views it gives me this strange error inside the layout:
<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Category:0x00000102542f10>
In my setup I have got this:
views/events/index.html.erb
<%=
event.categories.each do |events|
category.name
end
%>
models/category.rb
class Category < ActiveRecord::Base
belongs_to :event
belongs_to :profile
belongs_to :classified
belongs_to :page
extend FriendlyId
friendly_id :name, use: :slugged
end
admin/category.rb
ActiveAdmin.register Category do
controller do
def permitted_params
params.permit category: [:name, :description]
end
def find_resource
scoped_collection.friendly.find(params[:id])
end
end
form do |f|
f.inputs "Name" do
f.input :name
end
f.inputs "Description" do
f.input :description, :as => :ckeditor, :label => false, :input_html => { :ckeditor => { :toolbar => 'Full', :height => 400 } }
end
f.actions
end
end
In my categories table there is an event_id column in there so it can fnd the associated event and it links to both the events table and the categories table.
Any insight into this would be great
Thanks
Update views/events/index.html.erb as below:
<% if event.categories.count > 0 %>
<% event.categories.each do |category| %> ## Use <% %> to evaluate ruby code
<%= category.name %> ## Use <%= %> To evaluate and show the results
<% end %>
<% end %>
In your case, <%= %> will return event.categories value which is an instance of <ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_Category which is what you see on the rendered page.
UPDATE
OP also had foreign_key concerns. Add foreign_keys for event, profile, classified and page in categories table.
When using simple_form and creating a field for a HABTM associated model, we obtain a select box that accepts multiple options.
Is there any way of having multiple select boxes that accept a single option?
If we have categories, for example:
Category1 => <select>options...</select>
Category2 => <select>options...</select>
Category3 => <select>options...</select>
etc...
Assuming the following models:
class Business < ActiveRecord::Base
has_and_belongs_to_many :categories
class Category < ActiveRecord::Base
has_and_belongts_to_many :businesses
You can use the following rails helper to show a select box for each category.
- #business.categories.each do |c|
= f.collection_select :category_ids, Category.all, :id, :name, {:selected => c.id}, {:name => 'business[category_ids][]'}
Then you can use javascript to dynamically create new select boxes. This railscast explains the basics.
Within a simple_form_for eg states/regions
class State < ActiveRecord::Base
has_and_belongs_to_many :regions
(leaving out unnecessary form elements for clarity)
<%= simple_form_for #state do |f| %>
<%= f.association :regions, as: :check_boxes, collection: Region.all.sort, :selected => #state.regions, :label => false %>
<% end %>
This will display all Regions (obviously you can filter it) as a list of checkboxes, with those already recorded being selected
Im writing a form which uses formtastic to manage the BusinessUnit model, however when creating a new BusinessUnit it also has to create a number of other record types. The associations between the models are as below:
class BusinessUnit < ActiveRecord::Base
has_many :business_unit_sites
has_many :locations
class BusinessUnitSite < ActiveRecord::Base
belongs_to :site
belongs_to :business_unit
class Site < ActiveRecord::Base
has_many :locations
has_many :business_unit_sites
class Location < ActiveRecord::Base
belongs_to :business_unit
belongs_to :site
When a BusinessUnit is created, a Site must also be created using BusinessUnitSite as a join table. In addition a Location record should be created which must hold a foreign key to the new Site record and this is where Im having problems.
I can create a new Location using a nested form (below) but the Site will have to be created manually.
<%= semantic_form_for #business_unit do |f| %>
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :business_unit_id %>
<%= f.input :business_unit_group, :include_blank => false %>
<%= f.input :business_unit_type %>
<%= f.input :tax_region, :include_blank => false %>
<%= f.semantic_fields_for :locations do |l| %>
<%= l.input :name, :label => "Location Name" %>
<% end %>
<% end %>
<%= f.buttons %>
<% end %>
What is the best way to create the Location, Site records and ensure that Location holds the foreign key of the newly created Site?
You probably want to do something like using the "fields_for" approach for the sub-objects in your form.
See this related answer:
Multiple objects in a Rails form
More info about fields_for:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html
http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for