Dynamically Add contextmenu to Ext.tree.TreePanel - extjs

I am trying to add dynamically created contextmenu's to an Ext.tree.TreePanel object. The menus will all be different depending on user selections.
I can create the menu outside the treePanel descriptor but how can I append the dynamically created menu to the Ext.tree.TreePanel? The documentation seems to indicate that treePanel.on(nameOfMenuHere) would append the menu but it returns as undefined.
var menu1 = new Ext.menu.Menu({
id: 'menu1',
items: [{
id: 'menu1-item1',
text: 'Menu 1 - Item 1'
},
{
id: 'menu1-item2',
text: 'Menu 1 - Item 2'
}],
listeners: {
itemclick: function (item) {
switch (item.id) {
case 'menu1-item1':
var n = item.parentMenu.contextNode;
if (n.parentNode) {
alert(n.parentNode.text);
alert("node ID: " + n.id + ", node text: " + n.text); //Ext ID and text of selected node
}
break;
}
}
}
});
userLayerTree.on(menu1);

use the listener itemcontextmenu within the tree panel. something like this should work.
var tpanel = {
xtype : 'treepanel',
width: 250,
.........
..........
listeners : {
itemcontextmenu: showLyrContextMenu
}
}
and then create the function to create and show your menu
function showLyrContextMenu(view, record, item, index, event){
lyrTreeContextMenu = new Ext.menu.Menu({
id : 'lyrcontxtmenu',
.......
items: items
});
lyrTreeContextMenu.showAt(event.getXY());
event.stopEvent();
}

Related

How to solve this error "Uncaught TypeError: Cannot call method 'getForm' of undefined "

I tried to add edit button functionality in grid panel. I want to open an edit window on edit button click for updating grid row record using Ext Window Form which contains fields like (Shift Name, Time, Total, Requirement, Note). The window form is created, but the row values that I have selected in grid are not set in form fields.
I tried to use this code:
Ext.getCmp('shiftWindow').getForm().setValues(selection[0].data);
but it's giving the following error
Uncaught TypeError: Cannot call method 'getForm' of undefined
Here is my code:
var shiftWindow = Ext.create('Ext.window.Window', {
title: 'Edit Shift',
resizable: false,
id: 'shiftwindow',
width: 465, //bodyPadding: 5, modal: true, store: shiftStorePlanner,
items: {
xtype: 'form',
id: 'idFormShift',
bodyPadding: 10,
items: shiftViewModelPlannerData
},
buttons: [{
text: 'Save',
cls: 'planner-save-button',
overCls: 'planner-save-button-over',
handler: function () {
var wi = this.up('.window')
var form = Ext.getCmp('idFormShift');
if (form.isValid()) {
shiftTimemappingarray = [];
getShiftTime();
//this.up('.window').close();
}
}
}, {
text: 'Cancel',
handler: function () {
this.up('.window').close();
}
}]
});
var host1 = Ext.getCmp('plannershifteditor');
var selection = host1._shiftPlannerGrid.getSelectionModel().getSelection();
if (selection.length === 0) {
return;
}
selection[0].data.ShiftName = selection[0].data.ShiftName.replace('(ARCHIVED)', '').trim(); //if edit Archive record then text name show without (ARCHIVED)
//shiftWindow.getForm().setValues(selection[0].data);
Ext.getCmp('shiftWindow').getForm().setValues(selection[0].data);
//Ext.getCmp('shiftWindow').setValue(selection[0].data);
shiftWindow.show();
There's no getForm method in the window. You can get the form using shiftWindow.down('form'). Here's the snippet:
shiftWindow.down('form').form.setValues(selection[0].data)

ExtJS 6 - Bind disabled property to new records in a store

I'm trying to enable/disable a button when the store getNewRecords() function return the length, but not work!
bind: {
disabled: "{!grid.getStore().getNewRecords().length}"
}
Fiddle: https://fiddle.sencha.com/fiddle/1sj5
Someone have idea to how resolve this?
You need to create a formula in your viewmodel:
viewModel: {
formulas: {
hasNewRecords: function (r) {
return this.getView().down("treepanel").getStore().getNewRecords().length > 0;
}
}
}
then you can use it for your bindings:
bind: {
disabled: "{hasNewRecords}"
}
(probably not the best way to get the data you want).
You can read about it here, here and here .
What you're wanting to do here is currently not possible in the framework. Instead, you should create a ViewModel data value and modify that where need be, like this:
var form = Ext.create("Ext.form.Panel", {
viewModel: {
data: {
newRecords: false
}
},
items: [{
xtype: "textfield",
labelField: "Add Child",
name: "col1",
value: "Teste 123"
}],
tbar: {
xtype: "button",
text: "Add new record",
handler: function () {
var data = this.up("form").getForm().getFieldValues();
var rec = grid.getStore().getAt(0);
data["treeCol"] = rec.childNodes.length + 1;
// setting value, so binding updates
this.lookupViewModel().set('newRecords', true);
rec.appendChild(data);
}
},
bbar: {
xtype: "button",
text: "button to disabled when new records",
bind: {
disabled: "{newRecords}"
}
},
renderTo: Ext.getBody()
});
Or by simply doing this.
In your controller:
me.getView().getViewModel().set('storeLen', store.getNewRecords().length);
In your ViewModel, simply do this:
formulas : {
hasNewRecords : {
get : function(get){
var length = get('storeLen') // --> gets the one you set at your controller
return length > 0 ? true : false;
}
}
}
In your View:
bind : {
disabled : '{hasNewRecords}'
}

Drag and Drop from Grid to Tree and backwards

Since a few days now I try to change an ExtJs ['Grid to Tree Drag and Drop' Example][1] to work in both directions. But all I get is an 'almost' working application.
Now it works as far as I can drag an item from grid to tree, within tree, within grid but if i drag it from tree to grid, it doesn't drop. It just shows the green hook.
I also tried to differ the ddGroup from tree and grid, but then nothing works anymore.
This is too much for an ExtJs beginner.
// Stücklisten Grid
stuecklistengrid = Ext.extend(Ext.grid.GridPanel, {
initComponent:function() {
var config = {
store:itemPartStore
,columns:[{
id:'PART_ITE_ID'
,header:"PART_ITE_ID"
,width:200, sortable:true
,dataIndex:'PART_ITE_ID'
},{
header:"IS_EDITABLE"
,width:100
,sortable:true
,dataIndex:'IS_EDITABLE'
},{
header:"IS_VISIBLE"
,width:100
,sortable:true
,dataIndex:'IS_VISIBLE'
}]
,viewConfig:{forceFit:true}
}; // eo config object
// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));
this.bbar = new Ext.PagingToolbar({
store:this.store
,displayInfo:true
,pageSize:10
});
// call parent
stuecklistengrid.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
,onRender:function() {
// call parent
stuecklistengrid.superclass.onRender.apply(this, arguments);
// load the store
this.store.load({params:{start:0, limit:10}});
} // eo function onRender
});
Ext.reg('examplegrid', stuecklistengrid);
// Stücklisten Tree
var CheckTree = new Ext.tree.TreePanel({
root:{ text:'root', id:'root', expanded:true, children:[{
text:'Folder 1'
,qtip:'Rows dropped here will be appended to the folder'
,children:[{
text:'Subleaf 1'
,qtip:'Subleaf 1 Quick Tip'
,leaf:true
}]
},{
text:'Folder 2'
,qtip:'Rows dropped here will be appended to the folder'
,children:[{
text:'Subleaf 2'
,qtip:'Subleaf 2 Quick Tip'
,leaf:true
}]
},{
text:'Leaf 1'
,qtip:'Leaf 1 Quick Tip'
,leaf:true
}]},
loader:new Ext.tree.TreeLoader({preloadChildren:true}),
enableDD:true,
ddGroup:'grid2tree',
id:'tree',
region:'east',
title:'Tree',
layout:'fit',
width:300,
split:true,
collapsible:true,
autoScroll:true,
listeners:{
// create nodes based on data from grid
beforenodedrop:{fn:function(e) {
// e.data.selections is the array of selected records
if(Ext.isArray(e.data.selections)) {
// reset cancel flag
e.cancel = false;
// setup dropNode (it can be array of nodes)
e.dropNode = [];
var r;
for(var i = 0; i < e.data.selections.length; i++) {
// get record from selectons
r = e.data.selections[i];
// create node from record data
e.dropNode.push(this.loader.createNode({
text:r.get('PART_ITE_ID')
,leaf:true
,IS_EDITABLE:r.get('IS_EDITABLE')
,IS_VISIBLE:r.get('IS_VISIBLE')
}));
}
// we want Ext to complete the drop, thus return true
return true;
}
// if we get here the drop is automatically cancelled by Ext
}}
}
});
// Stücklisten Container
var itemPartList = new Ext.Container({
id: 'itemPartList',
title: 'Stücklisten',
border:false,
layout:'border',
items:[CheckTree, {
xtype:'examplegrid'
,id:'SLgrid'
,title:'Grid'
,region:'center'
,layout:'fit'
,enableDragDrop:true
,ddGroup:'grid2tree'
,listeners: {
afterrender: {
fn: function() {
// This will make sure we only drop to the view scroller element
SLGridDropTargetEl2 = Ext.getCmp('SLgrid').getView().scroller.dom;
SLGridDropTarget2 = new Ext.dd.DropTarget(SLGridDropTargetEl2, {
ddGroup : 'grid2tree',
notifyDrop : function(ddSource, e, data){
var records = ddSource.dragData.selections;
Ext.each(records, ddSource.grid.store.remove,
ddSource.grid.store);
Ext.getCmp('SLgrid').store.add(records);
return true
}
});
}
}
}
}]
});
You need to implement the onNodeDrop event of the grid. See http://docs.sencha.com/ext-js/4-1/#!/api/Ext.grid.header.DropZone-method-onNodeDrop

Sencha Touch 2 - Populate a TitleBar using a store

I am working with Sencha Touch 2 and I need to create a TitleBar which is sucked into a set of screens. The TitleBar elements are drop-down lists. The items within the drop-down lists must be dynamic and must be loaded from a data file.
I've managed to load the data but I cannot pass the data back to the TitleBar. In other words, I need somehow to create a reference to the titlebar.
Code:
Ext.define('CustomerToolbar', {
extend: 'Ext.TitleBar',
xtype: 'customer-toolbar',
initialize: function() {
this.callParent(arguments);
this.loadItems();
console.info("end of init");
},
config: {
layout: 'hbox',
defaults: {
}
},
loadItems: function (titleBar) {
var itemList = [];
var itemOptionList = [];
Ext.getStore('OrganizationStore').load(function(organizationList) {
console.info("getOptionList inside the store load function");
Ext.each(organizationList, function(organization) {
console.info("organizations: " + organization.get("name") + "," + organization.get("id"));
itemOptionList.push({text: organization.get("name"), value: organization.get("id")});
});
console.info("itemList - about to populate");
itemList.push(
{
xtype: 'selectfield',
name: 'customerOptions',
id :'organizationId',
options: itemOptionList,
action :'selectOrganizationAction'
}
);
console.info("itemList - populated");
console.info("itemList within the store block: " + itemList);
console.info("this: " + this);
//THIS IS WHERE I AM HAVING THE PROBLEM.
//The variable this points to the store and not to the TitleBar
//this.setItems(itemList);
});
console.info("itemList outside the store block: " + itemList);
}
});
You can add a listener to your selectfield and do
listeners:{
change:function(){
title = Ext.getCmp('organizationId').getValue();
Ext.getCmp('TitlBarID').setTitle(title);
}
}
I know Ext.getCmp is not fashionable but it works

Mistake in the Code

myTree.on('click',function(node){
if(node.isLeaf())
{
Ext.Msg.alert("You are in value ",nodeValue,"whose name is",nodeName);
alert("You are in value ",nodeValue,"whose name is",nodeName);
}
});
myTree is a TreePanel. I'm getting a tree but click function is not working. I'm very new to extjs. Help me out.
Thanks in advance
Try this instead:
myTree.on('click',function(node){
if(node.isLeaf())
{
Ext.MessageBox.show({
msg: 'You are in text ' + node.text + ', whose id is ' + node.id,
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
}
});
Haven't tried it, but it looks very similar to what I have been working with today :)
You can define your tree like :
var myTree = new Ext.tree.TreePanel({
region: 'west',
id: 'navTree',
title: 'Items',
width: 200,
store: store,
split: true,
collapsible: true,
listeners: {
itemclick: {
fn: function (view, record, item, index, event) {
//the record is the data node that was clicked
//the item is the html dom element in the tree that was clicked
//index is the index of the node relative to its parent
nodeId = record.data.id;
htmlId = item.id;
if (record.data.leaf) {
Ext.Msg.alert("Alert", "leaf");
}
else {
Ext.Msg.alert("Alert", "Not leaf");
}
}
}
}
})
Looks like you are looking for:
node.value
node.name
OR (I'm not good with Ext)
node.nodeValue
node.nodeName

Resources