martes, 20 de marzo de 2012

jqGrid–Crear jerarquía de registros con Tree Grid

 

Introducción

La finalidad buscada con el articulo articulo será demostrar como por medio del componente jqGrid se pueden representar estructuras de árbol en diferentes niveles de agrupación

El ejmeplo esta basado en la ordenes de compra de la db Northwind, tomando el campo “OrderData” y agrupando por año y mes

Es por eso que la opciones de expandir primero mostrarán los años, luego los mese y al final la info de la orden.

Se puede dejar el campo de Customer sin ingresar un valor, lo cual listara todas las ordenes registradas

Es muy importante notar en el código como se crea el grid que se enviara por json al grid

var grid = new
{
    page = 1,
    records = orderList.Count,
    total = orderList.Count,

    rows = from item in orderList
            select new
            {
                id = item.IdUnique,
                cell = new string[]
                {
                    item.Id,
                    item.Desc,
                    item.Level.ToString(),
                         item.Parent,
                         item.IsLeaf.ToString().ToLower(),
                        "false"
                }
            }

 

};

luego de los campos de datos se debe definir en orden los siguiente ítems:

  • nivel
  • parent
  • si es un nodo hoja
  • si debe mostrarse expandido el nodo

 

Código


El ejemplo esta confeccionado con VS 2010 y Sql Compact (la db se encuentra en la carpeta App_Data)

[C#]
[C# Skydrive]

18 comentarios:

  1. Hola Leandro,
    Tengo un problemita, esta vez con algo de Jquery.

    Tengo un json que llena una tabla llena de input. Ahora quiero que uno de esos input sea un combo.. Pero no logro llenarlo.. Tengo idea que es porque necesito seleccionar el combo dinamicamente...

    Como hago un selector dinamico??

    Esta función llena el combo:

    function ComboMoneda(datos, selector) {
    $.each(datos, function (index, dato) {
    $(selector).append(
    $('< option/>')
    .attr('value', dato.Value)
    .text(dato.Text)
    );
    });
    };

    ----

    Y esta es la llamada a esa funcion:

    $.each(coberturas, function (i) {
    ComboMoneda(monedas, "#[" + i + "].MonedaID");
    });

    Donde coberturas es un json, que lleno a una tabla, y creo los selects y otros inputs..

    Gracias!

    ResponderEliminar
  2. hola Pierina

    pero que seri este selector dinamico, porque alli veo que usas

    #[" + i + "].MonedaID

    como medio para determinar la seleccion
    pero existe un combno o control con un id como este ?

    o sea no veo que un control pudiera tener un id con este tipo de nombre

    aunque tampo veo de donde sale "coberturas"

    si este coberturas tiene los nombre de los controles, para que usas el .MonedaID ese parte no me convence

    realiza la prueba de selecciona un control unico y de forma fija valida que el selector aplica correctamente y luego ve haciandolo dinamico
    saludos

    ResponderEliminar
  3. Yo intente pegar todo el problema, pero no cabe, yo estoy trabajando con c#-mvc3 y, en este caso tengo una colección cuyos datos vienen del json (coberturas), coberturas es algo como esto:

    [{"CoberturaPolizaID":0,"DescCobertura":"Casco Cobertura Amplia","Moneda":null,"MonedaID":0,"PlanPoliza":null,"PlanPolizaID":null,"PorcSumaAseg":0,"PrimaPP":0,"PrimaPPA":0,"PrimaAnual":0.00,"PrimaCasco":0,"PrimaPPR":0,"Orden":0,"SumaAsegurada":0.00,"Tasa":0,"Timestamp":null},{"CoberturaPolizaID":0,"DescCobertura":"Cobertura Eventos Catastróficos","Moneda":null,"MonedaID":0,"PlanPoliza":null,"PlanPolizaID":null,"PorcSumaAseg":0,"PrimaPP":0,"PrimaPPA":0,"PrimaAnual":0.00,"PrimaCasco":0,"PrimaPPR":0,"Orden":0,"SumaAsegurada":0.00,"Tasa":0,"Timestamp":null}

    y lo que hago es colocarle el iterador al campo, para entre otras cosas que el mvc3 lo reconozca como una coleccion al hacer submit:
    #[" + i + "].MonedaID" = "#[0].MonedaID.. El i es la variable de iteracion del $.each..

    Voy a probar lo que me dices.. Gracias.

    ResponderEliminar
  4. hola Pierina
    aahh era un json, pero este es tipado no necesitas usar un selector

    en el $each ese i que defines no es el indice del item, es el item en si, es como si usaras el foreach

    si haces
    i.MonedaID
    deberias acceder directo

    igualmente escribe en el codigo la linea

    debugger;

    y esto hara que el codigo se detenga alli para que puedas inspeccionarlo


    saludos

    ResponderEliminar
  5. Voy a probar lo que me dices, y si entiendo bien el selector puede ser dinámico tal cual como lo coloco? Es que no me funciona:

    selector = "#0.MonedaID";
    $(selector).append(...);

    Yo puediera tambien cargar ese combo en todos los que tengo un clase?? Yo creo que por ahi como que esta mejor..

    Gracias!

    ResponderEliminar
  6. Ya lo resolvi, con la clase, quedo esto:

    function ComboMoneda() {
    $.getJSON("/Moneda/ComboMonedas", function (datos) {
    $('.moneda').empty();
    $.each(datos, function (index, dato) {
    $('.moneda').append(
    $('< option/>')
    .attr('value', dato.Value)
    .text(dato.Text)
    );
    });
    });
    };

    Una sola función, que llama a la clase que le coloque a cada registro de moneda, pero aun no se si puedo hacer selectores dinámicos!

    En tú ejemplo:

    $.each(result.d, function() {
    07.
    $("#<%=ddlCiudades.ClientID%>").append($("< option>").attr("value", this.cod).text(this.descripcion))
    08.
    });

    Esto <%=ddlCiudades.ClientID%> entiendo que lo estas tomando de campo asp, pero yo quisiera hacer un selector con una cadena combinada de texto.. como esta: "#[" + i + "].MonedaID", cuyo resultado es: [0].MonedaID, eso se puede?? hay que hacer algo especial para que funcione??

    Muchas gracias..

    ResponderEliminar
  7. hola Pierina Joplin


    pero que sera [0] ?

    porque eso no lo veo un seelctor valido

    si la idea es tomar un valor del json recuerda qu este es un objeto de javascript puede accederlo directo cin necesidad de un selector de jquery

    estudia un poco sobre las clases de javascript y veras lo que comento, aunque no tengas inteliseenses javascript es tipado
    si tienes

    $.each(result.d ....

    podrias hacer

    this.MonedaID

    de forma directa, porque this es del tipo de cada item que devuelves en json


    dato.

    saludos

    ResponderEliminar
  8. Hola, Leandro Me puedes decir como haces para agregar al bd al proyecto, no se como explicarlo yo bajo tu ejemplo y ya esta la bd y la estrucura.. yo quiero hacer eso con una pequeña app y entregarla y que ya esta la db pero no se como..

    Saludos..

    ResponderEliminar
  9. hola Juan Manuel

    la db que uso en este ejemplo es un .sdf, o sea Sql Compact

    solamente la pones en la estructura del proyecto donde quieres ubicarla y usas la opcion Add-> Existing Items, buscando ese .sdf donde lo has ubicado, eso es todo

    tambien podrias usar

    How to add an existing folder to solution explorer

    es otra forma valida

    saludos

    ResponderEliminar
  10. Hola Leandro
    Queria hacerte una consulta un poco fuera de este tema: es posible acceder a distintas bd en sql a traves de un mismo sitio asp? de ser posible, como? saludos

    ResponderEliminar
  11. hola Georgina

    puedes definir varios connection string para conectarte a tantas db como necesites

    o sea mientras tengas acceso a la db puedes establecer la conexion

    como hacerlo, solo usando el SqlConnection, OleDbConection, etc que proporciona ado.net para conectarte con als distintas base de datos

    pero no se si es esto lo que preguntabas

    saludos

    ResponderEliminar
  12. Hola Leandro, si, mi duda iba enfocada mas que todo, por ejemplo, utilizar un mismo sitio web de registro de expedientes clinicos, cada usuario seria una clinica, por lo que cada clinica tendrá acceso a su propia bd (la estructura de la bd es la misma para todass pero para cada clinica se genera una copia de la bd por decirlo asi) y dependiendo del usuario, asi acceder a la copia de la bd de ese usuario pero utilizando el mismo sitio web en asp, efectivamente como mencionas utilizo el SqlConnection para acceder a la bd a través de clases, se me ocurre que dependiendo del "user" asi cambiara el string de conexion

    ResponderEliminar
  13. hola Georgina

    el tema es que si estas en un mismo sitio web que usan varias personas no deberias suar diferentes base de datos, sino una unica a la cual le defines la tabla de usuario y relacionas esto con los datos de las demas tablas

    en la aplicacion cuando se autentica una persona tomas ese id para aplicarlo a los filtros del resto de la informacion, de esta forma solo muestras los datos de esa persona en la pagina, pero la db es una unica y las tablas tambien solo que tendran un campo de usuario para saber a quien pertenece ese dato

    por ejemplo si vas a recuperar las historia clinicas usarias

    SELECT * From HistoriasClinicas
    WHERE idusuario = @id

    y asi todas las queries que requieran mostrar solo al info perteneciente a ese usuario que se autentico

    saludos

    ResponderEliminar
  14. Hola Leandro, queria saber si en este proyecto hay alguna forma de habilitar la opcion de JqGrid "loadtext" para que se visualice el "Cargando..." cuando esta esperando los datos ya que la agregue y no esta funcionando, alguna idea? muchas gracias

    ResponderEliminar
  15. hola Gaston

    el tema creo que viene porque en el ejemplo es uno quien controla la carga de los datos
    no se lo damos al propio jqgrid para que lo haga desde una url, sino que se usa $.ajax

    entonces como no invoca quizas por eso no muestre el mensaje

    saludos

    ResponderEliminar
  16. Que tal Leandro

    me parecio muy bueno tu tutorial, pero me preguntaba si de casualidad tendras alguna otro tutorial de como hacer que los nodos hijos se cargen al momento de expander el nodo padre, (on demand)o de como hacer paginacion con los registros mostrados para poder mostrar solo unos pocos y no todos los registros, esto por que necesito que sea un poco mas rapida la aplicacion ya que se cargan demasiados registros

    ResponderEliminar
  17. hola Eduardo

    apuntas a algo como esto

    http://www.trirand.net/examples/grid/treegrid/rowsondemand/default.aspx

    alli se muestra un ejemplo de como cargar un nodo mediante ajax

    saludos

    ResponderEliminar