I have users pick genres from an autocomplete field. This field is in the edit view of the profile, so I have accepts_nested_attributes_for :genres in the Profile model. Also, Genre and Profile have a has_and_belongs_to_many association with one another. My question is how do you take the genres that the user picks and set them for that user's profile? What kind of controller code would I need? Would the code go in the profiles or genres controller?
I'm using this for autocomplete: http://loopj.com/jquery-tokeninput/ I've already prepopulated the genres table and hooked up the script to the text field. Right now when a user types, the autocomplete successfully displays suggestions. Now I want to update the database with the selected genres. This database is a join table between genres and profiles. How and where do I do this?
To sum up, I want to save the association between the profile id and the ids of the genres selected into the join table when I click the button in the profile edit view. Right now I get this error:
ActiveRecord::UnknownAttributeError in ProfilesController#update
unknown attribute: genre
Rails.root: /rubyprograms/dreamstill
app/controllers/profiles_controller.rb:18:in `update'
app/controllers/profiles_controller.rb:17:in `update'
Here's my profile edit view:
<%= form_for(:profile, #profile, :url => {:controller => "profiles", :action => "update"}, :html => { :multipart => true, :method => :put }) do |f| %>
...
<%= f.fields_for :genre do |g| %>
<div class="field">
<%= g.label :name, "Genres" %><br />
<%= g.text_field :name, :id => 'genre_field' %>
</div>
<% end %>
...
<div class="action">
<%= f.submit :profile, :value => "Update Profile" %>
</div>
<% end %>
Check this page http://loopj.com/jquery-tokeninput/demo.html
In this page clicking on submit alerts ids of the element, as per my understanding.
The script below in head does it
<script type="text/javascript">
$(document).ready(function() {
$("input[type=button]").click(function () {
alert("Would submit: " + $(this).siblings("input[type=text]").val());
});
});
</script>
This mat help you..
Basically there is an hidden text field which stores ids of the selected elements
Related
I have a 'country' model in my app with attributes name and status. If a country is activated, its status will be 1. Admin type of user can toggle this so I have given a multiple select dropdown for the same. My problem, how to update all the selected/unselected countries at one hit of submit button ?
My form on settings page for Admin user -
<%= simple_form_for #country do |form| %>
<%= form.collection_select :name, Country.order(:name), :id, :name, {:selected => #selected}, {:multiple => true, :class =>"ui fluid selection dropdown"} %>
<%= form.submit 'Submit' %>
<% end %>
Controller -
def settings
#country = Country.new
#selected = Country.where(status: '1').pluck(:id)
end
And the script -
<script>
$(document).on('turbolinks:load', function() {
$('.ui.dropdown').dropdown();
});
In my rails application the following relationships exist:
user belongs_to :team ,
element belongs_to :team ,
task belongs_to :element
A user can then create a task which belongs to an element.
When a user is creating a task, they can select the element they would like the task to belong to. How do I show only the elements that belong to the current_user's team? I am using Devise to get the current_user.
The samples below do not work.
<div class="field">
<%= form.label :element_id %>
<%= form.select :element_id, options_for_select(Element.current_user.team_id.map{|s|[s.title, s.id]}),{ :multiple => true} %>
</div>
I also tried to call the method below from the tasks_controller.rb file but it didnt work either
def new
#task = Task.new
#tasks_element_dropdown = Element.current_user.team_id.map{|s|[s.title, s.id]}
end
In the tasks/_form.html.erb file, I called the method with the code below
<%= form.select :element_id, options_for_select(#tasks_element_dropdown),{ :multiple => true} %>
When I tried the example below it does work but it displays all elements, and I only want the elements that belong to the user's team to display
<div class="field">
<%= form.label :element_id %>
<%= form.select :element_id, options_for_select(Element.all.map{|s|[s.title, s.id]}),{ :multiple => true} %>
</div>
The problem is in the following code, which should return the elements:
Element.current_user.team_id.map{|s|[s.title, s.id]}
Since you have a user, you can get the team: current_user.team
And then get the elements of the team (as long as has_many :elements is defined in the Team class): current_user.team.elements
Thus, the final code should be something like:
<div class="field">
<%= form.label :element_id %>
<%= form.select :element_id, options_for_select(current_user.team.elements.map{ |s| [s.title, s.id] }),{ :multiple => true} %>
</div>
I've been trying to get some dynamic select functionality working, but despite many different tutorial i've yet to get it to work. For ease of reading, i've brought the code examples down to basics. Any advise would be greatly appreciated.
On the faults page, i need to assign a company and contact to the fault, but I only want to be able to see the contacts associated with the selected company
Fault - belongs_to :company, :user, :contact
User - has_many :faults
Contacts - has_and_belongs_to_many :companies
Company - has_and_belongs_to_many :contacts, has_many :faults
/faults/_form.html.erb
<%= f.label :company, "Company:" %>
<%= collection_select(:fault,:company_id,#companies,:id,:full_name, :prompt => "Please select a company") %></br>
<%= f.label :contact, "Contact:" %>
<%= f.collection_select :contact_id, #contacts, :id, :name, :prompt => "Select a Contact" %>
<%= link_to "Add New Contact", {:controller => "companies", :action => "index"}, :confirm => "To add a contact for a company you need to do this from the companies page." %></br>
Gotcha. Using UJS you can dynamically populate your select in 5 steps.
Add class names to your selects in the view
Add JavaScript (or CoffeeScript) to watch the changes on the select element
Create a controller method to fetch the info you need based on your selection
Add a route to match your new controller method
Create a UJS view to update your contacts select
So,
Add class names:
<%= f.label :company, "Company:" %>
<%= collection_select(:fault,:company_id,#companies,:id,:name, {:prompt => "Please select a company"}, {:class => "company_selection"}) %>
<%= f.label :contact, "Contact:" %>
<%= f.collection_select :contact_id, #contacts, :id, :name, {:prompt => "Select a Contact"}, {:class=>"contact_selection"} %>
Throw in some CoffeeScript (app/assets/javascripts/faults.js.coffee)
$(document).ready ->
$(".company_selection").on "change", ->
$.ajax
url: "/faults/get_contacts"
type: "GET"
dataType: "script"
data:
company_id: $('.company_selection option:selected').val()
Update your faults controller
def get_contacts
#company = Company.find params[:company_id]
#contacts = #company.contacts
end
Add a route to your new method
resources :faults do
collection do
get 'get_contacts', to: "faults#get_contacts"
end
end
Add the UJS file (app/views/faults/get_contacts.js.erb)
$('.contact_selection').empty();
$('.contact_selection').append( $('<option>Select the Contact</option>'));
<% #contacts.each do |contact| %>
$('.contact_selection').append($('<option value="<%= contact.id %>"><%= contact.name %></option>'));
<% end %>
Vanilla JS Option
This can be achieved with vanilla javascript only. Make sure that there is a route at companies/[id]/contacts.json which returns correct data.
const select = document.querySelector('#company_id');
select.addEventListener('change',function(e) {
axios.get(`/companies/${e.target.value}/contacts.json`)
.then((res) => {
let contactSelect = document.querySelector('#contact_id')
contactSelect.innerHTML = ''
res.data.map((model, i) => {
contactSelect.options[i] = new Option(model.name, model.id);
})
})
});
I want to create a task and assign to a particular user who has_one profile with first name and last name.
And also user has_many tasks.
My new task form is
<%= form_for :task do |f| %>
<div>
<%= f.label :task %>
<%= f.text_area :task %>
</div>
<div>
<%= f.label :assigned_to %>
<%= f.collection_select(:assigned_to, User.profile.all, :fist_name, :fist_name, :include_blank => 'None')%>
</div>
in the collection select I should display something like " Sam Parker (sam#org.com)" like this all the users should be available in the collection select field.
Can anyone help me how to display it.
First of all read the documentation here:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormBuilder.html#method-i-collection_select
I guess you need to create a method that returns the option's text, for example:
class User < ActiveRecordBase
# ...
def label_for_select
"#{profile.full_name} (#{profile.email})"
end
end
Then, in your view it would be something like:
<div>
<%= f.label :assigned_to_id %>
<%= f.collection_select(:assigned_to_id, User.all, :id, :label_for_select, :include_blank => 'None')%>
</div>
Notice that the form sets the assigned_to_id not the assign_to ruby object. Rails will instantiate the assign_to object based on this id.
I have a set of 3 collection_selects that I would like to filter the next select. Upon selecting an item in the first select box, it should limit the possible values of the second and third select boxes.
A similar data model would be as follows...
Tables, and fields
Lock
lock_id
brand_id
master_id
regular_id
Lock Brand
brand_id
Master Key
master_id
brand_id
Regular Key
regular_id
brand_id
So while filling in the form for adding a new Lock there would be select boxes for brand, master, and regular. Upon selecting a brand, it would then limit the master and regular keys to those that are only of the selected brand.
I've found a couple partial examples of how to do this, however none are complete. I'd appreciate a complete example of how to implement this.
All you need to do is bind the selects with an event listener that fires off an ajax request populating the other 2 partials containing the subsequent selects. i.e.
<%= form_for #thing, :remote => true do, :update => 'second_form' |f| %>
<%= hidden_field_tag 'form_partial', :value => 'form_2' %>
<%= select_tag :some_param, [[a,a],[b,b],[c,c]] :class => 'submittable' %>
<%= f.label :checked %>
<%= thing.name %>
<% end %>
<div id='second_form'>
</div>
<div id='third_form'>
</div>
class ThingController < ApplicationController
def update
checkboxes = some_logic_to_select_checkboxes from params[:some_params]
render :partial => params[:form_partial], :locals => {:select_menu => select_menu}
end
end
$('.submittable').live('change', function() {
$(this).parents('form:first').submit();
return false;
});
Your form partial should contain your forms populated with whatever selects you want enabled. Thought is was redundant to just repeat the form.