Related
I am new to ExtJS.
I have 2 datecolumns I would like to be in UTC format. To do that, I use (from the web) :
renderer: function (value) {
return moment.utc(value).format('YYYY-MM-DD HH:mm:ssZZ');
},
The 2 datecolumns are defined like this :
..., {
xtype: 'datecolumn',
header: 'Start Date',
dataIndex: 'start_date',
flex: 1,
editor: {
xtype: 'datetimefield',
itemId: 'startdt',
allowBlank: false,
format: 'd/m/Y H:i:s',
},
renderer: function (value) {
return moment.utc(value).format('YYYY-MM-DD HH:mm:ssZZ');
},
},
{
xtype: 'datecolumn',
header: 'End Date',
dataIndex: 'end_date',
flex: 1,
editor: {
xtype: 'datetimefield',
itemId: 'enddt',
allowBlank: false,
format: 'd/m/Y H:i:s',
},
renderer: function (value) {
return moment.utc(value).format('YYYY-MM-DD HH:mm:ssZZ');
},
},...
For the model :
Ext.define('xxxxx.model.Deployment', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int',
persist: true
}, {
name: 'name',
type: 'string'
}, {
name: 'start_date',
type: 'date',
}, {
name: 'end_date',
type: 'date'
}, ...
When I click on one of the datetimefield to edit it, it adds one hour which corresponds to the local time (french) and the format is not the same :
Display :
Edition :
How to prevent this during the edition please ? I spent almost 2 days trying to fix this ...
Thanks for any help
Karim
Try to put the 'moment.utc(value).format('YYYY-MM-DD HH:mm:ssZZ');' in the convert or calculate of the model. Something like:
{
name: 'end_date',
type: 'date',
convert: function(value) { // or calculate, have a look in the api doc
return moment.utc(value).format('YYYY-MM-DD HH:mm:ssZZ');
}
}
After that remove the timezone conv from renderer.
enter image description hereI have 4 columns, namely Quantity, wastage, cost, Final Cost in a grid. at the last row of my grid, I have to show consolidated Final Cost, and nothing else.
My problem is,in last row Quantity, wastage, and Cost column, 0 is shown, whereas in store data for these column aren't there for last row.
I just want to show empty value on these columns.
data: [{"Name":"Part-0000112-01","Wastage":"4.63","Unit_Cost":"7.00","Quantity":"7.2200","Type":"Fabric","Net_Consumption":"11.8500","totalCost":"82.95"},{"Name":"Part-0000114-01","Wastage":"0.0","Unit_Cost":"1.00","Quantity":"10.0000","Type":"Fabric","Net_Consumption":"10.0000","totalCost":"10.00"},{"Name":"Part-0000116-01","Wastage":"2.0","Unit_Cost":"1.00","Quantity":"10.0000","Type":"Trim","Net_Consumption":"12.0000","totalCost":"12.00",},{"Name":"Part-0000118-01","Wastage":"0.0","Unit_Cost":"0.00","Quantity":"10.0000","Type":"Trim","Net_Consumption":"10.0000","totalCost":"0.00"},{"totalCost":"104.95","Name":"Total Material Costs (InDollar)"}]
Code:
Ext.create('Ext.grid.Panel', {
store: BOMStore,
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Quantity',
dataIndex: 'Quantity',
editor: {
xtype : 'numberfield',
allowBlank : false,
listeners : {
change : function(field, newValue,o ,e) {
var quantity = field.value;
var selectedModel = this.up('grid').getSelectionModel().getSelection()[0];
var wastage = selectedModel.get('Wastage');
var unitCost = selectedModel.get('Unit_Cost');
var updateTotalCost = getTotalCost(quantity,wastage,unitCost);
selectedModel.set('totalCost', updateTotalCost);
updateRowCosting(selectedModel);
}
}
}
}, {
text: 'Wastage',
dataIndex: 'Wastage',
editor: {
xtype : 'numberfield',
allowBlank : false,
}
},{
text: 'Cost',
dataIndex: 'Unit_Cost',
editor: {
xtype : 'numberfield',
allowBlank : false,
}
},{
text: 'Total Cost',
dataIndex: 'totalCost',
editor: {
xtype : 'numberfield',
allowBlank : false,
}
}]
});
You can use renderer which can be used as a converter, so you can check if the row is last one and return empty string.
FIDDLE
Ext.create('Ext.grid.Panel', {
store: Ext.data.StoreManager.lookup('simpsonsStore'),
columns: [{
text: 'Name',
dataIndex: 'name'
}, {
text: 'Email',
dataIndex: 'email',
flex: 1
}, {
text: 'Phone',
dataIndex: 'numm',
renderer: function (value, metaData, record, rowIndex, collIndex, store) {
if (store.indexOf(record) === (store.totalCount - 1)) {
return '';
}
return value;
}
}]
});
The issue got resolved.
Below is my model.
fields: [ 'Type', 'matid', 'ebomid' , 'srmid' ,'Name', 'Component_Location','Description',
'Article','Supplier_Item_Label','Supplier_Item_Description','UOM',
{ name: 'Quantity', type: 'float' },{ name: 'Wastage', type: 'float' },'Wastage_Percentage','Net_Consumption','Material_Currency','Target_Cost',
'markupInViewMode',{ name: 'Markup', type: 'float' },'markup_Percentage','Final_Material_Cost','Sourcing_Classification','Brand_Cost','Vendor_Cost','Total_Cost']
});
So, if I give type float/number in Model, and dont pass the data for corresponding columns, then defaults the value to 0.
We got to set the field type in column. xtype : 'numberfield',
I have a gridpanel with rowediting plugin enabled. I was wondering if it is possible to display in the same cell either checkbox control or numberfield based on data that's being returned from server. I have not seen anything like that before and googling has not yield any results so it may be impossible at all. It looks like I have to specify different editor types not per each column but per each cell.
How can I achieve that?
P.S. I must have a chance to edit that cell, i.e. change number value or check/uncheck checkbox.
That is very easy to achieve, you will need to use the getEditor method of your grid column and get it to return the form field you want:
Example:
{
xtype: 'gridcolumn',
getEditor: function(record) {
var grid = this.up('grid'),
cellediting = grid.findPlugin('cellediting'),
editors = cellediting.editors,
editor = editors.getByKey(this.id),
fieldType;
if (editor) {
// Do this to avoid memory leaks
editors.remove(editor);
}
fieldType = isNaN(parseFloat(record.get('salary'))) ? 'textfield' : 'numberfield';
return {
xtype: fieldType,
allowBlank: false
};
},
dataIndex: 'salary',
text: 'Salary',
flex: 1
}
I have created a fiddle demonstrating the use of this method, if the column Salary holds a string it will edit with a textfield, if it holds a number, it will edit with a Numberfield.
Hope it helps
Fiddle: https://fiddle.sencha.com/#fiddle/c2m
My fiddle is working with the CellEditor plugin, you will have to make the adjustments to make it work with your RowEditor plugin, for further reference, check the documentation for Grid Column and the getEditor method.
Many thanks to Guilherme Lopes for the nice code to begin with. Here is the sample of what I finally got:
var data = [{
name: 'Richard Wallace',
age: 24,
hired: '9/21/2013',
active: true,
salary: 1,
checkbox: true
}, {
name: 'Phyllis Diaz',
age: 29,
hired: '1/27/2009',
active: false,
salary: 41244,
checkbox: false
}, {
name: 'Kathryn Kelley',
age: 23,
hired: '9/14/2011',
active: false,
salary: 98599.9,
checkbox: false
}, {
name: 'Annie Willis',
age: 36,
hired: '4/11/2011',
active: true,
salary: 0,
checkbox: true
}];
var store = Ext.create('Ext.data.Store', {
data: data,
fields: [{
name: 'name'
}, {
type: 'float',
name: 'age'
}, {
type: 'date',
name: 'hired'
}, {
type: 'boolean',
name: 'active'
}, {
name: 'salary'
}]
});
Ext.define('MyApp.view.MyGridPanel', {
extend: 'Ext.grid.Panel',
alias: 'widget.mygridpanel',
height: 315,
width: 784,
title: 'Employees',
store: store,
viewConfig: {
listeners: {
beforecellclick: function (view, cell, cellIndex, record, row, rowIndex, e) {
if (cellIndex == 4 && record.get('checkbox')) {
if (record.get('salary')) {
record.set('salary', 0);
} else {
record.set('salary', 1);
}
return false;
}
return true;
}
}
},
columns: [{
xtype: 'gridcolumn',
dataIndex: 'name',
text: 'Name',
flex: 1,
editor: {
xtype: 'textfield'
}
}, {
xtype: 'gridcolumn',
dataIndex: 'age',
text: 'Age'
}, {
xtype: 'datecolumn',
dataIndex: 'hired',
text: 'Hired',
flex: 1
}, {
xtype: 'checkcolumn',
dataIndex: 'active',
text: 'Active'
}, {
xtype: 'gridcolumn',
getEditor: function (record) {
var fieldType = record.get('checkbox') ? 'checkboxfield' : 'textfield';
return Ext.create('Ext.grid.CellEditor', {
field: {
xtype: fieldType,
allowBlank: false
}
});
},
renderer: function (value, metaData) {
if (metaData.record.get('checkbox')) {
if (metaData.record.get('salary')) {
return '<div style="text-align: center"><img class="x-grid-checkcolumn x-grid-checkcolumn-checked" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div>';
} else {
return '<div style="text-align: center"><img class="x-grid-checkcolumn" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div>';
}
}
return value;
},
dataIndex: 'salary',
text: 'Salary',
flex: 1
}],
plugins: [{
ptype: 'cellediting',
autoCancel: false,
clicksToEdit: 1
}]
});
Ext.create('MyApp.view.MyGridPanel', {
renderTo: Ext.getBody()
});
Working example on Sencha's fiddle https://fiddle.sencha.com/#fiddle/c3p
Editor contains one field, and this editor is used for the whole column. You can't specify two xtypes or multiple editors for one column.
That said, it is not completely impossible, but it will require some work.
You will have to define a new custom field with custom xtype.
Tell this field to either render a checkboxfield or a numberfield, depending on the value.
This will require you to override/implement most if not all functions that a Ext.form.field.Base has...
I am trying to edit an information using editor grid. I have three fields, Interview By (combo), Date (date) and Performance (number), I get the date and the performance column, but the combo is not displaying the value initially. But when I click, then it shows the correct value. I am new to extjs and googled it for a solution, but could not find it. Kindly help me with a solution. Thanks in advance.
MY CODE:
initComponent: function() {
this.createTbar();
this.columns = [
{ xtype:'numbercolumn',
hidden:true,
dataIndex:'interview_id',
hideable:false
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_by_employee_id',
header: 'Interview By',
sortable: true,
width: 290,
editor: {
xtype: 'combo',
store: employee_store,
displayField:'employee_first_name',
valueField: 'employee_id',
hiddenName: 'employee_first_name',
hiddenValue: 'employee_id',
mode: 'remote',
triggerAction: 'all',
forceSelection: true,
allowBlank: false ,
editable: false,
listClass : 'x-combo-list-small',
style: 'font:normal 11px tahoma, arial, helvetica, sans-serif'
},
renderer: function(val){
index = employee_store.findExact('employee_id',val);
if (index != -1){
rs = employee_store.getAt(index).data;
return rs.employee_first_name;
}
}
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_date',
header: 'Date',
sortable: true,
readOnly: true,
width: 100,
editor: {
xtype: 'datefield'
}
},
{ xtype: 'numbercolumn',
header: 'Performance',
format:'0',
sortable: true,
width: 100,
align: 'right',
dataIndex: 'interview_performance',
editor: {
xtype: 'numberfield'
}
}
];
candidate_grid_interview.superclass.initComponent.call(this);
}
and the screen shots,
I faced the same problem and found my solution somewhere. Here is a reduced version of what I'm using. I think the key was the renderer property on the column. If your combo uses remote data, it might be loading its content after the grid is done loading - but I'm not sure it will cause the problem you're describing.
Try this concept:
var myStore = new Ext.data.JsonStore({
autoLoad: false,
...
fields: [
{ name: 'myID', type: 'int' },
{ name: 'myName', type: 'string' }
],
listeners: {
load: function () {
// Load my grid data.
},
scope: this
}
});
var myCombo = new Ext.form.ComboBox({
...
displayField: 'myName',
valueField: 'myID',
store: myStore
});
var grid = new Ext.grid.EditorGridPanel({
store: new Ext.data.ArrayStore({
...
fields: [
...
{ name: 'myID', type: 'int' },
...
]
}),
...
cm: new Ext.grid.ColumnModel({
columns: [
...
{
header: 'Header',
dataIndex: 'myID',
editor: myCombo,
renderer: function (value) {
var record = myCombo.findRecord(myCombo.valueField, value);
return record ? record.get(myCombo.displayField) : myCombo.valueNotFoundText;
}
}]
})
});
myStore.load();
Store loading is asynchronous, so it might be loading itself after rendering the grid. I recommend you render your grid within the store onload event. Also, datatypes can be painfull if you don't pay enough attention. Be sure that your grid store and combo store types match.
The server returns date in JSON as below,
{
"LastUpdated": "\/Date(1310117748850)\/"
}
I'm using ExtJs grid and the date is not showing up. How I can display it in M/dd/yyyy format?
this.store = new Ext.data.JsonStore({
autoLoad: {
params: {
start: 0,
limit: 10
}
},
autoDestroy: true,
url: '/home/jobs',
idProperty: 'Name',
fields: ['Name',
'Description',
'Type',
'Group',
'Data',
'Schedule.Name',
'Schedule.Description', {
name: 'LastUpdated',
type: 'date'
},
'Schedule.Expression',
'Status'],
root: 'data',
sortInfo: {
field: 'Name',
direction: 'ASC'
}
});
In Grid colModel:
{
header: 'Last Updated',
dataIndex: 'LastUpdated',
width: 80,
renderer: Ext.util.Format.dateRenderer('m/d/Y')
},
//Grid:
columns: [
{header: 'Last Updated', dataIndex: 'LastUpdated', renderer: Ext.util.Format.dateRenderer('m/d/Y')}
]
//store:
{
field:'LastUpdated',
type:'date',
convert:function(v,j){
return new Date(v.replace(/\/Date((\d+))\//, '$1'));
}
}
In the column section, you could create you own custom date renderer:
columns: [
{header: 'Last Updated', dataIndex: 'LastUpdated', renderer: dateRenderer}
]
And then create a function that processes your date:
function dateRenderer(value, id, r) {
var yourDate = r.data['uploadDate'];
// some js stuff here to strip out just the epoch time
var datevar = new Date(yourDateEpoch);
return Ext.Date.format(datevar, 'm/d/Y')
}
For date field you need also specify dateFormat. E.g.:
{name: 'LastUpdated', type: 'date', dateFormat: 'Y-m-d'}
But in your case you receive date in other format...
The only thing you need to do is to have the following in your model
{name: 'LastUpdated', type: Ext.data.Types.DATE, dateFormat: 'time' }
It tells ExtJS that the data coming into the model for this field is of form epoch time.
Use
return new Date(parseInt(v.replace('/Date(', '')));
full example below,
columns: [
{
header: 'Last Updated',
dataIndex: 'LastUpdated',
renderer: Ext.util.Format.dateRenderer('m/d/Y')
}
]
//store:
{
field:'LastUpdated',
type:'date',
convert:function(v, j) {
return new Date(parseInt(v.replace('/Date(', '')));
}
}