Simple question here: I have a working grid with expanding rows within my Ext JS application. Boom.
Currently I have html elements inside of my expanded row (it's just one big div), but that seems to be all the expanded row is capable of displaying.
Is there anyway to render Ext components inside of my expanded rows?
Cheers mates, upvotes await!
You can just render components into the row expanders element.
var grid = Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
plugins: {
ptype: 'rowexpander',
rowBodyTpl : [
'<div class="row-expander-ct"></div>'
]
},
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" }
]
},
columns: [
{ text: 'Name', dataIndex: 'name' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone' }
],
height: 300,
width: 400,
renderTo: Ext.getBody()
});
grid.store.on({
// Delay the execution of the listener because the grid view will also
// react to this event, and we want the rows to be rendered before we
// modify them...
delay: 1,
load: function() {
Ext.each(grid.el.query('.row-expander-ct'), function(ct) {
Ext.widget('textfield', {
renderTo: ct
,fieldLabel: "Label"
,width: '100%'
});
});
}
});
grid.store.load();
Related
How can I prevent qtip from showing on grid cells with "large" data that does not fit inside its width? (on ExtJS 6.5.2 - Modern Toolkit)
Example
Add this to a sencha fiddle:
Ext.application({
name : 'Fiddle',
launch : function() {
var store = Ext.create('Ext.data.Store', {
fields: ['name', 'email', 'phone'],
data: [
{ 'name': 'Lisaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', "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: 'Simpsons',
store: store,
columns: [
{
text: 'Name',
dataIndex: 'name',
minWidth: 200,
//flex: 1,
//cellWrap: true,
cell: {
bodyStyle: {
whiteSpace: 'normal'
}
}
},
{ text: 'Email', dataIndex: 'email', flex: 2, minWidth: 250 },
{ text: 'Phone', dataIndex: 'phone', flex: 1, minWidth: 120 }
],
//height: 200,
//layout: 'fit',
fullscreen: true
});
}
});
Grid without tooltip
Default wrapping behaviour but no tooltip, demo: https://fiddle.sencha.com/#view/editor&fiddle/29ii
Grid with wrapping capabilities
Demo: https://fiddle.sencha.com/#view/editor&fiddle/29if
In short you need to set these rules to wrap content:
white-space: normal;
word-break: break-word;
And set grid's "variableHeights" to true: http://docs.sencha.com/extjs/6.5.1/modern/Ext.grid.Grid.html#cfg-variableHeights
Note: in the fiddle the CSS rules are applied using grid's "cls" config param, and styles are placed inside index.html
I am using a grid with a checkbox and a combobox. Right now I am trying to find a way to make the combobox multi select if the checkbox is checked in roweditor.
var pEditing =
Ext.create('Ext.grid.plugin.RowEditing',
{
clicksToMoveEditor: 2,
errorSummary: false,
autoCancel: false,
listeners:
{
change: function (newValue, oldValue, eOpts)
{
if (newValue.value == true)
{
this.down().down('grid').queryById('comboboxColumn').multiSelect = true;
}
else
{
this.down().down('grid').queryById('comboboxColumn').multiSelect = false;
}
console.log("Checkbox Change Debug");
}
}
});
Grid creation code :
{
renderer: renderCheckbox,
itemId: 'checkboxColumn',
header: 'Checkbox',
width: 100,
sortable: false,
dataIndex: 'ddCheckbox',
editor: {
xtype: 'checkbox',
cls: 'x-grid-checkheader-editor',
listeners:{
change: function (newValue, oldValue, eOpts) {
pEditing.fireEvent('change',newValue, oldValue, eOpts);
}
},
},
},
{
header: 'Speed',
dataIndex: 'ddSpeed',
itemId: 'comboBoxColumn',
width: 125,
editor:
{
xtype: 'combo',
editable: false,
multiSelect: false,
store:
[
['1', '1'],
['2', '2'],
['3', '3'],
['4', '4'],
['5', '5']
]
}
}
Right now the event is firing off and I can see the debug message printed to the log. However the multiselect property is not persisting after the event is fired. Is there any easy way to change the property of this combobox in the row? For example, if there are 3 rows in the grid, row one can have the checkbox checked, and multiple values selected while row two has the checkbox unchecked and only one selection can be made? I know I can find the index of the checkbox selected by using in the change function.
this.down().down('grid').getSelectionModel().getSelection()[0].getData()
Thanks
"multiselect" property is not persisting because, your below code is not yet reach till combo box control.
this.down().down('grid').queryById('comboboxColumn').multiSelect = true;
As per your code, combo box control is under 'comboBoxColumn' item. So specify "itemID" for combo box like
xtype: 'combo',
editable: false,
multiSelect: false,
itemId: 'comboBoxItems',
store:[....]
Then, try below code
this.down().down('grid').queryById('comboboxColumn').queryById('comboBoxItems').multiSelect = true;
As you using RowEditing plugin
In checkbox on value change event you will get 4 parameters change:function(field, newValue, oldValue, eOpts)
1) Usign field parameter you will get your selected row(roweditor) like this field.up().
2) Using this roweditor you can use roweditor.down() method and get your combo.
3) After that getting your component(combo) and using second parameter newValue you can set multiSelect like combo.multiSelect = newValue
Here is I have created an sencha fiddle demo.
Hope this will help you to achieve your solution or requirement
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
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: 'homer#simpsons.com',
phone: '555-222-1244'
}, {
name: 'Marge',
email: 'marge#simpsons.com',
phone: '555-222-1254'
}]
});
// 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.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [{
header: 'Name',
dataIndex: 'name',
editor: 'textfield'
}, {
header: 'Email',
dataIndex: 'email',
flex: 1,
editor: {
xtype: 'combobox',
allowBlank: false
}
}, {
header: 'Multiple',
dataIndex: 'multiple',
sortable:false,
menuDisabled:true,
flex: 0.5,
editor: {
xtype: 'checkboxfield',
// checked:true,
listeners: {
change: function (field, newValue) {
var combo = field.up().down('#state');
combo.reset();
combo.multiSelect = newValue
}
}
}
}, {
header: 'States',
dataIndex: 'states',
flex: 1,
editor: {
xtype: 'combo',
store: states,
itemId: 'state',
queryMode: 'local',
displayField: 'name',
multiSelect:true,
valueField: 'abbr',
filterPickList: false,
listeners:{
afterrender:function(){
this.multiSelect=false;
}
}
}
}],
selModel: 'rowmodel',
plugins: {
ptype: 'rowediting',
clicksToEdit:1
},
height: 200,
width: '100%',
renderTo: Ext.getBody()
});
I'm working on an ExtJS 6.2 project. I need to perform some operations when the columns in a grid a resized. I think the correct event to do so is columnresize. The problem is, since the columns are being loaded from a database dynamically, this event is fired every time a new column is added to the grid, and I would like to prevent it. I mean, I need this event to be fired only when every column is loaded.
I've tried to set a flag (named lFirstInit) that would be false once the columns are loaded form database, but the columnresize event keeps on being fired from the start.
How could I approach this, please? Thanks.
View:
Ext.define('App.view.TMainBrowseGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.TMainBrowseGrid',
requires: [
'App.view.TMainBrowseGridViewModel',
'App.view.override.TMainBrowseGrid',
'Ext.view.Table',
'Ext.grid.column.RowNumberer',
'App.view.TMainBrowseGridViewController'
],
controller: 'TMainBrowseGrid',
config: {
oParent: null,
cBrwName: '',
cCodForm: ''
},
viewModel: {
type: 'TMainBrowseGrid'
},
flex: 1,
columns: [
{
xtype: 'rownumberer',
itemId: 'oColRowNum'
}
],
listeners: {
columnresize: 'onGridpanelColumnResize',
}
});
Controller
Ext.define('App.view.TMainBrowseGridViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.TMainBrowseGrid',
onGridpanelColumnResize: function (component, column, width, eOpts) {
// THINGS TO DO...
}
});
We have finally discarded the 'columnresize' approach. We thought it is more reliable performing thos operations when clicking on a 'Close' button. However, I would like to thank you for your suggestions, especially the person who posted the answer below, and later removed it before I could mark it as the chosen answer. This was the code he/she posted:
Ext.create('Ext.data.Store', {
storeId: 'simpsonsStore',
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: 'homer#simpsons.com',
phone: '555-222-1244'
}, {
name: 'Marge',
email: 'marge#simpsons.com',
phone: '555-222-1254'
}]
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'phone'
}],
height: 200,
width: 400,
renderTo: Ext.getBody(),
listeners: {
columnresize: function(ct, column, width, eOpts){
if(ct.containsFocus){// It will true when we resize column.
alert('resize');
console.log(`${column.text} Column resized`);
}
}
}
});
I have a grid with a column like this:
{ text: 'Name', dataIndex: 'Name', editor: 'rallytextfield', flex: 2.5, sortable: false },
When I fill in information in the text field and then click somewhere else, the data is saved; however, when I hit return or tab like in a Custom Grid, nothing happens. What can I configure to allow me to return away from this field and so get the value to save without clicking?
EDITED: It turns out that it's to do with adding checkboxes. If I add a selModel, the return doesn't work. If I take it away, the return works! Here's the full app:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
var store = Ext.create('Rally.data.custom.Store', {
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" }
]
});
this.add( Ext.create('Rally.ui.grid.Grid', {
title: 'Simpsons',
store: store,
columnCfgs: [
{ text: 'Name', dataIndex: 'name', editor: 'rallytextfield' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone', editor: 'textfield' }
],
height: 200,
width: 400,
selType: 'checkboxmodel',
selModel: {
injectCheckbox: 1,
mode: 'SIMPLE'
}
}) );
}
});
Commenting out selType & selModel and I can hit return to go from one row to the next, but with the selType & selModel in there, no return but tab does work.
The Return/Tab inline edit navigation should be built-in without any additional configuration. When I try to repro the issue the first thing I run into is this:
App works as desired in debug mode but crashes in Rally environment
That may be the root cause since the app is likely just refreshing once the field is edited.
My working column config on my gridConfig looks like this:
columnCfgs: [
'FormattedID',
{
text: 'Name',
dataIndex: 'Name',
editor: 'rallytextfield',
flex: 2.5,
sortable: false
},
'Owner'
],
I am new to ExtJS and I encountered a similar problem from Sencha forum which was left unsolved.
This is the link to the problem
Basically, What I want to do is open a desktop window module app displaying the data selected on the grid. I already created the same window displayed on the link. We have quite the same code so I think there's no sense on posting my code here. Any help will be appreciated. Thank you.
I don't think you are right about the code thing... But anyway, the code of this guy is a mess and mitchel already answered how it should be done. So forget about the code of the guy for a second, cause it is really simple to archive this.
Here's a working snipped how you can do this:
Ext.define('Ext.ux.DemoWin', {
extend: 'Ext.window.Window',
alias: 'widget.demowin',
width: 200,
height: 200,
title: 'demo',
initComponent: function() {
this.callParent(arguments);
},
loadRecord: function(rec) {
// simplified - just update the html. May be replaced with a dataview
this.update(rec.data.name + ' - ' + rec.data.email);
}
});
Ext.create('Ext.data.Store', {
storeId:'simpsonsStore',
fields:['name', 'email', 'phone'],
data:{'items':[
{ '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" }
]},
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'items'
}
}
});
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [
{ text: 'Name', dataIndex: 'name' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone' }
],
height: 200,
width: 400,
renderTo: Ext.getBody(),
listeners: {
// the registration should be done with the control() method of the responsible controller
itemclick: function(grid,record) {
var win = Ext.widget('demowin').show().loadRecord(record);
}
}
});
And here's a JSFiddle
Edit which applies to Ext.ux.desktop.Module
createWindow : function(){
var desktop = this.app.getDesktop();
var win = desktop.getWindow('grid-win');
if(!win){
win = desktop.createWindow({
// ...
loadRecord: function(rec) {
this.update(rec.data.name + ' - ' + rec.data.email);
}
//....