Original Select2 4.0.0 with Ajax

I have select2 v4.0.0 populated from an Ajax array. If I installed val select2, I can see, using javascript debugging, that it has selected the correct item (# 3 in my case), however this is not shown in the select box, it still shows placeholder. enter image description here

While I should see something like this: enter image description here

In my form fields:

<input name="creditor_id" type="hidden" value="3"> <div class="form-group minimal form-gap-after"> <span class="col-xs-3 control-label minimal"> <label for="Creditor:">Creditor:</label> </span> <div class="col-xs-9"> <div class="input-group col-xs-8 pull-left select2-bootstrap-prepend"> <select class="creditor_select2 input-xlarge form-control minimal select2 col-xs-8"> <option></option> </select> </div> </div> </div> 

My javascript:

 var initial_creditor_id = "3"; $(".creditor_select2").select2({ ajax: { url: "/admin/api/transactions/creditorlist", dataType: 'json', delay: 250, data: function (params) { return { q: params.term, c_id: initial_creditor_id, page: params.page }; }, processResults: function (data, page) { return { results: data }; }, cache: true }, placeholder: "Search for a Creditor", width: "element", theme: "bootstrap", allowClear: true }).on("select2:select", function (e) { var selected = e.params.data; if (typeof selected !== "undefined") { $("[name='creditor_id']").val(selected.creditor_id); $("#allocationsDiv").hide(); $("[name='amount_cash']").val(""); $("[name='amount_cheque']").val(""); $("[name='amount_direct']").val(""); $("[name='amount_creditcard']").val(""); } }).on("select2:unselecting", function (e) { $("form").each(function () { this.reset() }); ("#allocationsDiv").hide(); $("[name='creditor_id']").val(""); }).val(initial_creditor_id); 

How can I make the selected item and not placeholder in the selection box? Should I post this as part of an AJAX JSON response, perhaps?

In the past, Select2 required the initSelection parameter, which was defined whenever a custom data source was used, allowing you to determine the initial selection for the component. This worked fine for me in version 3.5.

+95
jquery-select2-4
May 19 '15 at 4:07
source share
12 answers

You are doing most of the things right, it seems that the only problem you are facing is that you are not running the change method after setting a new value. Without the change event, Select2 cannot know that the base value has changed, so it will only display the placeholder. Change your last part to

 .val(initial_creditor_id).trigger('change'); 

Your problem should fix, and you should immediately see the user interface update.




It is assumed that you already have an <option> that has value initial_creditor_id . If you did not select Select2 and the browser, you really cannot change the value, since there is no way to switch, and Select2 will not determine the new value. I noticed that your <select> contains only one parameter, one for the placeholder, which means you will need to create a new <option> manually.

 var $option = $("<option selected></option>").val(initial_creditor_id).text("Whatever Select2 should display"); 

Then add it to the <select> that you initialized Select2 on. You may need to get text from an external source in which initSelection used to enter the game, which is still possible with Select2 4.0.0. Like the standard selection, this means that you will need to make an AJAX request to get the value, and then adjust the <option> text on the fly to configure.

 var $select = $('.creditor_select2'); $select.select2(/* ... */); // initialize Select2 and any events var $option = $('<option selected>Loading...</option>').val(initial_creditor_id); $select.append($option).trigger('change'); // append the option and update Select2 $.ajax({ // make the request for the selected data object type: 'GET', url: '/api/for/single/creditor/' + initial_creditor_id, dataType: 'json' }).then(function (data) { // Here we should have the data object $option.text(data.text).val(data.id); // update the text that is displayed (and maybe even the value) $option.removeData(); // remove any caching data that might be associated $select.trigger('change'); // notify JavaScript components of possible changes }); 

Although this may seem like a lot of code, this is how you will do it for select boxes other than Select2 to ensure that all changes have been made.

+109
May 19 '15 at 14:49
source share

What I did is cleaner and requires two arrays:

  • one contains a list of objects with an identifier and text (in my case, its id and name, depending on your Result template) (its what you get from an ajax request)
  • the second is just an array of identifiers (selection value)

I initialize select2 using the first array as data and the second as val.

An example function with parameters a dict id: name.

 function initMyList(values) { var selected = []; var initials = []; for (var s in values) { initials.push({id: s, name: values[s].name}); selected.push(s); } $('#myselect2').select2({ data: initials, ajax: { url: "/path/to/value/", dataType: 'json', delay: 250, data: function (params) { return { term: params.term, page: params.page || 1, }; }, processResults: function (data, params) { params.page = params.page || 1; return { results: data.items, pagination: { more: (params.page * 30) < data.total_count } }; }, cache: true }, minimumInputLength: 1, tokenSeparators: [",", " "], placeholder: "Select none, one or many values", templateResult: function (item) { return item.name; }, templateSelection: function (item) { return item.name; }, matcher: function(term, text) { return text.name.toUpperCase().indexOf(term.toUpperCase()) != -1; }, }); $('#myselect2').val(selected).trigger('change'); } 

You can feed the initial value using ajax calls and use jquery promises to initialize select2.

+27
Jul 01 '16 at 9:14
source share

The forced trigger('change') problem drove me crazy, as I had special code in the change trigger, which should only fire when the user changes a parameter in the drop-down list. IMO, the change should not be triggered when setting the initial value at the beginning.

I dug deep and found the following: https://github.com/select2/select2/issues/3620

Example:

$dropDown.val(1).trigger('change.select2');

+6
Feb 27 '16 at 0:35
source share

One scenario that I have not seen people actually responding to is how to make a preliminary selection if the AJAX parameters are received, and you can select several. Since this is a preview version for AJAX preselection, I will add my solution here.

 $('#mySelect').select2({ ajax: { url: endpoint, dataType: 'json', data: [ { // Each of these gets processed by fnRenderResults. id: usersId, text: usersFullName, full_name: usersFullName, email: usersEmail, image_url: usersImageUrl, selected: true // Causes the selection to actually get selected. } ], processResults: function(data) { return { results: data.users, pagination: { more: data.next !== null } }; } }, templateResult: fnRenderResults, templateSelection: fnRenderSelection, // Renders the result with my own style selectOnClose: true }); 
+4
Mar 21 '17 at 13:08
source share

It works for me...

Do not use jQuery, only HTML: create a parameter value that you will display as selected . If the ID is in select2 data, it will be selected automatically.

 <select id="select2" name="mySelect2"> <option value="mySelectedValue"> Hello, I'm here! </option> </select> 

Select2.org - Preselected Defaults

+4
Aug 22 '17 at 13:17
source share

If you use templateSelection and ajax, some of these other answers may not work. It seems that creating a new option element and setting value and text will not satisfy the template method when your data objects use values ​​other than id and text.

Here is what worked for me:

 $("#selectElem").select2({ ajax: { ... }, data: [YOUR_DEFAULT_OBJECT], templateSelection: yourCustomTemplate } 

Have a look here jsFiddle: https://jsfiddle.net/shanabus/f8h1xnv4

In my case, I had to processResults , because my data did not contain the required fields id and text . If you need to do this, you will also need to run your initial selection using the same function. For example:

 $(".js-select2").select2({ ajax: { url: SOME_URL, processResults: processData }, data: processData([YOUR_INIT_OBJECT]).results, minimumInputLength: 1, templateSelection: myCustomTemplate }); function processData(data) { var mapdata = $.map(data, function (obj) { obj.id = obj.Id; obj.text = '[' + obj.Code + '] ' + obj.Description; return obj; }); return { results: mapdata }; } function myCustomTemplate(item) { return '<strong>' + item.Code + '</strong> - ' + item.Description; } 
+3
May 12 '17 at 16:05
source share

After spending several hours finding a solution, I decided to create my own. It is he:

  function CustomInitSelect2(element, options) { if (options.url) { $.ajax({ type: 'GET', url: options.url, dataType: 'json' }).then(function (data) { element.select2({ data: data }); if (options.initialValue) { element.val(options.initialValue).trigger('change'); } }); } } 

And you can initialize selections using this function:

 $('.select2').each(function (index, element) { var item = $(element); if (item.data('url')) { CustomInitSelect2(item, { url: item.data('url'), initialValue: item.data('value') }); } else { item.select2(); } }); 

And of course, here is the html:

 <select class="form-control select2" id="test1" data-url="mysite/load" data-value="123"></select> 
+1
Apr 01 '17 at 22:00
source share

https://github.com/select2/select2/issues/4272 only this solved my problem. even if you set the default value using a parameter, you must format the object that has the text attribute, and that is what you want to show in your parameter. So your formatting function should use || select an attribute that is not empty.

+1
Jun 10 '19 at 12:46 on
source share

I add this answer mainly because I can not comment on the above! I found this to be a comment by @Nicki and her jsfiddle, https://jsfiddle.net/57co6c95/ , which ultimately made me work for me.

Among other things, he gave examples of the format for json. The only change I had to make was that my original results were returned in the same format as the other ajax call, so I had to use

 $option.text(data[0].text).val(data[0].id); 

but not

 $option.text(data.text).val(data.id); 
0
Dec 14 '16 at 9:57
source share

Create a simple ajax combination with initial seleted value for select2 4.0.3

 <select name="mycombo" id="mycombo""></select> <script> document.addEventListener("DOMContentLoaded", function (event) { selectMaker.create('table', 'idname', '1', $("#mycombo"), 2, 'type'); }); </script> 

library.js

 var selectMaker = { create: function (table, fieldname, initialSelected, input, minimumInputLength = 3, type ='',placeholder = 'Select a element') { if (input.data('select2')) { input.select2("destroy"); } input.select2({ placeholder: placeholder, width: '100%', minimumInputLength: minimumInputLength, containerCssClass: type, dropdownCssClass: type, ajax: { url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type, type: 'post', dataType: 'json', contentType: "application/json", delay: 250, data: function (params) { return { term: params.term, // search term page: params.page }; }, processResults: function (data) { return { results: $.map(data.items, function (item) { return { text: item.name, id: item.id } }) }; } } }); if (initialSelected>0) { var $option = $('<option selected>Cargando...</option>').val(0); input.append($option).trigger('change'); // append the option and update Select2 $.ajax({// make the request for the selected data object type: 'GET', url: 'ajaxValues.php?getQuery=true&table=' + table + '&fieldname=' + fieldname + '&type=' + type + '&initialSelected=' + initialSelected, dataType: 'json' }).then(function (data) { // Here we should have the data object $option.text(data.items[0].name).val(data.items[0].id); // update the text that is displayed (and maybe even the value) $option.removeData(); // remove any caching data that might be associated input.trigger('change'); // notify JavaScript components of possible changes }); } } }; 

and server side php

 <?php if (isset($_GET['getQuery']) && isset($_GET['table']) && isset($_GET['fieldname'])) { //parametros carga de petición parse_str(file_get_contents("php://input"), $data); $data = (object) $data; if (isset($data->term)) { $term = pSQL($data->term); }else{ $term = ''; } if (isset($_GET['initialSelected'])){ $id =pSQL($_GET['initialSelected']); }else{ $id = ''; } if ($_GET['table'] == 'mytable' && $_GET['fieldname'] == 'mycolname' && $_GET['type'] == 'mytype') { if (empty($id)){ $where = "and name like '%" . $term . "%'"; }else{ $where = "and id= ".$id; } $rows = yourarrayfunctionfromsql("SELECT id, name FROM yourtable WHERE 1 " . $where . " ORDER BY name "); } $items = array("items" => $rows); $var = json_encode($items); echo $var; ?> 
0
Apr 27 '17 at 11:09 on
source share

For a simple and semantic solution, I prefer to define the initial value in HTML, for example:

 <select name="myfield" data-placeholder="Select an option"> <option value="initial-value" selected>Initial text</option> </select> 

Therefore, when I call $('select').select2({ ajax: {...}}); , the initial value is initial-value , and its initial-value option Initial text .

My current version is Select2 4.0.3 , but I think it is perfectly compatible with other versions.

0
Jun 03 '17 at 21:09 on
source share

Hi was almost fired and returned to pick 3.5.1. But finally, I got an answer!

 $('#test').select2({ placeholder: "Select a Country", minimumResultsForSearch: 2, ajax: { url: '...', dataType: 'json', cache: false, data: function (params) { var queryParameters = { q: params.term } return queryParameters; }, processResults: function (data) { return { results: data.items }; } } }); var option1 = new Option("new",true, true); $('#status').append(option1); $('#status').trigger('change'); 

Just make sure the new option is one of the select2 options. I get this from json.

-four
Oct 30 '15 at 15:02
source share



All Articles