EXTJS Window/Panel close error - javascript

I'm creating a new EXTJS window and inside that window there is a panel and inside that panel there is a form!
When I click on the 'X' or cancel to close the window I get this error:
Uncaught TypeError: Cannot read property 'className' of undefinedhasClass
# ext-all-debug.js:2252addClass
# ext-all-debug.js:2183Ext.Button.Ext.extend.onMouseOver
# ext-all-debug.js:31140aK
# miframe.js:1
I am using this handler in the cancel button:
handler: function () {
this.close();
},
Full code -
example.SurveyFieldDefaultWindow = Ext.extend(Ext.Window, {
id: 'survey-default-win',
title: 'Custom Survvey',
modal: true,
closable: true,
width: 500,
height: 600,
frame: true,
bodyStyle: 'padding: 5px',
forceFit: true,
constrainHeader: true,
layout: 'fit',
initComponent: function () {
this.canEdit = this.checkEditPermissions();
questionStore2 = questionStore;
var survey_window = Ext.getCmp('survey-win');
survey_window.afterRender(
survey_window.getFormValues()
);
formValues2 = formValuesObj;
survey_default_id = Math.floor(10000 + Math.random() * 90000);
Ext.apply(
this, {
items: [{
xtype: 'tabpanel',
id: 'survey-field-form-tabpanel',
layoutOnTabChange: true,
activeTab: 0,
items: [{
title: 'Questions',
layout: 'fit',
items: [{
xtype: 'form',
id: 'survey-field-form',
border: false,
bodyStyle: 'padding: 5px;',
frame: true,
defaultType: 'textfield',
}]
}]
}],
buttons: [{
id: 'save-button',
text: 'Default-Save',
handler: function () {
this.saveForm()
},
scope: this
}, {
text: 'Default-Cancel',
handler: function () {
this.close();
},
scope: this
}]
}
);
example.SurveyFieldDefaultWindow.superclass.initComponent.apply(this, arguments);
var data = questionStore2.data.items;
for (var i = 0; i < data.length; i++) {
if (data[i].data.fieldTypeName == "DropDownList" || data[i].data.fieldTypeName == "RadioButtonList" || data[i].data.fieldTypeName == "CheckBoxList" || data[i].data.fieldTypeName == "Rating" || data[i].data.fieldTypeName == "YesNo") {
// create a Record constructor:
var rt = Ext.data.Record.create([
{name: 'optionValue'},
{name: 'optionText'}
]);
var myStore = new Ext.data.Store({
// explicitly create reader
reader: new Ext.data.ArrayReader(
{
idIndex: 0 // id for each record will be the first element
},
rt // recordType
)
});
var myData = [];
for (var j = 0; j < data[i].data.selectOptions.list.length; j++) {
var optionText = data[i].data.selectOptions.list[j].optionText.toString();
var optionValue = data[i].data.selectOptions.list[j].optionValue.toString();
myData.push([optionValue, optionText]);
}
myStore.loadData(myData);
var id = data[i].data.name.toString();
var cb = new Ext.form.ComboBox({
fieldLabel: data[i].data.name,
id: id,
typeAhead: true,
allowBlank: true,
mode: 'local',
emptyText: 'Select Default value',
width: 190,
margin: '40 30 20 10',
store: myStore,
valueField: 'optionValue',
displayField: 'optionText',
selectOnFocus: true,
triggerAction: 'all',
listeners: {
'select': function (cb, newValue, oldValue) {
for (var i = 0; i < formValues2.fields.list.length; i++)
{
for (var j = 0; j < formValues2.fields.list[i].selectOptions.list.length; j++)
{
if(formValues2.fields.list[i].name == cb.fieldLabel ){
if( formValues2.fields.list[i].selectOptions.list[j].optionText == cb.lastSelectionText) {
formValues2.fields.list[i].selectOptions.list[j].preselect = true;
}
}
}
}
}
}
});
Ext.getCmp('survey-field-form').add(cb);
Ext.getCmp('survey-field-form').doLayout();
}
}
getDefaultSurveyFormValues = Ext.getCmp('survey-field-form');
getDefaultSurveyFormValues.on("afterrender", function () {
//this code will run after the panel renders.
if (getDefaultSurveyFormValues != undefined) {
getDefaultSurveyFormValues.getForm().getValues();
}
else {
console.log('undefined getDefaultSurveyFormValues');
}
});
},
checkEditPermissions: function () {
return Security.hasAccess("Surveys", Security.UPDATE_ACCESS);
},
saveForm: function () {
// disable save button while saving form
// Ext.getCmp('save-button').disable(); ----------------------------------- undo comment later
// submit the form using a jabsorb call
Ext.getCmp('survey-field-form').getForm().doAction("JabsorbSubmit", {
formValues: formValues2,
jabsorbMethod: Jabsorb.getInstance().surveyTemplateService.saveSurveyTemplate,
// timeout:300000,
failure: function (form, action) {
Ext.Msg.alert('Request Failed', 'Could not save survey template information to generate Survey View: ' + action.result.msg);
},
success: function (form, action) {
Ext.Msg.alert('magic' , 'magic');
}
});
}
});
Ext.reg('example.SurveyFieldDefaultWindow', example.SurveyFieldDefaultWindow);

I've made a fiddle, based on your code to create the window and using the close button. Check it here: https://fiddle.sencha.com/#fiddle/16lu
From what i've seen, in your initComponent: function() { you never call the this.callParent() method. It's very important for class inheritance if you use the initComponent config.
From the docs:
Call the "parent" method of the current method. That is the method
previously overridden by derivation or by an override (see
Ext.define).

In this scope, this represent the button and not the window, so you trying to close the button

Related

extjs combo box getCount() on store returns 0

I am trying to get the number of items in the combo box so that I can make the first value by default visible in the combo box using the getCount() method but I see it always return 0 so cannot get the first item to be displayed in the combo box.
Code for my combo box is as shown below:
Ext.define('something....', {
controller: 'some Controller',
initComponent: function() {
var me,
me = this;
me.items = [{
xtype: 'form',
items: [{
xtype: 'combo',
itemId: 'nameId',
name:'nameId',
labelAlign: 'top',
fieldLabel: 'Name',
store: me._getNames(),
//disabled:some condition?true:false,//doesn't gray out combo
valueField:'dataId',
displayField: 'firstName',
editable: false,
listeners:{
afterrender: function(combo,component) {
var combo = me.down('#nameId');
var nameStore = combo.getStore();
var setFirstRecord = function(combo){
var nameStore = combo.getStore();
if(nameStore.getCount() === 1){
combo.setValue(nameStore.getAt(0));
}
}
if(nameStore.isLoaded() === false){
nameStore.on('load', function(nameStore){
setFirstRecord(combo);
},this,{
single:true
});
}else{
setFirstRecord(nameStore);
}
},
}
}]
}];
}
Code for the store is as below:
_getNames: function (){
var nameStore = Ext.create('Ext.data.Store', {
autoLoad: true,
proxy: {
type: 'ajax',
url: 'name.json',
reader: {
type: 'json',
rootProperty:'items',
transform: function (data) {
var data = {
items: [{
dataId: data[0].dataId,
firstName: data[0].name.firstName,
nameDetails: data[0].nameDetails
}]
}
return data;
}
},
},
fields: ['dataId', 'firstName','nameDetails']
});
return namesStore;
}
})
The result returned from the api to populate the store is as follows:
[
{
"dataId":1,
"name":{
"dataId":1,
"firstName":"Julie",
"code":"10",
"connectionList":[
"EMAIL"
]
},
"nameDetails":{
"EMAIL":{
"dataId":1,
"detail":"EMAIL"
}
}
}
]
Any suggestions on what's missing would be great!
I am written that example for you in Sencha Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/3cdl
That solve your problem:
combo.getStore().on("load",
function (store, records, successful, operation, eOpts) {
if (store.getData().length > 0)
combo.setValue(store.getData().get(0).getData().id)
},
this
)
You must check if store is loaded or not and write appropriate code:
...
...
xtype: 'combo',
itemId: 'nameId',
name: 'nameId',
labelAlign: 'top',
fieldLabel: 'Name',
store: this._getNames(),
valueField: 'dataId',
displayField: 'firstName',
editable: false,
listeners: {
afterrender: function (combo) {
var store = combo.getStore();
var setFirstRecord = function (combo) {
var store = combo.getStore();
if (store.getCount() === 1) {
combo.setValue(store.getAt(0));
}
}
if (store.isLoaded() === false) {
store.on('load', function (store) {
setFirstRecord(combo);
}, this, {
single: true
});
} else {
setFirstRecord(combo);
}
}
}
...
...

How can i define databound in KendoUI Grid , syntax is very confusing?

I have a Kedno-Grid , with details below:
This is the data source:
var data = $scope.salesgroups;
var dataSource = new kendo.data.DataSource({
//data: data,
transport: {
read: function (e) {
e.success(data);
},
update: function (e) {
e.success();
},
create: function (e) {
var item = e.data;
item.Id = data.length + 1;
e.success(item);
}
},
schema: {
model: {
id: "Id",
fields: {
Name: { type: "string" }
}
}
}
});
Var grid = $("#grid").kendoGrid({
dataSource: dataSource,
scrollable: false,
navigatable: true,
editable: {
createAt: "bottom"
},
toolbar: ["save", "cancel", "create"],
columns: ["Name"]
}).data("kendoGrid")
The below code is for adding a new row when the user clicks on tab on the last row of the grid.
grid.tbody.on('keydown', function (e)
{
if (e.keyCode == 9)
{
if ($(e.target).closest('td').is(':last-child') && $(e.target).closest('tr').is(':last-
child')) {
setTimeout(function () {
grid.addRow();
})
}
}
});
Now where do I define the "databound" ? I want to add the following below code which will replace the buttons with font awesome icons instead of create and delete buttons
dataBound: function (e) {
e.sender.tbody.find(".k-grid-edit").each(function (idx, element) {
if (!$scope.validateDisabled)
$(element).remove();
else {
$(element).removeClass("k-button");
$(element).removeClass("k-button-icontext");
}
});
e.sender.tbody.find(".k-grid-Delete").each(function (idx, element) {
if (!$scope.validateDisabled)
$(element).remove();
else {
$(element).removeClass("k-button");
$(element).removeClass("k-button-icontext");
}
});
dataBound is a root property of grid parameters:
var grid = $("#grid").kendoGrid({
dataSource: ...,
scrollable: ...,
navigatable: ...,
editable: ...,
toolbar: ...,
columns: ...,
dataBound: function() {
}
}).data("kendoGrid")

Loop in Grid EXTJs

I have some store, which is formed data. On panel it looks how "fieldName" and text field (in depension from invoked form). For example, on one form is displayed "name document" and field, on another: date of selling and date field. Data is formed dynamicly
Here is store:
tableTempStore = new Ext.data.JsonStore({
url: objectUrlAddress,
baseParams: {
'objectID': objectID
},
root: 'Fields',
fields: [{
name: 'Type',
type: 'int'
}, {
name: 'Value'
}, {
name: 'IsRequired',
type: 'bool'
}, {
name: 'Identifier'
}, {
name: 'Data'
}],
listeners: {
load: function(obj, records) {
Ext.each(records, function(rec) {
var item = null;
switch (rec.get('Type')) {
case 0:
item = new Ext.form.NumberField();
item.id = rec.get('Identifier');
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.anchor = '100%';
item.allowBlank = !isRequired;
item.disabled = editDisabled;
item.value = rec.get('Data');
break;
case 1:
item = new Ext.form.NumberField();
item.id = rec.get('Identifier');
item.fieldLabel = rec.get('Hint');
var isRequired = rec.get('IsRequired');
item.anchor = '100%';
item.allowBlank = !isRequired;
item.allowDecimals = true;
item.disabled = editDisabled;
item.value = rec.get('Data');
break;
}
if (item != null) {
templateGrids.add(item);
columnsTable = item.__proto__.constructor.xtype;
source[item.fieldLabel] = '';
var s = null;
if (columnsTable == 'textfield')
{
s = 'textfield';
colm = {
xtype: s,
id: item.id,
allowBlank: item.allowBlank,
format: item.format,
value: item.value,
editable: true,
emptyText: item.emptyText,
disabled: item.disabled
};
}
else if (columnsTable == 'combo')
{
s = 'combo';
colm = {
xtype: s,
id: item.id,
allowBlank: item.allowBlank,
format: item.format,
value: item.value,
editable: true,
emptyText: item.emptyText,
disabled: item.disabled
};
}
else if (columnsTable == 'datefield')
{
s = 'datefield';
colm = {
xtype: s,
id: item.id,
allowBlank: item.allowBlank,
format: item.format,
value: item.value,
editable: true,
emptyText: item.emptyText,
disabled: item.disabled
};
}
});
for (var i = 0; i < templateGrids.getStore().data.length; i++) {
templateGrids.getColumnModel().setConfig([
{header: 'Name', id:'name', width:200},
{header:'Value', id:'val', dataIndex: rec.get('Value'), editable:true, width:200, editor: colm}]);
};
}
}
});
This code had worked in a form, but I need to use Grid (or Editor Grid). I know, how displayed field name ("document name" and etc.), but I don't understand, how displayed text field or etc. I try use loop, but on second column in xtype displayed last type in store. How i can resolve this problem?!
Here is a grid:
var templateGrids = new Ext.grid.EditorGridPanel({
id: 'tableId',
height:300,
width: '100%',
clicksToEdit:1,
frame: true,
store: tableTempStore,
columns: [
{header: 'Name'},
{header: 'Value'}]
});

ExtJS: How to utilize UTC time in custom DateTimeField

I am trying to convert UTC timestamps to UTC Dates, modify those dates, and return the UTC timestamp of the selected date/time. Since the Ext.form.field.Date and Ext.form.field.Time fields use local time internally, I have to add 5 hours to the time and make sure the date stays the same, to retrieve the timestamp, I have to reverse the process and get the ISO timestamp (without milliseconds).
Everything seems to work OK, but when I select 2015-01-01T01:15:00Z the date field is set to the following day (01/02/2015; See Figure #1). I am not sure where I am failing to convert the date correctly?
Figure #1: Date is set to next day.
Edit
After fiddling around a bit, It looks like I got the date correct, but now the time field complains (See Figure #2). Looks like the value that was set is removed from the time drop-down. This is extremely confusing.
setValue: function (value) {
// ...
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(me.convertFromUTC(timeDate));
}
// ...
}
Figure #2: Time field validation fails.
You can access a demo of the following code at the following sites:
JSFiddle
SenchaFiddle
DateTime.components.DateTimeField
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
ignoreOnSubmit: true,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
minValue: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80,
ignoreOnSubmit: true
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideData) {
me.lookupReference('dateField').hide();
}
me.callParent();
},
getValue: function () {
var me = this,
dateValue = me.getDate(),
timeValue = me.getTime();
if (dateValue != null && timeValue != null) {
dateValue = Ext.Date.add(dateValue, Ext.Date.MILLI, timeValue);
}
return this.convertToUTC(dateValue);
},
setValue: function (value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
// Debug
console.log('Parsed Date: ' + value);
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
timeDate = me.convertFromUTC(timeDate);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(timeDate);
}
},
getInputId: function () {
return null;
},
getTime: function () {
var me = this,
timeValue = me.lookupReference('timeField').getValue();
timeValue.setFullYear(1970, 0, 1);
timeValue = this.convertToUTC(timeValue, this.getDate());
return timeValue.getTime();
},
getDate: function () {
return this.lookupReference('dateField').getValue();
},
setDate: function (value) {
this.lookupReference('dateField').setValue(value);
},
convertToUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.subtract(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
},
convertFromUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.add(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
}
});
Full Code
//////////////////////////////////////////////////////////
// Requires
//////////////////////////////////////////////////////////
Ext.require(['*']);
//////////////////////////////////////////////////////////
// Data
//////////////////////////////////////////////////////////
var timestampData = [
['2014-02-28T08:45:00Z'],
['2015-01-01T01:15:00Z'],
['2014-12-31T11:30:00Z']
];
//////////////////////////////////////////////////////////
// Models
//////////////////////////////////////////////////////////
Ext.define('DateTime.model.Timestamp', {
extend: 'Ext.data.Model',
fields: ['timestamp']
});
//////////////////////////////////////////////////////////
// Stores
//////////////////////////////////////////////////////////
Ext.define('DateTime.store.Timestamp', {
extend : 'Ext.data.ArrayStore',
model: 'DateTime.model.Timestamp',
autoLoad: true,
autoSync: true,
proxy: {
type: 'memory'
}
});
//////////////////////////////////////////////////////////
// Mixins
//////////////////////////////////////////////////////////
Ext.define('DateTime.mixin.CommonUtils', {
dateToISOString: function (date) {
var pad = function (number) {
return ('00' + number).slice(-2);
};
return date.getUTCFullYear() + '-'
+ pad(date.getUTCMonth() + 1) + '-'
+ pad(date.getUTCDate()) + 'T'
+ pad(date.getUTCHours()) + ':'
+ pad(date.getUTCMinutes()) + ':'
+ pad(date.getUTCSeconds()) + 'Z';
}
});
//////////////////////////////////////////////////////////
// Components
//////////////////////////////////////////////////////////
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
ignoreOnSubmit: true,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
minValue: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80,
ignoreOnSubmit: true
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideData) {
me.lookupReference('dateField').hide();
}
me.callParent();
},
getValue: function () {
var me = this,
dateValue = me.getDate(),
timeValue = me.getTime();
if (dateValue != null && timeValue != null) {
dateValue = Ext.Date.add(dateValue, Ext.Date.MILLI, timeValue);
}
return this.convertToUTC(dateValue);
},
setValue: function (value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
// Debug
console.log('Parsed Date: ' + value);
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
timeDate.setFullYear(1970, 0, 1);
timeDate = me.convertFromUTC(timeDate);
me.lookupReference('dateField').setValue(
Ext.Date.add(value, Ext.Date.MILLI, timeDate.getTime()));
me.lookupReference('timeField').setValue(timeDate);
}
},
getInputId: function () {
return null;
},
getTime: function () {
var me = this,
timeValue = me.lookupReference('timeField').getValue();
timeValue.setFullYear(1970, 0, 1);
timeValue = this.convertToUTC(timeValue, this.getDate());
return timeValue.getTime();
},
getDate: function () {
return this.lookupReference('dateField').getValue();
},
setDate: function (value) {
this.lookupReference('dateField').setValue(value);
},
convertToUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.subtract(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
},
convertFromUTC: function (date, dateOffset) {
if (dateOffset == null) {
dateOffset = date;
}
if (this.utcValue) {
return Ext.Date.add(date, Ext.Date.MINUTE, dateOffset.getTimezoneOffset());
}
return date;
}
});
//////////////////////////////////////////////////////////
// Views
//////////////////////////////////////////////////////////
Ext.define('DateTime.view.MainView', {
extend: 'Ext.panel.Panel',
xtype: 'mainView',
alias: 'widget.mainview',
mixins: {
utils: 'DateTime.mixin.CommonUtils'
},
title: 'Date-Time Field Example',
referenceHolder: true,
layout: {
type: 'border',
//padding: 5
},
initComponent: function () {
var me = this;
me.items = [{
region: 'north',
xtype: 'grid',
itemId: 'timestampList',
store: Ext.create('DateTime.store.Timestamp', {
data : timestampData
}),
cls: 'timestamp-list',
multiSelect: false,
hideHeaders : true,
viewConfig: {
emptyText: 'No images to display'
},
columns: [{
dataIndex: 'timestamp',
text: 'Timestamp',
flex: 1
}]
}, {
region: 'center',
xtype: 'panel',
layout: {
type: 'vbox'
},
bodyPadding: 8,
items: [{
xtype: 'container',
layout: 'hbox',
margin: '8 0 0 0',
items: [{
xtype: 'textfield',
reference: 'txtTimestampIn',
fieldLabel: 'Timestamp In'
}, {
xtype: 'button',
itemId: 'btnSetTime',
text: 'Set Time',
margin: '0 0 0 12'
}]
}, {
xtype: 'container',
layout: 'hbox',
margin: '8 0 0 0',
items: [{
xtype: 'datetimefield',
name: 'startDate',
itemId: 'startDate',
reference: 'startDate',
dateConfig: {
fieldLabel: 'Start'
},
listeners: {
afterrender: {
fn: me.dateTimeField_onComplete,
scope: me
}
}
}, {
xtype: 'button',
itemId: 'btnExportTime',
text: 'Get Time',
margin: '0 0 0 12'
}]
}, {
xtype: 'textfield',
reference: 'txtTimestampOut',
fieldLabel: 'Timestamp Out',
margin: '8 0 0 0'
}]
}],
me.callParent();
},
dateTimeField_onComplete: function (field, eOpts) {
var me = this,
timestamp = timestampData[0][0];
field.setValue(timestamp);
}
});
////////////////////////////////////////////////////////////
// Controllers
////////////////////////////////////////////////////////////
Ext.define('DateTime.controller.MainController', {
extend: 'Ext.app.Controller',
views: ['DateTime.view.MainView'],
mixins: {
utils: 'DateTime.mixin.CommonUtils'
},
refs: [{
ref: 'mainView',
selector: 'mainView'
}],
init: function () {
var me = this;
me.control({
'#startDate': {
dateFieldChange: me.handleDateChange
},
'#btnSetTime': {
click: me.handleSetTime
},
'#btnExportTime': {
click: me.handleExportTime
},
'#timestampList' : {
selectionchange: me.handleChangeTimestamp
}
});
},
handleDateChange: function (field, newValue, oldValue) {
// Do nothing...
},
handleSetTime: function (button, e, eOpts) {
var me = this,
view = me.getMainView(),
timestampIn = view.lookupReference('txtTimestampIn');
view.lookupReference('startDate').setValue(timestampIn.getValue());
me.handleExportTime();
},
handleExportTime: function (button, e, eOpts) {
var me = this,
toISOStr = me.mixins.utils.dateToISOString,
view = me.getMainView(),
timestampIn = view.lookupReference('txtTimestampOut');
timestampIn.setValue(toISOStr(view.lookupReference('startDate').getValue()));
},
handleChangeTimestamp: function(grid, selected, eOpts) {
var me = this,
view = me.getMainView(),
timestamp = selected[0].data.timestamp;
view.lookupReference('txtTimestampIn').setValue(timestamp);
me.handleSetTime();
}
});
//////////////////////////////////////////////////////////
// Applications
//////////////////////////////////////////////////////////
Ext.define('DateTime.app.DateTimeApp', {
extend: 'Ext.app.Application',
name: 'DateTimeApp',
controllers: ['DateTime.controller.MainController'],
launch: function () {
Ext.create('Ext.Viewport', {
layout: 'fit',
flex: 1,
items: [{
xtype: 'mainview'
}]
});
}
});
//////////////////////////////////////////////////////////
// Startup
//////////////////////////////////////////////////////////
Ext.onReady(function () {
Ext.application('DateTime.app.DateTimeApp');
});
Looks like I figured it out, although there is still an issue. The selected time does not appear in the dropdown... It just does not appear which is very strange. If anyone has a suggestion, comment below, or add your own answer.
Anyways, If anyone needs a UTC date-time field, here it is. I cleaned it up a bit. I completely refactored the code from my question so that timezone information is irrelevant. Date are explicitly converted from UTC to local and vice versa. This way, there is no need to calculate anything.
Ext.ux.form.field.DateTimeField
Ext.define('DateTime.components.DateTimeField', {
extend: 'Ext.container.Container',
mixins: ['Ext.form.field.Field'],
alias: 'widget.datetimefield',
config: {
dateConfig: {},
timeConfig: {},
utcValue: true,
hideDate: false
},
referenceHolder: true,
layout: {
type: 'hbox'
},
initComponent: function () {
var me = this,
today = new Date(),
dateConfig = me.dateConfig,
timeConfig = me.timeConfig;
me.items = [Ext.apply({
xtype: 'datefield',
reference: 'dateField',
fieldLabel: 'Date',
value: today,
listeners: {
change: function (field, newValue, oldValue) {
me.fireEvent('dateFieldChange', field, newValue, oldValue);
}
}
}, dateConfig),
Ext.apply({
xtype: 'timefield',
reference: 'timeField',
format: 'H:i',
value: '00:00',
maxValue: '24:00',
increment: 15,
padding: '0 0 0 10',
width: 80
}, timeConfig)];
me.callParent();
},
afterRender: function () {
var me = this;
if (me.hideDate) {
me.getDateField().hide();
}
me.callParent();
},
getValue: function () {
var me = this;
var dateTime = me.combineDateTime(me.getDate(), me.getTime());
if (me.utcValue) {
return me.localToUtc(dateTime);
}
return dateTime;
},
setValue: function(value) {
var me = this;
if (value == null) {
return;
}
if (Ext.isString(value)) {
value = Ext.Date.parse(value, 'c');
}
if (value != null && Ext.isDate(value)) {
var timeDate = Ext.clone(value);
if (me.utcValue) {
timeDate = this.utcToLocal(timeDate);
}
me.setDate(timeDate);
me.setTime(timeDate);
}
},
getTimeField : function() {
return this.lookupReference('timeField');
},
getDateField : function() {
return this.lookupReference('dateField');
},
getTime: function() {
return this.getTimeField().getValue();
},
setTime: function(value) {
this.getTimeField().setValue(value);
},
getDate: function() {
return this.getDateField().getValue();
},
setDate: function(value) {
this.getDateField().setValue(value);
},
combineDateTime : function(date, time) {
var year = date.getFullYear();
var month = date.getMonth();
var day = date.getDate();
var hour = time.getHours();
var minute = time.getMinutes();
var second = time.getSeconds();
return new Date(year, month, day, hour, minute, second, 0);
},
utcToLocal : function(utcDate) {
var year = utcDate.getUTCFullYear();
var month = utcDate.getUTCMonth();
var day = utcDate.getUTCDate();
var hour = utcDate.getUTCHours();
var minute = utcDate.getUTCMinutes();
var second = utcDate.getUTCSeconds();
return new Date(year, month, day, hour, minute, second, 0);
},
localToUtc : function(localDate) {
var year = localDate.getFullYear();
var month = localDate.getMonth();
var day = localDate.getDate();
var hour = localDate.getHours();
var minute = localDate.getMinutes();
var second = localDate.getSeconds();
return new Date(Date.UTC(year, month, day, hour, minute, second, 0));
}
});
Demos
JSFiddle
SenchaFiddle

ExtJS-3, Ext.grid.GridPanel, muti-row checkboxes: how do I submit all checked items at once?

I'm using ExtJS3 and I have a Ext.grid.GridPanel where each row has a checkbox on the left. At the top there are two buttons: 'refresh' and 'submit'. I want to be able to select multiple rows and submit all of them in one click of the submit button. As it is right now when I select multiple rows and hit submit it will submit the first one, then remove that item from the grid, and I have to hit submit again (the formerly checked rows are still checked).
How do I change the following code to make the submit button send all of the rows at one time?
var dataStore = new Ext.data.SimpleStore({ fields: [
{name: 'node'},
{name: 'ip'},
{name: 'groups'}
]});
var checkBoxSelMod = new Ext.grid.CheckboxSelectionModel();
var dataGrid = new Ext.grid.GridPanel ({
renderTo: document.body,
clickstoEdit: 2,
selModel : checkBoxSelMod,
xtype: 'grid',
layout: 'fit',
sm: new Ext.grid.CheckboxSelectionModel(),
tbar: [
{
text: 'Refresh',
icon: '$nroot/includes/extjs3/resources/images/slate/button/table_refresh.png',
cls: 'x-btn-text-icon',
handler: function() {
window.location = '$nroot/index.php/imaging/index';},
scope: this,
},
{
text: 'Submit Machine(s)',
icon: '$nroot/includes/extjs3/resources/images/slate/button/table_add.png',
cls: 'x-btn-text-icon',
handler: function() {
var sm = dataGrid.getSelectionModel();
var sel = sm.getSelected();
if (sm.hasSelection()) {
Ext.Msg.show({
title: 'Image Machine?',
buttons: Ext.MessageBox.YESNO,
msg: 'Continue with imaging (no undo!) process for server: '+sel.data.node+'?',
fn: function(btn){
if (btn == 'yes'){
var conn = new Ext.data.Connection();
conn.request({
url: '$nroot/index.php/imaging/image/',
params: {
action: 'delete',
node: sel.data.node,
mgmtip: sel.data.ip
},
success: function(resp,opt) {
dataGrid.getStore().remove(sel);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to image server - check debug logs');
}
});
}
}
});
}
}
}
],
store: dataStore,
columns: [
checkBoxSelMod,
{ id: 'node', header: "Node", width: 150, sortable: true, dataIndex: 'node'},
{ id: 'ip', header: "IP", width: 120, sortable: false, dataIndex: 'ip'},
{ id: 'groups', header: "Groups", width: 100, sortable: true, dataIndex: 'groups'},
],
stripeRows: true,
autoExpandColumn: 'node',
listeners: {
render: function(){ this.store.loadData(dataList); }
}
})});
When I change the code from getSelected to getSelections it returns this on page load:
item type is invalid for AcceptItem action
I can't find any examples that show multi-select with submit for GridPanels. Is there one I can reference?
EDIT, based on the solutions below I've modified the code to work as follows:
var sels = sm.getSelections();
if (sels.length > 0) {
var ips = [], nodes = [];
Ext.each(sels, function(sel) {
ips.push(sel.get('ip'));
nodes.push(sel.get('node'));
});
Ext.Msg.show({
title: 'Image Machine?',
buttons: Ext.MessageBox.YESNO,
msg: 'Continue with imaging (no undo!) process for servers: '+nodes.join(",")+'?',
fn: function(btn){
if (btn == 'yes'){
Ext.each(sels, function(sel) {
var conn = new Ext.data.Connection();
conn.request({
url: '$nroot/index.php/imaging/image/',
params: {
node: sel.get('node'),
mgmtip: sel.get('ip')
},
success: function(resp,opt) {
dataGrid.getStore().remove(sel);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to image server - check debug logs');
}
});
})
}
}
});
}
}
The most simple approach is to loop through the selected records and ask a question for each record.
var sels = sm.getSelections();
Ext.each(sels, function(sel) {
var node = sel.get('node'),
ip = sel.get('ip');
Ext.Msg.show({
title: 'Image Machine?',
buttons: Ext.MessageBox.YESNO,
msg: 'Continue with imaging (no undo!) process for server: '+node+'?',
fn: function(btn){
if (btn == 'yes'){
var conn = new Ext.data.Connection();
conn.request({
url: '$nroot/index.php/imaging/image/',
params: {
action: 'delete',
node: node,
mgmtip: ip
},
success: function(resp,opt) {
dataGrid.getStore().remove(sel);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to image server - check debug logs');
}
});
}
}
});
});
However, this may not be nice for the user to get a prompt for every row selected in the DataGrid. But if your service ('$nroot/index.php/imaging/image/') support posting several items you can ask the user one time and post all of them. I.e.
var sels = sm.getSelections();
if (sels.length > 0) {
var ips = [], nodes = [];
Ext.each(sels, function(sel) {
ips.push(sel.get('ip'));
nodes.push(sel.get('node'));
});
Ext.Msg.show({
title: 'Image Machine?',
buttons: Ext.MessageBox.YESNO,
msg: 'Continue with imaging (no undo!) process for servers: '+nodes.join(",")+'?',
fn: function(btn){
if (btn == 'yes'){
var conn = new Ext.data.Connection();
conn.request({
url: '$nroot/index.php/imaging/image/',
params: {
action: 'delete',
nodes: nodes,
mgmtips: ips
},
success: function(resp,opt) {
Ext.each(sels, function() { dataGrid.getStore().remove(this) });
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to image server - check debug logs');
}
});
}
}
});
}

Categories