1
votes

I want to achieve following scenario with select2(4.0.0) and jquery(2.1.4):

  • I have a select box which takes data from external source (end point on java application server)
  • User can either pick one of the returned values or come up with his own value
  • Now when user submits the form and the validation on the server side fails I would like to display the form with all the values provided previously by the user, therefore select box should have the value send to the server.

To achieve that

  • I use ajax from select to query data from the server
  • I use createTag to allow user to create his own values
  • I wanted to use initSelection to prefill selectbox with a value previously added by user.

My code looks like this:

$("select[name='serie']").select2({
    ajax: {
        url: "http://javaendpoit/serie/filter",
        dataType: 'json',
        delay: 250,
        data: function (params) {
          return {
            name: params.term,
            page: params.page
          };
        },
        processResults: function (data, page) {
          return {
            results: $.map(data, function (item) {
              return {
                text: item.name,
                name: item.name,
                id: item.name
              }
            })
          };
        },
        cache: true
      },
      escapeMarkup: function (markup) { return markup; },
      minimumInputLength: 2,
      templateResult: formatRepo,
      templateSelection: formatRepoSelection,
      tags: true,
      createTag: function (tag) {
        return {
          id: tag.term,
          text: tag.term,
          name: tag.term,
          isNew : true
        };
      },
      /* below part is rendered by jsp so that it has the value from previous form submission; if it is initial form render the below part is not included */
      initSelection : function (element, callback) {
            callback({id:"Name",name:"Name","text":"Name"});
      }   
    });

 function formatRepo (serie) {
        if (serie.loading) return serie.text;
        var markup = '<div class="clearfix">' +
        '<div clas="col-sm-10">' +
        '<div class="clearfix">' +
        '<div class="col-xs-12">' + serie.name + '</div>' +
        '</div>';
        markup += '</div></div>';
        return markup;
  }

  function formatRepoSelection (serie) {
    return serie.name;
  }

This works just fine. Meaning that after the submission I can see value Name in the select box and it's the selected value. Nevertheless, if I try to submit this form again, the value is missing in the request.

As suggested in the number of topics here I added following line (see last line).

  /* [...] */
  initSelection : function (element, callback) {
        callback({id:"Name",name:"Name","text":"Name"});
  }   
}).select2("val","Name");

But after adding this the value Name is not even visible in the select2 box.

I have been trying to fix it for few hours now, but somehow cannot find the right solution. I bet I am missing some basic stuff. Plese help!

--- [EDIT]

After adding data I am able to see the value Name even when setting the value with val nevertheless if I resubmit the form this value is still not present in the request.

.select2('data',{id:"Name",name:"Name","text":"Name"})
.select2('val', "Name")

--- [EDIT 2]

In html I use select to create this element.

<select class="form-control" name="serie"></select>
2
This mailing list thread might help give you some pointers on how to do this.Kevin Brown
Also, in Select2 4.0.0 the select2('data') method is not writable and will trigger a warning if you set debug: true when initializing Select2.Kevin Brown
Hi. Thanks. I saw this thread before, but it had no responses until few our ago. Also I have checked the solutions proposed there (links to stackoverflow) but with no help. Nevertheless, I will try to re run the examples showed there during the weekend, maybe I have missed something. Regarding select2('data'), that explains why values specified there were not taken into account.wooki
Hi Kevin! I was able to solve the issue without using initSelection as you suggested in the mailing list thread. Thank you!wooki
The mailing list doesn't provide any solution to init locale data and then load data from ajax source. Initial html <option> aren't showing in the select2 dropdown. Any solutions ?singe3

2 Answers

3
votes

I manage to do that with select2 version 4.0.2 like this :

$("select[name='serie']").data('select2')
    .dataAdapter.select({
        id:"Name",
        name:"Name",
        "text":"Name"
    });
2
votes

Thanks to Kevin I was able to solve the puzzle. So ultimately I have given up on using initSelection. Instead I just filled select tag with options that should be selected.

<select class="form-control" id="author" name="author" multiple="multiple">
  <option value="name" selected="selected">name</option>
</select>

Removed initSelection from select2 definition

$("select[name='author']").select2({
    ajax: {
        url: "http://javaendpoit/serie/filter",
        dataType: 'json',
        delay: 250,
        data: function (params) {
            return {
                name: params.term,
                page: params.page
            };
        },
        processResults: function (data, page) {
            return {
                results: $.map(data, function (item) {
                    return {
                        text: item.name,
                        name: item.name,
                        id: item.name
                    }
                })
            };
        },
        cache: true
    },
    escapeMarkup: function (markup) {
        return markup;
    },
    minimumInputLength: 1,
    templateResult: formatRepo,
    templateSelection: formatRepoSelection,
    tags: true,
    createTag: function (tag) {
        return {
            id: tag.term,
            text: tag.term,
            name: tag.term,
            isNew: true
        };
    }
});

And changed formatRepoSelection to work with values without name attribute.

function formatRepoSelection(serie) {
    if (serie.name === undefined) {
        return serie.text;
    } else {
        return serie.name;
    }
}

I guess I could not use name attribute in the formatRepo and could remove the if clause for formatRepoSelection. But this is just a minor fix.