I want to search for specific node in an ExtJs tree. The current code that I have allows node to be searched only at the first level. Please check this fiddle
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "Javascript",
leaf: true
}, {
text: "ASP.net",
leaf: true
}, {
text: "Also ASP.net",
leaf: false,
children: [{
text: '1.1 foo',
leaf: false,
children: [{
text: "1.1.1 asp.net mvc",
expanded: true
}, {
text: "1.1.2 java",
expanded: true
}, {
text: "1.1.3 extjs",
expanded: true
}]
}, {
text: '1.2 bar',
leaf: true
}]
}, {
text: "ASP.net future",
leaf: true
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Example Tree',
width: 200,
height: 450,
store: store,
rootVisible: false,
multiSelect: true,
renderTo: Ext.getBody(),
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
text: 'Search for ASP.net',
handler: function () {
var me = this,
panel = me.up('panel'),
rn = panel.getRootNode(),
regex = new RegExp("ASP.net");
rn.findChildBy(function (child) {
var text = child.data.text;
if (regex.test(text) === true) {
console.warn("selecting child", child);
panel.getSelectionModel().select(child, true);
}
});
}
}]
}]
});
What I want:
Ability to search across all the levels in the tree
once a node is found, I want to expand it.
How can I achieve this?
Thank you
You can use this :
var c = rn.findChild("text","Also ASP.net",true);
c.expand();
true indicates a deep search.Please have a look at findChild.
Please check out the fiddle
This is what I was looking for : http://jsfiddle.net/tdaXs/17/
Thank you Devendra for suggesting Deep Search option.
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "Javascript",
leaf: true
}, {
text: "ASP.net",
leaf: true
}, {
text: "Also ASP.net",
leaf: false,
children: [{
text: '1.1 foo',
leaf: false,
children: [{
text: "1.1.1 ASP.net mvc",
leaf: true,
expanded: true
}, {
text: "1.1.2 java",
leaf: true,
expanded: true
}, {
text: "1.1.3 extjs",
leaf: true,
expanded: true
}]
}, {
text: '1.2 bar',
leaf: true
}]
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Example Tree',
width: 200,
height: 450,
store: store,
rootVisible: false,
multiSelect: true,
renderTo: Ext.getBody(),
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
text: 'Search for ASP.net',
handler: function () {
var me = this,
panel = me.up('panel'),
rn = panel.getRootNode(),
regex = new RegExp("ASP.net");
//var c = rn.findChild("text", " asp.net", true);
rn.findChildBy(function (child) {
var text = child.data.text;
if (regex.test(text) === true) {
console.warn("selecting child", child);
panel.getSelectionModel().select(child, true);
}
});
}
}]
}]
});
Related
I am trying to display my JSON in a propertygrid where I have nested level of JSON structure. As per to the property grid documentation the only types supported are boolean, string, date, number. So am only able to see the flatten level information and not the nested object.
Wanted to know if there is any configuration in propertygrid which will allow me to display and edit the nested information ? or any other component available which will be helpful instead of propertygrid
Below is the sample config and fiddle:
Ext.create('Ext.grid.property.Grid', {
title: 'Properties Grid',
width: 300,
renderTo: Ext.getBody(),
source: {
"allowBlank": "My Object",
"minValue": 1,
"maxValue": 10,
"itemDetails": {
"name": "name 1",
"type": "Object"
},
"Description": "A test object"
},
sourceConfig: {
allowBlank: {
displayName: 'Required'
}
}
});
You can use editable column tree:
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "allowBlank",
value: "My Object",
leaf: true
}, {
text: "minValue",
value: "1",
leaf: true
}, {
text: "maxValue",
value: 10,
leaf: true
}, {
text: "itemDetails",
value: "",
expanded: true,
children: [{
text: "name",
value: "name 1",
leaf: true
}, {
text: "type",
value: "Object",
leaf: true
}]
}, {
text: "Description",
value: "A test object",
leaf: true
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
height: 200,
store: store,
rootVisible: false,
plugins: {
cellediting: {
clicksToEdit: 2,
listeners: {
beforeedit: function (editor, context, eOpts) {
if (!context.record.isLeaf()) {
return false;
}
var column = context.column;
switch (typeof context.record.get('value')) {
case "string":
column.setEditor({
xtype: 'textfield'
});
return;
case "number":
column.setEditor({
xtype: 'numberfield'
});
return;
//...
//...
default:
column.setEditor({
xtype: 'textfield'
});
return;
}
},
}
}
},
columns: [{
xtype: 'treecolumn',
text: 'Headers',
dataIndex: 'text'
}, {
text: 'Value',
dataIndex: 'value',
editor: {
xtype: 'textfield'
}
}],
renderTo: Ext.getBody()
});
I have treepanel. I want to fire an event on click of only child element.
In my itemclick event it is firing all the time when I click. I want only to fire only when the last child is clicked.
Eg.: It should fire "Manage Application Child" not on the "Manage Application"
var root = {
expanded: true,
children: [{
text: "Configure Application",
expanded: true,
children: [{
text: "Manage Application",
children: [{
text: "Manage Application Child",
leaf: true
}]
}, {
text: "Scenario",
leaf: true
}]
}, {
text: "User Configuration",
expanded: true,
children: []
}, {
text: "Test Configuration",
//leaf: true,
expanded: true,
children: [{
text: "Manage User",
leaf: true
}, {
text: "User rights",
leaf: true
}]
}]
};
{
xtype: 'treepanel',
useArrows: true,
autoScroll: false,
animate: true,
enableDD: false,
title: 'Configuration',
width: 200,
height: 400,
rootVisible: false,
store: Ext.create('Ext.data.TreeStore', {
root: root
}),
listeners: {
itemclick: function (s, r) {
alert(r.data.text);
}
}
}
If i understand correctly, you just have to check if the node is "leaf":
itemclick: function (s, r) {
if (r.data.leaf){ //or r.data.children == null
alert(r.data.text);
}
}
I created FIDDLE i think it will help you what you want
I want to collapse or expand a node based on a condition in tree.panel in extjs 4.2.1
tree.on("beforeitemexpand",function(node) {
if (booleanFlag === true) {
//allow to expand
} else {
//donot allow to expand
}
});
I have tried the beforeitemExpand then return false if booleanFlag is false, but it is not working.
The event "beforeitemexpand" appears to have a bug in Extjs 4.2.1, its not ideal but you could use "beforeitemclick" and "beforeitemdblclick" to achieve the functionality that you want:
Ext.application({
name: 'Fiddle',
launch: function () {
var enableHomeExpand = false;
var enableBookExpand = false;
var store = Ext.create('Ext.data.TreeStore', {
root: {
children: [{
text: 'homework',
expanded: false,
children: [{
text: 'book report',
children: [{
text: 'test',
leaf: true
}, {
text: 'test 2',
leaf: true
}]
}, {
text: 'algebra',
leaf: true
}]
}, {
text: 'homework',
children: [{
text: 'book report',
children: [{
text: 'test',
leaf: true
}, {
text: 'test 2',
leaf: true
}]
}]
}]
}
});
var handleClick = function (node,rec,item){
if ((rec.data.text =="book report")&&(enableBookExpand)){
return true;
}
if ((rec.data.text =="homework")&&(enableHomeExpand)){
return true;
}
return false;
}
var treepanel = Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 400,
height: 200,
store: store,
rootVisible: false,
renderTo: Ext.getBody(),
listeners:{
beforeitemdblclick: handleClick,
beforeitemclick: handleClick
},
buttons:[{
text:'Enable Expand "homework"',
handler: function(){ enableHomeExpand = true; }
},
{
text:'Enable Expand "book report"',
handler: function(){ enableBookExpand = true; }
}]
});
}
});
Here is the FIDDLE
I want to create a tree panel and add an event to it when expand node, but code seems not work for me. I've already searched google for hours but no luck. Could anyone take a look and tell me why?
Here is my code:
Ext.onReady(function () {
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "detention",
leaf: true
}, {
text: "homework",
expanded: false,
children: [{
text: "book report",
leaf: true
}, {
text: "alegrbra",
leaf: true
}]
}, {
text: "buy lottery tickets",
leaf: true
}]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 200,
height: 150,
store: store,
rootVisible: false,
renderTo: Ext.getBody(),
listeners: {
afteritemexpand: function ( node, index, item, eOpts ){
alert('HAHA');
}
}
});
});
Thanks in advance!
You used the wrong event. You need to use afteritemexpand event.
afteritemexpand: function ( node, index, item, eOpts ){
alert('HAHA');
}
Here's a fiddle:
http://jsfiddle.net/johanhaest/RDC9W/1/
I would like to implement a tree panel with content loaded dynamically from the server (as Json) and with a custom data model. But I dont know how to define a model and a data store for that tree. Can you provide some examples? If possible, I'd like to conform to the sencha mvc recommendations (the model and the data store defined as separate classes).
I knew how to do it in extjs 3 but i'm lost in version 4.
Best regards
RG
I experimented with a new MVC approach recently, and I managed to get it work with the treepanel. Nothing special actually:
View:
Ext.define('RoleBuilder.view.RoleList', {
extend: 'Ext.tree.Panel',
alias: 'widget.roles',
title: 'Roles',
store: 'Roles'
});
Store:
Ext.define('RoleBuilder.store.Roles', {
extend: 'Ext.data.TreeStore',
model: 'RoleBuilder.model.Role',
requires: 'RoleBuilder.model.Role',
root: {
text: 'Roles',
expanded: true
},
proxy: {
type: 'ajax',
url: loadRolesUrl,
actionMethods: 'POST',
reader: {
type: 'json'
}
}
});
Model:
Ext.define('RoleBuilder.model.Role', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', type: 'int', mapping: 'Id' },
{ name: 'text', type: 'string', mapping: 'Text' },
{ name: 'leaf', type: 'boolean', mapping: 'Leaf' },
{ name: 'loaded', type: 'boolean', mapping: 'Loaded', defaultValue: false },
{ name: 'Properties'},
{ name: 'expanded', defaultValue: true }
]
});
Controller:
Ext.define('RoleBuilder.controller.RoleList', {
extend: 'Ext.app.Controller',
init: function () {
this.control({
'roles': {
itemcontextmenu: this.onItemContextMenuClick,
itemclick: this.onItemClick
}
});
this.application.on({
'role-saved': Ext.Function.bind(this.onRoleSaved, this)
});
},
..... too long, but you got the idea.
Hope it will help.
I struggle so much to get this working. I want to share with you in case you need it.
Here is my view:
Ext.define("GiipIq.view.Problem", {
extend: "Ext.window.Window",
alias: "widget.problemwindow",
titleAlign: "center",
closable: false,
layout: "border",
autoShow: true,
maximizable: true,
draggable: false,
resizable: false,
x: 0,
y: 0,
width: Ext.getBody().getViewSize().width/2,
height: Ext.getBody().getViewSize().height/2,
id: "problem-window",
getEastPanel: function() {
return {
region: "west",
xtype: "treepanel",
title: "Problems",
width: 200,
split: true,
collapsible: false,
floatable: false,
rootVisible: false,
useArrows: true,
store: Ext.create("GiipIq.store.Problems"),
id: "problems",
dockedItems: [{
xtype: "toolbar",
dock: "bottom",
layout: "fit",
items: [{
xtype: "button",
text: 'Click to Run Selected Problems',
id: "run-problems-button"
}]
}],
listeners: {
checkchange: function(node, checkedStatus, options) {
console.log("vp");
}
}
};
},
getCentralPanel: function() {
return {
xtype: "tabpanel",
width: (Ext.getBody().getViewSize()/2) - 200,
bodyBorder: false,
items: [{
title: "Problem Description",
id: "problem-description-tab"
},{
xtype: "panel",
title: "Source Code",
},{
xtype: "panel",
title: "Big O Analysis",
}]
};
},
initComponent: function () {
this.items = [
this.getEastPanel(),
this.getCentralPanel()
];
this.callParent(arguments);
}
});
Here is my store:
Ext.define("GiipIq.store.Problems", {
extend: "Ext.data.TreeStore",
storeId:"problems-store",
model: "GiipIq.model.Problem",
});
Here is my model:
Ext.define("GiipIq.model.Problem", {
extend: "Ext.data.Model",
fields: [
{ name: "text", type: "string" },
{ name: "leaf", type: "bool" },
{ name: "expanded", type: "bool" },
{ name: "checked", type: "bool" }
],
proxy: {
type: "ajax",
actionMethods: { read: "GET" },
api: { read: "app/problems.json", },
reader: {
type: "json",
root: "children"
},
listeners: {
exception: function(proxy, response, operation, opts) {
if(typeof(operation.error) == "string") {
Ext.Msg.alert("Error", "Connection to server interrupted" + operation.error);
}
}
}
}
});
Here is my json:
{
success: true,
children: [{
text: "algorithms", expanded: true, leaf: false, checked: false, children: [
{ text: "bit manipulation", leaf: true, checked: true },
{ text: "brain teaser", leaf: true, checked: true }
]
},{
text: "data structures", expanded: true, checked: false, leaf: false, children: [
{ text: "array and strings", leaf: true, checked: true },
{ text: "linked lists", leaf: true, checked: false}
]
},{
text: "knowledge based", expanded: true, leaf: false, checked: false, children: [
{ text: "C and C++", leaf: true, checked: false},
{ text: "Java", leaf: true, checked: false}
]
}]
}