Aplicación web con ASP.NET MVC 2 – parte 11

Después de un tiempo sin avanzar en el tutorial, hoy continuamos con la parte de gestionar los alumnos de los grupos, donde al estar en los grupos de un determinado cuatrimestre podamos acceder a las listas de alumnos.

Img. 1. Resultado final al terminar esta parte del tutorial.

Agregaremos un nuevo controlador llamado AdministrarAlumnos cuya acciónn Index muestre las listas cargadas dinámicamente al seleccionar opciones en los combobox, pero antes, agregue el link en cada registros de la tabla en la vista Index de AdministrarGrupos para acceder al nuevo controlador.

Img. 2. Agregar link para acceder a los grupos de alumnos.

La instrucción para crear el link es:

<%: Html.ActionLink(“Lista de alumnos”, “Index”, “AdministrarAlumnos”, new { idgrupo=item.IdGrupo }, null) %>

Crear controlado AdministrarAlumnos:

Img. 3. Controlador AdministrarAlumnos.

El código lo iremos agregando poco  a poco:

namespace EscuelaWebApp.Controllers
{
    public class AdministrarAlumnosController : Controller
    {
        BDEscolarEntities BD = new BDEscolarEntities();
        //
        // GET: /AdministrarAlumnos/

        public ActionResult Index(int idgrupo=0)
        {
            //...

            return View();
        }

    }
}

La acción Index:

Como en la acción Indes de AdministrarGrupos, esta nueva acción también recibe un parámetro (idgrupo), del cual mostraremos sus alumnos solo si el grupo pertenece al último cuatrimestre, caso contrario, mostraremos un mensaje de error, y si no se recibe un valor para este parámetro, mostraremos la vista vacía.

El código de la acción queda como:

public ActionResult Index(int idgrupo=0)
{
    //Consideremos que solos se pueden modificar las listas de alumno para el
    //último cuatrimestre registrado

    //Crear la lista de programas educativos para mostrarlos en la vista Index
    var programaseducativos = BD.ProgramaEducativo.ToList();
    programaseducativos.Insert(0, new ProgramaEducativo { IdPE = 0, NombreCorto = "" });
    //Pasar la lista de PE´s a la vista
    ViewData["ProgramasEducativos"] = programaseducativos;

    //Crear parámetros auxiliares para
    //Id del programa educativo (si se está recibiendo el id de grupo)
    //Id del grupo
    //Lista de grupos
    //Nombre del PE
    //Periodo del cuatrimestre
    //Nombre o letra del grupo
    ViewData["IdPE"] = "";
    ViewData["Grupos"] = "";
    ViewData["IdGrupo"] = "";
    ViewData["ProgramaEducativo"] = "";
    ViewData["Cuatrimestre"] = " - ";
    ViewData["Grupo"] = "";
    ViewData["Tutor"] = "";

    if (idgrupo == 0)
    {
        //Crear la lista vacía porque no se mostrará  ningún alumno.
        List<Alumno> alumnos = new List<Alumno>();
        return View(alumnos);
    }
    else
    {
        //si se esta recibiendo el id del grupo a mostrar
        var grupo = BD.Grupo.Where(g => g.IdGrupo == idgrupo && g.Cuatrimestre.Anio == DateTime.Now.Year)
            .FirstOrDefault();

        //si existe el grupo
        if (grupo != null)
        {

            //recuperar el ultimo cuatrimestre del mismo PE que el grupo para verificar que el grupo corresponde a este
            //Septiembre - Diciembre
            //Mayo - Agosto
            //Enero - Abril
            //podemos ordenarlos descendentemente por PeriodoInicio y sacar el primero de la lista :D

            var cuatrimestre = BD.Cuatrimestre.Where(c => c.IdPE == grupo.Cuatrimestre.IdPE && c.Anio == DateTime.Now.Year).OrderByDescending(g => g.PeriodoInicio).FirstOrDefault();

            //si el grupo pertenece al último cuatrimestre podremos ver su lista de alumnos
            if (grupo.IdCuatrimestre == cuatrimestre.Id)
            {

                //cargar la lista de alumnos del grupo
                var alumnos = grupo.Alumno.ToList();

                //Pasar los datos reales
                ViewData["IdPE"] = grupo.Cuatrimestre.IdPE;
                ViewData["Grupos"] = cuatrimestre.Grupo.OrderBy(g => g.Nombre).ToList();
                ViewData["IdGrupo"] = grupo.IdGrupo;
                ViewData["ProgramaEducativo"] = grupo.Cuatrimestre.ProgramaEducativo.NombreCorto.Trim();
                ViewData["Cuatrimestre"] = grupo.Cuatrimestre.PeriodoInicio.Trim() + " - " + grupo.Cuatrimestre.PeriodoFin.Trim() + " : " + cuatrimestre.Anio;
                ViewData["Grupo"] = grupo.Nombre;
                ViewData["Tutor"] = grupo.Tutor.Nombre.Trim() + " " + grupo.Tutor.Apellidos.Trim();
                return View(alumnos);
            }
            else
            {
                //si el grupo no es del último cuatrimestre, lo informaremos al usuario.
                ViewData["MensajeError"] = "No se puede modificar la lista de alumnos para el grupo seleccionado. " +
                    " Solo puede modificarse la lista de alumnos del último cuatrimestre, utilice esta vista.";

                //Crear la lista vacía porque no se mostrará  ningún alumno.
                List<Alumno> alumnos = new List<Alumno>();
                return View(alumnos);
            }
        }else
        return View("Error");
    }
}

La vista Index:

La creamos tipada para la clase Alumno con contenido List.

Img. 4. Agregar vista tipada para Alumno.

Agregaremos el código para crear nuestros combos para filtar los alumnos de determinado PE, Cuatrimestre y Grupo.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<EscuelaWebApp.Models.Alumno>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Administrar listas de alumnos
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
    <script src="../../Content/Scripts/adminalumnos.js" type="text/javascript"></script>

    <h2>Administrar listas de alumnos</h2>

    <p id="mensaje" class="error"><%: ViewData["MensajeError"]%></p>

    Filtrar por Programa Educativo: <%: Html.DropDownList("IdPE", new SelectList(ViewData["ProgramasEducativos"] as IEnumerable, "IdPE", "NombreCorto", ViewData["IdPE"]))%>
    Cuatrimestre: 

       <input type="text" id="Cuatrimestre" name="Cuatrimestre" size="10" readonly="readonly" value="<%: ViewData["Cuatrimestre"]%>"/>     

    Grupo: 

    <% if (ViewData["Grupos"] != null)
       { %>
       <%: Html.DropDownList("IdGrupo", new SelectList(ViewData["Grupos"] as IEnumerable, "IdGrupo", "Nombre", ViewData["IdGrupo"]))%>
       <%}
       else
       { %>
            <select id="IdGrupo" name="IdGrupo"><option>Seleccionar</option></select>
    <% } %>
    <br /><br />

<fieldset>
            <legend>Datos de grupo</legend>
<strong>Programa Educativo</strong>: <span id="nombrepe"><%: ViewData["ProgramaEducativo"] %></span>,
    <strong>Cuatrimestre</strong>: <span id="Cuatrimestre"><%: ViewData["Cuatrimestre"] %></span>,
    <strong>Grupo</strong>: <span id="nombregrupo"><%: ViewData["Grupo"]%></span>.<br /><br />
    <strong>Tutor</strong>: <span id="tutor"><%: ViewData["Tutor"]%></span>.<br /><br />

    <table id="AlumnosTbl">
        <% //Cambia de TR a THEAD la fila del encabezado de la tabla %>
        <thead>
            <th></th>
            <th>
                Matricula
            </th>
            <th>
                Nombre
            </th>
            <th>
                Apellidos
            </th>
        </thead>
            <% //Agregar la etiqueta TBODY a la tabla
            //Lo utilizaremos para manipular su contenido %>
        <tbody>

    <% foreach (var item in Model) { %>

        <tr>
            <td>
                <%: Html.ActionLink("Editar", "Editar", new { id=item.Matricula }) %> |
                <%: Html.ActionLink("Eliminar", "Eliminar", new { id=item.Matricula })%>
            </td>
            <td>
                <%: item.Matricula %>
            </td>
            <td>
                <%: item.Nombre %>
            </td>
            <td>
                <%: item.Apellidos %>
            </td>
        </tr>

    <% } %>
        </tbody>
        <% // Agregar el pie de la tabla para mostrar los totales %>
        <tfoot>
			<tr>
				<th class="derecha">Total</th>
				<th colspan="3"><span id="total"><%:Model.Count() %></span>Alumnos</th>
			</tr>
		</tfoot>

    </table>

    <p id="LinkAltaAlumno">
        <% if (ViewData["IdGrupo"] != "")
           { %>

            <%: Html.ActionLink("Registrar nuevo alumno en este grupo.", "Registrar", new { idgrupo = ViewData["IdGrupo"] }, null)%>

        <% } %>
    </p>

</asp:Content>
</fieldset>

Las acciones a devolver JSON en el controlador.

Nuestro JS llamará a las acciones en el controlador que le devolverán tanto la lista de grupos del último cuatrimestre para el PE seleccionado como la lista de alumnos para el grupo seleccionado, para ello recuerde que no podemos transformar una colección de Entities a JSON, por lo tanto crearemos una clase llamada AuxAlumno, ya hemos creado anteriormente otra clase llamada AuxGrupo que también se utilizará aquí:

La acción Grupos:

Esta acción nos devolverá la lista de grupos del último cuatrimestre para el PE seleccionado.

[ActionName("Grupos")]
public JsonResult Grupos(int idpe)
{
    //cargar los grupos del ultimo cuatrimestre del PE seleccionado

    //primero buscamos el ultimo cuatrimestre de PE
    var cuatrimestre = BD.Cuatrimestre.Where(c => c.IdPE == idpe && c.Anio == DateTime.Now.Year).OrderByDescending(g => g.PeriodoInicio).FirstOrDefault();

    if (cuatrimestre != null)
    {
        //ahora obtenemos sus grupos
        var grupos = cuatrimestre.Grupo.OrderBy(g => g.Nombre).ToList();

        //crear nuestra lista con la clase auxiliar AuxGrupo
        List<AuxGrupo> listagrupos = new List<AuxGrupo>();

        //convertir de la clase original a la auxiliar de Grupo
        foreach (Grupo grupo in grupos)
        {
            listagrupos.Add(
                new AuxGrupo
                {
                    Id = grupo.IdGrupo,
                    Nombre = grupo.Nombre.Trim(),
                    Cuatrimestre = "-", //para no pasar tantos datos que no se usarán
                    Tutor = grupo.Tutor.Nombre.Trim() + " " + grupo.Tutor.Apellidos.Trim()
                });
        }

        //Prepara nuestro resultado JSON para que:
        //envie el periodo del cuatrimestre
        //Envie la lista de sus grupos
        return this.Json(
            new
            {
                cuatrimestre = cuatrimestre.PeriodoInicio.Trim() + " - " + cuatrimestre.PeriodoFin.Trim() + " - " + cuatrimestre.Anio,
                grupos = listagrupos
            }, JsonRequestBehavior.AllowGet);
    }else
return this.Json(new { msg = "Error al recuperar los grupos del último cuatrimestre del PE seleccionado, " +
                    "compruebe que el PE tiene registrados cuatrimestres y estos tienen  grupos."}, JsonRequestBehavior.AllowGet);
}

Ejemplos:

Para este ejemplo: http://localhost:2958/administraralumnos/grupos?idpe=1

El usuario seleccionó el PE con el ID=1 y este es válido, la acción devolverá su último cuatrimestre del año actual, y devolverá también la lista de sus grupos, el resultado JSON sería como:

{
"cuatrimestre":"Septiembre - Diciembre : 2011",
"grupos":[{
			"Id":1,
			"Nombre":"A",
			"Cuatrimestre":"-",
			"Tutor":"Juan Vicente Pérez López"
		  },
		  {
			"Id":2,
			"Nombre":"B",
			"Cuatrimestre":"-",
			"Tutor":"Pedro Torres"
		  }]
}

Otro caso sería, cuando se pasara un Id de PE no válido, ejemplo, para http://localhost:2958/administraralumnos/grupos?idpe=20  el resultado será:

{"msg":"Error al recuperar los grupos del último cuatrimestre del PE seleccionado."}

La acción AlumnosGrupo:

Esta acción devolverá en resultado JSON la lista de alumnos para el PE seleccionado, para ello primero crearemos la clase AuxAlumno de la que se comentó más arriba.

La clase AuxAlumno:

    public class AuxAlumno
    {
        private int matricula;
        private string apellidos;
        private string nombre;

        public int Matricula
        {
            get { return matricula; }
            set { matricula = value; }
        }

        public string Nombre
        {
            get { return nombre; }
            set { nombre = value; }
        }

        public string Apellidos
        {
            get { return apellidos; }
            set { apellidos = value; }
        }

    }

Ahora sí, la acción AlumnosGrupo:

[ActionName("AlumnosGrupo")]
public JsonResult AlumnosGrupo(int idgrupo)
{
    //buscar el grupo
    var grupo = BD.Grupo.Where(g => g.IdGrupo == idgrupo && g.Cuatrimestre.Anio == DateTime.Now.Year).FirstOrDefault();
        //si existe el grupo
    if (grupo != null)
    {

        //recuperar el ultimo cuatrimestre del mismo PE que el grupo para verificar que el grupo corresponde a este
        //Septiembre - Diciembre
        //Mayo - Agosto
        //Enero - Abril
        //podemos ordenarlos descendentemente por PeriodoInicio y sacar el primero de la lista :D
        var cuatrimestre = BD.Cuatrimestre.Where(c => c.IdPE == grupo.Cuatrimestre.IdPE && c.Anio == DateTime.Now.Year).OrderByDescending(g => g.PeriodoInicio).FirstOrDefault();

        //si el grupo pertenece al último cuatrimestre podremos devolver su lista de alumnos
        if (grupo.IdCuatrimestre == cuatrimestre.Id)
        {
            //crear nuestra lista con la clase auxiliar
            List<AuxAlumno> alumnos = new List<AuxAlumno>();

            //transformar de Alumno a AuxAlumno
            foreach (Alumno item in grupo.Alumno.OrderBy(a => a.Apellidos).ToList())
            {
                alumnos.Add(
                    new AuxAlumno
                    {
                        Matricula = item.Matricula,
                        Nombre = item.Nombre.Trim(),
                        Apellidos = item.Apellidos.Trim()
                    });
            }

            //devolver el resultado JSON
            return this.Json(new { tutor = grupo.Tutor.Nombre.Trim() + " " + grupo.Tutor.Apellidos.Trim(), alumnos = alumnos }, JsonRequestBehavior.AllowGet);

        } return this.Json(new { msg = "Error al recuperar los alumnos del grupo seleccionado, el grupo no corresponde al último cuatrimestre." }, JsonRequestBehavior.AllowGet);
    }
    else
        return this.Json(new { msg = "Error al recuperar los alumnos del grupo seleccionado, no se encontró el grupo." }, JsonRequestBehavior.AllowGet);
}

Para comprobar que funciona la acción AlumnosGrupo, registraremos a mano algunos alumnos para algunos  grupos.

Img. 5. Registrar alumnos manualmente.

Nota: En esta imagen se están registrando alumnos para determinados grupos que SI Existen en mi tabla y pertenecen al último cuatrimestre de alguno de mis PE´s registrado.

Comprobando que la acción AlumnosGrupo funciona.

Para mi grupo con el Id=1, ingreso manualmente a la dirección http://localhost:2958/administraralumnos/alumnosgrupo?idgrupo=1 y el resultado es:

      {
	"tutor":"Juan Vicente Pérez López",
	"alumnos":[
		{"Matricula":111,"Nombre":"Benito","Apellidos":"Méndez"},
		{"Matricula":112,"Nombre":"Jorge","Apellidos":"Meza"}
		]
       }

Por lo tanto, si ingreso a http://localhost:2958/AdministrarAlumnos?idgrupo=1 también obtendré los datos en el resultado.

Img. 6. Resultado en la vista Index.

El código JavaScript.

Ahora nuevamente entra en función el uso de jQuery para recuperar los datos desde el servidor, para ello, cree un nuevo archivo llamado adminalumnos.js en la carpeta Content/Scripts como en los casos anteriores, agreguemos entonces el código para recuperar los datos desde el servidor y mostrarlos en la vista.

Nuestro JavaScript queda como este:

//Al seleccionar un PE, cargar los grupos del ultimo cuatrimestre
$("#IdPE").live("change", function (event) {
    //obtener el Id del PE seleccionado
    var idpe = $("#IdPE").val();

    //Si el ID del PE seleccionado es diferente de 0
    if (idpe > 0) {

        //limpiar el combo de grupos
        $("#IdGrupo").children("option").remove();
        $("#Cuatrimestre").val(""); //limpiar cuatrimestre
        $("#mensaje").html(""); // limpiar mensaje por si tiene algo
        $("#notif").html("");
        //cargar los grupos del último cuatrimestre con JSON
        var url = "/AdministrarAlumnos/Grupos?idpe=" + idpe;
        //hacer la llamada JSON
        $.getJSON(url,
			function (data) {
			    var opcion = "<option value=\"0\"></option>";
			    $("#IdGrupo").append(opcion);
			    $("#Cuatrimestre").val(data.cuatrimestre);

			    if (data.msg) //si devolvió error
			        $("#mensaje").html(data.msg);

			    $.each(data.grupos, function (i, item) {
			        //agregar los cuatrimestres al combo IdCuatrimestre"
			        var opcion = "<option value=\"" + item.Id + "\">" + item.Nombre + "</option>";
			        $("#IdGrupo").append(opcion);
			    });

			    $("#IdGrupo").focus();
			    $("#notif").html(" <i><strong>Seleccione el grupo.</strong></i>");
			});
    }
});

//Al seleccionar el Grupo, cargar sus alumnos
$("#IdGrupo").live("change", function (event) {
    //obtener el Id del grupo seleccionado
    var idgrupo = $("#IdGrupo").val();

    //eliminar todas las filas de la tabla
    $("#AlumnosTbl").find('tbody').children("tr").remove();
    $("#total").html("");

    if (idgrupo > 0) {
        //mostrar el nombre del PE, periodo del cuatrimestre y grupo
        $("#nombrepe").html($("#IdPE option:selected").html());
        $("#NCuatrimestre").html($("#Cuatrimestre").val());
        $("#nombregrupo").html($("#IdGrupo option:selected").html());

        //cargar los alumnos del grupo con JSON
        var url = "/AdministrarAlumnos/AlumnosGrupo?idgrupo=" + idgrupo;

        //hacer la llamada JSON
        $.getJSON(url,
		function (data) {
                    if (data.msg) //si devolvió error
		        $("#mensaje").html(data.msg);

		    $("#tutor").html(data.tutor);
		    $.each(data.alumnos, function (i, item) {
		        //agregar los alumnos a la tabla
		        var fila = "<tr><td><a href=\"/AdministrarAlumnos/Editar/" + item.Matricula + "\">Editar</a> | <a href=\"/AdministrarAlumnos/Eliminar/" + item.Matricula + "\">Eliminar</a></td><td>" + item.Matricula + "</td>" + "<td>" + item.Nombre + "</td>" + "<td>" + item.Apellidos + "</td></tr>";
		        $("#AlumnosTbl").append(fila);
		    });

		    //mostrar el total de alumnos
		    $("#total").html(data.alumnos.length);
		});

        //habilitar el link para registrar un nuevo alumno en este grupo
        $("#LinkAltaAlumno").html("<a href=\"/AdministrarAlumnos/Registrar?idgrupo=" + idgrupo + "\">Registrar nuevo alumno en este grupo.</a>");
    }
});

Hora de comprobar funcionalidad.

Ejecutemos nuestra App, vayamos a nuestra vista para ver las listas de alumnos.

Img. 7. Accediendo a nuestras listas.
Img. 8. Seleccionando un PE que no tiene cuatrimestres.
Img. 9. Seleccionando otro grupo en el combobox.

Hasta aquí es todo, por su parte implemente las acciones correspondientes para Registrar, Editar y si lo prefiere, también Eliminar.

En la siguiente parte solo mostraré la generación de reportes partiendo desde estas listas de alumnos para cada grupo.

Anuncios

Escribe tu comentario:

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s