viernes, 30 de enero de 2015

Funcion de ordenamiento DataTable jQuery con C# con ASP .NET Entitie Framework y MVC

Cascaron DataLayerIng En el post anterior mostré como usar el componente data table de JQuery; cuando el componete se usa generando el contenido con html se ordena automaticamnte al dar clic en la cabecera de cada columna; pero si se rellena por medio de Ajax se tiene que ordenar del lado del controlador revisando la orden que se envía del componente (Vista), por lo que se debe ordenar el resultado de nuestra consulta; para ordenar el resultado pude usarse el siguiente codigo:

switch (dataTable.iSortCol_0) //iSortCol_0: Esta variable nos devuekve un entero con la posicion de la columna en la que se desea ordenar
                {
                    case 0:
                        {
                            if (dataTable.sSortDir_0 == "asc")//sSortDir_0 Nos indica la forma de ordenacion ancendete o desendente
                            {
                                List = List.OrderBy(o => o.ID).ToList(); //Ordenamos utilizando Sintaxis LinQ sobre lalista estraida de Entityframework
                            }
                            else
                            {
                                List = List.OrderByDescending(o => o.ID).ToList(); //Ordenamos utilizando Sintaxis LinQ sobre lalista estraida de Entityframework
                            }
                            break;
                        }
                    case 1:
                        {
                            if (dataTable.sSortDir_0 == "asc")//sSortDir_0 Nos indica la forma de ordenacion ancendete o desendente
                            {
                                List = List.OrderBy(o => o.p_Numero).ToList(); //Ordenamos utilizando Sintaxis LinQ sobre lalista estraida de Entityframework
                            }
                            else
                            {
                                List = List.OrderByDescending(o => o.p_Numero).ToList(); //Ordenamos utilizando Sintaxis LinQ sobre lalista estraida de Entityframework
                            }
                            break;
                        }
                    default:
                        break;
                }
Usando la logica se debera usar una "case" por cada columna de nuestra tabla y es importante ordernarlo una ves que hallamos obtenido la informacion en bruto de nuestra tabla y para no ordenar solo los datos que estamos enviando de vuelta a la vista.

miércoles, 28 de enero de 2015

DataTable jQuery con C# con ASP .NET Entitie Framework y MVC

Cascaron DataLayerIng El componente DataTable es muy útil para presentar datos cargando parcialmente mediante AJAX y jQuery, o bien si los datos son pocos podemos darle funcionalidad a la tabla solo inicializando los componentes por Jquery, como por ejemplo cuando el Visual Studio nos crea el conmtrolador y vistas basico bajasandose en un origen de datos en el index pondiamos:

En la parte de Java Script:

          <script language="JavaScript">
            $(document).ready(function () {
                  $('#table_id').DataTable();
              });
          </script>

Importando las librerias:


O de una carpeta local si es que hemos descargado las librerias ne nuestro proyecto
          <script src="~/Scripts/DataTables-1.9.4/media/js/jquery.dataTables.js"></script>


Y el Razor generado automaticamente pro Visual Studio:

          <table id="table_id" class="display">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_Clave)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_NOMBRE)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_RFC)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_COMERCIAL)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.ID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.C_Clave)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.C_NOMBRE)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.C_RFC)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.C_COMERCIAL)
                </td>
                <td>
                    @Html.ActionLink("Editar", "Edit", new { id = item.ID }) |
                    @Html.ActionLink("Detalles", "Details", new { id = item.ID }) |
                    @Html.ActionLink("Eliminiar", "Delete", new { id = item.ID })
                </td>
            </tr>
        }
    </tbody>
    <tfoot>
    </tfoot>
</table>

Ahora bien si deseamos inicial izarla a través de Ajax con una función MVC el Javascript queda de esta forma:
          $('#table_id').dataTable({
            "sDom": "frtp",
            "bFilter": false,
            "bJQueryUI": true,
            "sPaginationType": "full_numbers",
            "bProcessing": true,
            "bServerSide": true,
            "bDestroy": true,
            "sAjaxSource": "/Controlador/FuncionDeLLenado",
            "aoColumnDefs": [
    /* En esta seccion se definel a estructura del componente y las columnas       */
                        { "bSearchable": false, "bVisible": false, "aTargets": [0] },
                        { "bVisible": false, "aTargets": [0] }
            ],
            "fnServerParams": function (aoData) {
            },
            "fnRowCallback": function (nRow, aData, iDisplayIndex) {
                /* En esta seccion se puede personalizar la informacion que se desplegara en la tabla    */
    /* Usamos los valores que regresan para rellenar la columna con los links de funcion     */
                $('td:eq(10)', nRow).html('<a href=\"/Partes/Edit/' + aData[0] + '\">Editar</a> | ' +
                    '<a href="/Partes/Details/' + aData[0] + '">Detalles</a> | ' +
                    '<a href="/Partes/Delete/' + aData[0] + '">Eliminar</a> ');
            },
            "fnServerData": function (url, data, callback) {
                $.ajax({
                    "url": url,
                    "data": data,
                    "success": callback,
                    "dataType": "json",
                    "type": "POST",
                    //  "cache": false,
                    "error": function () {
                        alert("DataTables warning: JSON data from server failed to load or be parsed. " +
                        "This is most likely to be caused by a JSON formatting error.");
                    }
                });
            }
        });
y la funcion desde el controlador requiere un modelo que recibe la informacion del componente Jquery modelo que definimos a continuacion:

          
           public class jQueryDataTableParamModel
    {
        /// 
        /// Request sequence number sent by DataTable,
        /// same value must be returned in response
        ///        
        public string sEcho { get; set; }

        /// 
        /// Text used for filtering
        /// 
        public string sSearch { get; set; }

        /// 
        /// Number of records that should be shown in table
        /// 
        public int iDisplayLength { get; set; }

        /// 
        /// First record that should be shown(used for paging)
        /// 
        public int iDisplayStart { get; set; }

        /// 
        /// Number of columns in table
        /// 
        public int iColumns { get; set; }

        /// 
        /// Number of columns that are used in sorting
        /// 
        public int iSortingCols { get; set; }

        /// 
        /// Comma separated list of column names
        /// 
        public string sColumns { get; set; }

        /// 
        /// Sort column
        /// 
        public int iSortCol_0 { get; set; }

        /// 
        /// Asc or Desc
        /// 
        public string sSortDir_0 { get; set; }
    }


Y ahora la Funcion en el controlador que llenara nuestra tabla mediante la pation ajax:
          
          [HttpPost]
        public ActionResult FuncionDeLLenado(jQueryDataTableParamModel dataTable)//jQueryDataTableParamModel define las variables que enviarion desde el java script
        {
            try
            {

                //Aqui Extremos la informacion de la Base de Datos
                //En este caso se Saco con Entityframework 5.0
                InventariosEntitys db = new InventariosEntitys(); //Inicio de conexion
                List rows = db.NombreTabla.ToList();

                if (rows != null)//Valida que la consulta traiga resultados
                {
                    //Definimos y aplicamos los Filtros a los campos de la tabla
                    //dataTable.sSearch define el valor que se teclea en el campo de busqueda
                    var filteredRows = (from e in rows
                                        where (dataTable.sSearch == null
                                            || e.C_Clave.ToLower().Contains(dataTable.sSearch.ToLower()) //se aplicala funcion Contais para buscar los valores
                                            || e.C_Nombre.ToLower().Contains(dataTable.sSearch.ToLower())//junto con el or para que lo busque en cualquiera
                                            || e.C_RFC.ToLower().Contains(dataTable.sSearch.ToLower())   // de las columnas en las que se encuentre el valor
                                            )
                                        select e).ToList();

                    var displayedRows = filteredRows
                                .Skip(dataTable.iDisplayStart //dataTable.iDisplayStart: define donde estan iniciando los registros
                                .Take(dataTable.iDisplayLength); //dataTable.iDisplayLength: define el tamaño dela paginacion


                    DateTime dti = new DateTime(2014, 04, 1, 0, 0, 0);
                    DateTime dtf = new DateTime(2014, 04, 30, 23, 59, 59);

                    //Creamos el filtro final de la tabla enviando solo los datos que requerimos en la tabla de forma posicional 
                    //en un arreglo de String
                    var result = from c in displayedRows
                                 select new List() {
                                    c.ID.ToString(),
                                    c.C_CALVE,
                                    c.C_NOMBRE,
                                    c.C_RFC,
                                    c.C_COMERCIAL
                                 };

                    table = result.ToList();//reconstruimos como una lista de Strings
                    //Enviamos el resultado en formato Json de vuelata a la vista
                    return Json(new
                    {
                        sEcho = dataTable.sEcho,
                        iTotalRecords = rows.Count,
                        iTotalDisplayRecords = filteredRows.Count,
                        aaData = table
                    }, JsonRequestBehavior.AllowGet);
                }
                else
                {
                     //Enviamos el resultado en formato Json de vuelata a la vista
                    //Se regresan valores nulos
                    return new DataTableResult(dataTable.sEcho, rows.Count, 0, table);
                }
            }
            catch (Exception ex)
            {
                //Manejo de posilbes errores
                String result = "Error con el Mensaje:" + ex.Message;
                return Json(new
                {
                    error = result
                }, JsonRequestBehavior.AllowGet);
            }
        }



Y ahora la Finalmente como debe mostrarse el codigo de la tabla en Razor:
          <table id="table_id" class="display">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.ID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_Clave)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_NOMBRE)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_RFC)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.C_COMERCIAL)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
    </tbody>
    <tfoot>
    </tfoot>
</table>