Adding new values to chosen plugin

Hey there!

Chosen is a jQuery Plugin, which gives some beautifully looking multiple selects in your form. The select can have some options populated, and the user can select one or multiple of them.

download

Recently, while using this plugin, I wanted to allow the user to add his own values to the list dynamically. Currently, in case the value is not there in the result, a ‘No result found’ message is shown.

1
No result found text.

I googled for a solution, and got some tweaks. This is what I did to achieve.

In the source code (chosen.jquery.js), I made a slight modification to the keyup_checker function.

1. Go to case 13 option in the switch block. (13 is the keycode for ‘Enter’)

if (this.results_showing) {
 return this.result_select(evt);
 }

What it currently does is, it checks whether there is a result bound to the user input, if so, it returns it. If not, it does nothing.

So, we need to handle when this condition fails, i.e. when the user inputs a value, and it does not match any result.

2. This is the code to handle it.

$(this.form_field).append('<option>' + $(evt.target).val() + '</option>');
$(this.form_field).trigger('chosen:updated');
this.result_highlight = this.search_results.find('li.active-result').last();
return this.result_select(evt);

$(evt.target).val() has the user input value. You add it to the list. Then do a chosen:update trigger to update the list.

According to the docs(link),

If you need to update the options in your select field and want Chosen to pick up the changes, you’ll need to trigger the “chosen:updated” event on the field. Chosen will re-build itself based on the updated content.

Finally, you add it to the results and return it.

Your final code in case 13 looks like this:

case 13:
 evt.preventDefault();
 if (this.results_showing) {
   if (!this.is_multiple || this.result_highlight) {
     return this.result_select(evt);
   }
   $(this.form_field).append('<option>' + $(evt.target).val() + '</option>');
   $(this.form_field).trigger('chosen:updated');
   this.result_highlight = this.search_results.find('li.active-result').last();
   return this.result_select(evt);
  }
  break;

You can also modify the ‘No result text’ text to include your added functionality.

$("#your-element").chosen(
 {no_results_text: "No result found. Press enter to add "}
);

Modify the text message.
Modify the text message.

 

3
Voila! Your input is added!

That’s all about it! 🙂

Do leave a comment if you have better solution.

Cheers,

Aishwarya 🙂

Advertisements

40 thoughts on “Adding new values to chosen plugin

  1. Hello, thank you for your idea. Please, could you share thhe final program file *.js for direct downloading?

    And I have a question. I need exactly this, i.e. to add a record if is not added yet. BUT. I need to add new content of one node in Drupal. So, no just add word, but add the whole node (for example I am adding car. In the list you see just name and types of cars /AUDI TT, SKODA SUPERB, CITROEN C6 et/, but in details of that nodes are pictures, characters, description, version etc… So if I will add new car for example “BMW xyz”, I also need to be redirected to form for add all the information to that node/content; not only the name of car).

    I am not good developer, but I have particular requirements for my pages..

    Thank you!

    Like

    1. Hi Kejmil,

      In my post above, look for the code snippet having case 13: (it is the last but one code).
      Find case 13: in your chosen.jquery.js file, and replace it with the code snippet I have provided.

      If you need to redirect the user to a form to add other details of the car, before the $(this.form_field).trigger(‘chosen:updated’); statement(can be found in the same code block as above), you need to redirect the user to your form page.

      Hope this helps. Let me know if you have any confusions.

      Like

  2. and please, I have change the code, but i dont know how to trigger the “chosen:updated”. I dont understand the process. Where to go and how to trigger it? what to set? how to update?

    Like

    1. Please check case 13: in the code snippet I have given.
      chosen:updated has already been triggered.

      Check this line: $(this.form_field).trigger(‘chosen:updated’);

      Like

  3. I got this website from my friend who told me concerning this web site and at the moment this time I am visiting this web page and reading very informative content here. kkdeabfbbbaf

    Like

  4. Hello there, just became alert to your blog through Google,
    and found that it is truly informative. I’m gonna watch out for brussels.
    I’ll be grateful if you continue this in future. Many people
    will be benefited from your writing. Cheers!

    Like

  5. I wanted to do the same & ran into your post. I needed to add some application logic besides just adding the value. So I decided to pass a callback function & execute it.

    I added these two lines in AbstractChosen.prototype.set_default_values to get the callback & a value to know if the add element functionailty is needed.

    this.add_no_result_not_found = this.options.add_no_result_not_found || false;
    /*
    (If we want the add functionality)
    */
    this.no_result_found_callback = this.options.no_result_found_callback || false;
    /*
    (The callback )
    */

    //This is my case 13 block inside keyup_checker
    if (this.results_showing) {
    if (this.result_highlight) {
    return this.result_select(evt);
    }
    if (this.add_no_result_not_found){
    if (typeof(this.no_result_found_callback) == ‘function’){
    this.no_result_found_callback($(evt.target).val());
    return this.result_select(evt);
    }
    }
    }

    The value is added inside my callback alongwith my application logic.

    My chosen invocation looks like this,

    if(addNotFound && notFoundCallback){
    options[‘add_no_result_not_found’] = addNotFound;
    options[‘no_result_found_callback’] = notFoundCallback;
    options[‘no_results_text’] = “Enter to add the option”;
    }
    select.chosen(options);

    Hope this help 🙂

    Like

  6. Hey Awesome stuff!
    I made it work but it doesn’t select the new entry automatically but it shows in the drop menu. Have you encountered the same issue?

    Regards

    Like

    1. I have found the solution you just need to add selected to the tag so instead of this:
      $(this.form_field).append(” + $(evt.target).val() + ”);
      is this:
      $(this.form_field).append(” + $(evt.target).val() + ”);

      This will add automatically to the list the new items.

      Again, awesome stuff!

      Like

  7. Hi Albert!

    Thanks for your comments.
    The new entry would automatically show up according to the code given above.
    Please check for the following line which performs the operation:
    return this.result_select(evt);

    Also, you have mentioned the same line of code in your solution comment, did you mean something else?

    I have found the solution you just need to add selected to the tag so instead of this:
    $(this.form_field).append(” + $(evt.target).val() + ”);
    is this:
    $(this.form_field).append(” + $(evt.target).val() + ”);

    Like

  8. i don’t know if your website messed up the formatting of your code when you copy and pasted it, but i had to make some changes to get mine to work.

    the code above looked like:

    .lasteturn this.result_select(evt);
    }

    i needed to end the last(); and fix the “return” part. changes seen below. your code also seemed to work only for single-selects, so i commented out the part that prevented it for working for multi-selects (which i needed too)

    case 13:
    evt.preventDefault();
    if (this.results_showing) {
    // if (this.is_multiple || this.result_highlight) {
    if (this.result_highlight) {
    return this.result_select(evt);
    }
    $(this.form_field).append(” + $(evt.target).val() + ”);
    $(this.form_field).trigger(‘chosen:updated’);
    this.result_highlight = this.search_results.find(‘li.active-result’).last();
    return this.result_select(evt);
    }

    Like

  9. Thank you for sharing useful knowledge.

    Please help me for following issues….

    this is in step 2 of your code
    this.result_highlight = this.search_results.find(‘li.active-result’).lastrn this.result_select(evt);

    and this is in step 3
    this.result_highlight = this.search_results.find(‘li.active-result’).lasteturn this.result_select(evt);
    i’m confusing @lastrn of step 2 and @lasteturn of step 3.
    Can you please explain it, If you don’t mind

    Like

  10. Thanks for the useful code! but I have an issue: the javascript array is (the one bonded to ng-options) is not updating. only the HTML is. how can I fix this?

    Like

  11. Am I doing something wrong – I can’t get this to add the term to the taxonomy when I save the form.

    I understand probably because I’m using a select list, which doesn’t allow adding taxonomy terms, but Chosen doesn’t work with Autocomplete Tagging widget (which does allow adding tags).

    Any help out for a noob?

    Like

  12. Great.. you made my day .. #Perfect trick I was looking for this solution.
    Need a help for one more problem . I have string (test1,test2,test3,test4) when users hits enter key i want separate the string and update a chosen listz with test1 and test2 and test3 and test4 as a 4 options selected …

    Below is my code

    case 13:
    //if (a.preventDefault(), this.results_showing)
    // return this.result_select(a);
    //break;
    a.preventDefault();
    if (this.results_showing) {
    if (!this.is_multiple || this.result_highlight) {
    return this.result_select(a);
    }
    if($(a.target).val().indexOf(‘,’) !== -1) {
    // console.log(“You are in”);
    // console.log($(a.target).val());
    var source =$(a.target).val().split(‘,’);
    //console.log(source);
    $.each(source, function (i) {
    console.log(source[i]);
    $(this.form_field).append(” + source[i] + ”);
    $(this.form_field).trigger(‘chosen:updated’);
    //this.result_highlight = this.search_results.find(‘.active-result’).last();
    //return this.result_select(a);
    });
    } else {
    $(this.form_field).append(” + $(a.target).val() + ”);
    $(this.form_field).trigger(‘chosen:updated’);
    this.result_highlight = this.search_results.find(‘.active-result’).last();
    return this.result_select(a);
    }
    }
    break;
    failed to update the list

    Like

    1. finally done with this 🙂
      case 13:
      //if (a.preventDefault(), this.results_showing)
      // return this.result_select(a);
      //break;

      a.preventDefault();
      if (this.results_showing) {
      if (!this.is_multiple || this.result_highlight) {
      return this.result_select(a);
      }
      if($(a.target).val().indexOf(‘,’) !== -1) {
      var source =$(a.target).val().split(‘,’);
      var inputId=$(this.form_field);
      inputId=inputId[0][‘id’];
      $.each(source, function (i) {
      $(“#”+inputId).append(” + source[i] + ”);
      $(“#”+inputId).trigger(‘chosen:updated’);
      });
      } else {
      $(this.form_field).append(” + $(a.target).val() + ”);
      $(this.form_field).trigger(‘chosen:updated’);
      }
      this.result_highlight = this.search_results.find(‘.active-result’).last();
      return this.result_select(a);}
      break;

      Like

  13. Hi in your code
    this.result_highlight = this.search_results.find(‘li.active-result’).lasteturn this.result_select(evt);
    this will get an error in javascript. The error is “expecting new line or semicolon”. Any idea how to fix this.

    Like

    1. Ok I have fix the problem there is a typo in your code

      In your code
      this.result_highlight = this.search_results.find(‘li.active-result’).lasteturn this.result_select(evt);

      I change it to
      this.result_highlight = this.search_results.find(‘.active-result’).last();
      return this.result_select(evt);

      Like

  14. Please can you show a demo of your code i’m trying to implement the same thing as you stated above but it is just disrupting the chosen format and making it a simple multiselect list,
    P.S. – I am trying it for a multiple select list ,

    Just a demo or a link where this is working would do 🙂 !

    Like

  15. Correct this line

    this.result_highlight = this.search_results.find(‘li.active-result’).lasteturn this.result_select(evt);

    to

    this.result_highlight = this.search_results.find(‘li.active-result’).last();
    return this.result_select(evt);

    Like

  16. Great Stuff !! I wanted to use this with a multi-select however i did notice that the code was wrong for the case 13 it should be this:

    case 13:
    evt.preventDefault();
    if (this.results_showing) {
    if (!this.is_multiple || this.result_highlight) {
    return this.result_select(evt);
    }
    $(this.form_field).append(” + $(evt.target).val() + ”);
    $(this.form_field).trigger(‘chosen:updated’);
    this.result_highlight = this.search_results.find(‘li.active-result’).last();
    return this.result_select(evt);
    }
    break;

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s