I am working with Laravel 5.8, I have a form in which I have a multiple select2, which I am trying to load the select2 with the data that the user has that I want to edit, what I need is that the classes that the user already has registered are selected in said select2.
this is my select2
<div class="select2-blue">
<select class="select2" name="licencias[]" id="licencias" multiple="multiple" data-placeholder="Seleccione licencia/s" data-dropdown-css-class="select2-blue" style="width: 100%;">
</select>
</div>
This is my controller in which I get the user data
public function edit($id)
{
$profesor = profesorModel::find($id);
$licencias = array();
foreach($profesor->licencias as $licencia){
$licencias[] = array(
"id"=>$licencia->id_licencia,
"text"=>$licencia->clase
);
}
$profesor['licencias'] = $licencias;
return response()->json($profesor);
}
When I click on edit (in my datatable) it loads the form with the user's data, in which I have also tried to load the select2 in different ways, as shown below
$('body').on('click', '.editarProfesor', function () { // Boton editar Datatable
var id_profesor = $(this).data('id');
$.get("{{ route('profesor.index') }}" +'/' + id_profesor +'/edit', function (data) {
$('#header-modal').html("Editar profesor");
$('#btnCrear').val("Guardar cambios");
$('#modal-profesor').modal('show');
$('#id_profesor').val(data.id_profesor);
$('#rut').val(data.rut);
$('#nombre').val(data.nombre);
$('#apellidos').val(data.apellidos);
$('#correo').val(data.correo);
$('#clave').val(data.clave);
$('#telefono').val(data.telefono);
$('#direccion').val(data.direccion);
$('#fecha_nacimiento').val(data.fecha_nacimiento);
if(data.curriculum.length > 0) // Verifica si profesor tiene este documento
{
$('#actualizar-curriculum').removeAttr('hidden'); //activa input
$('#fila-curriculum').attr('hidden', "hidden"); //oculta input
$('#nombre-curriculum-pdf').val(data.curriculum); //muestra el nombre del pdf en el input
}
if(data.contrato.length > 0) // Verifica si profesor tiene este documento
{
$('#actualizar-contrato').removeAttr('hidden'); //activa input
$('#fila-contrato').attr('hidden', "hidden"); //oculta input
$('#nombre-contrato-pdf').val(data.contrato); //muestra el nombre del pdf en el input
}
var licencias = data.licencias;
licencias.forEach(function(element) {
// OPCION 1 -------------------------
var selectLicencias = $('#licencias').select2();
var option = new Option(element.clase, element.id_licencia, true, true); //FUNCIONA PERO CADA VEZ QUE ELIJO UN PROFESOR, ME SUMA SUS CLASES AL SELECT
selectLicencias.append(option).trigger('change');
selectLicencias.trigger({
type: 'select2:select',
params: {
data: element
}
});
// OPCION 2 -------------------------
var data1 = [
{
id: element.id_licencia,
text: element.clase
}
];
var data2 =
{
id: element.id_licencia,
text: element.clase
}
;
var data3 = [
id=> element.id_licencia,
text=> element.clase
];
console.log(data1);
console.log(data2);
console.log(data3);
$('#licencias_select').val(data1).trigger("change"); // NO FUNCIONA
$('#licencias_select').val(data2).trigger("change"); // NO FUNCIONA
$('#licencias_select').val(data3).trigger("change"); // NO FUNCIONA
// OPCION 3 -------------------------
var id = element.id_licencia;
var clase = element.clase;
var $licencia_seleccionadas = $("<option selected></option>").val(id).text(clase);
$('#licencias').append($licencia_seleccionadas).trigger('change'); // FUNCIONA, PERO AL SELECCIONAR UNA LICENCIA QUE ESTE CARGADA POR ESTE METODO, SE SELECCIONA 2 VECES O MAS (FUNCIONA MAL)
// OPCION 4 -------------------------
$('#licencias') // FUNCIONA Y NO DEJA SELECCIONAR LA LICENCIA QUE YA ESTA SELECCIONADA (LO QUE NO HACE EL METODO DE ARRIBA), PERO SOLO MUESTRA 1 LICENCIA (AUN QUE ESTE TENGA MAS DE 1 REGISTRADA)
.empty() // limpio el select
.append($("<option/>") // agrego el tag option
.val(element.id_licencia) // cargo valor del id
.text(element.clase)) // cargo el texto a mostrar
.val(element.id_licencia) // selecciona el id en la lista del box
.trigger("change"); // aplica los cambios al select
});
})
});
To make it clearer, the idea is that when editing, the user appears with the licenses that he already has registered in select2 as "selected", like the following image (this user has registered 2/3 licenses and the data is false just in case)
I hope I explained myself well, thanks in advance. SOLUTION: Take option 3
var licencias = data.licencias;
licencias.forEach(function(element) {
var id = element.id_licencia;
var clase = element.clase;
var $licencia_seleccionadas = $("<option selected></option>").val(id).text(clase);
$('#licencias').append($licencia_seleccionadas).trigger('change');
});
and when canceling or clicking outside the modal, do the following
$("#btnCerrar").on("click",function(event){
$('#licencias').val(null).trigger("change");
$('#licencias').empty();
});
$('#modal').on('hidden.bs.modal', function () {
$('#licencias').val(null).trigger("change"); // deja el select en null
$('#licencias').empty(); // limpia el input
});
For me the best answer is to make a callback function to execute code when we have already pre-loaded the user, I did it by loading a random array and then in my callback function I make them select, using the method to select objects that it puts in the select2 documentation . There are several methods but it seems quite easy, you are probably loading the options and the user's selected options from different sources or databases but in this case the same ones that I download from the API are the ones that I select, it is a matter of imagination.
Here I leave you a functional example, I hope it helps you, greetings.
Here is an example with two teachers, you just have to clear/reset the input when getting the new user: