The solution was to modify the code that generated in PHP the data to be sent to the browser and make a decoding of the JSON returned by the database to be able to integrate with the rest of the PHP data that are subsequently converted to JSON:
<?php
/* Reproducimos los datos obtenidos de la base de datos */
$valores = [
0 => (object)[
'text' => 'Life Good',
'children' => '[{"id" : 1, "text" : "Lg Prueba 1"}, {"id" : 2, "text" : "Lg Prueba 2"}]',
],
1 => (object)[
'text' => 'Samsung',
'children' => '[{"id" : 3, "text" : "Samsung Prueba 1"}, {"id" : 4, "text" : "Samsung Prueba 2"}]',
],
];
?><h3>ANTES:</h3>
<pre><?= htmlspecialchars(
json_encode($valores, JSON_PRETTY_PRINT)
) ?></pre>
<?php
foreach($valores as $clave => $elemento) {
$valores[$clave]->children = json_decode($valores[$clave]->children);
}
?><h3>DESPUÉS:</h3>
<pre><?= htmlspecialchars(
json_encode($valores, JSON_PRETTY_PRINT)
) ?></pre>
Resulting in:
ANTES:
[
{
"text": "Life Good",
"children": "[{\"id\" : 1, \"text\" : \"Lg Prueba 1\"}, {\"id\" : 2, \"text\" : \"Lg Prueba 2\"}]"
},
{
"text": "Samsung",
"children": "[{\"id\" : 3, \"text\" : \"Samsung Prueba 1\"}, {\"id\" : 4, \"text\" : \"Samsung Prueba 2\"}]"
}
]
DESPUÉS:
[
{
"text": "Life Good",
"children": [
{
"id": 1,
"text": "Lg Prueba 1"
},
{
"id": 2,
"text": "Lg Prueba 2"
}
]
},
{
"text": "Samsung",
"children": [
{
"id": 3,
"text": "Samsung Prueba 1"
},
{
"id": 4,
"text": "Samsung Prueba 2"
}
]
}
]
The work is done in the following loop after obtaining the data:
foreach($valores as $clave => $elemento) {
$valores[$clave]->children = json_decode($valores[$clave]->children);
}
In which we decode the data in the children
field of each record returned so that they go from being a normal text to real data that can be treated as such later by the json_encode
that sends the content to the javascript code will run in the browser.
Original reply
You have the data children
encoded in JSON as string. Or use a JSON.parse()
to convert them back into real data or you do it manually as follows:
var data = {
"results": [
{
"text": "Life Good",
"children": [
{
"id" : 1,
"text" : "Lg Prueba 1",
"element" : HTMLOptionElement
},
{
"id" : 2,
"text" : "Lg Prueba 2",
"element" : HTMLOptionElement
}
],
"element": HTMLOptGroupElement
},
{
"text": "Samsung",
"children": [
{
"id" : 3,
"text" : "Samsung Prueba 1",
"element" : HTMLOptionElement
},
{
"id" : 4,
"text" : "Samsung Prueba 2",
"element" : HTMLOptionElement
}
],
"element": HTMLOptGroupElement
}
],
"pagination": {
"more": false
}
};
$("select").select2({
placeholder: "Elija...",
allowClear: true,
data: data.results,
templateResult: function (data) {
// We only really care if there is an element to pull classes from
if (!data.element) {
return data.text;
}
var $element = $(data.element);
var $wrapper = $('<span></span>');
$wrapper.addClass($element[0].className);
$wrapper.text(data.text);
return $wrapper;
}
});
<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>
Example by dumping the JSON directly from the database
If you do not make any escaped of the result you get from the database , you can use the information obtained directly.
var data = {
"results": [
{
"text": "Life Good",
"children": [{"id":1,"text":"LG-001"},{"id":2,"text":"LG-002"},{"id":3,"text":"LG-003"}],
"element": HTMLOptGroupElement
},
{
"text": "Samsung",
"children": [{"id":4,"text":"Sam-004"},{"id":5,"text":"Sam-005"},{"id":6,"text":"Sam-006"}],
"element": HTMLOptGroupElement
}
],
"pagination": {
"more": false
}
};
$("select").select2({
placeholder: "Elija...",
allowClear: true,
data: data.results,
templateResult: function (data) {
// We only really care if there is an element to pull classes from
if (!data.element) {
return data.text;
}
var $element = $(data.element);
var $wrapper = $('<span></span>');
$wrapper.addClass($element[0].className);
$wrapper.text(data.text);
return $wrapper;
}
});
<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>
Example using JSON.parse()
of the strings obtained from the database
If you escape the string (or use json_encode
or similar functions on the server side) in the result that you get from the database , you must use JSON.parse()
to convert the data back to useful for javascript.
var data = {
"results": [
{
"text": "Life Good",
"children": JSON.parse("[{\"id\":1,\"text\":\"LG-001\"},{\"id\":2,\"text\":\"LG-002\"},{\"id\":3,\"text\":\"LG-003\"}]"),
"element": HTMLOptGroupElement
},
{
"text": "Samsung",
"children": JSON.parse("[{\"id\":4,\"text\":\"Sam-004\"},{\"id\":5,\"text\":\"Sam-005\"},{\"id\":6,\"text\":\"Sam-006\"}]"),
"element": HTMLOptGroupElement
}
],
"pagination": {
"more": false
}
};
$("select").select2({
placeholder: "Elija...",
allowClear: true,
data: data.results,
templateResult: function (data) {
// We only really care if there is an element to pull classes from
if (!data.element) {
return data.text;
}
var $element = $(data.element);
var $wrapper = $('<span></span>');
$wrapper.addClass($element[0].className);
$wrapper.text(data.text);
return $wrapper;
}
});
<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>