Reputation: 527
I've some problem with Select2, basically i need to fill some other form fields with data retrieved from Select2 Ajax search.
even following example found here:
Select2 4.0 - Push new entry after creation
I'm not able to fill some field programmatically with results founds from Select2
Just as example, consider that I've Three fields, i can use two of these fields to search data and i want that other remaining fields will be filled automatically after choosing one of ajax call returned values.
so, as example:
Test field 01 (Select2 field)
Test field 02 (Select2 field)
Test field 03 (standard input field)
If i search something on "Test field 01" i want that 02 and 03 will be filled automatically.
I've implemented one solution that you can find below but doesn't work with the Select2 fields, only with the input one.
If i use the code inspector i see that the new option inside the "select" element are correctly created and tagged as "selected" but seem that the "select2-selection__rendered" span element is not correctly update after triggering the "change" event
During my tests, I also notice that the the function "updateselect2" that i use to update the data is called four times each time i select one value from results and consequentially i found 4 time the same value in the destination select box.
take a look at animated gif below to see the complete behavior
There is something that i did wrong?
My setup is:
Below you can find a complete example of my current work:
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<title>Test</title>
<script src="jquery-3.1.0.min.js"></script>
<link rel="stylesheet" href="select2.min.css"/>
<script src="select2.full.js"></script>
</head>
<body>
<div class="section ">
<div class="container ">
<div class="row">
<div class="col-md-2">
<div class="form-group">
<label for="testField01" class="control-label">Test field 01</label>
<select id="testField01" class="form-control" name="testField01" style="width:150px;">
<option value=""></option>
</select>
</div>
</div>
<div class="col-md-2">
<div class="form-group">
<label for="testField02" class="control-label" >Test field 02</label>
<select id="testField02" class="form-control" name="testField02" style="width:150px;">
<option value=""></option>
</select>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="testField03" class="control-label" style="width:150px;">Test field 03</label>
<input id="testField03" class="form-control" value="" readonly="readonly" />
</div>
</div>
</div>
</div>
</div>
</body>
</html>
JAVASCRIPT:
var select2_query = {};
function markMatch(text, term) {
// Find where the match is
var match = text.toUpperCase().indexOf(term.toUpperCase());
var $result = $('<span></span>');
// If there is no match, move on
if (match < 0) {
return $result.text(text);
}
// Put in whatever text is before the match
$result.text(text.substring(0, match));
// Mark the match
var $match = $('<span style="color:red"></span>');
$match.text(text.substring(match, match + term.length));
// Append the matching text
$result.append($match);
// Put in whatever is after the match
$result.append(text.substring(match + term.length));
return $result;
}
function updateselect2(elId, values) {
var $element = $('#' + elId); // the element that Select2 is initialized on
if ($element.attr('id') == undefined) {
return false;
}
$element.empty();
var $option = $("<option selected></option>"); // the new base option
$option.val(values[elId]); // set the id
$option.text(values[elId]); // set the text
$element.append($option); // add it to the list of selections
$element.trigger("change"); // tell Select2 to update
}
function formatResult(result) {
if (result.loading) {
return result.text;
}
var term = select2_query.term || '';
var $formattedResult = markMatch(result.testField01 + ' - ' + result.testField03, term);
return $formattedResult;
}
function formatSelection(selection) {
if (!selection.selected) {
updateselect2('testField02', selection);
$('#testField03').val(selection.testField03);
}
return selection.testField01;
}
function initSearch(fieldId, searchType) {
$("#" + fieldId).select2({
ajax: {
url: "/search/data",
dataType: 'json',
delay: 250,
data: function (params) {
return {
id: params.term, // search term
by: searchType,
page: params.page
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 4,
templateResult: formatResult,
templateSelection: formatSelection,
language: {
searching: function (params) {
select2_query = params;
return 'Searching…';
}
}
});
}
$(document).ready(function() {
$('testField01').select2();
$('testField02').select2();
initSearch('testField01', 'testField01');
initSearch('testField02', 'testField02');
});
JSON DATA SAMPLE:
{"total_count":1,"incomplete_results":false,"items":[{"id":1,"testField01":"123456789","testField01":"987654321", "testField03":"ABCDEFGHIJK"}]}
Upvotes: 0
Views: 1200
Reputation: 1213
Well, when you append options to an select field, you need to reinitialize the select2 element like:
$element.select2("destroy");
instead of $element.trigger("change");
in the updateselect2()
function.
Also, the correct way to change the value in select2 is not by triggering the change
listener, but by invoking .select2('val', thevalue)
which in your case would not work because of the new options, but keep that in mind.
Another note: No need to initialize the select2 in the document.ready, as initSearch will do it for you.
Last note: your sample json is wrong, you're passing testField01 twice
Upvotes: 1