Select2 4.1 add newTag from ajax won't change ID

I try to create newTag and set the new ID from server response, the newTag is successfully identified and inserted to database, but the new ID value not set properly.

I’m using Laravel so the url part are using laravel blade template.

Here’s the server response when newTag successfully inserted to database:

{"response":{"news_tags":"lorem-ipsum","tags_id":61290}}

and this is my Select2 code :

$(".tags").select2({
          ajax : {
            url : "{{ url('get_tags/') }}",
            data : function(params){
              var query   = {
                keywords : params.term
              }

              return query;
            },
            processResults : function(data){
                return {
                  results : $.map( data.items, function( obj ) {
                              return {
                                text : obj.news_tags,
                                id   : obj.tags_id
                              };
                            })
                };
            }
          },
          createTag: function (params) {
            var term = $.trim(params.term);

            if (term === '') {
              return null;
            }

            return {
              id: term,
              text: term,
              newTag: true // add additional parameters
            }
          },
          minimumInputLength : 3,
          tags: true
      }).on("select2:select", function (e){
          if(e.params.data.tag == false) {
            return;
          }

          var select2element  = $(this);

          if(e.params.data.newTag === true)
          {
            $.ajax({
                url : "{{ url('new_tags/') }}",
                data: { "new_tags" : e.params.data.text },
                type: "POST",
                success: function( res )
                {
                  data =  {
                    "id" : res.response.tags_id,
                    "text" : res.response.news_tags
                  }

                  var selection   = select2element.val();
                  var index       = selection.indexOf( res.response.news_tags );

                  if( index !== -1 )
                  {
                      selection[index]  = res.response.tags_id.toString();
                  }

                  select2element.val(selection).trigger("change");

                },
            });
          }
      });

Anyone can help me to resolve this issue?

Your processResults callback expects a response object that contains an array field called “items” , but your server’s response doesn’t include this field. Review your server-side coffee and make sure it’s outputting the correct data format.

I’ve changed the response to "items" but the value of new tags doesn’t change to the latest ID, you can see in the last value “sit dolor amet” on image below.

image

I’m sorry; I think I steered you wrong. It looks like you had the data format right the first time.

However, I think I’ve found the real problem: You’re calling the jQuery .val() function on the <select> and (apparently) thinking that changing a value in that returned array and assigning it back to the <select> will change the value attribute of the underlying <option>s the array represents. But it will not. You need to get the actual <option> element that represents the new tag and change its id attribute directly. Then trigger the “change” event on the <select> (you don’t need to call .val() before doing so, because your new tag’s <option> is already selected).

You can do what you want with the following jQuery:

success: function(res) {
    // Find the <option> element corresponding to the new tag...
    $('option#' + res.response.news_tags, select2element)
        // ...and change its `id` attribute to the ID value from the AJAX call.
        .attr('id', res.response_tags_id);
    // Inform Select2 that the <option> has changed.
    select2element.trigger("change");
}
1 Like

Thank you for your suggestion John, finally can fix this issue
I do little modification in case if any other people facing same issue.

success: function( res )
{
              // Find option based on user input because i remove space and replace it with '-'
              // And using value="" not  id (#)
              $('option[value="' + e.params.data.text + '"]', select2element)
               // change the value so when user press submit the IDs will be sent to server side
               .attr('value', res.response.tags_id);

               // Inform Select2 that the <option> has changed.
               select2element.trigger("change");
},

Awesome! I’m glad you got it working.

That’s great. however, struggling in getting another new tag added. Only latest is saved. i believe i would need to iterate on new tags, but no idea how to do it.

NB: all new tags are created in DB.

please help!