How do I use the ajax mode of select2 with optgroup and option?

3

Following the documentation I try the following:

var data = {
  "results": [
    {
      "text": "Life Good",
      "children": "[{\"id\" : 1, \"text\" : \"Lg Prueba 1\", \"element\" : \"HTMLOptionElement\"}, {\"id\" : 2, \"text\" : \"Lg Prueba 2\", \"element\" : \"HTMLOptionElement\"}]",
      "elment": HTMLOptGroupElement
    },
    {
      "text": "Samsung",
      "children": "[{\"id\" : 3, \"text\" : \"Samsung Prueba 1\", \"element\" : \"HTMLOptionElement\"}, {\"id\" : 4, \"text\" : \"Samsung Prueba 2\", \"element\" : \"HTMLOptionElement\"}]",
      "elment": 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>

But he does not show me the children, which are reflected in json as children .

Here's an example of what I want but not with ajax.

    
asked by Pablo Contreras 09.05.2017 в 10:09
source

1 answer

1

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>
    
answered by 09.05.2017 / 10:20
source