I am using a menu to display a number of options for rows in my grid. The menu displays the text correctly and I want to be able to disable some of these options dynamically.
This is my menu:
Ext.create('Ext.menu.Menu', {
items: [{
text: 'option 1'
},{
text: 'option 2'
},{
text: 'option 3'
}]
});
I've tried giving each item an id and disabling it by id but I get an error in my console saying
Uncaught TypeError: Cannot read property 'contains' of undefined(…)
Does anyone know a solution to this?
You just need to call method disable on the menuitem.
var item = Ext.first('#mySpecialMenuItem');
item.disable();
Something like this:
{
xtype: 'menu',
floating: false,
id: 'myMenu',
width: 120,
items: [
{
xtype: 'menuitem',
id: 'mySpecialMenuItem',
text: 'Menu Item'
},
{
xtype: 'menuitem',
text: 'Menu Item'
},
{
xtype: 'menuitem',
text: 'Menu Item'
}
]
},
{
xtype: 'button',
handler: function(button, e) {
// somehow get the item
var item = Ext.first('#mySpecialMenuItem');
// call disable
item.disable();
},
text: 'Disable Item'
}
Check the full example in this fiddle
https://fiddle.sencha.com/#view/editor&fiddle/1m2q
var menu=Ext.create('Ext.menu.Menu', {
items: [{
text: 'option 1'
},{
text: 'option 2'
},{
text: 'option 3'
}]
});
var item=menu.getComponent(//index of the item)
item.setDisabled(true);
Related
I have the following code in ExtJS
var formPanel = Ext.create('Ext.form.Panel', {
title: 'Panel title',
renderTo: Ext.getBody(),
items: [{
xtype: 'container',
layout: 'hbox',
items: [{
xtype: 'textfield',
fieldLabel: 'First Name',
name: 'FirstName',
}, {
xtype: 'textfield',
fieldLabel: 'Last Name',
name: 'LastName',
},{
xtype:'fieldset',
title: 'Phone Number',
defaultType: 'textfield',
items :[{
fieldLabel: 'Home',
name: 'home',
value: '(888) 555-1212'
},{
fieldLabel: 'Business',
name: 'business',
toBeRendered: IS_BUSINESS_FIELD_SUPPORTED_IN_CURRENT_RELEASE // custom property that must restrict rendering
rendered: IS_BUSINESS_FIELD_SUPPORTED_IN_CURRENT_RELEASE //doesn't work
}]
}]
}]
});
I want to create an application, that will have properties file where I can set up flags for SUPPORTED fields e.g IS_BUSINESS_FIELD_SUPPORTED_IN_CURRENT_RELEASE = false. If it's false than text input fieldLabel: 'Business' will not be rendered at all - no hidden/disabled text input Business in html.
I've tried rendered property - but it doesn't work, the only solution so far is to use items = Ext.Array.filter(items,filterFunction) in onRender;
Are there any other solutions how can I restrict rendering input elements?
Thanks in advance.
Instead of the constructor, use the initItems method:
Ext.define('MyComponent', {
extend: 'Ext.panel.Panel',
xtype: 'mycomponent',
bodyPadding: 10,
border: true,
title: 'My component',
items : [
{
xtype: 'button',
text: 'My allowed button'
}
],
initItems : function() {
var items = this.items;
// Your conditions
if (false) {
items.push({
xtype: 'button',
text: 'My denied button'
});
}
this.callParent();
}
});
https://fiddle.sencha.com/#fiddle/17qi
I think that best approach is to define custom components for your application parts and add required components within its constructor, like this:
constructor: function () {
var myComponentItems = [
{
xtype: 'button',
text: 'My allowed button'
}
];
// Your conditions
if(false) {
myComponentItems.push({
xtype: 'button',
text: 'My denied button'
});
}
Ext.apply(this, {
items: myComponentItems
});
this.callParent(arguments);
}
Working fiddle
Currently I'm working on a code migration from ExtJS 4.2 to ExtJS 5.1. And I noticed MANY changes on default behavior of many components.
One of the things I noticed is that the default tab key navigation between components has changed and in this case is not quite predictable.
To reproduce go to the 4.2 fiddle here, and then click on the first text field, hit tab and then it would change focus to state combo box; hit tab again and it would go to "Next" button, hit tab again and it would go to "Second option" radio button, and so on in a predictable order.
Then repeat the same thing on 5.1 fiddle here. First thing you'll notice is that "My First Option" radio is unchecked (that's another issue), but the main issue I would like to fix is the odd order it follows on tab key press.
How can I make tab key navigation behave as it did on 4.2 version?
Including sample code here:
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
]
});
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.form.Panel', {
title: 'My Navigable Panel',
items: [
{
xtype: 'radiogroup',
layout: 'vbox',
items: [
{
xtype: 'radiofield',
boxLabel: 'My First Option',
name: 'radio',
value: true,
checked: true,
listeners: {
change: function(group, newValue, oldValue) {
if(newValue) {
group.up('form').down('fieldcontainer[name=containerA]').show();
group.up('form').down('fieldcontainer[name=containerB]').hide();
} else {
group.up('form').down('fieldcontainer[name=containerA]').hide();
group.up('form').down('fieldcontainer[name=containerB]').show();
}
}
},
},
{
xtype: 'fieldcontainer',
layout: 'hbox',
name: 'containerA',
fieldDefaults: {
labelAlign: 'top',
margin: '0 5 0 5'
},
items: [
{
xtype: 'textfield',
fieldLabel: 'First field',
allowBlank: false
},
{
xtype: 'combo',
fieldLabel: 'State',
width: 50,
store : states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
},
{
xtype: 'button',
text: 'Next'
}
]
},
{
xtype: 'radiofield',
boxLabel: 'My Second Option',
name: 'radio',
value: false
}
]
},
{
xtype: 'fieldcontainer',
padding: '0 0 0 25',
name: 'containerB',
hidden: true,
items: [{
xtype: 'radiogroup',
layout: 'vbox',
items: [
{
xtype: 'radiofield',
fieldLabel: 'My nested radio button A',
name: 'subradio'
},
{
xtype: 'radiofield',
fieldLabel: 'My nested radio button B',
name: 'subradio'
}
]
}]
}
],
renderTo: Ext.getBody()
}).show();
}
});
Well, I did not find a way to tell ExtJS 5.1 to navigate through the form as it did on 4.2, but I managed to get the desired behavior by modifying my form composition (although it looks the same) in a way that ExtJS 5.1 was able to orderly follow.
To make that happen I removed the radiogroup component but kept all that was inside of it (which was pretty much the whole form content). It seems that structure didn't feel quite natural to the updated framework.
Here is a fiddle with the mentioned changes.
Including code here:
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
]
});
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.create('Ext.form.Panel', {
title: 'My Navigable Panel',
items: [
{
xtype: 'radiofield',
boxLabel: 'My First Option',
name: 'radio',
value: true,
checked: true,
listeners: {
change: function(group, newValue, oldValue) {
if(newValue) {
group.up('form').down('fieldcontainer[name=containerA]').show();
group.up('form').down('fieldcontainer[name=containerB]').hide();
} else {
group.up('form').down('fieldcontainer[name=containerA]').hide();
group.up('form').down('fieldcontainer[name=containerB]').show();
}
}
},
},
{
xtype: 'fieldcontainer',
layout: 'hbox',
name: 'containerA',
fieldDefaults: {
labelAlign: 'top',
margin: '0 5 0 5'
},
items: [
{
xtype: 'textfield',
fieldLabel: 'First field',
allowBlank: false
},
{
xtype: 'combo',
fieldLabel: 'State',
width: 50,
store : states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
},
{
xtype: 'button',
text: 'Next'
}
]
},
{
xtype: 'radiofield',
boxLabel: 'My Second Option',
name: 'radio',
value: false
},
{
xtype: 'fieldcontainer',
padding: '0 0 0 25',
name: 'containerB',
hidden: true,
items: [{
xtype: 'radiogroup',
layout: 'vbox',
items: [
{
xtype: 'radiofield',
fieldLabel: 'My nested radio button A',
name: 'subradio'
},
{
xtype: 'radiofield',
fieldLabel: 'My nested radio button B',
name: 'subradio'
}
]
}]
}
],
renderTo: Ext.getBody()
}).show();
}
});
I have a radio buttons in a window in Ext 3.4. Based on which radio button is clicked I have to populate the data accordingly in a combo box.
for e.g: Radio Buttons: 1. Window 2. Linux.
If the user checks Window, then all windows images will be populated in the combo box.
Now for fetching all the window images I am not making any call to the server to fetch those images but have it is a client side stored in an local array.
Below is the code snippet:
var ImagesArray = new Array();
ImagesArray=[];// On load the array contains no data
{
xtype: 'radiogroup',
fieldLabel: 'Image type',
cls: 'x-check-group-alt',
itemid: 'ImageType',
items: [
{boxLabel: 'WindowsImages', name: 'rb-auto', inputValue: 'Windows', id: 'Windows',checked:true,
listeners: {
'check' : function(radio, checked) {
data =['Windows 2008 Server','Windows 2012 server'];
ImagesArray.loadData(data,false);
ImagesArray.store.reload();
}
},
// My combo box
{
xtype : 'combo', // 6
fieldLabel : 'Template/Image name',
id: 'VMTemplate',
name: 'VMTemplate',
labelWidth: 250,
triggerAction: 'all',
forceSelection: true,
editable:false,
store : ImagesArray,
},
But this is not working. I am getting an error store.reload() is not defined.
How do i make it work?
Since multiple selections are possible, I think checkboxgroup is more suitable than radiogroup in your case. Sample Code.
Ext.create('Ext.form.Panel', {
width: 300,
height: 500,
bodyPadding: 10,
renderTo: Ext.getBody(),
items:[{
xtype: 'checkboxgroup',
fieldLabel: 'Two Columns',
columns: 2,
vertical: true,
listeners:{
change: function(){
var data = Ext.Array.flatten(Ext.Object.getValues(this.getValue()));
data = data.map(function(n){ return { name: n } });
Ext.getCmp("VMTemplate").getStore().loadData(data);
}
} ,
items: [
{ boxLabel: 'Item 1', name: 'rb-auto', inputValue: 'Item 1'},
{ boxLabel: 'Item 2', name: 'rb-auto', inputValue: 'Item 2'},
{ boxLabel: 'Item 3', name: 'rb-auto', inputValue: 'Item 3' },
{ boxLabel: 'Item 4', name: 'rb-auto', inputValue: 'Item 4' },
{ boxLabel: 'Item 5', name: 'rb-auto', inputValue: 'Item 5' },
{ boxLabel: 'Item 6', name: 'rb-auto', inputValue: 'Item 6' }
]
},{
xtype: 'combo',
store:{
fields: ['name'],
data: []
},
displayField: 'name',
valueField: 'name',
emptyText: 'Template',
id: 'VMTemplate',
queryMode: 'local'
}]
});
I have 5 columns on my grid, and I want to disallow users to be able to drag the columns on the right of the middle column to the left, and same goes disallow columns on the left dragged to the right.
My fiddle: https://fiddle.sencha.com/#fiddle/10ei
I have a column called No Crossing Zone, how I can disallow id and name from dragged to the right side of the No Crossing Zone, and disable Group 1 and Group 2 to the left side of the No Crossing Zone?
I can add any new key:value pairs to the data set if needed.
With this code, the column right of the No Crossing Zone will be moved back right of it if it is moved left of it. And vise versa:
1st solution:
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('Ext.grid.Panel', {
columns: [
{
text: 'Id'
},
{
text: 'Name'
},
{
text: 'No Crossing Zone',
draggable: false
},
{
text: 'Group 1',
},
{
text: 'Group 2',
}],
listeners:{
columnmove: function (ct, column, fromIdx, toIdx, eOpts) {
var noCrossCol = undefined,
crossCol = undefined,
i = 0;
Ext.each(ct.getGridColumns(), function(col) { // There may be a better way to get "crossColIdx" and "crossCol"...
if(col.text == 'No Crossing Zone') {
crossColIdx = i;
crossCol = col;
return false;
}
i++;
});
console.log("fromIdx: " + fromIdx + "; toIdx: " + toIdx);
if((fromIdx <= crossColIdx) && (toIdx > crossColIdx)) {
console.log("moved too far");
ct.moveBefore(column, crossCol);
}
if((fromIdx >= crossColIdx) && (toIdx < crossColIdx)) {
console.log("moved too near");
ct.moveAfter(column, crossCol);
}
}
},
renderTo: Ext.getBody()
})
}
});
Second solution:
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('Ext.grid.Panel', {
columns: [{
text: 'left part',
sealed: true,
columns: [{
text: 'Id'
}, {
text: 'Name',
sealed: true,
columns: [{
text: 'Sub 1'
}, {
text: 'Sub 2'
}]
}]
}, {
text: 'No Crossing Zone',
draggable: false
}, {
text: 'right part',
sealed: true,
columns: [{
text: 'Group 1',
sealed: true,
columns: [{
text: 'Sub 1'
}, {
text: 'Sub 2'
}]
}, {
text: 'Group 2',
sealed: true,
columns: [{
text: 'Sub 1'
}, {
text: 'Sub 2'
}]
}]
}],
flex: 1,
renderTo: Ext.getBody()
})
}
});
You could even delete the No Crossing Zone column.
(Edited after request in the comments)
In my UI, I have a single-select RadioGroup with a few options to choose from. One of the options will contain a textfield that the user can enter input into like this:
() Option A
() Option B
() Other (Please specify) ____
How would I add something like this to a RadioGroup?
For creating layout of "Other" option you can use container component with hbox layout. This component will have two items. First item will be radio and the second item will be textfield.
For creating space between radio and textfield components you can use splitter.
{
xtype: 'radiogroup',
fieldLabel: 'Choose',
columns: 1,
vertical: true,
items: [
{ boxLabel: 'Option 1', name: 'rb', inputValue: '1' },
{ boxLabel: 'Option 2', name: 'rb', inputValue: '2' },
{
xtype: 'container',
layout: 'hbox',
items: [
{
xtype: 'radio',
boxLabel: 'Other (Please specify)',
name: 'rb',
inputValue: '3'
},
{
xtype: 'splitter'
},
{
xtype: 'textfield',
name: 'option3detail'
}
]
}
]
}
Fiddle with live example: https://fiddle.sencha.com/#fiddle/2kj