Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select2: Update option after selecting new tag

I implemented a tagging system where you can choose from existing tags or add new tags. After a new tag has been selected it will persisted using an AJAX call.

For achieving this I use the callback createTag and the event select2:select. Because I like to create the tag only when it is selected I do an AJAX call for this if the event select2:select gets triggered.

The problem is that I need to update the already created option of select2 with the ID I get from persisting my new tag to the database. What's the cleanest solution for this?

Here's what I have:

$('select.tags').select2({
     tags: true,
     ajax: {
         url: '{{ path('tag_auto_complete') }}',
         processResults: function (data) {
             return {
                 results: data.items,
                 pagination: {
                     more: false
                 }
             };
         }
     },
     createTag: function (tag) {
         return {
             id: tag.term, // <-- this one should get exchanged after persisting the new tag
             text: tag.term,
             tag: true
         };
     }
 }).on('select2:select', function (evt) {
     if(evt.params.data.tag == false) {
         return;
     }

     $.post('{{ path('tag_crrate_auto_complete') }}', { name: evt.params.data.text }, function( data ) {
        // ----> Here I need to update the option created in "createTag" with the ID
        option_to_update.value = data.id;

     }, "json");
 });
like image 740
TiMESPLiNTER Avatar asked Dec 08 '15 21:12

TiMESPLiNTER


People also ask

How do you add new option if not exist in the list using Select2?

New options can be added to a Select2 control programmatically by creating a new Javascript Option object and appending it to the control: var data = { id: 1, text: 'Barn owl' }; var newOption = new Option(data.text, data.id, false, false); $('#mySelect2').append(newOption).trigger('change');

How do I create a Select2 dynamically?

HTML. Create a <select class="select2_el" > element to initialize select2 on page load and create <div id="elements" > container to store <select > element on button click using jQuery AJAX.

How do I use Select2 tags?

Automatic tokenization into tags Select2 supports ability to add choices automatically as the user is typing into the search field. Try typing in the search field below and entering a space or a comma. The separators that should be used when tokenizing can be specified using the tokenSeparators options.

What Select2 dropdown?

By default, Select2 will attach the dropdown to the end of the body and will absolutely position it to appear above or below the selection container. Select2 will display the dropdown above the container if there is not enough space below the container, but there is enough space above it.


1 Answers

My problem was that I did not add the new tag as an <option> tag to the native select field.

This is necessary because select2 checks for the values set trough select2.val(values) if an <option> tag with this value does exist. If not select2 silently throws the value out of the array and sets the array of values which have a corresponding option tag in the underlying select field.

So this is how it works correct now (for select2 4.0.x):

$('select.tags').select2({
     tags: true,
     ajax: {
         url: '{{ path('tag_auto_complete') }}',
         processResults: function (data) {
             return {
                 results: data.items,
                 pagination: {
                     more: false
                 }
             };
         }
     },
     createTag: function (tag) {
         return {
             id: tag.term,
             text: tag.term,
             tag: true
         };
     }
 }).on('select2:select', function (evt) {
     if(evt.params.data.tag == false) {
         return;
     }

     var select2Element = $(this);

     $.post('{{ path('tag_crrate_auto_complete') }}', { name: evt.params.data.text }, function( data ) {
        // Add HTML option to select field
        $('<option value="' + data.id + '">' + data.text + '</option>').appendTo(select2Element);

        // Replace the tag name in the current selection with the new persisted ID
        var selection = select2Element.val();
        var index = selection.indexOf(data.text);            

        if (index !== -1) {
            selection[index] = data.id.toString();
        }

        select2Element.val(selection).trigger('change');

     }, 'json');
 });

The minimal AJAX response (JSON format) has to look like this:

[
    {'id': '1', 'text': 'foo'},
    {'id': '2', 'text': 'bar'},
    {'id': '3', 'text': 'baz'}
]

You may add additional data to each result for let's say own rendering of the result list with additional data in it.

like image 63
TiMESPLiNTER Avatar answered Sep 21 '22 01:09

TiMESPLiNTER