How to calculate totals in a grid with the summary function - extjs

I have a grid with two summary positions. I have a summary at the end of the grid. This is working great. But what I want is to calculate the total price per row. I have 4 columns called 'Aantal, Stukprijs,korting and Totaal'. What I need is that in the 'Totaal' column this sum: (Aantal X Stukprijs) - %korting(means discount).
This is the code for that grid:
xtype: 'gridpanel',
id: 'materiaalGrid',
autoScroll: true,
forceFit: true,
store: 'MyArrayStore8',
columns: [
{
xtype: 'rownumberer'
},
{
xtype: 'gridcolumn',
dataIndex: 'naam',
text: 'Naam',
editor: {
xtype: 'combobox'
}
},
{
xtype: 'gridcolumn',
dataIndex: 'type',
text: 'Type'
},
{
xtype: 'numbercolumn',
summaryType: 'sum',
dataIndex: 'gewicht',
text: 'Gewicht'
},
{
xtype: 'numbercolumn',
summaryType: 'sum',
dataIndex: 'aantal',
text: 'Aantal',
editor: {
xtype: 'numberfield'
}
},
{
xtype: 'numbercolumn',
dataIndex: 'stuks',
text: 'Stukprijs'
},
{
xtype: 'numbercolumn',
dataIndex: 'korting',
text: 'Korting',
editor: {
xtype: 'numberfield',
maxValue: 100
}
},
{
xtype: 'numbercolumn',
summaryType: 'sum',
dataIndex: 'stuks',
text: 'Totaal'
},
{
xtype: 'booleancolumn',
dataIndex: 'verkoop',
text: 'Verkoop'
},
{
xtype: 'actioncolumn',
maxWidth: 50,
minWidth: 50,
width: 50,
defaultWidth: 50,
emptyCellText: 'Delete',
menuDisabled: true,
items: [
{
handler: function(view, rowIndex, colIndex, item, e, record, row) {
var selection = me.getView().getSelectionModel().getSelection()[0];
if (selection) {
store.remove(selection);
}
},
altText: 'Delete'
}
]
}
],
viewConfig: {
enableTextSelection: false
},
features: [
{
ftype: 'summary'
}
],
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
})
],
I can only get the sum of aantal and gewicht in the bottom row.

To solve this specific scenario you can try doing this:
For the result of "Aantal X Stukprijs" AKA Quantity X Unit price (thanks God Google translator exists!) you can create a calculated field implementing the convert function on the field declaration, as follows:
{
name: 'total',
type: 'number',
convert: function(value, record) {
if(!value) {
// Only calculate the value if no value set since the
// Calculated total column will fill this field with a real
// value we don't want to mess
value = record.get('price') * record.get('units');
}
return value;
}
}
This will still leave inconsistencies when changing the record value using the inline editor you will need to add an extra handler for that like this:
grid.on('edit', function(editor, e) {
// commit the changes right after editing finished
e.record.set('total'); // force total re-calculation
e.record.commit();
});
You con see a complete example here, hope it helps.

Related

How to dynamically add columns for Grid ExtJs

I want dynamically load columns for grid from loaded store.
I used code like in sencha fiddle https://fiddle.sencha.com/#fiddle/lc5&view/editor, it work, but in modern version it dose not work. Because modern version not have reconfigure method.
How can I solve that problem.
Based on your example, the solution is as follows:
var grid = Ext.create({
xtype: 'grid',
fullscreen: true,
minHeight: 150,
renderTo: document.body,
plugins: {
gridsummaryrow: true
},
store: {
fields: ['student', 'mark'],
idProperty: 'student',
data: [{
"student": 'Student 1',
"mark": 84
}, {
"student": 'Student 2',
"mark": 72
}, {
"student": 'Student 3',
"mark": 96
}, {
"student": 'Student 4',
"mark": 68
}],
proxy: {
type: 'memory'
}
},
columns: [{
dataIndex: 'student',
text: 'Name'
}]
});
grid.getStore().load();
grid.setColumns([{
width: 200,
dataIndex: 'student',
text: 'Name',
summaryType: 'count',
summaryRenderer: function(value){
return Ext.String.format('Number of students: {0}', value);
}
}, {
"dataIndex": 'mark',
"text": 'Mark',
"summaryType": 'average'
}]);
the most important
You must define a column on the grid columns, even though it will be changed at a future time on your grid.
I removed the dependency from your students.json sample file and put the data into an in-memory store to facilitate the demonstration here.
In modern version, you will use setColumns method.
Working Sample on fiddle.
Another option I did is to bind the columns after populating them in the controller.
Sample code:
{
xtype: 'gridpanel',
id: 'user-grid',
cls: 'user-grid',
width: '100%',
scrollable: false,
bind: {
store: '{userStore}',
columns: '{columns}'
}
}
In the controller I populated the columns this way:
setUserGridColumns: function () {
var fields = ['title', 'Surname', 'Profession', 'Age', 'randomValue'];// this can come from server
var columns = [];
fields.forEach(element => {
var column = {
xtype: 'gridcolumn',
cls: 'content-column',
dataIndex: element,
text: element,
flex: 1,
sortable: false,
align: 'center',
style: 'border-width:0px !important; margin-bottom:15px'
}
columns.push(column);
});
this.getViewModel().set('columns', columns);
}

displaying minus in grid extjs. displaying only NOT CHANGE the value to minus

i'm new comer in ext js..
i want to display one of field in grid ext js. the field type is smallint. let's say it "Dayfrom". I want to display DayFrom in Grid like (-3) days in minus without calculate the value. only display in grid.
i have try to for this. but not work
var s = Ext.String.format('<div class="{0}">{1}</div>','-','--');
storePendingApprovalDetail = Ext.create('Ext.data.Store', {
storeId: 'pendingapprovaldetail-store',
model: 'pendingapprovaldetail-model',
sorters: ['DayFrom']
});
gridPendingApprovalDetail = Ext.create('Ext.grid.Panel', {
store: 'pendingapprovaldetail-store',
columns: [{
text: 'Day From',
flex: 1,
renderer: s,
dataIndex: 'DayFrom'
}, {
text: 'Day To',
flex: 1,
dataIndex: 'DayTo'
}, {
text: 'Frequent',
flex: 1,
dataIndex: 'Frequent'
}],
dockedItems: [{
xtype: 'toolbar',
items: [actAddPendingApprovalDetail, actEditPendingApprovalDetail, actDeletePendingApprovalDetail]
}],
listeners: {
}
});
Have you looked at the renderer example at http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.grid.column.Column-cfg-renderer ?
Do you actually know what Ext.String.format does? If not, please read http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.String-method-format
If you had done so, and understood, your code for the renderer would be sth like this:
renderer: function(value){
if(typeof value=="number") return -value;
return value;
}
many thanks buddies... :)
i'm using this and it works
gridPendingApprovalDetail = Ext.create('Ext.grid.Panel', {
store: 'pendingapprovaldetail-store',
columns: [{
text: 'Day From',
flex: 1,
dataIndex: 'DayFrom', renderer: function (value, metaData, record, rowIndex, colIndex, store) {
var returnString = "-" + value;
return returnString;
}
}, {
text: 'Day To',
flex: 1,
dataIndex: 'DayTo'
}, {
text: 'Frequent',
flex: 1,
dataIndex: 'Frequent'
}],
dockedItems: [{
xtype: 'toolbar',
items: [actAddPendingApprovalDetail, actEditPendingApprovalDetail, actDeletePendingApprovalDetail]
}],
listeners: {
}
});

How to Update Total Row in Grid from store in extjs4.1

I have calculated Total Row using SummaryType:sum in Grid View Row. If the user selects combo, I need to display the Total Row value from store. My grid Values are coming from a different store. Can anybody tell me how to do this?
Ext.define('TestGrid.view.GlobalTeamTable1', {
extend: 'Ext.grid.Panel',
alias: 'widget.globalteamtable1',
id:'gridid',
features: [{
ftype: 'summary'
}],
store: Ext.create('TestGrid.store.TestResultStore'),
columns: [{
dataIndex: 'month',
text: 'Month',
summaryRenderer: function(){
return '<b>Totals:</b>';
}
}, {
dataIndex: 'target1',
text: 'Target1',
summaryType: 'sum'
}, {
dataIndex: 'target2',
text: 'Target2',
summaryType: 'sum'
}, {
dataIndex: 'targetDiff',
text: 'Target(2-1)',
summaryType: 'sum'
}, {
dataIndex: 'targetPercent',
text: 'Target%',
summaryType: function(records){
var totals = records.reduce(function(sums, record){
return [sums[0] + record.data.target2,
sums[1] + record.data.targetDiff];
}, [0,0]);
return (totals[0] * totals[1]) / 100;
}
}]
});
Thanks
you could try update store with store.reload...
When I neew update data grid's I try reload the store.

Use MVC to manage grid column events

I have a grid with some columns(combobox columns) which I need to manage their change events. I want to do it from a controller. The goal is to send the server the selected combo id when i need to insert or update the row and update the other columns depending of the value of this selected combo. Could you give me an example how I much do this?
I have 2 hidden columns which must be updated when the Combo Empresa and Camion changes with the id.
This is my grid def:
{
xtype: 'gridpanel',
id: 'grdListaFichaEmbarques',
minWidth: 1024,
autoScroll: true,
title: 'Listado de Fichas',
store: 'ListaFichasTransporte',
plugins: [
Ext.create('Ext.grid.plugin.RowEditing', {
pluginId: 'ListaFEPlugin'
})
],
columns: [
{
xtype: 'numbercolumn',
dataIndex: 'NumEmbarque',
text: 'NumEmbarque'
},
{
xtype: 'gridcolumn',
dataIndex: 'Empresa',
text: 'Empresa',
editor: {
xtype: 'combobox',
allowBlank: false,
displayField: 'Nombre',
hiddenName: 'Id',
store: 'ListaEmpresa',
valueField: 'Id'
}
},
{
xtype: 'gridcolumn',
dataIndex: 'Contacto',
text: 'Contacto'
},
{
xtype: 'gridcolumn',
dataIndex: 'Celular',
text: 'Celular'
},
{
xtype: 'gridcolumn',
dataIndex: 'Placa1',
text: 'Placa1',
editor: {
xtype: 'combobox',
allowBlank: false,
displayField: 'Placa1',
store: 'ListaCamiones',
valueField: 'Id'
}
},
{
xtype: 'gridcolumn',
dataIndex: 'Placa2',
text: 'Placa2'
},
{
xtype: 'gridcolumn',
dataIndex: 'Capacidad',
text: 'Capacidad'
},
{
xtype: 'gridcolumn',
dataIndex: 'Chofer',
text: 'Chofer'
},
{
xtype: 'gridcolumn',
dataIndex: 'Nextel',
text: 'Nextel'
},
{
xtype: 'gridcolumn',
dataIndex: 'CelularPeru',
text: 'CelularPeru'
},
{
xtype: 'gridcolumn',
dataIndex: 'CelularEcuador',
text: 'CelularEcuador'
},
{
xtype: 'gridcolumn',
dataIndex: 'Termoregistro1',
text: 'Termoregistro1'
},
{
xtype: 'gridcolumn',
dataIndex: 'Termoregistro2',
text: 'Termoregistro2'
},
{
xtype: 'gridcolumn',
dataIndex: 'PuntoRecojo',
text: 'PuntoRecojo',
editor: {
xtype: 'combobox',
displayField: 'Nombre',
store: 'ListaOrigenDestino',
valueField: 'Id'
}
},
{
xtype: 'datecolumn',
dataIndex: 'FechaHoraLlegadaOrigen',
text: 'FechaHoraLlegadaOrigen',
editor: {
xtype: 'datefield',
format: 'd/m/Y h:i:s',
submitFormat: 'd/m/Y h:i:s'
}
},
{
xtype: 'datecolumn',
dataIndex: 'FechaHoraDespachoOrigen',
text: 'FechaHoraDespachoOrigen',
editor: {
xtype: 'datefield',
format: 'd/m/Y h:i:s',
submitFormat: 'd/m/Y h:i:s'
}
},
{
xtype: 'datecolumn',
dataIndex: 'FechaHoraLlegadaTumbes',
text: 'FechaHoraLlegadaTumbes',
editor: {
xtype: 'datefield',
format: 'd/m/Y h:i:s',
submitFormat: 'd/m/Y h:i:s'
}
},
{
xtype: 'gridcolumn',
dataIndex: 'PuntoLlegadaEcuador',
text: 'PuntoLlegadaEcuador',
editor: {
xtype: 'combobox',
displayField: 'Nombre',
store: 'ListaOrigenDestino',
valueField: 'Id'
}
},
{
xtype: 'datecolumn',
dataIndex: 'FechaHoraLLegadaDestinoEcuador',
text: 'FechaHoraLLegadaDestinoEcuador',
editor: {
xtype: 'datefield',
format: 'd/m/Y h:i:s',
submitFormat: 'd/m/Y h:i:s'
}
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'IdEmpresa',
text: 'IdEmpresa'
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'IdCamion',
text: 'IdCamion'
}
]
}
This is my Controller:
Ext.define('Fplweb2.controller.FichaEmbarque', {
extend: 'Ext.app.Controller',
refs: [
{
ref: 'GrillaFE',
selector: 'grid[id=grdListaFichaEmbarques]',
xtype: 'Ext.grid.Panel'
}
],
onButtonClick: function(button, e, eOpts) {
this.save();
},
onComboboxSelect: function(combo, records, eOpts) {
var grid = this.getGrillaFE();
var store = grid.getStore();
//HERE I WAS TRYING TO UPDATE THE COLUMNS
if( grid.getSelectionModel().hasSelection() )
{
var row = grid.getSelectionModel().getSelection();
var srow;
for(var i=0; i<store.count(); i++)
{
srow = store.getAt(i);
if(srow.get('NumEmbarque') == row[0].data.NumEmbarque)
{
console.log("ASIGNARA");
srow.IdEmpresa = records[0].data.Id;
srow.Contacto = records[0].data.Contacto;
srow.Celular = records[0].data.Celular;
}
}
}
},
init: function(application) {
this.listen({
controller: {},
component: {
'grid[xtype=gridpanel]': {
edit: this.save,
canceledit: this.cancel
}
});
this.control({
"button[id=btnFichaEmbarqueAgregar]": {
click: this.onButtonClick
},
"combobox[id=cmbGrdListaFichaEmbarquesEmpresa]": {
select: this.onComboboxSelect
}
});
},
save: function() {
var fechaact = new Date();
var grid = this.getGrillaFE();
var plugin = grid.editingPlugin;
var store = grid.getStore();
//SET THE FIRTS COMBO VALUE
//Combo Lista Empresas
var lestore = Ext.data.StoreManager.lookup('ListaEmpresa').getAt(0).get('Nombre');
//Combo Lista Origen - Destino
var odstore = Ext.data.StoreManager.lookup('ListaOrigenDestino').getAt(0).get('Nombre');
//Combo Lista Camiones
var lcstore = Ext.data.StoreManager.lookup('ListaCamiones').getAt(0).get('Placa1');
plugin.cancelEdit();
var r = Ext.create('Fplweb2.model.ListaFichasTransporte', {
NumEmbarque: store.getCount() + 1,
Empresa: lestore,
Contacto: 'Nuevo Contacto',
Celular: '999999999',
Placa1: lcstore,
Placa2: '',
Capacidad: '',
Chofer: 'Nuevo Chofer',
Nextel: '999999999',
CelularPeru: '999999999',
CelularEcuador: '999999999',
Termoregistro1: '',
Termoregistro2: '',
PuntoRecojo: odstore,
FHTranspPuntoRecojo: fechaact,
FHDespaPuntoRecojo: fechaact,
FHLlegadaTumbes: fechaact,
PuntoLlegadaEcuador: odstore,
FHLlegadaPuntoEcuador: fechaact
});
store.insert(0, r);
plugin.startEdit(0, 0);
store.sync();
},
cancel: function(editor, context, eOpts) {
console.log("cancelo");
var grid = this.getGrillaFE();
var plugin = grid.editingPlugin;
var store = grid.getStore();
plugin.cancelEdit();
store.removeAt(0);
if( context.record.phantom ) {
context.store.remove( context.record );
}
}
});
I want to do this FROM a controller.
Thanks in advance...
You need to catch the edit event of the grid (added by the editing plugin):
listeners: {
edit: function(editor, e) {
if (e.field === 'Empresa') {
// do a trip to the server if needed
// or update your column locally
e.record.set('IdCamion', e.value);
}
}
}

container control as a grid editor does not update values

So I have a grid with two columns, the first has just text, the second needs to have a custom control (with a checkbox and a combo box)
Check the screenie:
Here is a link to a screenie:
The Problem:
When I click update to update the row. The first column gets updated, but the second column doesn't
I naively added a getValue() into my custom control but no luck!! (Note: I'm using row editing plugin)
Here is my code:
Ext.define('MainGrid', {
extend: 'Ext.grid.Panel',
//defs for all the toolbars and buttons
plugins: [rowEditing],
columns: [
{
xtype: 'rownumberer'
},
{
xtype: 'gridcolumn',
text: 'Column Titles',
dataIndex: 'ColumnTitle',
editor: {
xtype: 'textfield',
}
},
{
xtype: 'gridcolumn',
sortable: false,
align: 'center',
dataIndex: 'IssueCondition',
editor: {
xtype: 'reportpopulation'
}]
});
The reportpopulation is the custom control here. Here is the code for it:
Ext.define('SelectPopulation', {
extend: 'Ext.container.Container',
itemId: 'ctrSelectpopulation',
alias: 'widget.reportpopulation',
layout: {
type: 'hbox'
},
initComponent: function () {
//code to add combo box and checkbox snipped
....
},
getValue: function () {
//This doesn't work!
return "Booo";
}
});
So clicking Update doesn't :
Is there something I'm missing?
Should I inherit from FieldBase? Can I use multiple controls and create something like the screenie with FieldBase?
This works, even your getValue() was working, the problem is that you used a custom type value on that grid column (IssueCondition) and did not specified any renderer for it, try something like this:
Ext.define('MainGrid', {
extend: 'Ext.grid.Panel',
height: 300,
plugins: [Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 1
})],
columns: [{
xtype: 'rownumberer'
}, {
xtype: 'gridcolumn',
text: 'Column Titles',
dataIndex: 'ColumnTitle',
editor: {
xtype: 'textfield'
}
}, {
xtype: 'gridcolumn',
sortable: false,
text: "Issue Condition",
align: 'center',
dataIndex: 'IssueCondition',
width: 200,
editor: {
xtype: 'reportpopulation'
},
renderer: function (v, attr, rec) {
console.info(arguments);
return 'cb: ' + rec.data.IssueCondition.cb + ' combo: ' + rec.data.IssueCondition.combo;
}
}],
store: Ext.create("Ext.data.Store", {
fields: ["ColumnTitle", "IssueCondition"],
proxy: {
type: "memory",
reader: {
type: "json"
}
}
})
});
Ext.define('SelectPopulation', {
extend: 'Ext.container.Container',
itemId: 'ctrSelectpopulation',
alias: 'widget.reportpopulation',
layout: {
type: 'hbox'
},
initComponent: function () {
Ext.apply(this, {
items: [{
xtype: "checkbox"
}, {
xtype: "combobox",
allowBlank: false,
store: [
[0, 'Zero'],
[1, 'One'],
[2, 'Two']
]
}]
});
this.callParent(arguments);
},
getValue: function () {
return {
cb: this.child('checkbox').getValue(),
combo: this.child('combobox').getValue()
};
}
});
Be aware that this is just an example.
Check the Fiddle here
Hope this helps.

Resources