Aprende en casa Ir a KODOTI
Aprende en casa KODOTI

JSRender + PHP selección multiple con checkbox

En esta entrada vamos a ver como manipular colecciones para presentar nuestra data obtenida.

Rodríguez Patiño, Eduardo
Rodríguez Patiño, Eduardo
2020-07-03 | 4,190 lecturas

En esta nueva entrada vamos hacer un ejemplo más para reforzar nuestras habilidades con JSRender de lo que hemos aprendido en este post Trabajando con JSON y Templates con JSRender y PHP. Tenemos el caso de que queremos mostrar un formulario de nuestro alumno elegido, luego se tiene la opción de elegir los cursos que está cursando, entonces lo que debemos hacer es seleccionar aquellos cursos que ya había elegido usando nuestro sistema de template JSRender.

El escenario es de la siguiente manera, debemos consumir un JSON que nos traiga todos los cursos disponibles, los datos del alumno y los cursos que se le han asignado. Mi JSON ha quedado de esta manera:

{  
  "Cursos":[  
    {  
      "id":"3",
      "Nombre":"Angular"
    },
    {  
      "id":"4",
      "Nombre":"Ember"
    },
    {  
      "id":"2",
      "Nombre":"Laravel"
    },
    {  
      "id":"1",
      "Nombre":"PHP"
    }
  ],
  "Alumno":{  
    "id":"3",
    "Nombre":"Eduardo",
    "Apellido":"Rodriguez Pati\u00f1o",
    "Sexo":"1",
    "FechaNacimiento":"1989-02-11",
    "FechaRegistro":"2014-05-26",
    "Foto":"150211034428-logo.png",
    "Correo":"hitogoroshi@outlook.com",
    "Cursos":[  
      {  
        "id":"1",
        "Nombre":"PHP"
      },
      {  
        "id":"2",
        "Nombre":"Laravel"
      },
      {  
        "id":"4",
        "Nombre":"Ember"
      }
    ]
  }
}

Para armar ese tipo de JSON lo que hice en PHP fue lo siguiente:

$data = array();
$data['Cursos'] = $this->model_curso->Listar();
$data['Alumno'] = $this->model->Obtener($_REQUEST['id']);
print_r( json_encode( $data ) );

Manipulación de nuestro JSON

En primer lugar, debemos traer todos los cursos disponibles, ya que vamos a iterarlo para mostrarlo en la lista de cursos disponibles a seleccionar.

Image title

En segundo lugar, debemos alterar nuestro código de javascript que se encargá de realizar la petición AJAX para obtener el JSON, ya que desde javascript vamos a marcar los cursos que nuestro alumno ha elegido previamente, y para esto necesitamos hacer 2 foreach, uno para recorrer todos los cursos y otro recorrer los cursos seleccionados, así de esta manera a los cursos seleccionados le agregaré una nueva propiedad que diga isChecked dandole por valor de defecto TRUE. Mi función quedaría de la sigueinte manera:

function EditarUsuario(id)
{
    $.post('?c=Alumno&a=Obtener', {
        id: id
    }, function(data){
        var template = $.templates("#tmpl-usuario-editar");

        /* Hacemos una lógica para decirle a nuestro template los cursos que van a estar seleccionados */
        $.each(data.Cursos, function(indice, curso){

            /* Recorremos los cursos que tiene asignado nuestro alumno */
            $.each(data.Alumno.Cursos, function(i, curso_asignado){
                if(curso.id == curso_asignado.id)
                {
                    data.Cursos[indice]['isChecked'] = true;
                    return false;
                }
            })
        })

        $("#frm-alumno").html(template.render(data));
        $("#modal-alumno-editar").modal();
    }, 'json')
}

Otra opción podría ser traer el JSON ya armado inidicando que cursos tiene seleccionado el alumno, esto lo harías desde PHP. Sin embargo, me gustaría tener un JSON mapeado desde PHP que sea muy genérico y no haya sido pensado para solucionar un problema, ya que este mismo JSON lo podría reutilizar para otro formulario y al que le doy la responsabilidad de acomodar la data a la mejor manera conveniente para resolver el problema sería a javascript.

Nuestro template

Finalmente, nuestro template, la parte de los cursos a mostrar tiene que ser de la siguiente forma:

<div class="form-group">
    <label>Cursos asignados:</label>
    <ul class="list-group">
        {{for Cursos}}
        <li class="list-group-item">
            <label><input type="checkbox" {{if isChecked}}checked{{/if}} name="Curso_id[]" value="{{:id}}" /> {{:Nombre}}</label>
        </li>
        {{/for}}
    </ul>
</div>

Adicionalmente he creado otra función para mostrar los datos del alumno para presentar su información sin formulario, obteniendo algo así:

Image title

Siendo su template maquetado de la siguiente manera:

<div class="row">
    <div class="col-xs-8">
        <dl class="dl-horizontal">
          <dt>Nombre</dt>
          <dd>{{:Nombre }} {{:Apellido }}</dd>
          <dt>Correo</dt>
          <dd>{{:Correo }}</dd>
          <dt>Sexo</dt>
          <dd>
              {{if Sexo == 1 }} Masculino {{else}} Femenino {{/if}}
          </dd>
          <dt>Cursos</dt>
          <dd>{{for Cursos}}<span class="badge">{{:Nombre}}</span>{{/for}}</dd>
        </dl>   
    </div>
    <div class="col-xs-4">
        {{if Foto != ''}}
            <div class="img-thumbnail text-center">
                <img src="uploads/{{:Foto}}"  />
            </div>
        {{/if}} 
    </div>
</div>

Estudia con nosotros

🚀 Mejora tus oportunidades laborales