3

I hope you can help me, I have a structure like this:

- root A
    -child_A1
        -child_A1_1
        -child_A1_2
        -child_A1_3
    -child_A2
        -child_A2_1
        -child_A2_2
        -child_A2_3

- root B
    - child_B1
         -child_B1_1
         -child_B1_2
         -child_B1_3

But when I show the data in TreeGrid, it shows like this:

- root A
    -child_A1

    -child_A2
         -child_A1_1

- root B
    - child_B1
         -child_B1_1
         -child_B1_2
         -child_B1_3
         -child_A1_2
         -child_A1_3
         -child_A2_1
         -child_A2_2
         -child_A2_3

Anybody knows why..??? please help, I search information about this error but don`t have luck....

Here's my JavaScript:

<script type="text/javascript">
$(document).ready(function () {
    var lastsel;
    $(function () {
        jQuery('#tree').jqGrid({
            url: '/Ubicacion/TreeGrid/',
            datatype: 'json',
            height: 250,
            colNames: ['Nombre', 'Descripcion'],
            colModel: [
                        { name: 'Nombre', index: 'Nombre', width: 100, sortable: true, editable: true, edittype: "text"},
                        { name: 'Descripcion', index: 'Descripcion', width: 80, editable: true, edittype: "text" }
                      ],
            caption: 'Listado de Ubicaciones',
            treeGridModel: 'adjacency',
            sortname: 'Nombre',
            loadonce: true,
            height: 'auto',
            width: '500',
            pager: "#pager",
            treeGrid: true,
            ExpandColumn: 'Id',
            ExpandColClick: true,
        });
    });
});

And here is the server side function that I used for generate json string:

public ActionResult TreeGrid(string sidx, string sord, int? page, int? rows)
    {
        List<Ubicacion> ubicacion = new List<Ubicacion>();
        ubicacion = UbicacionRepository.GetAll().ToList<Ubicacion>();

        int pageIndex = Convert.ToInt32(page) - 1;
        int totalrecords = ubicacion.Count();

        JsonResult json = new JsonResult();
        json.JsonRequestBehavior = JsonRequestBehavior.AllowGet;

        json.Data = new
        {
            sidx = "Nombre",
            sord = "asc",
            page = page,
            records = totalrecords,
            rows = (from ubi in ubicacion
                    select new
                    {
                        cell = new string[] 
                            {
                                ubi.Nombre,
                                ubi.Descripcion,
                                ubi.Nivel.ToString(),
                                ubi.IdPadre == 0 ? "null" : ubi.IdPadre.ToString(),
                                ubi.Nivel < 2 ? "false" : "true",
                                "false",
                                "true"
                            }
                    })
        };
        return json;
    }

And here's the json generated:

{"total":1,"page":null,"records":18,"rows":[
      {"cell":["Parent A","ubicacion","0","null","false","false","true"]},
      {"cell":["Child A1","ubicacion","1","1","false","false","true"]},
      {"cell":["Child A2","ubicacion","1","1","false","false","true"]},
      {"cell":["Child A1_1","ubicacion","2","2","true","false","true"]},
      {"cell":["Parent B","ubicacion","0","null","false","false","true"]},
      {"cell":["Child B1","ubicacion","1","5","false","false","true"]},
      {"cell":["Child B1_1","ubicacion","2","6","true","false","true"]},
      {"cell":["Child B1_2","ubicacion","2","6","true","false","true"]},
      {"cell":["Child B1_3","ubicacion","2","6","true","false","true"]},
      {"cell":["Child A1_2","ubicacion","2","2","true","false","true"]},
      {"cell":["Child_A1_3","ubicacion","2","2","true","false","true"]},
      {"cell":["Child A2_1","ubicacion","2","3","true","false","true"]},
      {"cell":["Child A2_2","ubicacion","2","3","true","false","true"]},
      {"cell":["Child A2_3","ubicacion","2","3","true","false","true"]}
    ]}
verofairy
  • 77
  • 3
  • 13

2 Answers2

1

I encountered this same problem. It would appear that jqGrid expects the data to be already sorted in the tree structure (i.e. it does not perform the sort at the client) but I may be wrong. Below are some extensions I created to perform a tree sort of a generic IEnumerable that contains objects with the specified ID and Parent ID properties. Objects will null in the Parent ID property are placed at the root.

public static class TreeSortExtensions
{
    public static IEnumerable<T> OrderByTreeStructure<T>(
        this IEnumerable<T> source,
        string objectIDProperty,
        string parentIDPropery)
    {
        IEnumerable<T> result = source;

        if (!string.IsNullOrEmpty(objectIDProperty) && !string.IsNullOrEmpty(parentIDPropery))
        {
            result = source.GetChildrenOfTreeNode(null, objectIDProperty, parentIDPropery, true);
        }

        return result;
    }

    public static IEnumerable<T> GetChildrenOfTreeNode<T>(
        this IEnumerable<T> source,
        object parent,
        string property,
        string parentProperty,
        bool recurse)
    {
        if (!string.IsNullOrEmpty(property) && !string.IsNullOrEmpty(parentProperty))
        {
            IEnumerable<T> children;
            if (parent == null)
            {
                children = source.Where(x => x.GetPropertyValue(parentProperty) == null);
            }
            else
            {
                var parentIDValue = parent.GetPropertyValue(property);
                children = source.Where(x => (x.GetPropertyValue(parentProperty) != null) && 
                                             (x.GetPropertyValue(parentProperty).Equals(parentIDValue)));
            }

            foreach (T child in children) 
            {
                yield return child;

                if (recurse)
                {
                    var grandChildren = source.GetChildrenOfTreeNode(child, property, parentProperty, true).ToArray();
                    foreach (T grandchild in grandChildren)
                    {
                        yield return grandchild;
                    }
                }
            }
        }
    }

    public static object GetPropertyValue(this object obj, string property)
    {
        return obj.GetType().GetProperty(property).GetValue(obj, null);
    }

}

Note that the "parent" argument is of type object and not T. This allows a null to be passed as the parent of root level objects.

Usage:

var result1 = someEnumerable.OrderByTreeStructure("SomeIDProperty", "SomeParentIDProperty");
var result2 = someDbContext.SomeTable.OrderByTreeStructure("ID", "ParentID");
moomoo
  • 636
  • 7
  • 9
1

I got it! you need to order recursively the list, because it's rendering in the exact order you extracted from your db..

    private static List<MENU> Listado = new List<MENU>();
    private static List<MENU> lstOrdenada = new List<MENU>();

    public List<MENU> MenuRecursivo()
    {
        //the whole list of MENU
        Listado = (from m in db.MENU where m.men_eliminado == "N" select m).ToList();
        // a list where we'll put the ordered items
        lstOrdenada = new List<MENU>();

        foreach (MENU item in Listado.Where(x => x.ID_MENU == x.id_menu_padre).ToList()) // in my case, only the root items match this condition

        {
            lstOrdenada.Add(item);
            GMenuHijo(item.ID_MENU, ref lstOrdenada);
        }
        return lstOrdenada;
    }

`

Then, for each root item, recursively find the next levels:

private static void GMenuHijo(int idPadre, ref List<MENU> lst)
{
    List<MENU> listado2 = Listado.Where(x => x.id_menu_padre == idPadre && x.ID_MENU != x.id_menu_padre).ToList();
    if (listado2.Count > 0)
    {
        foreach (MENU item in listado2)
        {
            lst.Add(item);
            GMenuHijo(item.ID_MENU, ref lst);
        }
    }
}
mjormy
  • 11
  • 1