#258 Token Fields (revised)
The Chosen plugin makes it easy to turn a many-to-many select menu into a searchable token field. Then see how the jQuery Tokeninput field can help with AJAX loading and creating new records.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Hey, you are missing when user did not select any item on the list, episode-258 / revised / bookstore-chosen-after.
I do the following:
before_filter :clear_medicine_ids, only: [:create, :update]
def clear_medicine_ids
@medical_consultation.medicine_ids = [] unless params[:medical_consultation][:medicine_ids].present?
end
thank you, somehow it didn't work with filtering, but I used
@medical_consultation.medicine_ids = [] unless params[:medical_consultation][:medicine_ids].present?
directly in update and create action and now it works nice.
Great episode Ryan, but i think is better to use:
ilike
instead of using:
like
To avoid problems with case sensitive strings.
And another tip for using TokenInput is to set the option of:
preventDuplicates: true
'ilike' dosn't work for mysql.
MySql has an alternative: 'select * from foo where upper(bar) like upper(?)'.
preventDuplicates is really useful, thanks
TokenInput seems great. It strikes me as a great solution for tags. Any comments on this?
A little late to this party, but yes, he does mentions this in the notes for "tagging" episode, along with autocomplete.
Great episode, but shouldn't the token source be based on a path or url function like this?
Please note this is from a project that uses Mongoid and SimpleForm.
In order for this to work you have to use the following syntax:
Not sure why this is the case. The preventDuplicates option is just to show for extra options that a comma is needed (but it is super useful).
i need to set the border-color dynamically????
Hi
any idea why the content in field with the .tokenInput() is not sent with the rest of the form? I'm using mongoid
in my coffee script file:
$("#profile_tagg_tokens").tokenInput '/taggs.json'
theme: 'facebook'
In my form (using slim)
=f.text_field :tagg_tokens
In my model
attr_accessible :user_tags, :displayname, :city, :country, :tagg_tokens
attr_reader :tagg_tokens
What I'm trying to achieve is:
- user creates his profile(city, displayname, etc...) and selects taggs from a taggs list
My issue is as soon as I call .tokenInput on the taggs_token text_field, the content is not sent when the form is submitted
Thx for your help
Another excellent and very useful episode. Folks, there is a pattern here. When Ryan says, "Hold on to your seats." He is not kidding. That is when he is at his best :) Hey Ryan, please make a point of saying that every week in either the "Pro" or the "Revised" episodes :)
Best regards,
Bharat
+1
I've a little question about Ruby: at 5:46, when Bates wrote
attr_accessible :author_tokens
,attr_reader :author_tokens
will be optional, right?No its not. It seems you are confusing attr_accessible with attr_accessor.
Awesome episode. Thanks Ryan.
Is there a way to configure Chosen to support the inline create option?
Check out https://github.com/harvesthq/chosen/pull/166
Ryan - Thanks for another great episode.
Anyone using Chosen with Twitter Bootstrap? Any issues?
Yep... https://github.com/leonkenneth/jquery-tokeninput-bootstrap-theme
I think it was built for an older version of bootstrap, I had to set the appropriate widths to 200px for it to look just right. My issues could also be simple_form related, so I'm not sure.
Thanks. I had trouble getting that less theme to work, so I just decided to make my own css theme based off of the facebook theme. I put it on github if anyone else would like to give it a try:
https://github.com/fw-coder/jQuery-TokenInput-Bootstrap-CSS-Theme
You just set the theme to facebook and drop in this css file in place of the facebook css file.
A friend of mine has put together a select2-rails gem if anyone is interested.
I love Select2 - I started with Chosen, but ended up going with Select2 for the flexibility and great looking (bootstrap friendly) styles.
Using it on a submission form on metajury.com
Nice. i like the vote up thingy..... Just out of curiosity how come you are not precompiling your assets for better performance?
hey, i accidentially broke your site. Also your tagging system is stuck at "please enter 1 more characters"[sic]
cool site. has already proven to be extremely useful for me as i have been scoping out ipad cases recently, and came across this: http://www.kickstarter.com/projects/552506690/brydge-ipad-do-more
Has anyone here used Select2 without any problems? It looks pretty awesome, but on github it currently has 76 total downloads, which is discouraging. I just wonder how supported it will be in the future if I were to implement it in an app.
The current select2-rails gem has 114 downloads so far, if it helps you. :)
Hello, I get this error when trying to create the author_token field using simple_form:
The funny thing is I get that error even if I do this:
Seems that no matter what I put into
:data =>
I keep getting this error. I even get it if I don't usesimple_form
but the regularform_for
tag. I should mention that I'm using Ruby 1.8.7 if that makes any difference.Help please.
You have to pass the html_options into the input_html option
SimpleForm README
I tried this as well and I get the same error. I even tried this:
Please disregard, I was being an idiot and my method in book.rb had this
Instead of this:
Does anyone know how to make Chosen behave with existing styles? It works in my simple_form based forms but it is completely out of whack with the styling of other elements? My form elements have the labels at the top with the input boxes/dropdowns in the bottom. Chosen forces the labels to be on left hand side. Also it is misaligned.
Any pointers on how to make it blend with the rest of the form?
Thanks.
Bharat
Does anyone know how to add the new
to the results when token input can find something? I tried just doing
but for some reason that throws out an error. Firebug tells me the error is 'value undefined' and the token input drop down list disappears. I just don't get it. If the authors is empty it will return the new field just fine but if it finds any results it does not like the new added in.
if you get the 'value is undefined' it might be because the property it should be searching for isn't set in the tokeninput settings
For instance, if the field that holds the names in your Authors model isn't called names, you need to specify it in the tokenInput option called "propertyToSearch" and change ti to propertyToSearch: "title" (or however you identify your authors)
You'll see it in the configuration settings here.
http://loopj.com/jquery-tokeninput/
Has anyone figure this out?
For example, in my app I have a genre field, and if, say "Punk Rock" is already an option, and someone wants to just add "Punk", "Punk Rock" shows up in the dropdown and there is no option to add just "Punk".
Seems that If you want to add anything that is already included in another name you won't be able to.
authors << {id: "<<<#{query}>>>", name: "New: \"#{query}\""}
Removing the brackets makes it work.
thank you : it worked here too :
def self.tokens(query)
filter_query = query.gsub(/[^a-zA-Z&\s]/, '')
filter_query = filter_query.strip
topics = where("LOWER(name) like ?", "%# {filter_query.downcase}%")
topics << {id: "<<<#{query}>>>", name: "New: \"##{filter_query}\""}
end
I was able to create the relationship with a many to many, but with a many to one (where the book table has a corresponding ID for the format table for example) it doesn't work.
I can search but it will not save the values, nor will it prepolue the existing ones.
I'm sure I'm doing something wrong, but I pretty much copy/pasted the one for authors. Is there anything else that needs to change for this to work?
I don't get any javascript errors or warnings whatsoever.
Thanks.
Turns out that the field expects the values to be an array and in a many to one the result is a string so I've amended the code to this in the form:
Which does list the entry properly, but even if I add another one, it will not save it. The resulting json list is in proper array format (I can see it with: http://localhost:3000/list_formats.json?q=hard), so I'm still missing something.
Thanks.
I'm using form_tag not form_for. I got the autocomplete working but when I submit the form, no parameters are passed. If I remove the javascript and submit the form, my inputs are passed as expected. Any ideas?
hello, i was wondering if it was possible to have the drop down display something different from what the user selects? ie in stack overflow, if you type in java, it might display something like 'java x 34' because its count is 34. but when you select it, it just becomes 'java'. is it possible to do it with the jquery token input? ive been reading the documentation and it seems like it only has the :id and :name attribute. i tried doing something like...
tags.map{ |tag| { id: "#{tag.id}", name: "#{tag.name} x #{tag.count}", value: "#{tag.name}" } }
but no success. any ideas?
thanks = )
hello I am trying to save to the field society_id which takes the data from User table (current_user.society_id). I am using Devise.
def self.ids_from_tokens(tokens)
tokens.gsub!(/<<<(.+?)>>>/) { create!(name: $1, society_id: current_user.society_id).id}
tokens.split(',')
end
It gives an error undefined variable current_user.
Current_user is defined by Devise for controller and view but it doesn't work with model i guess.
can someone help me how to make it work
I'm having the same problem.
I know that the helper method I have for
current_user
is not available in models. Since this goesI read a post where someone suggested storing the current user inside the Model (http://rails-bestpractices.com/posts/47-fetch-current-user-in-models) but I'm leary of that solution because it seems like a bad idea to store something that might leak to other users.
This is a bit of a blocker since it's important to tie a particular tag to a user.
Did you ever figure out a solution to this? I'd also like to be able to save a user_id with the token record getting created.
I ran into the same method. I have a project model with many conflicts through project_conflicts. I want to isolate conflicts to the user that generates them though.
My solution was to add an after_create callback on the join model that updated the newly generated conflict object with the project's user_id. This seems to be working since the join belongs to both and is created last.
Did you find out how to solve this? I have the same problem here.
I'm having problems with chosen.
jQuery ->
$('#resource_tag_ids').chosen()
is returning
Uncaught TypeError: Object [object Object] has no method 'chosen'
in Chrome.(Putting tags on a resource instead of authors on a book, but that shouldn't matter)
I can see that for some reason the chosen javascript file is being included twice, one with code, and the other is a blank 4 lines... which is really odd.
I'm getting the same error as David Fisher no matter what browser I use. I'm using rails 3.2.5. I've tried both the 'chosen-rails' gem and installing the files by hand.
Object # has no method 'chosen'
I'm getting the same error, also tried it both ways, no luck. Anybody figured it out?
I am assuming you added the require's in your assets for js & css ...
Run rake assets:precompile and see if it errors out?
If that doesn't fix it let me know there is a few other tricks with development mode for the asset pipeline.
Thanks, I had the same issue, and that was it - recompiling assets helped!
recompiling doesn't work for me. what else should I try?
Great episode as always. One small question thought: What's the best way to handle validation? (Especially if you create multiple new records using jquery tokeninput)
Has anyone gotten the TokenInput to work with Nested Forms from his revised #196 episode? (http://railscasts.com/episodes/196-nested-model-form-revised)
yes, after you insert a new field, find the select element and call chosen on it.
In my case it was like this:
this is my association:
I add the class chzn-select which is used to find the element.
+1
Thanks a lot.
There is some magic in the tokenInput code i don't understand. It's closely related to one of the problems I'm having at the moment.
seems to create the association between book and authors.
Now the problem. What if I have more attributes on the book_author join table I wish to set before saving the association?
How can I go about this, I'm pretty lost at the moment as I've tried several ways but none works nicely and looks like the Rails way to do it.
PLEASE HELP - any hint would be greately appreciated!
I have used this with my meal planner app. I have it working but wonder, as above user. Can you add additional data? Example
I have it working to add ingredients to a meal. How could I specify the quantity of each ingredient? I am experimenting with the onAdd method, any help would be appreciated.
For my app, my models are Feature instead of Book, Tag instead of Author and Tagging instead of Authorship.
I must have made a mistake:
I'm getting an error NameError in FeaturesController#create of
uninitialized constant Feature::Tagging
and under the trace:
app/models/feature.rb:33:in
tag_tokens='`app/controllers/features_controller.rb:66:in
create'`Has anyone else made this mistake?
Thank you,
Doug
solved
How did you solve this? I am having exactly the same issue.
A little sad that after so long, jQuery-tokeninput still doesn't support adding new tags.
I needed a simple solution for tagging. The usual Tag => HABTM <= User stuff.
I tried a different solution, using Drew Wilson's Autosuggest and ActsAsTaggableOn. Save the tag tokens as textfields and insert those those as tags.
Because ActsAsTaggableOn has those stuff like removing entries without associations etc, so that's all I did.
I am having trouble getting the javascript to load properly
any suggestions on what I'm missing and yes it is loaded in the list of scripts
If you're using acts-as-taggable-on and you're getting 'Validation failed: Context can't be blank', the following should work:
You'll still need to split:
Quick and dirty way to even add new tags on the fly.
Maybe a better way is to just change the behavior on the client side?
Is there any idea not to select the name that is already choosen in token input? for example In first i select mango when i search for m. Next time again when i search for m Mango should not be displayed as mango is already choosen. Is there any idea?
hi, were you able to do that? if so how?
I've spent hours trying to get Chosen to work and have posted question on Stackoverflow with no luck--including necessary lines in application.js, application.css, and adding the appropriate coffeescript. I'm using Bootstrap and think that may be getting in the way. Are there any css directories I should be clearing out? Thanks!
Hi there, anybody know how I can implement this to self referential model. I am creating a record and on a form view also creating any associations needed if exists. if it doesn't exist, I should be able to add new one like in this railscast. this is where I got stuck. can anybody please help. Thanks!
i need to set the border-color dynamically????
Hi Ryan, great episode.. thank you.
anyone know what formtastic needs in the form to replace the collection_select for the first example (using Chosen). I have this:
f.input :change_set_revisions, :as => :select, :collection => ChangeSetRevision.all.sort_by(&:name).reverse
but it sticks with the normal multiple-select drop-down box. I do not get the javascript decoration.
@chewmanfoo, I'm not sure but I'm guessing you're missing the css style and instantiating the behavior:
And then instantiate add the behavior to elements with the
.chzn-select
css class:Hi I have a problem, only the first row of my table is the right chosen dropdown and the next rows are not.
I have an issue where the form is sending nil when it has found a match for the query.
anyone know what up wit dat?
My needs are a little different than the video. I want a field where I can put in the name of a book. It does the index jason search and has a tokenLimit of 1. If the book is not found - it makes a new book. If the book is found I want the controller to direct me to the book that already exists show page. For some reason right now if the book is found it sends an empty name parameter to the controller and I cant figure out why.
got it - had to set the tokenValue
Has anybody got the tokeninput example working with Postgres? I've tried substituting the like for ilike and ILIKE but it doesn't seem to work, in the console the q is registering but the query itself remains blank, %%. Any help would be appreciated.
I am using this in conjunction with Postgres by using texticle. So far it seems to be working quite well.
hm, for me using pg in production everything worked fine so far with tags = where("name ILIKE ?", "%#{query}%"). The problem thus seems to be somewhere else in your app i guess.
Thank you so much! The issue was pg using different query syntax. good to know!
I'm still having an issue where the existing tags don't show up when I go to the edit page.
Anyone realize that tokeninput doesn't work on IE9? Seems like a pretty obvious no-go considering 17% of the internet still uses IE.
Looks it does work in IE9:
https://github.com/loopj/jquery-tokeninput/issues/236
Die to IE9!
Does someone know how to implement the same function of this railscast instead of jQuery tokeninput with select2?
after upgrading from rails 3.2 to 3.2.13 tokeninput doesn't get the results anymore. Something doesn't work. The only clue I have are these 2 parameters that weren't sent in 3.2:
/tags.json?callback=jQuery191040979262322760657_1364525075625&q=books&_=1364525075627
All the logic in controller and model works fine. The request goes through, but then the results aren't submitted back to tokeninput. Does anybody experience similar things in 3.2.13??
i was able to find out that it's not rails 3.2.13 which causes the misfunctioning. still didn't find the real problem tho
this is inexplicable to me. if I make the exact same requests in the console (even with the 2 strange parameters), everything works fine and I get the results. However, in the token form the results aren't displayed. This normally should mean that the tokeninput itself is the problem, however, it is an exact copy of a different app where it works just fine.
edit: might the usage of subdomains be the problem?
the form is within a subdomain blogs, I make the call to /tags.json that doesn't have a subdomain in front of it.
fixed. this had nothing to do with rails 3.2.13 or so. The problem was tokeninput was making a crossDomain request from within a subdomain towards a path without a subdomain, logically. I should have noticed. All I needed to do was to send the json response together with the callback. Should have done more research on this topic. Sorry
Missing this!
Got this from the source.
Can someone please help me - very desperate, will pay!
My very simple Rails App has a Model with two methods:
:From :To
I use the awesome (Google Maps API) powered address-rails-picker app for the :to and :from in the form to automplete any location the user types in.
I do however have trouble in writing a validation that forces the user to choose an autocomplete location instead of writing any gibberish the user wants.
Would the Token Input help here by limiting it to one? I don't wan the Facebook look though with the X etc.
Thank you, Ryan.
I got a syntax error with tokenInput and Rails 3.2.13, but fortunately fixed it by myself.
I guess that the new version of CoffeeScript compiler in Rails caused it.
What I got was
The solution is simple.
Just add "," after '/tags.json' in books.js.coffee.
Would you also need a comma after 'facebook'? If not, why?
this works, thanks!
How do you use this plugin with SimpleForm?
I have issue integrating tokeninput facebook them with bootstrap modal. I googled the issue and it looks like a z-index problem. But I cannot get it working after trying every solutions. I would really appreciate if there could be a tutorial on tokeninput with bootstrap (maybe with modal)
If I want to create a Book manually, how do I pass the Authors manually? An array doesn't seem to work. I'd basically like to do something like:
I need to call the create action from another model... and I can't seem to pass the author_tokens properly.
for anyone that comes across it... the format that it needs to be in is just a string of ids, separated by commas.
I have an issue with several has many throughs connecting the same models. As an example Book and Person connected through Reader and Writer. How does my equivalent of "author_tokens" setter method distinguish which one to save?
I have made reader_tokens and writer_tokens methods, but when they do
self.person_ids = Person.ids_from_token(tokens) I can't name the relationship (reader or writer). Should I move my method to the relationship models, or how can I modify them, so they work?
And in anyone else has a similar issue, the solution was simple. I had tried already but not for all my hmts at the same time, so didn't get the right outcome. All you have to do is make an alias like this:
has_many: reader_persons, :through => :persons, :source => :person
def reader_tokens=(tokens)
self.reader_person_ids = Person.ids_from_tokens(tokens)
end
and similar for writer_persons
Hi,
How can I implement tokeninput in Rails 4 ?
With the strong parameters I can't use attr_accessor so it doesn't work.
Any idea ?
I'm using Rails 4 and haven't needed the attr_accessor, I've used attr_reader :author_tokens though and it works
Well I'm a comparative newbie here but with my limited Rails4 work I would suggest whitelisting by doing this (using Ryan's example). In the private area of the books controller add the author_ids to the book_params:
Many Thanks! codeduffer
Since rails 4.0.1 it is not working anymore. Cause activerecord is doing a check which results in the following error: "ActiveRecord::RecordNotFound (Couldn't find all Tasks with IDs (2, 3, 1) (found 0 results, but was looking for 3)):"
I did opened a issue a github for it: https://github.com/rails/rails/issues/14272
I ran into the same issue. Had to add the following strong params to the books_controller
http://stackoverflow.com/questions/23212898/tokeninput-not-load-the-existing-data-unless-reloading-page
I followed the railscast tutorial , but I found I can not load the "saved tokens".
I think the problem is that when click 'edit' link (created by scaffold),
it didn't trigger the preload function, how do you fix the problems in Rails 4
View page
My coffeescript
Require the css and js file
Did you fix it?
I too have the same problem. any help
Thank you so much, I've been looking for doing this with has_many :through for so long. I'm trying to work this with autocomplete as well. It's surprising how so few results there are for "has many through autocomplete" in a search.
How would you implement chosen or select2 if your has_many through join table is not using the default id as a primary key? Is the syntax
author_ids
something rails handles automagically in the standard join table?Did anyone get the saving to work? My search works fine but I can't insert anything to my join table. Sample please!
Testing with capybara/cucumber? check my gist https://gist.github.com/victorhazbun87/46d86d9de77540bbbceb
Any solution on prepopulating the authors data in edit page. It's not working for me. I am using rails 4.2.8 version.
_form.html.erb
<%= f.label :author_tokens, "Authors" %>
<%= f.text_field :author_tokens, data: { load: "@book.authors" } %>
books.coffee
jQuery ->
$('#book_author_tokens').tokenInput '/authors.json'
theme: 'facebook'
prePopulate: $('#book_author_tokens').data('load')