I really confused by ExtJs tree object, something is wrong with my code but I don't know what.
Consider I have this code:
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{ text: "detention", leaf: true },
{ text: "homework", expanded: true, 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()
});
How can I bind a click event to my tree's children/leaf?
Like so?
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{ text: "detention", leaf: true },
{ text: "homework", expanded: true, 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: {
itemclick: function(s,r) {
alert(r.data.text);
}
}
});
see this JSFiddle
Related
I am using ExtJS 4.1. I have a TreePanel which I bind to one of two TreeStore. After I rebind a store & expand collapse nodes, records are getting duplicate & I see error Uncaught TypeError: Cannot read property 'internalId' of undefined
Another issue is, I am only able to bind store once. When i call treePanel.setRootNode() second time it does not work (irrespective of whether I expand the nodes or not).
Look at this fiddle
Here is the code:
var sportsStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
id: 133,
children: [{
text: "Audi",
id: 1,
leaf: true
},
{
text: "sports cars",
expanded: true,
id: 2,
children: [{
id: 3,
text: "Porsche",
leaf: true
},
{
text: "Mustang",
id: 4,
leaf: true
}
]
},
{
text: "Jaguar",
id: 5,
leaf: true
}
]
}
});
var carStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
id: 1444,
children: [{
id: 6,
text: "Toyota",
leaf: true
},
{
text: "cars",
id: 7,
expanded: true,
children: [{
id: 8,
text: "honda",
leaf: true
},
{
text: "Nissan",
id: 9,
leaf: true
}
]
},
{
text: "Kia",
id: 10,
leaf: true
}
]
}
});
Ext.create('Ext.panel.Panel', {
title: 'Car Simple Tree',
width: 300,
height: 450,
renderTo: Ext.getBody(),
items: [{
xtype: 'button',
text: 'sports',
handler: function() {
alert('You clicked the sports button!');
var t = Ext.getCmp('tp');
t.setRootNode(sportsStore.getRootNode());
}
},
{
xtype: 'button',
text: 'car',
handler: function() {
alert('You clicked the car button!');
var t = Ext.getCmp('tp');
t.setRootNode(carStore.getRootNode());
}
},
{
xtype: 'treepanel',
id: 'tp',
store: sportsStore,
rootVisible: false,
lines: true
}
]
});
Just for the record you know your problem is solved in one line in 6.0 with just calling setStore() and passing as parameter the store you want right?
Here is a demo of this working in 6.0.
I played with this for a good amount of time and although my Sencha is somewhat rusty (used to be a big fan back in the day) I managed to get something working.
Now it might not be your cup of tea but it does exactly what you want ... you change the stores and expanding/collapsing works etc. The trick is I dynamically re-create the tree on every store change and set the store as the default store to that new tree. The decommissioned trees are removed by Ext.destroy etc.
Here is that Ext 4.1 working example in Fiddle
And here is the code for your reference:
Ext.define('Thing', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int'
}, {
name: 'text',
type: 'string'
}]
});
var sportsStore = Ext.create('Ext.data.TreeStore', {
model: 'Thing',
storeId: 'sportsStore',
clearOnLoad: true,
root: {
expanded: true,
id: 133,
children: [{
text: "Audi",
id: 1,
leaf: true
}, {
text: "sports cars",
expanded: true,
id: 2,
children: [{
id: 3,
text: "Porsche",
leaf: true
}, {
text: "Mustang",
id: 4,
leaf: true
}]
}, {
text: "Jaguar",
id: 5,
leaf: true
}]
}
});
var carStore = Ext.create('Ext.data.TreeStore', {
model: 'Thing',
storeId: 'carStore',
clearOnLoad: true,
root: {
expanded: true,
id: 1444,
children: [{
id: 6,
text: "Toyota",
leaf: true
}, {
text: "cars",
id: 7,
expanded: true,
children: [{
id: 8,
text: "honda",
leaf: true
}, {
text: "Nissan",
id: 9,
leaf: true
}]
}, {
text: "Kia",
id: 10,
leaf: true
}]
}
});
// This function does the magic by removing/then destroying the old tree and
// adding the newly created one with default new store setup
function setupTree(storeName) {
var pnl = Ext.getCmp('pnl');
var treePanel = Ext.getCmp('tp')
if (treePanel) {
pnl.remove(treePanel)
Ext.destroy(treePanel)
}
pnl.add(new Ext.create('Ext.tree.Panel', {
id: 'tp',
autoRender: true,
rootVisible: false,
store: storeName,
animate: false,
lines: true
}))
}
Ext.create('Ext.panel.Panel', {
id: 'pnl',
title: 'Car Simple Tree',
width: 300,
height: 450,
renderTo: Ext.getBody('#canvas'),
items: [{
xtype: 'button',
text: 'sports',
handler: function() {
setupTree('sportsStore')
}
}, {
xtype: 'button',
text: 'car',
handler: function() {
setupTree('carStore')
}
}],
listeners: {
afterrender: function(self) {
setupTree('sportsStore')
}
}
});
I also added ids to the stored as well as defined a model for the stores just to be more close to best practices etc.
The thing that makes this move is the setupTree function which looks for a tree with certain id, if it finds it cleans it and then creates a new one with a default store the one we clicked on.
Hope this helps.
I suggest the following approach, which may be a workaround, but ExtJS 4.1 version has some issues in UpdateIndexes() method:
define an empty tree store (baseStore) and bind it to the tree panel
on every button click, fill this empty store with data from appropriate store.
Code:
Ext.onReady(function(){
Ext.QuickTips.init();
Ext.FocusManager.enable();
// Stores
var baseStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
leaf: false,
children: []
}
});
var sportsStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
id: 133,
children: [
{
text: "Audi",
id: 1,
leaf: true
},
{
text: "sports cars",
expanded: true,
id: 2,
children: [{
id: 3,
text: "Porsche",
leaf: true
},
{
text: "Mustang",
id: 4,
leaf: true
}
]
},
{
text: "Jaguar",
id: 5,
leaf: true
}
]
}
});
var carStore = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
id: 1444,
children: [
{
id: 6,
text: "Toyota",
leaf: true
},
{
text: "cars",
id: 7,
expanded: true,
children: [
{
id: 8,
text: "honda",
leaf: true
},
{
text: "Nissan",
id: 9,
leaf: true
}
]
},
{
text: "Kia",
id: 10,
leaf: true
}
]
}
});
// Filling data
function fillStore(xparent, xnode) {
for (var i = 0; i < xnode.childNodes.length; i++) {
var current = xnode.childNodes[i];
var added = xparent.appendChild(
{
text: current.data.text,
leaf: current.data.leaf,
id: current.data.id
}
);
if (current.data.leaf === false) {
fillStore(added, current);
}
}
}
function setStore(store) {
var root = baseStore.getRootNode();
if (root.hasChildNodes()) {
root.removeAll();
}
fillStore(root, store.getRootNode());
}
// First fill
setStore(carStore);
Ext.create('Ext.panel.Panel', {
title: 'Car Simple Tree',
width: 300,
height: 450,
renderTo: Ext.getBody(),
items: [
{
xtype: 'button',
text: 'sports',
handler: function() {
alert('You clicked the sports button!');
var t = Ext.getCmp('tp');
setStore(sportsStore);
}
},
{
xtype: 'button',
text: 'car',
handler: function() {
alert('You clicked the car button!');
var t = Ext.getCmp('tp');
setStore(carStore);
}
},
{
xtype: 'treepanel',
id: 'tp',
store: baseStore,
rootVisible: false,
lines: true
}
]
});
});
Notes:
Working fiddle can be found here.
ExtJS6: Second instance of TreeStore has no grandchildren.
I have a class, MyStore, which inherits from TreeStore.
Then, I created an instance of MyStore to be displayed in a treepanel.
So far so good.
Then, I created another instance of MyStore to be displayed in another treepanel.
Here comes the problem: the second treepanel does not have grandchild. All it has are it's root node and it's root node's children.
How do I code this so that the 2nd (and succeeding) instance of TreeStore will have grandchildren?
https://fiddle.sencha.com/#fiddle/1ehq
Ext.define('MyStore',{
extend: 'Ext.data.TreeStore',
root: {
expanded: true,
text: 'This is the root node',
children: [
{
text: 'Food',
expanded: true,
children: [
{
text: 'Cake',
leaf: true
},
{
text: 'Ice cream',
leaf: true
}
]
},
{
text: 'Toys',
expanded: true,
children: [
{
text: 'Ball',
leaf: true
},
{
text: 'Bat',
leaf: true
}
]
}
]
}
});
Ext.widget('treepanel',{
title: 'first tree panel',
renderTo: Ext.getBody(),
store: new MyStore()
});
Ext.widget('treepanel',{
title: 'second tree panel',
renderTo: Ext.getBody(),
store: new MyStore()
});
Ext.widget('panel', {
html: 'What happend to the "Food" and "Toys" of the second tree panel? Why did they loose their children?',
renderTo: Ext.getBody(),
});
Use this Fiddle:https://fiddle.sencha.com/#fiddle/1hti
Ext.define('MyStore',{
extend: 'Ext.data.TreeStore'
});
var store1 = Ext.create('MyStore',{
extend: 'Ext.data.TreeStore',
root: {
expanded: true,
text: 'This is the root node',
children: [
{
text: 'Food',
expanded: true,
children: [
{
text: 'Cake',
leaf: true
},
{
text: 'Ice cream',
leaf: true
}
]
},
{
text: 'Toys',
expanded: true,
children: [
{
text: 'Ball',
leaf: true
},
{
text: 'Bat',
leaf: true
}
]
}
]
}
});
var store2 = Ext.create('MyStore',{
extend: 'Ext.data.TreeStore',
root: {
expanded: true,
text: 'This is the root node',
children: [
{
text: 'Food',
expanded: true,
children: [
{
text: 'Cake',
leaf: true
},
{
text: 'Ice cream',
leaf: true
}
]
},
{
text: 'Toys',
expanded: true,
children: [
{
text: 'Ball',
leaf: true
},
{
text: 'Bat',
leaf: true
}
]
}
]
}
});
Ext.widget('treepanel',{
title: 'first tree panel',
renderTo: Ext.getBody(),
store: store1
});
Ext.widget('treepanel',{
title: 'second tree panel',
renderTo: Ext.getBody(),
store: store2
});
Ext.widget('panel', {
html: 'What happend to the "Food" and "Toys" of the second tree panel? Why did they loose their children?',
renderTo: Ext.getBody(),
});
For Ext.tree.Panel nodes, arrow button is not displayed, even though useArrow property is used. While doing moveover the left of the nodes, pointer is displaying, but the visibility of arrow is false.
How can I solve this issue ??
Giving below the code, I used.
Ext.create('Ext.tree.Panel', {
useArrows: true,
autoScroll: false,
animate: true,
enableDD: false,
title: 'Configuration',
width: 200,
height: 150,
rootVisible: false,
store: [{
root: {
expanded: true,
children: [{
text: "Configure Application",
expanded: true,
children: [{
text: "Manage Application",
leaf: true
}, {
text: "Scenario",
leaf: true
}]
}, {
text: "User Configuration",
expanded: true,
children: [{
text: "Manage User",
leaf: true
}, {
text: "User rights",
leaf: true
}]
}, {
text: "Test Configuration",
leaf: true,
children: [{
text: "Manage User",
leaf: true
}, {
text: "User rights",
leaf: true
}]
}]
}
}]
});
Attaching the screenshot of the UI tree.
]
I am using extjs-4.2.2
I changed your store definition and now it shows arrows as expected if useArrows property is set to true in config json.
You can try that in sencha fiddle.
var root = {
expanded: true,
children: [{
text: "Configure Application",
expanded: true,
children: [{
text: "Manage Application",
leaf: true
}, {
text: "Scenario",
leaf: true
}]
}, {
text: "User Configuration",
expanded: true,
children: [{
text: "Manage User",
leaf: true
}, {
text: "User rights",
leaf: true
}]
}, {
text: "Test Configuration",
leaf: true,
children: [{
text: "Manage User",
leaf: true
}, {
text: "User rights",
leaf: true
}]
}]
};
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('Ext.tree.Panel', {
useArrows: true,
autoScroll: false,
animate: true,
enableDD: false,
title: 'Configuration',
width: 400,
height: 400,
renderTo: Ext.getBody(),
rootVisible: false,
store: Ext.create('Ext.data.TreeStore', {
root: root
})
});
}
});
I have a tree panel, and I am trying to add a bellow the selected item.
http://jsfiddle.net/zer8oLo7/
If you click on "Add To Root", it is working.
But. if you click on "Add To Selected", it doesn't work:
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [{
text: "detention",
leaf: true
}, {
text: "homework",
expanded: true,
children: [{
text: "book report",
leaf: true
}, {
text: "algebra",
leaf: true
}]
}, {
text: "buy lottery tickets",
leaf: true
}]
}
});
Ext.create('Ext.tree.Panel', {
//title: 'Simple Tree',
itemId: 'projectTree',
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop'
}
},
id: 'projectTree',
width: 200,
height: 500,
store: store,
renderTo: Ext.getBody(),
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
text: 'Add To Selected',
handler: function () {
var treeNode = Ext.getCmp('projectTree').getSelectionModel().getSelection()
treeNode.appendChild({
text: 'Child 4',
leaf: false
});
}
}, {
text: 'Add to root',
handler: function () {
var treeNode = Ext.getCmp('projectTree').getRootNode();
treeNode.appendChild({
text: 'Child 4',
leaf: false
});
}
}]
}],
});
}
});
getSelection() somehow returns an array of nodes, so you need to take only first node:
...
treeNode[0].appendChild({
text: 'Child 4',
leaf: false
});
...
this is a node in the tree
{
text:'more then a_veryverylongword ',
leaf: true
}
Here the problem is that a very very long word is not shown but if I resize the panel the word is shown?
Does someone tell me, what i should do to break the word? the css is not working to modify the size of the panel is not an option.
Thanks
Here is the sample edited code from sencha and its working...
var store = Ext.create('Ext.data.TreeStore', {
root: {
expanded: true,
children: [
{ text: "detention", leaf: true },
{ text: "homework", expanded: true, children: [
{ text: "book report", leaf: true },
{ text: 'more then a_veryverylongword ', leaf: true}
] },
{ text: "buy lottery tickets", leaf: true }
]
}
});
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
width: 250,
height: 150,
store: store,
rootVisible: false,
renderTo: Ext.getBody()
});