What I intend to do is that when selecting one of the options, the text of the parent (optgroup) is placed and it shows me something like " LG / Lg - Test 1 " (notice in the example that I place that "LG" is the parent (optgroup ) and "Lg - Test 1" is the child (option)) and I want to make it so that the user can see which parent (optgroup) they are selecting.
In the example that I place, the function formatDataSelection
is the one in charge of placing the text when selecting an option.
Here is the code of what I have:
var data = {"results":[{"text":"LG","children":[{"id":1,"text":"Lg - Prueba 1"},{"id":2,"text":"Lg - Prueba 2"}]},{"text":"Samsung","children":[{"id":3,"text":"Sam - Prueba 1"},{"id":4,"text":"Sam - Prueba 2"}]}],"pagination":{"more":false}};
$("select").select2({
placeholder: "Elija...",
allowClear: true,
data: data.results,
escapeMarkup: function (markup) { return markup; },
templateResult: formatData,
templateSelection: formatDataSelection
});
function formatData (data) {
if (data.loading) return data.text;
return data.text;
}
function formatDataSelection (data) {
return data.text;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select style="width: 100%"></select>
The answer that the user @JuankGlezz gave me, led me to this other problem: The text of the parent label of the selected option is not obtained.
$('select').select2({
placeholder: "Elija...",
allowClear: true,
ajax: {
type: "GET",
dataType: 'json',
url: 'https://api.myjson.com/bins/12apr1',
delay: 250,
data: function(params) {
return {
term: params.term, // search term
page: params.page || 1, //page number
}
},
processResults: function (data, page) {
return {
results: $.map(data.results, function (n) {
return {
text: n.text,
children: n.children
}
}),
//results: data.results,
pagination: {
more: data.pagination.more,
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
templateResult: crear_marca_modelo_formatData,
templateSelection: crear_marca_modelo_formatDataSelection
});
function crear_marca_modelo_formatData (data) {
if (data.loading) return data.text;
return data.text;
}
function crear_marca_modelo_formatDataSelection (data) {
let labelOptg = $(data.element).parent().attr('label');
return labelOptg + " / " + data.text;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<select style="width: 100%"></select>
If you look at the DOM that is created when generating your second script, it is not the typical one with
optgroup
, but it creates one with the following form:Therefore, by referring to the parent element you are not referring to the
optgroup
(as you currently have it in your example) but to theul
.I have also been able to observe that each of the elements of the
select
when you select them obtain a certain class called.select2-results__option--highlighted
, so I have used this class to refer to the element that we have just selected.Subsequently, and seeing how the DOM takes the structure once the dropdown is generated, I am going to scale two positions through
.parent().parent()
to reach theli
although I am going to filter so that I only get the elements withrole="group"
doing the filter.find("[role='group']")
.Lastly, I'll get the element
prevObject
to detect which one is before the element we just selected and I'll get its attributearia-label
.Additionally: I have also made a condition so that if there is no element that has been selected, it does not appear
undefined... / Elija...
and only the word appearsElija...
so that it is seen in a much more "friendly" way.Your modified example:
UPDATE: According to the comments, the problem is in deselecting an element that has already been selected, since it gives problems that it cannot obtain the
getAttribute
one of a null element.Since both creating and deleting an element from the dropdown uses the same function, I have created a new condition that only uses the function
getAttribute
if the object exists to solve the error:In this way we would solve the error. I've edited the above example so you can see that it no longer throws an error when deselecting dropdown items.
It is only a matter of modifying the function a little
templateSelection
, because in the data that the function receives it also contains an attributeelement
which you can select with jQuery to later search for the parent in this case<optiongorup>
, then the function would be as follows:Your working example: