Thursday, January 1, 2015

Fun with jQWidgets (jqxTreeGrid)

Fun with jQWidgets (jqxTreeGrid)

Building a parent child  hierarchy TreeView


So I’ve been working on this project lately, where my teammate asked me to write an advance TreeView with JQuery. The sample data and the TreeView structure was something like this

Sample Data


Name
Phone
CurrentBalance
UserType
UserCode
ParentCode
Hakeem
076 4876 6579
6,026
Administrator
AD-00001
NULL
Lucian
055 9658 5713
9,741
Branch
BR-00001
AD-00001
Felix
076 2291 6071
8,852
Distributor
DR-00001
BR-00001
Aquila
056 5580 0460
9,095
Agent
AG-00001
DR-00001
Tyrone
0916 103 0684
5,822
User
UR-00001
AG-00001

TreeView Structure



Name
Phone
CurrentBalance
Administrator
Hakeem
076 4876 6579
6,026
     Branch
Lucian
055 9658 5713
9,741
        Distributor
Felix
076 2291 6071
8,852
            Agent
Aquila
056 5580 0460
9,095
                 User
Tyrone
0916 103 0684
5,822
               

As you can see the TreeView structure follows the parent child relation hierarchy. However I’ve shown you a single node example here but in reality one node can have multiple child nodes then these child nodes can have multiple child nodes and so on and so forth.

So the first thing that comes to my mind is run a recursive function on this data and bind those data to one of thousands free JQuery TreeView scattered around the web. But to be frank I don’t like the idea of the recursion. I am not going to say that it increase my data manipulation time, thing is this time I won’t going to use recursion.

So I googled for some JQuery TreeView widgets on the web and finally came across a great JQuery widgets library which has a fantastic TreeView widget that just fits my requirements. So the name of the widget library is jQWidgets. You can surf their official website on this link


If you go to the Demo section you will see that they have over 42 widget ready for you. One of those is jqxTreeGrid widget. I read the documentation there and came across some fantastic features the widget provides.

So let’s build a demo application.

Binding data to jqxTreeGrid from ASP.net web method  


Open Visual Studio and create an ASP.net empty web forms application. I named it jqxTreeGridDemo.



Go to the official site of jQWidgets and in the download section, download the non-commercial version from there. The scripts will be downloaded as a zip file. Let’s unzip it and from the unzipped folder copy three folders and add to your project. These folders are


  • jqwidgets
  • scripts
  • styles




Now create a new web form in the project. I named it jqxWidget.

To create a list of sample user data, Lets create a complex User datatype. Means create a POCO class named User inside the model folder. The class will have these following properties

namespace jqxTreeGridDemo.Models
{
    public class User
    {
        public string Name { get; set; }
        public string Phone { get; set; }
        public decimal CurrentBalance { get; set; }
        public string UserType { get; set; }
        public string UserCode { get; set; }
        public string ParentCode { get; set; }
    }
}

Let’s go to the code behind of our form and declare a web method. The web method will simply return our predefined sample data in a json format to our UI. Remember to declare your web method as a static member otherwise you won’t able to get data from it with an Ajax call.

Building and sending a list of collection in json format will require a small library. So fire up the NuGet package manager and install the package called JSON.net.



Okay so our web method will look like this

 [WebMethod]
        [ScriptMethod(UseHttpGet = true)]
        public static string GetData()
        {
            List<User> users = new List<User>
            {
                new User {Name = "Hakeem", Phone = "076 4876 6579", CurrentBalance = 6026, UserType = "Administrator", UserCode = "AD-00001"},
                new User {Name = "Lucian", Phone = "055 9658 5713", CurrentBalance = 9741, UserType = "Branch", UserCode = "BR-00001", ParentCode = "AD-00001"},
                new User {Name = "Felix",  Phone = "076 2291 6071", CurrentBalance = 8852, UserType = "Distributor", UserCode = "DR-00001", ParentCode = "BR-00001"},
                new User {Name = "Aquila", Phone = "056 5580 0460", CurrentBalance = 9095, UserType = "Agent", UserCode = "AG-00001", ParentCode = "DR-00001"},
                new User {Name = "Tyrone", Phone = "0916 103 0684", CurrentBalance = 5822, UserType = "User", UserCode = "UR-00001", ParentCode = "AG-00001"},

                new User {Name = "Jasper", Phone = "0916 103 0684", CurrentBalance = 9935 , UserType = "Branch", UserCode = "BR-00002", ParentCode = "AD-00001"},
                new User {Name = "Erasmus", Phone = "0314 951 0576", CurrentBalance = 5636 , UserType = "Distributor", UserCode = "DR-00002", ParentCode = "BR-00002"},
                new User {Name = "Elton", Phone = "0887 799 4296", CurrentBalance = 6448 , UserType = "Distributor", UserCode = "DR-00003", ParentCode = "BR-00002"},
                new User {Name = "Colt", Phone = "07624 841017", CurrentBalance = 5425, UserType = "Agent", UserCode = "AG-00002", ParentCode = "DR-00003"},
                new User {Name = "Phillip", Phone = "070 7469 2182", CurrentBalance = 8344, UserType = "User", UserCode = "UR-00002", ParentCode = "AG-00001"},
                new User {Name = "Lucian", Phone = "055 9658 5713", CurrentBalance = 9741, UserType = "User", UserCode = "UR-00003", ParentCode = "AG-00001"},
                new User {Name = "Aron", Phone = "0800 722148", CurrentBalance = 5527, UserType = "User", UserCode = "UR-00004", ParentCode = "AG-00002"},
            };

            string data = JsonConvert.SerializeObject(users);
            return data;
        }

Now let’s get back to the UI (jqxTreeGrid.aspx). Give a title to the page and add the scripts reference as follow

<head runat="server">
    <title>jqxTreeGrid Demo</title>
    <link href="jqwidgets/styles/jqx.base.css" rel="stylesheet" />
    <script src="scripts/jquery-1.10.2.min.js"></script>
    <script src="jqwidgets/jqxcore.js"></script>
    <script src="jqwidgets/jqxdata.js"></script>
    <script src="jqwidgets/jqxbuttons.js"></script>
    <script src="jqwidgets/jqxscrollbar.js"></script>
    <script src="jqwidgets/jqxdatatable.js"></script>
    <script src="jqwidgets/jqxtreegrid.js"></script>
</head>

Now the main part. Create a script section after those reference declared above and past this code

<script>
        $(document).ready(function() {
            function onSuccess(data) {
                var users = data.d;
                var source =
                {
                    dataType: "json",
                    dataFields: [
                        { name: 'UserType', type: 'string' },
                        { name: 'Name', type: 'string' },
                        { name: 'Phone', type: 'string' },
                        { name: 'CurrentBalance', type: 'number' },
                        { name: 'UserCode', type: 'string' },
                        { name: 'ParentCode', type: 'string' }
                    ],
                    hierarchy:
                    {
                        keyDataField: { name: 'UserCode' },
                        parentDataField: { name: 'ParentCode' }
                    },
                    id: 'UserCode',
                    localData: users
                };
                var dataAdapter = new $.jqx.dataAdapter(source);

                $("#treeGrid").jqxTreeGrid(
                {
                    width: 700,
                    height: 390,
                    source: dataAdapter,
                    ready: function () {
                        $("#treeGrid").jqxTreeGrid('expandRow', '2');
                    },
                    columns: [
                      { text: 'User Type', dataField: 'UserType', width: 150 },
                      { text: 'Name', dataField: 'Name', width: 150 },
                      { text: 'Phone', dataField: 'Phone', width: 200 },
                      { text: 'Current Balance', dataField: 'CurrentBalance', width: 200, cellsalign: 'right', cellsFormat: "c2" }
                    ]
                });
            }

            $.ajax({
                type: "GET",
                url: "jqxTreeGrid.aspx/GetData",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                success: onSuccess,
                failure: function(response) {
                    alert(response.d);
                }
            });
        });
    </script>

As you can see at the bottom I’m initiating an Ajax call to my web method declared in the code behind. Since our backend code will return JSON data only when an HTTP GET is initiated, I set the Ajax request type to "GET". Then we have the URL and returned data type declared. On a success request we have a callback. The callback function will rearrange the data according to our setting. I leave rest up to you because it’s easy to understand what’s going on there after having the response data. Just look at the hierarchy property and we will get the point.

And in the html all you need to do is to declare a <div></div> tag with the id of treeGrid like below

<body>
    <form id="form1" runat="server">
    <div>
     <div id="treeGrid"></div>
    </div>
    </form>
</body>

So everything is done. Set the jqxTreeGrid.aspx page as default starting page and run. You will get an output like this one.


Git repository for this example can be found here 


Thanks for reading this post. I will see you again.