Extjs - Tree Panel collapse and expand based on condition - javascript

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

Related

Sencha 6.5 (modern) how to dynamically change the items in a menu in a title bar?

Well considering a grid I create in my application:
{
xtype: 'ordergrid',
itemId: 'ordergrid',
titleBar: {
shadow: false,
items: [{
align: 'right',
xtype: 'button',
text: 'Update status',
stretchMenu: true,
menu: {
itemId: 'status_menu',
defaults: {
handler: 'updateStatus'
},
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
}
}]
},
With ordergrid being defined with:
extend: 'Ext.grid.Grid',
xtype: 'ordergrid',
I wish to modify the items of the menu dynamically. I've first tried doing this through a store:
menu: {
itemId: 'status_menu',
defaults: {
handler: 'updateStatus'
},
indented: false,
store: { type: 'status' }
Though this doesn't seem to work. Then I tried accessing this menu through a component query, during the init function of some controller:
Ext.define('BinkPortalFrontend.view.main.OrderController', {
extend: 'Ext.app.ViewController',
alias: 'controller.order',
init: function () {
console.log('..... initializing ......');
const menus = Ext.ComponentQuery.query('ordergrid #status_menu');
const menu = menus[0];
menu.setItems([{
text: 'some',
value: 'some'
}, {
text: 'new',
value: 'mew'
}]);
},
};
However this returns an error: "Cannot read property 'setItems' of undefined"
Debugging shows the obvious problem: it doesn't find any menu.
What's more, even a "catch all" query like
Ext.ComponentQuery.query('menu');
or
Ext.ComponentQuery.query('#status_menu');
Shows an empty array: so what's going on? (I most definitely see the menu from its initial load).
There is one reason your menu is not created. Menu will created whenever button will tap or whenever getMenu() method get called.
If you want to get your menu using Ext.ComponentQuery.query(), so for this you need to do use initialize event of button and forcefully create menu using getMenu() method like below :-
{
xtype: 'button',
text: 'Update status',
stretchMenu: true,
menu: {
itemId: 'status_menu',
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
},
listeners: {
initialize: function(btn) {
Ext.defer(function() {
// This will print undefined because menu have not created
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
//When we use getMenu method it will create menu item
btn.getMenu().hide();
// This will print menu component
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
}, 10)
}
}
}
Another way you can use getMenu() method of button. It will return the menu component.
In this FIDDLE, I have created a demo using grid, button and menu. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'email', 'phone'],
data: [{
'name': 'Lisa',
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
"email": "home#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
});
Ext.create('Ext.grid.Grid', {
title: 'Change menu items dynamically',
titleBar: {
shadow: false,
items: [{
align: 'right',
xtype: 'button',
text: 'Update status',
stretchMenu: true,
itemId: 'statusbtn',
menu: {
itemId: 'status_menu',
defaults: {
// handler: 'updateStatus'
},
indented: false,
items: [{
text: 'test1',
value: 'test1'
}, {
text: 'test2',
value: 'test2'
}, {
text: 'test3',
value: 'test4'
}]
},
listeners: {
initialize: function (btn) {
Ext.defer(function () {
// This will undefined because menu has not been created
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
//When we use getMenu method it will create menu item
btn.getMenu().hide();
// This will menu component
console.log(Ext.ComponentQuery.query('#status_menu')[0]);
}, 10)
}
}
}, {
xtype: 'button',
align: 'right',
text: 'Change Items',
handler: function (btn) {
var newItems = [];
store.each(rec => {
newItems.push({
text: rec.get('name'),
value: rec.get('name')
})
});
/*
* You can also get menu using button
* btn.up('titlebar').down('#statusbtn').getMenu().setItems(newItems);
*/
Ext.ComponentQuery.query('#status_menu')[0].setItems(newItems);
Ext.toast('Menu items has been change. Please check', 2000);
}
}]
},
store: store,
columns: [{
text: 'Name',
dataIndex: 'name',
width: 200
}, {
text: 'Email',
dataIndex: 'email',
width: 250
}, {
text: 'Phone',
dataIndex: 'phone',
width: 120
}],
height: 200,
layout: 'fit',
fullscreen: true
});
}
});
For more details about component you can also see this ComponentManager

Seaching for node in ExtJs tree

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);
}
});
}
}]
}]
});

How to disable a particular row in Picker in Sencha touch

I have created a picker in Sencha touch 2.1. My Data is displaying properly. I want to disable a particular value not all so that if I select that value and click "doneButton" then it shouldn't be taken.
Example:
function loadPicker(paramName, valueSet) {
Ext.Viewport.remove(Ext.getCmp(paramName + 'Pickerfield'), true);
if (!paramName.picker) {
paramName.picker = Ext.Viewport.add({
xtype: 'picker',
id: paramName + 'Pickerfield',
useTitles: true,
slots: [{
name: paramName,
title: paramName,
data: valueSet
}],
doneButton: {
listeners: {
tap: function(button, event, eOpts) {
var selectedPacingModeValue =
Ext.getCmp(paramName + 'Pickerfield').getValue()[paramName];
sendSetPendingRequest(paramName, selectedPacingModeValue);
}
}
}
});
}
}
lets take these are the values in my picker field. What I am doing on select of an value and click of "doneButton", I am showing the value in a textfield. What I want is if I will select "option 2" and click "doneButton" then option 2 shouldn't be displayed in textfield but for all other values this selecting and showing in textfield operation should work.
You can just get the selected record and check that flag upon click of the done button, then move to textbox (or not).
Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'fieldset',
title: 'Select',
items: [
{
xtype: 'selectfield',
itemId: 'mySelectField',
label: 'Choose one',
options: [
{
text: 'apple',
value: 50
}, {
text: 'orange',
value: 100,
disabled: true
}, {
text: 'banana',
value: 200
}, {
text: 'papaya',
value: 300
}
]
},
{
xtype: 'button',
text: 'done',
handler: function(button){
var panel = button.up(),
sf = panel.down('#mySelectField'),
tf = panel.down('#answerfield');
/* you can only access the raw value unless you use
* an actual store and an actual model with the
* disabled field. In that case you can do
* sf.getRecord().get('disabled')
*/
if(sf.getRecord().raw.disabled === true){
tf.setValue(''); //noting to see :)
} else {
tf.setValue(sf.getRecord().get('text')); //display value
}
}
},
{
xtype: 'textfield',
itemId: 'answerfield',
title: 'answer'
}
]
}
]
});
Working fiddle: http://www.senchafiddle.com/#d46XZ
UPDATE
Like you asked: with the picker
Ext.Loader.setConfig({
enabled: true
});
Ext.application({
name: 'SenchaFiddle',
launch: function() {
var picker = Ext.create('Ext.Picker', {
slots: [
{
name : 'stuff',
title: 'Stuff',
data : [
{
text: 'apple',
value: 50
}, {
text: 'orange',
value: 100,
disabled: true
}, {
text: 'banana',
value: 200
}, {
text: 'papaya',
value: 300
}
]
}
],
listeners: {
change: function(p, value){
var tf = panel.down('#answerfield'),
firstSlot = p.getItems().get(1), //index 0 is the toolbar 1 first slot and so on..
selectedRecord = firstSlot.getData()[firstSlot.selectedIndex];
if(selectedRecord.disabled === true){
tf.setValue(''); //noting to see :)
} else {
console.log(selectedRecord);
tf.setValue(selectedRecord.text); //display value
}
}
}
});
var panel = Ext.create('Ext.form.Panel', {
fullscreen: true,
items: [
{
xtype: 'fieldset',
title: 'Select',
items: [
{
xtype: 'button',
text: 'show picker',
handler: function(button){
Ext.Viewport.add(picker);
picker.show();
}
},
{
xtype: 'textfield',
itemId: 'answerfield',
title: 'answer'
}
]
}
]
});
}
});
working fiddle: http://www.senchafiddle.com/#SFgpV

Extjs 4 save state of a checkboxGroup when parent window is closed

I have a window with a checkboxGroup in it. I would like whatever selections are made in the checkboxGroup to be saved when my "apply" button on the window is pressed. So far I have
xtype: 'checkboxgroup',
stateful: true,
stateID: 'checks',
getState: function() {
return {
items: this.items
};
},
stateEvents: ['close'],
columns: 2,
vertical: false,
items: [...]
I'm pretty sure my stateEvents are wrong, what would I use to indicate that I want the state to be saved when the parent window is closed?
I have this line in my app.js file's launch function, right before I create the top viewport
Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
Thank you!
apparently the state of the checkbox group does not include the values of the checkboxes http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.CheckboxGroup-method-getState
i had to go via a session variable and the parent window events ..
var configPopup;
var configForm = Ext.create('Ext.form.Panel', {
id: 'form-config',
name: 'form-config',
frame: true,
layout: 'anchor',
items: [
{
border:0,
anchor: "100%",
xtype: 'checkboxgroup',
fieldLabel: 'Include options',
labelWidth: 100,
id: 'opt_relation',
labelStyle: 'margin-left:10px;',
items: [
{
boxLabel: 'relation 1',
name: 'opt_relation',
inputValue: 'rel1',
checked: true
},
{
boxLabel: 'relation 2',
name: 'opt_relation',
inputValue: 'rel2',
checked: true
},
{
boxLabel: 'relation 3',
name: 'opt_relation',
inputValue: 'rel3',
checked: true
}
]
}
],
buttons: [
{
text: 'Close',
handler: function() {
configPopup.hide();
}
}]
});
configPopup = new Ext.Window({
id:'configPopup',
title: 'Chart configuration',
layout : 'fit',
width : 390,
closeAction :'hide',
plain : true,
listeners: {
show: function() {
var v = Ext.state.Manager.get("optRelation");
if (v) {
Ext.getCmp('opt_relation').setValue(v);
}
},
hide: function() {
var v = Ext.getCmp('opt_relation').getValue();
Ext.state.Manager.set("optRelation",v);
}
},
items : [
configForm
]
});

ExtJS and event listeners : 'load' not called. How comes?

Here's my ExtJs component.
Everything works perfectly.... err well almost everything.
I just don't get why the this.on('load', function (form,action) {}) is not called whereas the same declaration for this.on('actioncomplete', function (form,action) {}); is called:
DossierPanel = Ext.extend(Ext.form.FormPanel, {
closable: true,
autoScroll:true,
initComponent : function(){
this.id = 'id_dossier_'+this.id_dossier;
this.bodyStyle = 'padding:15px';
this.labelWidth = 150;
this.items = [{
layout:'column',
border:false,
autoHeight: true,
items:[{
columnWidth:.5,
layout: 'form',
border:false,
items: [{
xtype:'textfield',
fieldLabel: 'Civilite ',
name: 'CIVILITE',
readOnly: true
}]
},{
columnWidth:.5,
layout: 'form',
border:false,
items: [{
xtype:'textfield',
fieldLabel: 'Email ',
name: 'EMAIL',
vtype:'email',
anchor:'95%'
}]
}]
},{
xtype:'tabpanel',
plain:true,
activeTab: 0,
deferredRender: false,
defaults:{bodyStyle:'padding:10px'},
items:[{
title:'Détails personnels',
layout:'form',
autoHeight: true,
defaults: {width: '99%'},
defaultType: 'textfield',
items: [{
xtype:'datefield',
fieldLabel: 'Date de naissance ',
name: 'NAISSANCEJMA',
format:'d/m/Y'
}]
},{
title:'Adresse',
layout:'form',
autoHeight: true,
defaults: {width: '95%'},
defaultType: 'textfield',
items: [{
fieldLabel: 'Adresse 1 ',
name: 'ADRESSE1'
}]
},{
title:'Téléphone(s)',
layout:'form',
autoHeight: true,
defaults: {width: 230},
defaultType: 'textfield',
items: [{
fieldLabel: 'DescTelephone1 ',
name: 'DESCTELEPHONE1',
readOnly: true
}]
},{
title:'Divers',
layout:'form',
autoHeight: true,
defaults: {width: 230},
defaultType: 'textfield',
items: [{
fieldLabel: 'ReferenceExterne ',
name: 'REFERENCEEXTERNE'
}]
}]
}];
this.buttonAlign = 'left';
this.buttons = [{
text: 'Recharger',
handler: function() {
this.getForm().load( {
url: '/w.php',
params: {
id_dossier: this.id_dossier
},
failure:function(form, action) {
handleAjaxError(action.response,'Refresh error');
}
});
},
scope: this
},{
text: 'Sauver',
handler: function() {
this.getForm().submit({
url: '/ws.php',
params: {
write: 1
},
waitTitle: 'Patientez',
waitMsg: 'Sauvegarde',
success: function (form, action) {
var b = Ext.util.JSON.decode(action.response.responseText);
if (b.success==true) {
if (b.msg) {
Ext.MessageBox.alert('Done!', b.msg);
}
else {
Ext.MessageBox.alert('Done!', 'Saved');
}
}
},
failure:function(form, action) {
handleAjaxError(action.response,'Refresh error');
}
});
},
scope: this
}];
//this.listeners = {
// actioncomplete: handleActionComplete,
// load: handleLoad
//};
this.on('load', function (a,b,c) {
console.log(a);
console.log(b);
console.log(c);
});
this.on('actioncomplete', function (form,action) {
if (action.type=='load') {
console.log('actioncomplete => action load');
}
});
this.on('load', function (form,action) {
if (action.type=='load') {
console.log('LOAAAAAD');
}
});
DossierPanel.superclass.initComponent.call(this);
console.log(this.events)
}
});
Watch carefully the this.on() code juste above: the console log shows only "'actioncomplete => action load'", not the 'LOAAAAAD'. From my pov this is not normal. Am I missing something?
Thank you very much
The Ext.form.FormPanel do not have a load event. So, even if you define a function for load event, the event is never fired and your function is never executed.
The actioncomplete event is an event of BasicForm and is fired when an action is completed.

Categories

Resources