PDA

View Full Version : Implementing a ComboTree extension



pschojer
Jun 30, 2009, 4:56 AM
Hi guys,

as i`ve already posted here (http://forums.ext.net/showthread.php?3974) I need a ComboTree component for my application.

I am now trying to implement the extension on myself within the Ext.UX project.

I`ve compiled my customized extension library successfully and the control is showing up in my application.
However, when i expand a node within the tree popup the assigned TreeLoader event is never raised server-side.

A request to the server is made, but it fails with an error message ("control ext-gen1000 not found").

Here is my code:

ComboTree.js


Ext.namespace('Ext.ux');

/**
*
* @class ComboTree
* @extends Ext.form.ComboBox
*/
Ext.ux.ComboTree = Ext.extend(Ext.form.ComboBox, {
extStore: null,
tree: null,
treeId: 0,
setValue: function(v) {
var text = v;
if (this.valueField) {
var r = this.findExtRecord(this.valueField, v);
if (r) {
text = r.data[this.displayField];
} else if (this.valueNotFoundText !== undefined) {
text = this.valueNotFoundText;
}
}
Ext.ux.ComboTree.superclass.setValue.call(this, text);
this.lastSelectionText = text;
if (this.hiddenField) {
this.hiddenField.value = v;
}
this.value = v;
},
initComponent: function() {
this.treeId = Ext.id();
this.focusLinkId = Ext.id();
Ext.apply(this, {
store: new Ext.data.SimpleStore({
fields: [],
data: [[]]
}),
editable: false,
shadow: false,
mode: 'local',
triggerAction: 'all',
maxHeight: 200,
tpl: '<tpl for="."><div style="height:200px"><div id="'
+ this.treeId + '">

</tpl>',
selectedClass: '',
onSelect: Ext.emptyFn,
valueField: 'id'
});

var treeConfig = {
border: false,
rootVisible: true,
loader: this.loader // loader is assigned here
};
Ext.apply(treeConfig, this.treeConfig);
if (!treeConfig.root) {
treeConfig.root = new Ext.tree.AsyncTreeNode({
text: 'treeRoot',
id: '0'
});
}
this.tree = new Ext.tree.TreePanel(treeConfig);
this.on('expand', this.onExpand);
this.tree.on('click', this.onClick, this);
Ext.ux.ComboTree.superclass.initComponent.apply(th is,
arguments);
},
findExtRecord: function(prop, value) {
var record;
if (this.extStore != null) {
if (this.extStore.getCount() > 0) {
this.extStore.each(function(r) {
if (r.data[prop] == value) {
record = r;
return false;
}
});
}
}
return record;
},
onClick: function(node) {
if (node.attributes.parameter == 9) {
//
} else {
//
this.setValue(node.text);
this.hiddenField.value = node.id;
this.collapse();
}
},
onExpand: function() {
this.tree.render(this.treeId);
}
});


Ext.reg("combotree", Ext.ux.ComboTree);


ComboTree.cs


[assembly: WebResource("Coolite.Ext.UX.Extensions.ComboTree.resources.Comb oTree.js", "text/javascript")]

namespace Coolite.Ext.UX
{
[Designer(typeof(EmptyDesigner))]
[DefaultProperty("")]
[Xtype("combotree")]
[InstanceOf(ClassName = "Ext.ux.ComboTree")]

[ClientScript(Type = typeof(ComboTree), WebResource =
"Coolite.Ext.UX.Extensions.ComboTree.resources.Comb oTree.js", FilePath
= "ux/extensions/combotree/combotree.js")]
[ToolboxData("<{0}:ComboTree runat=\"server\" Title=\"Combo tree\" Height=\"300\"></{0}:ComboTree>")]
[Description("Combobox with tree functionality")]
public class ComboTree : ComboBox
{
private TreeLoaderCollection treeLoader;

[ClientConfig("loader>Primary")]
[Category("Config Options")]
[NotifyParentProperty(true)]
[DefaultValue(null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[Description("The root node for the tree.")]
public virtual TreeLoaderCollection Loader
{
get
{
if (this.treeLoader == null)
{
this.treeLoader = new TreeLoaderCollection();
}

return this.treeLoader;
}
}
}
}


Usage:


<ux:ComboTree ID="_ct" runat="server">
<Loader>
<ext:PageTreeLoader OnNodeLoad="LoadTreeNodeEntries">
</ext:PageTreeLoader>
</Loader>
</ux:ComboTree>


I`m
trying to figure out whats the correct way to implement extensions by
the GMap extension, but i`m not sure if the code above is the right one
for my extension.

Can you pelase help me ?

Thx,
Peter

Vladimir
Jun 30, 2009, 8:47 AM
Hi,

I am not tested it but try the following

1. ComboTree.cs (don't forget required attributes for ComboTree class)


public class ComboTree : ComboBox
{
private ItemsCollection<TreePanel> tree;

[ClientConfig("tree", typeof(ItemCollectionJsonConverter))]
[Category("Config Options")]
[NotifyParentProperty(true)]
[DefaultValue(null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual ItemsCollection<TreePanel> Tree
{
get
{
if (this.tree == null)
{
this.tree = new ItemsCollection<TreePanel>();
this.tree.SingleItemMode = true;
this.tree.AfterItemAdd += this.AfterItemAdd;
}

return this.tree;
}
}

protected virtual void AfterItemAdd(Component item)
{
this.Controls.Add(item);

if (!this.LazyItems.Contains(item))
{
this.LazyItems.Add(item);
}
}
}


2. ComboTree.js (initComponent.js function)


initComponent: function() {
this.treeId = Ext.id();
this.focusLinkId = Ext.id();
Ext.apply(this, {
store: new Ext.data.SimpleStore({
fields: [],
data: [[]]
}),
editable: false,
shadow: false,
mode: 'local',
triggerAction: 'all',
maxHeight: 200,
tpl: '<tpl for="."><div style="height:200px"><div id="'
+ this.treeId + '">

</tpl>',
selectedClass: '',
onSelect: Ext.emptyFn,
valueField: 'id'
});

this.tree = new Coolite.Ext.TreePanel(this.tree);
this.on('expand', this.onExpand);
this.tree.on('click', this.onClick, this);
Ext.ux.ComboTree.superclass.initComponent.apply(th is, arguments);
}


3. Example


<%@ Page Language="C#" %>

<%@ Register Assembly="Coolite.Ext.Web" Namespace="Coolite.Ext.Web" TagPrefix="ext" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>

<script runat="server">
protected void NodeLoad(object sender, NodeLoadEventArgs e)
{
if (!string.IsNullOrEmpty(e.NodeID))
{
for (int i = 1; i < 6; i++)
{
AsyncTreeNode asyncNode = new AsyncTreeNode();
asyncNode.Text = e.NodeID + i;
asyncNode.NodeID = e.NodeID + i;
e.Nodes.Add(asyncNode);
}

for (int i = 6; i < 11; i++)
{
Coolite.Ext.Web.TreeNode treeNode = new Coolite.Ext.Web.TreeNode();
treeNode.Text = e.NodeID + i;
treeNode.NodeID = e.NodeID + i;
treeNode.Leaf = true;
e.Nodes.Add(treeNode);
}
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<ext:ScriptManager ID="ScriptManager1" runat="server" />

<ext:ComboTree ID="_ct" runat="server">
<Tree>
<ext:TreePanel
ID="TreePanel1"
runat="server"
Title="Tree"
AutoHeight="true"
Border="false">
<Loader>
<ext:PageTreeLoader OnNodeLoad="NodeLoad">
</ext:PageTreeLoader>
</Loader>
<Root>
<ext:AsyncTreeNode NodeID="0" Text="Root" />
</Root>
</ext:TreePanel>
</Tree>
</ext:ComboTree>
</form>
</body>
</html>

pschojer
Jun 30, 2009, 9:34 AM
Hi Vlad,

thanks for your reply.

The problem with the solution you provided is, that the AfterItemAdd event and the SingleItemMode property of the ItemCollection can be accessed internally only. So I would need to move the control to the Coolite core package.
But I would like to keep it in the plugin package because I think it`s a far cleaner approach.

Do you have any ideas or workarounds ?

Thx,
Peter

Vladimir
Jul 01, 2009, 6:43 AM
Hi,

Well, you can skip SingleItemMode (just be sure that you use single tree or check it manually, for example on LoadComplete event)

I think AfterItemAdd can be skiped also. Just add tree to the Controls collection on OnLoad function (override it)


protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}

pschojer
Jul 08, 2009, 10:25 AM
Thanks vlad, that`s it !

For anyone who has the same problem, do not forget to add the tree to the LazyItems-Collection too !!



protected override void OnLoad(EventArgs e)
{
this.Controls.Add(Tree[0]);

if (!this.LazyItems.Contains(Tree[0]))
{
this.LazyItems.Add(Tree[0]);
}

base.OnLoad(e);
}

supermanok
Jul 13, 2009, 4:43 AM
pschojer (6/29/2009)Hi guys,

as i`ve already posted here (http://forums.ext.net/showthread.php?threadid=15853-17-1.aspx) I need a ComboTree component for my application.

I am now trying to implement the extension on myself within the Ext.UX project.

I`ve compiled my customized extension library successfully and the control is showing up in my application.
However, when i expand a node within the tree popup the assigned TreeLoader event is never raised server-side.

A request to the server is made, but it fails with an error message ("control ext-gen1000 not found").

Here is my code:

ComboTree.js


Ext.namespace('Ext.ux');

/**
*
* @class ComboTree
* @extends Ext.form.ComboBox
*/
Ext.ux.ComboTree = Ext.extend(Ext.form.ComboBox, {
extStore: null,
tree: null,
treeId: 0,
setValue: function(v) {
var text = v;
if (this.valueField) {
var r = this.findExtRecord(this.valueField, v);
if (r) {
text = r.data[this.displayField];
} else if (this.valueNotFoundText !== undefined) {
text = this.valueNotFoundText;
}
}
Ext.ux.ComboTree.superclass.setValue.call(this, text);
this.lastSelectionText = text;
if (this.hiddenField) {
this.hiddenField.value = v;
}
this.value = v;
},
initComponent: function() {
this.treeId = Ext.id();
this.focusLinkId = Ext.id();
Ext.apply(this, {
store: new Ext.data.SimpleStore({
fields: [],
data: [[]]
}),
editable: false,
shadow: false,
mode: 'local',
triggerAction: 'all',
maxHeight: 200,
tpl: '<tpl for="."><div style="height:200px"><div id="'
+ this.treeId + '">

</tpl>',
selectedClass: '',
onSelect: Ext.emptyFn,
valueField: 'id'
});

var treeConfig = {
border: false,
rootVisible: true,
loader: this.loader // loader is assigned here
};
Ext.apply(treeConfig, this.treeConfig);
if (!treeConfig.root) {
treeConfig.root = new Ext.tree.AsyncTreeNode({
text: 'treeRoot',
id: '0'
});
}
this.tree = new Ext.tree.TreePanel(treeConfig);
this.on('expand', this.onExpand);
this.tree.on('click', this.onClick, this);
Ext.ux.ComboTree.superclass.initComponent.apply(th is,
arguments);
},
findExtRecord: function(prop, value) {
var record;
if (this.extStore != null) {
if (this.extStore.getCount() > 0) {
this.extStore.each(function(r) {
if (r.data[prop] == value) {
record = r;
return false;
}
});
}
}
return record;
},
onClick: function(node) {
if (node.attributes.parameter == 9) {
//
} else {
//
this.setValue(node.text);
this.hiddenField.value = node.id;
this.collapse();
}
},
onExpand: function() {
this.tree.render(this.treeId);
}
});


Ext.reg("combotree", Ext.ux.ComboTree);


ComboTree.cs


[assembly: WebResource("Coolite.Ext.UX.Extensions.ComboTree.resources.Comb oTree.js", "text/javascript")]

namespace Coolite.Ext.UX
{
[Designer(typeof(EmptyDesigner))]
[DefaultProperty("")]
[Xtype("combotree")]
[InstanceOf(ClassName = "Ext.ux.ComboTree")]

[ClientScript(Type = typeof(ComboTree), WebResource =
"Coolite.Ext.UX.Extensions.ComboTree.resources.Comb oTree.js", FilePath
= "ux/extensions/combotree/combotree.js")]
[ToolboxData("<{0}:ComboTree runat=\"server\" Title=\"Combo tree\" Height=\"300\"></{0}:ComboTree>")]
[Description("Combobox with tree functionality")]
public class ComboTree : ComboBox
{
private TreeLoaderCollection treeLoader;

[ClientConfig("loader>Primary")]
[Category("Config Options")]
[NotifyParentProperty(true)]
[DefaultValue(null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
[Description("The root node for the tree.")]
public virtual TreeLoaderCollection Loader
{
get
{
if (this.treeLoader == null)
{
this.treeLoader = new TreeLoaderCollection();
}

return this.treeLoader;
}
}
}
}


Usage:


<ux:ComboTree ID="_ct" runat="server">
<Loader>
<ext:PageTreeLoader OnNodeLoad="LoadTreeNodeEntries">
</ext:PageTreeLoader>
</Loader>
</ux:ComboTree>


I`m
trying to figure out whats the correct way to implement extensions by
the GMap extension, but i`m not sure if the code above is the right one
for my extension.

Can you pelase help me ?

Thx,
Peter


Hi,pschojer (void('');)
do you shaing your component?
that it's very cool .

pschojer
Jul 13, 2009, 11:14 AM
Ok, here is the final source (attached also!).

ComboTree.js:


Ext.namespace('Ext.ux');

/**
*
* @class ComboTree
* @extends Ext.form.ComboBox
*/
Ext.ux.ComboTree = Ext.extend(Ext.form.ComboBox, {
extStore: null,
tree: null,
treeId: 0,
setValue: function(v) {
var text = v;
if (this.valueField) {
var r = this.findExtRecord(this.valueField, v);
if (r) {
text = r.data[this.displayField];
} else if (this.valueNotFoundText !== undefined) {
text = this.valueNotFoundText;
}
}
Ext.ux.ComboTree.superclass.setValue.call(this, text);
this.lastSelectionText = text;
if (this.hiddenField) {
this.hiddenField.value = v;
}
this.value = v;
},
initComponent: function() {
this.treeId = Ext.id();
this.focusLinkId = Ext.id();
Ext.apply(this, {
store: new Ext.data.SimpleStore({
fields: [],
data: [[]]
}),
editable: false,
shadow: false,
mode: 'local',
triggerAction: 'all',
maxHeight: 200,
tpl: '<tpl for="."><div style="height:200px"><div id="'
+ this.treeId + '">

</tpl>',
selectedClass: '',
onSelect: Ext.emptyFn,
valueField: 'id'
});

this.tree = new Coolite.Ext.TreePanel(this.tree);
this.on('expand', this.onExpand);
this.tree.on('click', this.onClick, this);
Ext.ux.ComboTree.superclass.initComponent.apply(th is, arguments);
},
findExtRecord: function(prop, value) {
var record;
if (this.extStore != null) {
if (this.extStore.getCount() > 0) {
this.extStore.each(function(r) {
if (r.data[prop] == value) {
record = r;
return false;
}
});
}
}
return record;
},
onClick: function(node) {
if (node.attributes.parameter == 9) {
//
} else {
//
this.setValue(node.text);
this.hiddenField.value = node.id;
this.collapse();
}
},
onExpand: function() {
this.tree.render(this.treeId);
}
});


Ext.reg("combotree", Ext.ux.ComboTree);


ComboTree.cs


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web.UI;
using Coolite.Ext.Web;

[assembly: WebResource("Coolite.Ext.UX.Extensions.ComboTree.resources.Comb oTree.js", "text/javascript")]

namespace Coolite.Ext.UX
{
[Designer(typeof(EmptyDesigner))]
[DefaultProperty("")]
[Xtype("combotree")]
[InstanceOf(ClassName = "Ext.ux.ComboTree")]
[ClientScript(Type = typeof(ComboTree), WebResource = "Coolite.Ext.UX.Extensions.ComboTree.resources.Comb oTree.js", FilePath = "ux/extensions/combotree/combotree.js")]
[ToolboxData("<{0}:ComboTree runat=\"server\" Title=\"Combo tree\" Height=\"300\"></{0}:ComboTree>")]
[Description("Combobox with tree functionality")]
public class ComboTree : ComboBox
{
private ItemsCollection<TreePanel> tree;

[ClientConfig("tree", typeof(ItemCollectionJsonConverter))]
[Category("Config Options")]
[NotifyParentProperty(true)]
[DefaultValue(null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual ItemsCollection<TreePanel> Tree
{
get
{
if (this.tree == null)
{
this.tree = new ItemsCollection<TreePanel>();
}

return this.tree;
}
}

protected override void OnLoad(EventArgs e)
{
this.Controls.Add(Tree[0]);

if (!this.LazyItems.Contains(Tree[0]))
{
this.LazyItems.Add(Tree[0]);
}

base.OnLoad(e);
}
}
}


Thanks also to the original coder of the ExtJS extension neo_sun !

Peter

supermanok
Jul 13, 2009, 11:22 AM
very thx.

But i use that add into Coolite.ux project and generate to dll,adding ux to toolbox,and usage

can not find like this:


<Loader>
<ext:PageTreeLoader OnNodeLoad="LoadTreeNodeEntries">
</ext:PageTreeLoader>
</Loader>

that like this:


<ux:ComboTree ID="ComboTree1" runat="server" Height="300" Title="Combo tree">
<Tree>
<ext:TreePanel ></ext:TreePanel>
</Tree>
</ux:ComboTree>


when i run my page ,can't see anymore in my page,it's none.
how to use that?

Richardt
Aug 24, 2009, 6:40 AM
Hi can you so usage.

Because when I run it I get js error object required.

here is how I used it

html





<ux:ComboTree ID="ComboTree1" runat="server" Height="400" Title="Combo tree" >
<Tree>
<ext:TreePanel ID="Tree" runat="server" Height="300" AutoHeight="true">
<Root>
<ext:AsyncTreeNode NodeID="0" Text="Root" />
</Root>
<Listeners>
<BeforeLoad Fn="nodeLoad" />
</Listeners>
</ext:TreePanel>
</Tree>
</ux:ComboTree>

js





function nodeLoad(node) {
Coolite.AjaxMethods.NodeLoad(node.id, {
success: function(result) {
var data = eval("(" + result + ")");
node.loadNodes(data);
},
failure: function(errorMsg) {
Ext.Msg.alert('Failure', errorMsg);
}
});
}

Vb





<Coolite.Ext.Web.AjaxMethod()> _


Public Function NodeLoad(ByVal sender As Object, ByVal e As Coolite.Ext.Web.NodeLoadEventArgs) As String


Dim nodes As Coolite.Ext.Web.TreeNodeCollection = New Coolite.Ext.Web.TreeNodeCollection()


Dim dr As MySqlDataReader


Dim getInfo As New general


dr = getInfo.coolMY("select * from structure where parentid = 0", Session.Item("strcon"))


While dr.Read


Dim asyncNode As Coolite.Ext.Web.AsyncTreeNode = New Coolite.Ext.Web.AsyncTreeNode()


asyncNode.Text = dr(2)


asyncNode.NodeID = dr(1)


nodes.Add(asyncNode)


End While


Return nodes.ToJson()


End Function

geoffrey.mcgill
Aug 25, 2009, 6:57 PM
Moving to USER EXTENSIONS AND PLUGINS forum.

easypower
Nov 04, 2011, 8:50 AM
The latest attached files is for Coolite and I updated ComboTree for Ext.Net 1.2. You can get it in the attached files.
But When I test it in a page, I got a js error. My codes are belows.
pages:


<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="pages_Default" %>

<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<%@ Register Assembly="Ext.Net.UX" Namespace="Ext.Net.UX" TagPrefix="ux" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />
<ux:ComboTree ID="ComboTree1" runat="server" Height="300" Title="Combo tree">
<Tree>
<ext:TreePanel ID="TreePanel1" runat="server" Title="Tree" AutoHeight="true" Border="false">
<Loader>
<ext:PageTreeLoader OnNodeLoad="NodeLoad">
</ext:PageTreeLoader>
</Loader>
<Root>
<ext:AsyncTreeNode NodeID="0" Text="Root" />
</Root>
</ext:TreePanel>
</Tree>
</ux:ComboTree>
</form>
</body>
</html>

page code behiend


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

public partial class pages_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void NodeLoad(object sender, NodeLoadEventArgs e)
{
if (!string.IsNullOrEmpty(e.NodeID))
{
for (int i = 1; i < 6; i++)
{
AsyncTreeNode asyncNode = new AsyncTreeNode();
asyncNode.Text = e.NodeID + i;
asyncNode.NodeID = e.NodeID + i;
e.Nodes.Add(asyncNode);
}
for (int i = 6; i < 11; i++)
{
Ext.Net.TreeNode treeNode = new Ext.Net.TreeNode();
treeNode.Text = e.NodeID + i;
treeNode.NodeID = e.NodeID + i;
treeNode.Leaf = true; e.Nodes.Add(treeNode);
}
}
}
}


ComboTree.js


Ext.namespace('Ext.ux');

/**
*
* @class ComboTree
* @extends Ext.form.ComboBox
*/
Ext.ux.ComboTree = Ext.extend(Ext.form.ComboBox, {
extStore: null,
tree: null,
treeId: 0,
setValue: function(v) {
var text = v;
if (this.valueField) {
var r = this.findExtRecord(this.valueField, v);
if (r) {
text = r.data[this.displayField];
} else if (this.valueNotFoundText !== undefined) {
text = this.valueNotFoundText;
}
}
Ext.ux.ComboTree.superclass.setValue.call(this, text);
this.lastSelectionText = text;
if (this.hiddenField) {
this.hiddenField.value = v;
}
this.value = v;
},
initComponent: function() {
this.treeId = Ext.id();
this.focusLinkId = Ext.id();
Ext.apply(this, {
store: new Ext.data.SimpleStore({
fields: [],
data: [[]]
}),
editable: false,
shadow: false,
mode: 'local',
triggerAction: 'all',
maxHeight: 200,
tpl: '<tpl for="."><div style="height:200px"><div id="'
+ this.treeId + '"></div></div></tpl>',
selectedClass: '',
onSelect: Ext.emptyFn,
valueField: 'id'
});

this.tree = new Ext.tree.TreePanel(this.tree);
this.on('expand', this.onExpand);
this.tree.on('click', this.onClick, this);
Ext.ux.ComboTree.superclass.initComponent.apply(th is, arguments);
},
findExtRecord: function(prop, value) {
var record;
if (this.extStore != null) {
if (this.extStore.getCount() > 0) {
this.extStore.each(function(r) {
if (r.data[prop] == value) {
record = r;
return false;
}
});
}
}
return record;
},
onClick: function(node) {
if (node.attributes.parameter == 9) {
//
} else {
//
this.setValue(node.text);
this.hiddenField.value = node.id;
this.collapse();
}
},
onExpand: function() {
this.tree.render(this.treeId);
}
});


Ext.reg("combotree", Ext.ux.ComboTree);


ComboTree.cs


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Web.UI;
using Ext.Net;

[assembly: WebResource("Ext.Net.UX.Extensions.ComboTree.resources.ComboTre e.js", "text/javascript")]

namespace Ext.Net.UX
{
[Designer(typeof(EmptyDesigner))]
[DefaultProperty("")]
[ToolboxBitmap(typeof(UX.ComboTree), "Extensions.ComboTree.ComboTree.bmp")]
[ToolboxData("<{0}:ComboTree runat=\"server\" Title=\"Combo tree\" Height=\"300\"></{0}:ComboTree>")]
[Description("Combobox with tree functionality")]
public class ComboTree : ComboBox
{
protected override List<ResourceItem> Resources
{
get
{
List<ResourceItem> baseList = base.Resources;
baseList.Capacity += 1;

baseList.Add(new ClientScriptItem(typeof(ComboTree), "Ext.Net.UX.Extensions.ComboTree.resources.ComboTre e.js", "ux/extensions/combotree/combotree.js"));

return baseList;
}
}

public override string XType
{
get
{
return "combotree";
}
}

public override string InstanceOf
{
get
{
return "Ext.ux.ComboTree";
}
}

private ItemsCollection<TreePanel> tree;

[ConfigOption("tree", typeof(ItemCollectionJsonConverter))]
[Category("Config Options")]
[NotifyParentProperty(true)]
[DefaultValue(null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual ItemsCollection<TreePanel> Tree
{
get
{
if (this.tree == null)
{
this.tree = new ItemsCollection<TreePanel>();
}

return this.tree;
}
}

protected override void OnLoad(EventArgs e)
{
this.Controls.Add(Tree[0]);

if (!this.LazyItems.Contains(Tree[0]))
{
this.LazyItems.Add(Tree[0]);
}

base.OnLoad(e);
}
}
}



The error:
Missing ';'


<script type="text/javascript">
//<![CDATA[
Ext.net.ResourceMgr.init({id:"ResourceManager1",BLANK_IMAGE_URL:"/UserCenter/extjs/resources/images/default/s-gif/ext.axd",aspForm:"form1",theme:"blue",appName:"UserCenter"});Ext.onReady(function(){Ext.QuickTips.init();new Ext.ux.ComboTree({id:"ComboTree1",renderTo:"ComboTree1_Container",height:300,displayField:"text",hiddenName:"ComboTree1_Value",mode:"local",queryDelay:10,title:"Combo tree",triggerAction:"all",valueField:"value",store:new Ext.data.SimpleStore({fields:["text","value"],data :[]}),submitValue:true});{id:"TreePanel1",xtype:"nettreepanel",autoHeight:true,border:false,title:"Tree",loader:new Ext.net.PageTreeLoader({}),nodes:[{id:"0",text:"Root",nodeType:"async"}]}});
//]]>
</script>

Daniil
Nov 04, 2011, 10:34 AM
In Ext.Net 1.x please use DropDownField.
https://examples1.ext.net/#/Form/DropDownField/Overview/

easypower
Nov 04, 2011, 1:05 PM
Thank you very much.
I got it. DropDownField will fit for me.
But I also want to know where is the error of my code? Maybe it is another bug in Ext.Net 1.2?
Because I think there will be many no-business UserControl and business one in a big Web Applications.
Could you help me to find out where is the error?
By the way, I can not upload the attached both .zip and .rar file in the thread.

Daniil
Nov 04, 2011, 4:13 PM
I guess you didn't override the ConfigOptions property, isn't that so?

Here is the minimized working code.

ComboTree.cs


using System;
using System.ComponentModel;
using System.Collections.Generic;
using Ext.Net;

namespace Work
{
public class ComboTree : ComboBox
{
protected override List<ResourceItem> Resources
{
get
{
List<ResourceItem> baseList = base.Resources;
baseList.Capacity += 1;

baseList.Add(new ClientScriptItem(typeof(ComboTree), "Work.resources.js.ComboTree.js", "ux/extensions/combotree/combotree.js"));

return baseList;
}
}

public override string XType
{
get
{
return "combotree";
}
}

public override string InstanceOf
{
get
{
return "Ext.ux.ComboTree";
}
}

ItemsCollection<TreePanel> tree;

[DefaultValue(null)]
public virtual ItemsCollection<TreePanel> Tree
{
get
{
if (this.tree == null)
{
this.tree = new ItemsCollection<TreePanel>();
}

return this.tree;
}
}

protected override void OnLoad(EventArgs e)
{
this.Controls.Add(Tree[0]);

if (!this.LazyItems.Contains(Tree[0]))
{
this.LazyItems.Add(Tree[0]);
}

base.OnLoad(e);
}

public override ConfigOptionsCollection ConfigOptions
{
get
{
ConfigOptionsCollection config = base.ConfigOptions;
config.Add("tree", new ConfigOption("tree", new SerializationOptions("tree", typeof(ItemCollectionJsonConverter)), null, this.tree));
return config;
}
}
}
}

As well you should use the Ext.net.TreePanel class instead of Ext.tree.TreePanel.

The Ext.tree.TreePanel class is our extended version of Ext.tree.TreePanel.

easypower
Nov 05, 2011, 1:05 PM
I am sorry, I do not know it is need that ConfigOptions function must be override.
But I follow your code and there is also a js error "missing object"
error js code is


store:new Ext.data.SimpleStore({fields:["text","value"],data :[]}),
submitValue:true,
tree:{id:"TreePanel1",...}

tree is not like store??
Here is my code:
ComboTree.cs


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Web.UI;

[assembly: WebResource("Ext.Net.UX.Extensions.ComboTree.resources.ComboTre e.js", "text/javascript")]

namespace Ext.Net.UX
{
[Designer(typeof(EmptyDesigner))]
[DefaultProperty("")]
[ToolboxBitmap(typeof(UX.ComboTree), "Extensions.ComboTree.ComboTree.bmp")]
[ToolboxData("<{0}:ComboTree runat=\"server\" Title=\"Combo tree\" Height=\"300\"></{0}:ComboTree>")]
[Description("Combobox with tree functionality")]
public class ComboTree : ComboBox
{
protected override List<ResourceItem> Resources
{
get
{
List<ResourceItem> baseList = base.Resources;
baseList.Capacity += 1;

baseList.Add(new ClientScriptItem(typeof(ComboTree), "Ext.Net.UX.Extensions.ComboTree.resources.ComboTre e.js", "ux/extensions/combotree/combotree.js"));

return baseList;
}
}

public override string XType
{
get
{
return "combotree";
}
}

public override string InstanceOf
{
get
{
return "Ext.ux.ComboTree";
}
}

private ItemsCollection<TreePanel> tree;

[ConfigOption("tree", typeof(ItemCollectionJsonConverter))]
[Category("Config Options")]
[NotifyParentProperty(true)]
[DefaultValue(null)]
[PersistenceMode(PersistenceMode.InnerProperty)]
public virtual ItemsCollection<TreePanel> Tree
{
get
{
if (this.tree == null)
{
this.tree = new ItemsCollection<TreePanel>();
}

return this.tree;
}
}

protected override void OnLoad(EventArgs e)
{
this.Controls.Add(Tree[0]);

if (!this.LazyItems.Contains(Tree[0]))
{
this.LazyItems.Add(Tree[0]);
}

base.OnLoad(e);
}

public override ConfigOptionsCollection ConfigOptions
{
get
{
ConfigOptionsCollection config = base.ConfigOptions;
config.Add("tree", new ConfigOption("tree", new SerializationOptions("tree", typeof(ItemCollectionJsonConverter)), null, this.tree));
return config;
}
}
}
}


ComboTree.js


Ext.namespace('Ext.ux');

/**
*
* @class ComboTree
* @extends Ext.form.ComboBox
*/
Ext.ux.ComboTree = Ext.extend(Ext.form.ComboBox, {
extStore: null,
tree: null,
treeId: 0,
setValue: function (v) {
var text = v;
if (this.valueField) {
var r = this.findExtRecord(this.valueField, v);
if (r) {
text = r.data[this.displayField];
} else if (this.valueNotFoundText !== undefined) {
text = this.valueNotFoundText;
}
}
Ext.ux.ComboTree.superclass.setValue.call(this, text);
this.lastSelectionText = text;
if (this.hiddenField) {
this.hiddenField.value = v;
}
this.value = v;
},
initComponent: function () {
this.treeId = Ext.id();
this.focusLinkId = Ext.id();
Ext.apply(this, {
store: new Ext.data.SimpleStore({
fields: [],
data: [[]]
}),
editable: false,
shadow: false,
mode: 'local',
triggerAction: 'all',
maxHeight: 200,
tpl: '<tpl for="."><div style="height:200px"><div id="'
+ this.treeId + '"></div></div></tpl>',
selectedClass: '',
onSelect: Ext.emptyFn,
valueField: 'id'
});

tree = new Ext.net.TreePanel(this.tree);
this.on('expand', this.onExpand);
this.tree.on('click', this.onClick, this);
Ext.ux.ComboTree.superclass.initComponent.apply(th is, arguments);
},
findExtRecord: function (prop, value) {
var record;
if (this.extStore != null) {
if (this.extStore.getCount() > 0) {
this.extStore.each(function (r) {
if (r.data[prop] == value) {
record = r;
return false;
}
});
}
}
return record;
},
onClick: function (node) {
if (node.attributes.parameter == 9) {
//
} else {
//
this.setValue(node.text);
this.hiddenField.value = node.id;
this.collapse();
}
},
onExpand: function () {
this.tree.render(this.treeId);
}
});


Ext.reg("combotree", Ext.ux.ComboTree);

Daniil
Nov 07, 2011, 7:38 AM
But I follow your code and there is also a js error "missing object"
error js code is


store:new Ext.data.SimpleStore({fields:["text","value"],data :[]}),
submitValue:true,
tree:{id:"TreePanel1",...}

tree is not like store??


Please try the page under FireFox with FireBug or Chrome with Developer Tools - it will more helpful message about a JS error.

And, I'm afraid, I don't understand this question:

tree is not like store??

Please clarify.

As well, is the ComboTree.js loaded correctly?

easypower
Nov 07, 2011, 7:56 AM
in the source file of the page, there are some js codes like bellows.
but the store define is not the same like tree's

store:new Ext.data.SimpleStore({fields:["text","value"],data :[]}),

tree:{id:"TreePanel1",...}

I guess the right js may be "tree:new Ext.net.TreePanle({id:"TreePanel1",...})"

Daniil
Nov 07, 2011, 8:05 AM
Well, a tree is rendered as a lazy item, because you add into a LazyItems collection. And the ItemsCollection class can work with lazy items only.

Generally speaking, a lazy item is an item's config to pass into its constructor.

And this happens in the script, see the .initComponent().

tree = new Ext.net.TreePanel(this.tree);

easypower
Nov 07, 2011, 9:00 AM
and then what can I need do to resolve the question?

Daniil
Nov 07, 2011, 9:01 AM
What is the question?

easypower
Nov 07, 2011, 9:04 AM
I am sorry, I do not know it is need that ConfigOptions function must be override.
But I follow your code and there is also a js error "missing object"
error js code is


store:new Ext.data.SimpleStore({fields:["text","value"],data :[]}),
submitValue:true,
tree:{id:"TreePanel1",...}



"missing object".
I guess the missing object is reference to "tree:{id:"TreePanel1",...}"

easypower
Nov 07, 2011, 9:05 AM
And could you pay some attention to my another thread "http://forums.ext.net/showthread.php?16089-How-to-defined-a-UserControl-inheirt-from-Ext.Net.Component-with-business-ruler" please?

Daniil
Nov 07, 2011, 9:06 AM
"missing object".
I guess the missing object is reference to "tree:{id:"TreePanel1",...}"

Well, you did not answer/comment some things here:
http://forums.ext.net/showthread.php?4019&p=68225&viewfull=1#post68225

easypower
Nov 07, 2011, 9:09 AM
OK,I will download Chrome with Developer Tools tonight, and post the new information after 2-3 hours later.
Thank you.

Daniil
Nov 07, 2011, 9:44 AM
What about this?

As well, is the ComboTree.js loaded correctly?

easypower
Nov 07, 2011, 11:28 AM
In Chrome,there is nothing alarm,and in the console the error is:
Failed to load resource: the server responded with a status of 404 (Not Found)
Uncaught TypeError: undefined is not a function Default.aspx:17
(anonymous function) Default.aspx:17
h.Event.name ext.axd:7
b ext.axd:7

and I do not know how to make sure that is ComboTree.js is load correctly. Could you tell me?

Daniil
Nov 07, 2011, 11:35 AM
It looks like a resource is not loaded, but I'm not sure what exactly resource.

See the "Network" tab of the Developer Tools.

easypower
Nov 07, 2011, 12:38 PM
WebResource.axd
I research past threads by "WebResource.axd", but I also can not resolve this question.

Daniil
Nov 07, 2011, 1:23 PM
It doesn't help.

What is the url of a request?

easypower
Nov 07, 2011, 1:40 PM
http://localhost:44432/WebResource.axd?d=7c9m2p4qzFKiFavKPpGnW-hDiQrApW6NMZiLyiejVpLTbSgZGBXHe1ITsHLOLkWjeFT-lQrAKrHTVpg5nM4CH2d4v09j8AlRYy7TFxWzWq-TaoOM4ZNUNHLAZqEhNg8YT6Z2uzi0YG2zAthcEqm8jk5says0C uLV0K7fNcy_bMQ1&t=634561830553612886
I do not know where WebResource.axd come from
in the source code of the page, there is a line more than correct page
"<script type="text/javascript" src="/WebResource.axd?d=7c9m2p4qzFKiFavKPpGnW-hDiQrApW6NMZiLyiejVpLTbSgZGBXHe1ITsHLOLkWjeFT-lQrAKrHTVpg5nM4CH2d4v09j8AlRYy7TFxWzWq-TaoOM4ZNUNHLAZqEhNg8YT6Z2uzi0YG2zAthcEqm8jk5says0C uLV0K7fNcy_bMQ1&amp;t=634561830553612886"></script>"

Daniil
Nov 07, 2011, 1:41 PM
This blog post will help to decode that url.
http://blogs.telerik.com/blogs/posts/07-03-26/debugging_asp_net_2_0_web_resources_decrypting_the _url_and_getting_the_resource_name.aspx

easypower
Nov 07, 2011, 2:02 PM
the decoded url is "pExt.Net.UX|Ext.Net.UX.Extensions.ComboTree.resour ces.ComboTree.js"

Ext.Net.UX is a assembly dll.But I do not know why there is a 'p' before the url?

Is it necessary to set the ext.net.ux.meta.xml file? I have not do this.
But I researched the ext.net.ux.meta.xml, there is none of the "js" key word.

Daniil
Nov 07, 2011, 2:17 PM
But I do not know why there is a 'p' before the url?
Don't worry about it.

Where did you place the ComboTree.js?

Did you mark that file as an Embedded resources?


Is it necessary to set the ext.net.ux.meta.xml file? I have not do this.

No.

easypower
Nov 08, 2011, 4:40 AM
Here is my file path tree of the solution.
3416

Daniil
Nov 08, 2011, 6:22 AM
The path looks correct according to:

baseList.Add(new ClientScriptItem(typeof(ComboTree), "Ext.Net.UX.Extensions.ComboTree.resources.ComboTre e.js", "ux/extensions/combotree/combotree.js"));

But please answer:

Did you mark that file as an Embedded resources?

easypower
Nov 08, 2011, 8:14 AM
You got the truth. I have not mark that file as an Embedded resources. I am sorry for that stupid question for a begineer.
But all js error will not display. There is nothing display in the page also.
I noticed that in the console there is a line texted:
"Uncaught TypeError: Object #<Object> has no method 'on'"
it is about js file line 51
"this.tree.on('click', this.onClick, this);"
and if I remark this line, ComboBox will display but when I drop it , no tree display.

Daniil
Nov 08, 2011, 8:22 AM
You should replace that line with

tree.on('click', this.onClick, this);

Then I tried that custom control I saw a tree.

easypower
Nov 08, 2011, 1:22 PM
OK, I will try it tomorrow. Thank you very much and best wishes to you!
And Could you help me some with another thread also about UserControl?
If you are busy,please tell me if I can do that or can not achieve my think.
http://forums.ext.net/showthread.php?16089-How-to-defined-a-UserControl-inheirt-from-Ext.Net.Component-with-business-ruler

And another is a bug about grouped GridPanel
http://forums.ext.net/showthread.php?16104-GridPanel-with-Group-may-have-some-bugs-about-sort