PDA

View Full Version : [CLOSED] TreePanel with AjaxProxy + JsonReader



jwf
Sep 11, 2013, 10:47 PM
Hello,

I'm making my first TreePanel in Ext.NET 2.2. I'm doing something wrong and getting buggy behavior from the control.

The panel defines a store which retrieves node data from an httphandler. I will post a brief example below to illustrate the issue.

Default Namespace for the web application: SandboxExt2._2

Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SandboxExt2._2.Default" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<!DOCTYPE html>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ext.NET 2.2 Example</title>
<ext:ResourcePlaceHolder runat="server" ID="ResourcePlaceHolder1" />
</head>
<body>
<form id="form1" runat="server">
<ext:ResourceManager runat="server" ID="ResourceManager1" Theme="Gray">
</ext:ResourceManager>

<asp:ScriptManager runat="server" ID="ScriptManager1">
<Scripts>
<asp:ScriptReference Path="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" />
</Scripts>
</asp:ScriptManager>

<%-- Viewport --%>
<ext:Viewport runat="server" ID="ViewportMain" StyleSpec="background-color: #DFE8F6" Layout="FitLayout">
<Items>
<ext:TreePanel runat="server" ID="ServiceNodeTreePanel" ClientIDMode="Static" RootVisible="false" SingleExpand="true">
<Store>
<ext:TreeStore runat="server" ID="ServiceNodeTreeStore" ClientIDMode="Static" AutoLoad="true">
<Proxy>
<ext:AjaxProxy Url="~/DataHandler.ashx">
<Reader>
<ext:JsonReader Root="nodes" IDProperty="ServiceNodeID" />
</Reader>
</ext:AjaxProxy>
</Proxy>
<Model>
<ext:Model runat="server" ID="ServiceNodeModel">
<Fields>
<ext:ModelField Name="ServiceNodeID" Type="Int" />
<ext:ModelField Name="ParentServiceNodeID" Type="Int" />
<ext:ModelField Name="Title" Type="String" />
<ext:ModelField Name="ShowInMainMenu" Type="Boolean" />
<ext:ModelField Name="IsActive" Type="Boolean" />
<ext:ModelField Name="Rank" Type="Int" />
</Fields>
</ext:Model>
</Model>
<Parameters>
<ext:StoreParameter Name="DataAction" Value="GetServiceNodes" Mode="Value" />
</Parameters>
</ext:TreeStore>
</Store>
<ColumnModel>
<Columns>
<ext:TreeColumn ID="TreeColumn1" runat="server" Text="ID" DataIndex="ServiceNodeID" />
<ext:TreeColumn ID="TreeColumn2" runat="server" Text="Parent ID" DataIndex="ParentServiceNodeID" />
<ext:TreeColumn ID="TreeColumn3" runat="server" Text="Title" DataIndex="Title" />
<ext:TreeColumn ID="TreeColumn4" runat="server" Text="Main Menu" DataIndex="ShowInMainMenu" />
<ext:TreeColumn ID="TreeColumn5" runat="server" Text="Active" DataIndex="IsActive" />
</Columns>
</ColumnModel>
</ext:TreePanel>
</Items>
</ext:Viewport>
</form>
</body>
</html>


DataHandler.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Ext.Net;


namespace SandboxExt2._2
{
public class DataHandler : IHttpHandler
{
#region IsReusable
public bool IsReusable
{
get { return true; }
}
#endregion


#region ProcessRequest
public void ProcessRequest(HttpContext context)
{
StoreRequestParameters parms = new StoreRequestParameters(context);


if (context.Request["DataAction"] != null)
{
string dataAction = context.Request["DataAction"].ToString().Trim();
switch (dataAction)
{
case "GetServiceNodes":
GetServiceNodes(context, parms);
break;


default: break;
}
}
}
#endregion

#region GetServiceNodes
public void GetServiceNodes(HttpContext context, StoreRequestParameters parms)
{


Ext.Net.Node root = new Node();
root.Text = "Service Nodes";


root.CustomAttributes.Add(new ConfigItem() { Name = "ServiceNodeID", Value = "1", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "ParentServiceNodeID", Value = "null", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "Title", Value = "Root Node", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "ShowInMainMenu", Value = "true", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "IsActive", Value = "true", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "Rank", Value = "1", Mode = ParameterMode.Value });


Ext.Net.Node child = new Node();


child.CustomAttributes.Add(new ConfigItem() { Name = "ServiceNodeID", Value = "2", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "ParentServiceNodeID", Value = "1", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "Title", Value = "First Child Node", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "ShowInMainMenu", Value = "true", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "IsActive", Value = "true", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "Rank", Value = "1", Mode = ParameterMode.Value });


root.Children.Add(child);


context.Response.ContentType = "text/json";
context.Response.Write(string.Format("{{'nodes':{0}}}", JSON.Serialize(root)));
}
#endregion
}
}


Web.config:

<httpHandlers>
<add path="DataHandler.ashx" verb="*" type="SandboxExt2._2.DataHandler, SandboxExt2._2"/>
<add path="*/ext.axd" verb="*" type="Ext.Net.ResourceHandler" validate="false" />
</httpHandlers>


When I run this, I don't see the nice tree panel I expect. Instead I see this:

6885

When I click on a + sign to expand, I get this:

6886

So, obviously, I'm doing something horribly wrong. At the moment, I don't know what that is. Help? :D

Thanks,

jwf

Daniil
Sep 12, 2013, 7:29 AM
Hi @jwf,

First of all I see you are using several TreeColumns. It is supposed there must the only TreeColumn. As here:
http://examples2.ext.net/#/TreePanel/Advanced/TreeGrid/

jwf
Sep 13, 2013, 5:50 PM
Hi Daniil,

First off, thanks for the tip about the TreeColumns. I saw the first one and then just spammed out the rest without seeing that they were different. I've corrected that issue, but also found that unless my "root" property was consistent in the json returned by the handler, the treepanel would not work. Since I'm using JSON.Serialize on my root node, I had to change the reader's "root" property to 'children' to match:

<ext:JsonReader Root="children" IDProperty="ServiceNodeID" />

Setting the leaf property correctly also fixed the infinite expansion problem.

I've almost got this working, but at present the root node is showing despite setting the "RootVisible" property to false on the treepanel. I will post updated code below - can you help me understand why this root node is showing? Thanks!

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SandboxExt2._2.Default" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>


<!DOCTYPE html>


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Ext.NET 2.2 Example</title>
<ext:ResourcePlaceHolder runat="server" ID="ResourcePlaceHolder1" />
</head>
<body>
<form id="form1" runat="server">
<ext:ResourceManager runat="server" ID="ResourceManager1" Theme="Gray">
</ext:ResourceManager>

<asp:ScriptManager runat="server" ID="ScriptManager1">
<Scripts>
<asp:ScriptReference Path="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js" />
</Scripts>
</asp:ScriptManager>


<%-- Viewport --%>
<ext:Viewport runat="server" ID="ViewportMain" StyleSpec="background-color: #DFE8F6" Layout="FitLayout">
<Items>
<ext:TreePanel runat="server" ID="ServiceNodeTreePanel" ClientIDMode="Static" RootVisible="false" SingleExpand="true">
<Store>
<ext:TreeStore runat="server" ID="ServiceNodeTreeStore" ClientIDMode="Static" AutoLoad="true">
<Proxy>
<ext:AjaxProxy Url="~/DataHandler.ashx">
<Reader>
<ext:JsonReader Root="children" IDProperty="ServiceNodeID" />
</Reader>
</ext:AjaxProxy>
</Proxy>
<Model>
<ext:Model runat="server" ID="ServiceNodeModel">
<Fields>
<ext:ModelField Name="ServiceNodeID" Type="Int" />
<ext:ModelField Name="ParentServiceNodeID" Type="Int" />
<ext:ModelField Name="Title" Type="String" />
<ext:ModelField Name="ShowInMainMenu" Type="Boolean" />
<ext:ModelField Name="IsActive" Type="Boolean" />
<ext:ModelField Name="Rank" Type="Int" />
</Fields>
</ext:Model>
</Model>
<Parameters>
<ext:StoreParameter Name="DataAction" Value="GetServiceNodes" Mode="Value" />
</Parameters>
</ext:TreeStore>
</Store>
<ColumnModel>
<Columns>
<ext:TreeColumn ID="TreeColumn1" runat="server" Text="ID" DataIndex="ServiceNodeID" />
<ext:Column ID="Column2" runat="server" Text="Parent ID" DataIndex="ParentServiceNodeID" />
<ext:Column ID="Column3" runat="server" Text="Title" DataIndex="Title" />
<ext:Column ID="Column4" runat="server" Text="Main Menu" DataIndex="ShowInMainMenu" />
<ext:Column ID="Column5" runat="server" Text="Active" DataIndex="IsActive" />
</Columns>
</ColumnModel>
</ext:TreePanel>
</Items>
</ext:Viewport>
</form>
</body>
</html>


DataHandler.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Ext.Net;


namespace SandboxExt2._2
{
public class DataHandler : IHttpHandler
{
#region IsReusable
public bool IsReusable
{
get { return true; }
}
#endregion


#region ProcessRequest
public void ProcessRequest(HttpContext context)
{
StoreRequestParameters parms = new StoreRequestParameters(context);


if (context.Request["DataAction"] != null)
{
string dataAction = context.Request["DataAction"].ToString().Trim();
switch (dataAction)
{
case "GetServiceNodes":
GetServiceNodes(context, parms);
break;


default: break;
}
}
}
#endregion

#region GetServiceNodes
public void GetServiceNodes(HttpContext context, StoreRequestParameters parms)
{


Ext.Net.Node root = new Node();
root.Text = "Service Nodes";


root.CustomAttributes.Add(new ConfigItem() { Name = "ServiceNodeID", Value = "1", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "ParentServiceNodeID", Value = "null", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "Title", Value = "Root Node", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "ShowInMainMenu", Value = "true", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "IsActive", Value = "true", Mode = ParameterMode.Value });
root.CustomAttributes.Add(new ConfigItem() { Name = "Rank", Value = "1", Mode = ParameterMode.Value });


Ext.Net.Node child = new Node();
child.Leaf = true;


child.CustomAttributes.Add(new ConfigItem() { Name = "ServiceNodeID", Value = "2", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "ParentServiceNodeID", Value = "1", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "Title", Value = "First Child Node", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "ShowInMainMenu", Value = "true", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "IsActive", Value = "true", Mode = ParameterMode.Value });
child.CustomAttributes.Add(new ConfigItem() { Name = "Rank", Value = "1", Mode = ParameterMode.Value });


root.Children.Add(child);


context.Response.ContentType = "text/json";
context.Response.Write(string.Format("{{'children':{0}}}", JSON.Serialize(root)));
}
#endregion
}
}

jwf
Sep 13, 2013, 6:43 PM
Update: I was able to resolve my issues once I found this example http://examples2.ext.net/TreePanel/Loaders/Using_Handler/ and modified my approach. The root node is now defined in the layout, and the handler returns a collection of nodes serialized using the .ToJson extension method. As a result the root is hidden correctly and the child nodes display correctly.

You can mark this as resolved.