Ext js 7 modern grid plugin RowExpander only certain rows - extjs

I'm trien to use the RowExpander plugin for Ext js 7 modern grid.
I need the RowExpander only on a few rows, not on all.
I'm not sure how to achieve this, I searched for some examples but they are all for ext js 4.
I tried overriding
applyColumn: function(column, oldColumn) {
console.log('override applyColumn:');
console.log(column);
return Ext.factory(Ext.apply({}, column), null, oldColumn);
},
updateGrid: function(grid) {
var me = this;
console.log('override test:');
console.log(grid);
if (grid) {
grid.hasRowExpander = true;
grid.addCls(Ext.baseCSSPrefix + 'has-rowexpander');
me.colInstance = grid.registerColumn(me.getColumn());
grid.refreshScrollerSize();
grid.element.on({
tap: 'onGridTap',
delegate: me.expanderSelector,
scope: me
});
}
},
But i cant "hook into a single row" when data is there.
Looking for something like this but for ext js 7 modern grid:
How can I get the ExtJs RowExpander to only show the icon ([+]) on certain rows?

You can bind the 'hidden', something like this:
Ext.define('Ext.grid.plugin.CustomRowExpander', {
extend: 'Ext.plugin.Abstract',
requires: [
'Ext.grid.cell.Expander'
],
alias: 'plugin.customrowexpander',
config: {
grid: null,
column: {
weight: -1100,
xtype: 'gridcolumn',
align: 'center',
text: '',
width: 50,
resizable: false,
hideable: false,
sortable: false,
editable: false,
ignore: true,
ignoreExport: true,
cell: {
xtype: 'expandercell',
hideMode: 'opacity',
bind: {
hidden: '{record.expandable}'
}
},
menuDisabled: true
}
},
expanderSelector: '.' + Ext.baseCSSPrefix + 'expandercell .' + Ext.baseCSSPrefix + 'icon-el',
init: function (grid) {
grid.setVariableHeights(true);
this.setGrid(grid);
},
destroy: function () {
var grid = this.getGrid(),
col = this.colInstance;
if (col && !grid.destroying) {
grid.unregisterColumn(col, true);
}
this.callParent();
},
applyColumn: function (column, oldColumn) {
return Ext.factory(Ext.apply({}, column), null, oldColumn);
},
updateGrid: function (grid) {
var me = this;
if (grid) {
grid.hasRowExpander = true;
grid.addCls(Ext.baseCSSPrefix + 'has-rowexpander');
me.colInstance = grid.registerColumn(me.getColumn());
grid.refreshScrollerSize();
grid.element.on({
tap: 'onGridTap',
delegate: me.expanderSelector,
scope: me
});
}
},
onGridTap: function (e) {
var cell = Ext.Component.from(e),
row = cell.row;
// May have tapped on a descendant grid row. We're only interested in our own.
if (row.getGrid() === this.getGrid()) {
row.toggleCollapsed();
}
}
});
Ext.application({
name: 'Fiddle',
launch: function () {
var store = Ext.create('Ext.data.Store', {
fields: ['fname', 'lname', 'talent', 'powers'],
data: [{
'fname': 'Barry',
'lname': 'Allen',
'talent': 'Speedster',
'expandable': true
}, {
'fname': 'Oliver',
'lname': 'Queen',
'talent': 'Archery',
'expandable': false
}, {
'fname': 'Kara',
'lname': 'Zor-El',
'talent': 'All',
'expandable': true
}, {
'fname': 'Helena',
'lname': 'Bertinelli',
'talent': 'Weapons Expert',
'expandable': false
}, {
'fname': 'Hal',
'lname': 'Jordan',
'talent': 'Willpower',
'expandable': true
}, ]
});
Ext.create('Ext.grid.Grid', {
title: 'DC Personnel',
store: store,
plugins: {
customrowexpander: true
},
itemConfig: {
viewModel: true,
body: {
tpl: '<div>Lorem ipsum dolor sit amet, consetetur sadipscing elitr..</div>'
}
},
columns: [{
text: 'First Name',
dataIndex: 'fname',
flex: 1
}, {
text: 'Last Name',
dataIndex: 'lname',
flex: 1
}, {
text: 'Talent',
dataIndex: 'talent',
flex: 1
}],
height: 400,
layout: 'fit',
fullscreen: true
});
}
});

Related

Deleting the row is not updating the grid? Sencha Extjs Application

When I delete any current row, the next row and pagination has to get updated in the empty row. But it is not updating the pagination but the url is passing in network correctly. When I refresh the page, the empty row is replaced by the next row.
List.js:
/**
* This view is an example list of people.
*/
Ext.define('CRUD.view.main.List', {
extend: 'Ext.grid.Panel',
xtype: 'home',
requires: [
'CRUD.store.Personnel',
'CRUD.view.main.MainController',
'Ext.toolbar.Paging',
],
title: 'Heroes',
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})
],
layout: 'fit',
fullscreen: true,
store: {
type: 'personnel',
},
selModel: {
pruneRemoved: false
},
selType: 'cellmodel',
columns: [{
text: 'Name',
align: 'center',
dataIndex: 'name',
sortable: true,
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
allowBlank: false
}
},
{
text: 'Email',
align: 'center',
dataIndex: 'email',
sortable: true,
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
allowBlank: false
}
},
{
text: 'Phone',
align: 'center',
dataIndex: 'phone',
sortable: true,
flex: 1,
editor: {
xtype: 'textfield',
selectOnFocus: true,
allowBlank: false
}
},
{
text: 'Save',
align: 'center',
xtype: 'actioncolumn',
items: [{
icon: 'http://icons.iconarchive.com/icons/oxygen-icons.org/oxygen/128/Actions-document-edit-icon.png',
xtype: 'submit',
handler: function(grid, rowIndex, colIndex, item, e, record) {
Ext.Msg.confirm("Confirmation", "Do you want to Save?", function(btnText) {
if (btnText === "yes") {
Ext.Ajax.request({
url: 'http://localhost:8080/edit?id=' + record.data.id + '&name=' + record.data.name + '&email=' + record.data.email + '&phone=' + record.data.phone,
method: 'POST', //this is the url where the form gets submitted
useDefaultXhrHeader: false,
success: function(response) {
store.load()
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action);
}
});
}
});
}
}],
}, {
text: 'Delete',
xtype: 'actioncolumn',
align: 'center',
items: [{
icon: 'http://www.freeiconspng.com/uploads/delete-button-png-27.png',
xtype: 'submit',
// handler: function(grid, rowIndex, colIndex, item, e, record) {
// console.log(record.data.id)
// // Ext.Msg.confirm('Confirmation', 'Are you sure?', function(btnText) {
// // if (btnText === 'yes') {
// // Ext.Ajax.request({
// // url: 'http://localhost:8080/del/' + record.data.id,
// // method: 'DELETE', //this is the url where the form gets submitted
// // useDefaultXhrHeader: false,
// // cors: true,
// // success: function(form, action) {
// // store.load()
// // },
// // failure: function(form, action) {
// // Ext.Msg.alert('Failed', action);
// // }
// // });
// // }
// // })
// }
}],
listeners: {
click: 'onDeleteClick'
}
}
],
bbar: Ext.create('Ext.PagingToolbar', {
xtype: 'pagingtoolbar',
displayInfo: true,
doRefresh: function() {
this.doLoad(this.cursor);
},
}),
// columns: [
// { text: 'Name', dataIndex: 'name', flex: 1 },
// { text: 'Email', dataIndex: 'email', flex: 1 },
// { text: 'Phone', dataIndex: 'phone', flex: 1 }
// ],
// listeners: {
// select: 'onItemSelected',
// },
});
Store:
Ext.define('CRUD.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
model: 'CRUD.model.User',
fields: [
'name', 'email', 'phone'
],
// data: [
// { name: 'Jean Luc', email: "jeanluc.picard#enterprise.com", phone: "555-111-1111" },
// { name: 'Worf', email: "worf.moghsson#enterprise.com", phone: "555-222-2222" },
// { name: 'Deanna', email: "deanna.troi#enterprise.com", phone: "555-333-3333" },
// { name: 'Data', email: "mr.data#enterprise.com", phone: "555-444-4444" }
// ],
autoLoad: { offset: 0, limit: 5 },
pageSize: 5,
proxy: {
type: 'ajax', //cross domain calls - json parser
enablePaging: true,
url: 'http://localhost:8080/list',
useDefaultXhrHeader: false,
startParam: 'offset',
limitParam: 'limit',
reader: {
totalProperty: 'total',
rootProperty: 'items'
},
listeners: {
//this is used to construct the proxy url before the load is done
// beforeload: {
// fn: function() {
// var me = this;
// me.updateProxyURL(); //write this function yourself
// }
// }
}
},
// proxy: {
// type: 'memory',
// reader: {
// type: 'json',
// }
// },
});
Controller.js
/**
* This class is the controller for the main view for the application. It is specified as
* the "controller" of the Main view class.
*
* TODO - Replace this content of this view to suite the needs of your application.
*/
Ext.define('CRUD.view.main.MainController', {
extend: 'Ext.app.ViewController',
alias: 'controller.main',
store: {
type: 'personnel',
},
onClick: function(grid) {
Ext.Msg.alert("tesdt")
},
onDeleteClick: function(selModel, record, index, options, grid, store) {
//Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
Ext.Msg.confirm({
title: 'Confirm',
msg: 'Are you sure?',
buttons: Ext.Msg.OKCANCEL,
fn: this.onConfirm,
icon: Ext.MessageBox.QUESTION,
config: {
grid: grid,
action: 'del',
store: store
}
});
},
onConfirm: function(btn, text, opt) {
console.log(opt.config.action)
if (btn === 'ok') {
//
opt.config.grid.item.remove();
Ext.Ajax.request({
url: 'http://localhost:8080/' + opt.config.action + '/' + opt.config.grid.record.data.id,
// method: 'DELETE', //this is the url where the form gets submitted
useDefaultXhrHeader: false,
success: function(form, action) {
opt.config.store.load({
start: 0,
limit: 5
})
},
failure: function(form, action) {
},
listeners: {
doRefresh: function() {
this.doLoad(this.cursor);
},
}
});
}
}
});
Please find the screenshot here
Doing grid.getStore().reload() should be sufficient.
BTW. The doRefresh listener is weird. Are you sure you wanted this as Ext.Ajax.request config? This doesn't make sense to me.

How to create a Form for each row in a grid panel:extjs

How do i create a different form for each row in the Grid...
i have a grid like ..
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()
});
Your question doesn't explain your problem very well. Please update your topic and question. As I understood from your question, yes, you can. There are couple of ways. One of them is putting a form into a grid cell using grid column renderer. Another way is using editor in grid column. The second way is easy, but it's not proper way. If you want the second way also, I can add it. So, I'll add an efficient one. Please check the code below and fiddle:
https://fiddle.sencha.com/#fiddle/11i5
Ext.define('UploadForm', {
extend: 'Ext.form.Panel',
width: 200,
frame: true,
items: [{
xtype: 'filefield',
name: 'photo',
msgTarget: 'side',
allowBlank: false,
buttonText: 'Select'
}],
buttons: [{
text: 'Upload',
handler: function() {
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
url: 'photo-upload.php',
waitMsg: 'Uploading your photo...',
success: function(fp, o) {
Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
}
});
}
}
}],
initComponent: function () {
if (this.delayedRenderTo) {
this.delayRender();
}
this.callParent();
},
delayRender: function () {
Ext.TaskManager.start({
scope: this,
interval: 200,
run: function () {
var container = Ext.fly(this.delayedRenderTo);
if (container) {
this.render(container);
return false;
} else {
return true;
}
}
});
}
});
var store = Ext.create('Ext.data.Store', {
fields: ['Name', 'Phone', 'Email', 'filePath'],
data: [{
Name: 'Rick',
Phone: '23122123',
Email: 'something#mail.com',
filePath: '/home'
}, {
Name: 'Jane',
Phone: '32132183',
Email: 'some#thing.com',
filePath: '/home'
}]
});
var renderTree = function(value, meta, record) {
var me = this;
var container_id = Ext.id(),
container = '<div id="' + container_id + '"></div>';
Ext.create('UploadForm', {
delayedRenderTo: container_id
});
return container;
}
Ext.create('Ext.grid.Panel', {
title: 'Simpsons',
store: store,
columns: [
{ text: 'Name', dataIndex: 'Name' },
{ text: 'Email', dataIndex: 'Email' },
{ text: 'Phone', dataIndex: 'Phone' },
{ text: 'Upload',
dataIndex: 'filePath',
width: 300,
renderer: renderTree
}
],
renderTo: Ext.getBody()
});
P.s. Its based from Render dynamic components in ExtJS 4 GridPanel Column with Ext.create

ExtJS5 Web Desktop Sample: Unable to fire event from controller

I have been working with web desktop example in ExtJS5. The example has static data and no events. I wanted to implement a click event on 'Remove Something' button on grid window. Here is my modified code:
Ext.define('SampleApp.view.main.GridWindow', {
extend: 'Ext.ux.desktop.Module',
requires: [
'Ext.data.ArrayStore',
'Ext.util.Format',
'Ext.grid.Panel',
'Ext.grid.RowNumberer'
],
init: function () {
this.launcher = {
text: 'Grid Window',
iconCls: 'icon-grid'
};
},
controller: 'gridwindow',
createWindow: function () {
var desktop = this.app.getDesktop();
var win = desktop.getWindow('grid-win');
if (!win) {
win = desktop.createWindow({
id: 'grid-win',
title: 'Grid Window',
width: 740,
height: 480,
iconCls: 'icon-grid',
animCollapse: false,
constrainHeader: true,
layout: 'fit',
items: [
{
border: false,
xtype: 'grid',
store: mock.view.main.GridWindow.getDummyData(),
columns: [{ xtype: 'rownumberer', sortable: false, text: "S.N.", width: 70 }, {
id: 'topic',
text: "Topic",
dataIndex: 'gridTopic',
flex: 1,
align: 'center'
}, {
text: "Author",
dataIndex: 'gridAuthor',
flex: 1,
align: 'center',
sortable: true
}, {
text: "Replies",
dataIndex: 'gridReplies',
align: 'center',
flex: 1,
sortable: true
}, {
id: 'last',
text: "Last Post",
dataIndex: 'gridLastPost',
flex: 1,
align: 'center',
sortable: true
}]
}
],
tbar: [{
text: 'Add Something',
tooltip: 'Add a new row',
iconCls: 'add'
}, '-', {
text: 'Options',
tooltip: 'Modify options',
iconCls: 'option'
}, '-', {
text: 'Remove Something',
tooltip: 'Remove the selected item',
iconCls: 'remove',
listeners: {
click: 'onDeleteClick'
}
}]
});
}
return win;
},
statics: {
getDummyData: function () {
var _store = Ext.create('Ext.data.Store', {
fields: [
{ name: 'gridId', type: 'int' },
{ name: 'gridTopic', type: 'string' },
{ name: 'gridAuthor', type: 'string' },
{ name: 'gridReplies', type: 'string' },
{
name: 'gridLastPost', type: 'date', convert: function (value) {
var _date = new Date(value);
return Ext.Date.format(_date, "Y-m-d H:i:s");
}
}
]
});
var _responseText;
Ext.Ajax.request({
async: false,
url: 'http://localhost/sampleapp/getusers',
method: 'GET',
success: function (resp) {
_responseText = Ext.decode(resp.responseText);
_store.loadData(_responseText);
}
});
return _store;
}
}
});
I am unable to handle 'onDeleteClick' event inside the controller. Here is the controller definition:
Ext.define('SampleApp.view.main.GridWindowController', {
extend: 'Ext.app.ViewController',
alias: 'controller.gridwindow',
onDeleteClick: function (button, evt) {
alert('Clicked');
}
});
Can someone point out the mistake. How can this event be handled?
Ext.ux.desktop.Module does not accept controller config option.
Use your controller on an Ext.Component — in your case either the grid or the window.

rally set default value for combo box

I have a combobox for State that successfully filters in Rally. The code below works. I want to add an enhancement and have the combobox default to 'In Progress'. I added defaultValue but it has no effect. Thanks for your help.
Rally.onReady(function() {
Ext.define('Rally.example.CustomStoreGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Ext.create('Rally.data.wsapi.Store', {
model: 'defect',
autoLoad: true,
limit: 1000,
pageSize: 1000,
listeners: {
load: this._onDataLoaded,
scope: this
},
fetch: ['FormattedID', 'Name', 'Severity', 'State', 'InProgressDate', 'c_PlannedDeliveryVersion']
});
},
_onSelect: function() {
var grid = this.down('rallygrid'), store = grid.getStore();
store.clearFilter(true);
store.filter(this._getStateFilter());
},
_getStateFilter: function() {
return {
property: 'State',
operator: '=',
defaultValue: 'In Progress',
value: this.down('#priorityComboBox').getValue()
};
},
_onDataLoaded: function(store, data) {
var records = _.map(data, function(record) {
//Perform custom actions with the data here
//Calculations, etc.
return Ext.apply({
// Age: Math.round(((new Date() - record.get('InProgressDate')) / 86400000) * 10) / 10;
}, record.getData());
});
this.add({
xtype: 'rallyfieldvaluecombobox',
itemId: 'priorityComboBox',
fieldLabel: 'Filter by State:',
model: 'defect',
// multiSelect: true,
field: 'State',
listeners: {
select: this._onSelect,
// ready: this._onLoad,
scope: this
}
});
this.add({
xtype: 'rallygrid',
showPagingToolbar: false,
showRowActionsColumn: false,
editable: false,
store: Ext.create('Rally.data.custom.Store', {
limit: 1000,
pageSize: 1000,
data: records
}),
columnCfgs: [
{
xtype: 'templatecolumn',
text: 'ID',
dataIndex: 'FormattedID',
width: 100,
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1
},
{
text: 'Severity',
dataIndex: 'Severity'
},
{
text: 'State',
dataIndex: 'State'
},
{
text: 'Planned Delivery Version',
dataIndex: 'c_PlannedDeliveryVersion',
flex: 0.25
},
{
text: 'In Progress Date',
dataIndex: 'InProgressDate',
xtype: 'datecolumn',
format:'Y-m-d'
},
{
text: 'Age',
dataIndex: 'InProgressDate'
,
renderer: function(value) {
return Math.round(((new Date() - value) / 86400000) * 10) / 10;
}
}
]
});
}
});
Rally.launchApp('Rally.example.CustomStoreGrid', {
name: 'Custom Store Grid Example'
});
});
Using value config property sets the default value:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
items:{ html:'App SDK 2.0rc3 Docs'},
launch: function() {
this.add({
xtype: 'rallyfieldvaluecombobox',
model: 'UserStory',
field: 'ScheduleState',
value: 'In-Progress'
});
}
});

Live Search on Grid --ExtJs

I am new to ExtJs, and i am playing around to build logic to perform "live search" on Grid columns.
From the code below i am able to populate data into the grid but cannot make live search functionality. i am not sure where i am missing the logic.
Ext.define('abc.view.EmployeePanel', {
extend: 'Ext.window.Window',
alias: 'widget.EmployeePanel',
requires: [
'Ext.tab.Panel',
'Ext.form.*'],
constructor: function () {
this.callParent(arguments);
},
this. employeePopUPGridStore = new Ext.data.ArrayStore({
fields: [
{
name: 'empid',
type: 'number'
},
{
name: 'fname',
type: 'string'
},
{
name: 'lname',
type: 'string'
},
],
});
this.employeePopUPGridStore.loadData(localAr, false);
this.down('#addempgrid').bindStore(this.employeePopUPGridStore);
this.down('#addempgrid').getView().refresh();
},
items: [{
xtype:'textfield',
name:'search',
itemId:'search',
emptyText:'Search by First Name / Last Name',
listeners: {
onTextFieldChange: function(field, newValue, oldValue, eOpts){
var grid = field.down('addempgrid');
grid.store.clearFilter();
if (newValue) {
var matcher = new RegExp(Ext.String.escapeRegex(newValue), "i");
grid.store.filter({
filterFn: function(item) {
return matcher.test(item.get('empid')) ||
matcher.test(item.get('fname')) ||
matcher.test(item.get('job'));
}
});
}
}
}
},
{
xtype: 'gridpanel',
itemId: 'addempgrid',
autoHeight: true,
columns: [
{
header: "Employee ID",
flex: 1,
dataIndex: 'empid',
},
{
header: "Full Name",
flex: 3,
dataIndex: 'fname'
},
{
header: "LastName",
flex: 1,
dataIndex: 'lname'
},
]
}
] }
});
Any help around is much appreciated.
Hi Please try this way once..
{
xtype: 'textfield',
itemId: 'searchBar',
cls: 'search-bar',
width: 230,
margin: '0 0 0 10',
listeners: {
buffer: 250,
scope: this,
change: function (field, newVal) {
var grid = field.down('addempgrid');
grid.store.clearFilter();
if (newValue) {
var matcher = new RegExp(Ext.String.escapeRegex(newValue), "i");
grid.store.filter({
filterFn: function(item) {
return matcher.test(item.get('empid')) ||
matcher.test(item.get('fname')) ||
matcher.test(item.get('job'));
}
});
}
}
}
}
Hope it helps you

Resources