Search code examples
javascriptjqueryjquery-select2jquery-select2-4

Select2 v4 .val() does not maintain order of elements in data object


I have a select2 (v4) select box where people are choosing codes, and the order must be maintained. This works great when they originally add the elements: enter image description here

However, this is a popup that is used for many different elements on the page. That means I must clear this array and load it with stored data objects on the fly.

My data object preserves the order as var codeArray = ['7990', '268'].

But when I use:

$(element).val(codeArray).trigger("change")

I get the following:

enter image description here

How can I maintain the order on load? Is there a sneaky workaround?


Solution

  • Okay, the fix was pretty hacky, but I'll post what I have:

    function rebuildForm(codeArray) {
      clearFormContents();
      $.each(codeArray, function(j,obj){
        var found = false;
          code_list.some(function(el){
            if (el.value == obj) {
                var str = (el.text).split(")");
                $("element option[value=" + el.value + "]").remove();
                $(element).append(new Option("(" + el.value + ")" + str[1] , obj));
                found = true;
            }
          })
          if (!found) {
            $(element).append(new Option("(" + obj + ") Custom Tag" , obj));
          }
        $(element).val(codeArray).trigger("change");
    }
    

    Sorry if the above code doesn't work perfectly, I had to clean it up to remove some fluff and hide the client/project identity.

    Basically, on the rebuild of the form, I clear the old form contents then loop through the array grabbing each value/object. Then, if the value exists in the original code list of options in the select2 element I delete the option and rebuild it. This appends it to the bottom of the element list so that the order is maintained in the box. I also add any free form text tags using the 'found' boolean.

    Once the new list of options are created in the "correct" order, then I am able to add the values back into the select input DOM element and trigger the select2 change to build the tags.

    This thread posted by @RohitS in the comments showed the concept: https://github.com/select2/select2/issues/3106

    I just adapted it to my needs.