At the moment when I remove a row - it reappears on the client side - refreshing the page I see it has indeed been deleted
Adding a store.reload in the method means it appears again and then disappears when the store is reloaded.
Any help appreciated
// The DataWriter component.
var writer = new Ext.data.JsonWriter({
encode: false
})
Ext.namespace('codeblender');
codeblender.app = function() {
/**
* Render the ground links
*
* #param val
* #param p
* #param record
* #return
*/
function rendererGroundLink(val, p, record) {
var string = record.data.ground;
var newContent = string.replace(/ /g, '-');
return ('' + record.data.ground + '');
}
// Public space
return {
// Public methods
init: function() {
// !Create the data store
var store = new Ext.data.JsonStore({
fields: [{
name: 'id',
type: 'int'
}, {
name: 'division_id',
type: 'int'
}, {
name: 'competition',
type: 'string'
}, {
name: 'date',
type: 'date',
dateFormat: 'Y-m-d'
}, {
name: 'time',
type: 'time'
}, {
name: 'referee',
type: 'string'
}, {
name: 'ground',
type: 'string'
}, {
name: 'team_a',
type: 'string'
}, {
name: 'score_a',
type: 'string'
}, {
name: 'scorer_a',
type: 'string'
}, {
name: 'team_b',
type: 'string'
}, {
name: 'score_b',
type: 'string'
}, {
name: 'scorer_b',
type: 'string'
}],
idProperty: 'id',
messageProperty: 'message',
pruneModifiedRecords: true,
remoteSort: true,
restful: true,
root: 'data',
sortInfo: {
field: 'date',
direction: "DESC"
},
successProperty: 'success',
totalProperty: 'totalCount',
url: '/restfixture',
writer: writer
});
store.load({
params: {
start: 0,
limit: 50,
sort: 'date',
dir: 'DESC'
}
});
// !Create the Team data store
var storeTeam = new Ext.data.JsonStore({
baseParams: {
status: 'Active'
},
fields: [{
name: 'id',
type: 'int'
}, {
name: 'team',
type: 'string'
}],
restful: true,
root: 'data',
sortInfo: {
field: 'team',
direction: "ASC"
},
url: '/restteam'
});
// !Create the Ground data store
var storeGround = new Ext.data.JsonStore({
fields: [{
name: 'id',
type: 'int'
}, {
name: 'ground',
type: 'string'
}],
restful: true,
root: 'data',
url: '/restground'
});
// !Create the Referee data store
var storeReferee = new Ext.data.JsonStore({
fields: [{
name: 'id',
type: 'int'
}, {
name: 'referee',
type: 'string'
}],
restful: true,
root: 'data',
url: '/restreferee'
});
// !Create the column model
var columns = [{
header: 'Division',
sortable: true,
dataIndex: 'division_id',
width: 75,
editor: {
allowBlank: false,
editable: false,
lazyRender: true,
mode: 'local',
store: [
[1, 'Division 1'],
[2, 'Division 2'],
[3, 'Division 3']
],
triggerAction: 'all',
xtype: 'combo'
}
}, {
header: 'Competition',
sortable: true,
dataIndex: 'competition',
editor: {
allowBlank: false,
editable: false,
lazyRender: true,
mode: 'local',
store: ['Season 8', 'Cup 8', 'Season 7', 'Cup 7', 'Season 6', 'Cup 6', 'Season 5', 'Cup 5', 'Season 4', 'Cup 4', 'Season 3', 'Cup 3', 'Season 2', 'Cup 2', 'Season 1', 'Cup 1'],
triggerAction: 'all',
xtype: 'combo'
}
}, {
header: 'Date',
sortable: true,
dataIndex: 'date',
xtype: 'datecolumn',
format: 'Y-m-d',
width: 100,
editor: {
allowBlank: false,
editable: true,
emptyText: 'Date',
format: 'Y-m-d',
xtype: 'datefield'
}
}, {
header: 'Time',
sortable: false,
dataIndex: 'time',
editor: {
allowBlank: false,
editable: false,
format: 'H:i:s',
increment: 5,
minValue: '09:00:00',
xtype: 'timefield'
}
}, {
header: 'Referee',
sortable: true,
dataIndex: 'referee',
editor: {
allowBlank: false,
displayField: 'referee',
editable: false,
emptyText: 'Select Referee',
forceSelection: true,
lazyRender: true,
mode: 'remote',
store: storeReferee,
triggerAction: 'all',
valueField: 'id',
xtype: 'combo'
}
}, {
header: 'Ground',
sortable: true,
dataIndex: 'ground',
renderer: rendererGroundLink,
editor: {
allowBlank: false,
displayField: 'ground',
editable: false,
emptyText: 'Select Ground',
forceSelection: true,
lazyRender: true,
mode: 'remote',
store: storeGround,
triggerAction: 'all',
valueField: 'id',
xtype: 'combo'
}
}, {
header: 'Team A',
sortable: true,
dataIndex: 'team_a',
editor: {
allowBlank: false,
displayField: 'team',
editable: false,
emptyText: 'Select Team A',
forceSelection: true,
lazyRender: true,
mode: 'remote',
name: 'team',
store: storeTeam,
triggerAction: 'all',
valueField: 'id',
xtype: 'combo'
}
}, {
header: 'Score A',
sortable: true,
dataIndex: 'score_a',
editor: {
xtype: 'spinnerfield'
}
}, {
header: 'Scorer A',
sortable: false,
dataIndex: 'scorer_a',
editor: {
xtype: 'textarea'
}
}, {
header: 'Team B',
sortable: true,
dataIndex: 'team_b',
editor: {
allowBlank: false,
displayField: 'team',
editable: false,
emptyText: 'Select Team B',
forceSelection: true,
lazyRender: true,
mode: 'remote',
name: 'team',
store: storeTeam,
triggerAction: 'all',
valueField: 'id',
xtype: 'combo'
}
}, {
header: 'Score B',
sortable: true,
dataIndex: 'score_b',
editor: {
xtype: 'spinnerfield'
}
}, {
header: 'Scorer B',
sortable: false,
dataIndex: 'scorer_b',
editor: {
xtype: 'textarea'
}
}
];
// Create the pager
var pagingBar = new Ext.PagingToolbar({
displayInfo: true,
displayMsg: '{0} - {1} of {2}',
emptyMsg: 'No Data',
pageSize: 50,
store: store
});
// Create the Grid
var grid = new xg.GridPanel({
bbar: pagingBar,
columns: columns,
height: 500,
iconCls: 'icon-grid',
loadMask: {
msg: 'Loading data.',
enabled: true
},
plugins: [rowEditor],
renderTo: 'dbGrid',
sm: new Ext.grid.RowSelectionModel({
singleSelect: true
}),
store: store,
stripeRows: true,
tbar: [{
text: 'Add',
iconCls: 'icon-add',
handler: function() {
var record = new store.recordType({
division_id: 1,
date: (new Date()).clearTime(),
time: '10:00:00',
referee: '',
ground: '',
team_a: '',
score_a: '',
team_b: '',
score_b: ''
});
grid.suspendEvents();
rowEditor.stopEditing();
grid.store.insert(0, record);
grid.getView().refresh();
grid.getSelectionModel().selectRow(0);
rowEditor.startEditing(0);
grid.resumeEvents();
}
}, {
iconCls: 'icon-del',
text: 'Remove Fixture',
handler: function() {
rowEditor.stopEditing();
grid.suspendEvents();
var record = grid.getSelectionModel().getSelected();
if (record) {
store.remove(record);
}
store.reload({}, true);
grid.resumeEvents();
}
}],
title: 'Fixtures',
viewConfig: {
forceFit: true
}
});
}
};
}();
Try:
grid.getView().refresh()
Instead of:
store.reload({}, true);
Related
I have a form and a grid. I'm trying to allow the user to select one of the rows in the grid then click a button in order to load the data from the row into the form.
Here is my view so far:
Ext.define('Project.view.main.Main', {
extend: 'Ext.panel.Panel',
autoScroll: true,
height: 600,
layout: 'border',
bodyBorder: false,
defaults: {
collapsible: true,
split: true,
bodyPadding: 10
},
initComponent: function () {
this.items = [
{
collapsible: false,
region: 'center',
margin: '5 0 0 0',
title: 'Record Event',
id: 'SaveEvent',
bodyPadding: 5,
layout: 'column',
items: [{
xtype: 'fieldset',
title: 'Event Information',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [{
xtype: 'fieldcontainer',
fieldLabel: 'Event',
layout: 'hbox',
defaults: {
hideLabel: 'true'
},
items: [{
xtype: 'combobox',
forceSelection: true,
name: 'eventTypeId',
width: 300,
store: {
type: 'events'
},
valueField: 'eventTypeId',
tpl: Ext.create('Ext.XTemplate',
'<ul class="x-list-plain"><tpl for=".">',
'<li role="option" class="x-boundlist-item">{eventType}/{detail}</li>',
'</tpl></ul>'
),
// template for the content inside text field
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{eventType}/{detail}',
'</tpl>'
),
allowBlank: false
}]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'textfield',
fieldLabel: 'Event Number',
name: 'name',
allowBlank: true
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'datefield',
fieldLabel: 'Date',
format: 'Y-m-d',
name: 'startDate',
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
emptyText: 'Start',
allowBlank: false
},
{
xtype: 'datefield',
format: 'Y-m-d',
name: 'endDate',
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
margin: '0 0 0 6',
emptyText: 'End',
allowBlank: false
},
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'tagfield',
fieldLabel: 'Environment',
name: 'environmentIds',
width: 500,
store: {
type: 'environments'
},
valueField: 'environmentId',
displayField: 'environmentName',
allowBlank: false
}]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'tagfield',
fieldLabel: 'Geographic Location',
name: 'geographicLocationIds',
width: 500,
store: {
type: 'locations'
},
valueField: 'locationId',
tpl: Ext.create('Ext.XTemplate',
'<ul class="x-list-plain"><tpl for=".">',
'<li role="option" class="x-boundlist-item">{region}/Sub region: {subRegion}</li>',
'</tpl></ul>'
),
labelTpl: '{region}/Sub region: {subRegion}',
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'textfield',
fieldLabel: 'Geographic Location (Out of Area)',
name: 'geographicLocationNotes',
width: 400,
emptyText: 'e.g. 30.2500 N, 97.7500 W',
allowBlank: true
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'combobox',
forceSelection: true,
fieldLabel: 'Organization',
name: 'organizationId',
store: {
type: 'organizations'
},
valueField: 'organizationId',
displayField: 'displayName',
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'textarea',
fieldLabel: 'Event Notes',
name: 'eventNotes',
width: 500,
height: 74
}
]
},
{
xtype: 'textarea',
fieldLabel: 'Event ID',
name: 'eventId',
hidden: true
}
]
}],
buttons: [
{
text: 'Save Event',
handler: function() {
var form = this.up('form'); // get the form panel
var formData = form.getValues();
if (form.isValid()) { // make sure the form contains valid data before submitting
Ext.Ajax.request({
url: 'api/events/create',
method:'POST',
headers: { 'Content-Type': 'application/json' },
params : Ext.JSON.encode(formData),
success: function(form, action) {
Ext.Msg.alert('Success', action.result);
},
failure: function(form, action) {
Ext.Msg.alert('Submission failed', 'There was an error.', action.result);
}
});
} else { // display error alert if the data is invalid
Ext.Msg.alert('Submit Failed', 'Please make sure you have made selections for each required field.')
}
}
}
]
},
{
title: 'Created Events',
region: 'east',
floatable: false,
margin: '5 0 0 0',
width: 500,
minWidth: 100,
maxWidth: 1000,
collapsed: true,
xtype: 'gridpanel',
store: {
type: 'createdEvents'
},
columns: [
{
header: 'Database ID',
dataIndex: 'eventId'
},
{
header: 'Event',
dataIndex: 'eventTypeId',
renderer: function(value, p, r) {
{return r.data['eventTypeName'] + '/' + r.data['eventDetail']}
}
},
{
header: 'Event Number',
dataIndex: 'name'
},
{
header: 'Start Date',
//this will be a problem because the form date is formatted as yyyy-mm-dd
dataIndex: 'startDateYear',
renderer: function(value, p, r) {
{return r.data['startDateYear'] + '-' + r.data['startDateMonth'] + '-' + r.data['startDateDay']}
}
},
{
header: 'End Date',
dataIndex: 'endDateYear',
renderer: function(value, p, r) {
{return r.data['endDateYear'] + '-' + r.data['endDateMonth'] + '-' + r.data['endDateDay']}
}
},
{
header: 'environments',
dataIndex: 'environmentIds',
renderer: function(value, p, r) {
{return r.data['environmentNames']}
}
},
{
header: 'Geographic Location',
dataIndex: 'geographicLocationIds',
renderer: function(value, p, r) {
{ return r.data['geographicLocationRegion'] + '/' + r.data['geographicLocationSubregion'] }
}
},
{
header: 'Geographic Location Notes',
dataIndex: 'geographicLocationNotes'
},
{
header: 'Organization',
dataIndex: 'organizationID',
renderer: function(value, p, r) {
{return r.data['organizationDisplayName']}
}
},
{
header: 'Event Notes',
dataIndex: 'eventNotes'
}
],
tbar: [{
text: 'Add new record to event',
scope: this,
handler: this.onAddClick
}]
},
];
this.callParent();
},
onAddClick: function(sm, row, rec){
//how to populate the form with the grid row data?
}
});
I've tried this solution, but it didn't work for me:
http://examples.sencha.com/extjs/6.0.0/examples/kitchensink/#form-grid
Your example does not work because there is no form xtype definition nor Ext.form.Panel presented.
Please look carefully to that Sencha - KitchenSink. You will see that there is definition of Ext.form.Panel since KitchenSink.view.form.FormGrid extends from that.
So your first step should be:
Change this
Ext.define('Project.view.main.Main', {
extend: 'Ext.panel.Panel',
to
Ext.define('Project.view.main.Main', {
extend: 'Ext.form.Panel',
and this is example that could potentially works:
Ext.define('Project.view.main.Main', {
extend: 'Ext.form.Panel',
autoScroll: true,
height: 600,
layout: 'border',
bodyBorder: false,
defaults: {
collapsible: true,
split: true,
bodyPadding: 10
},
initComponent: function () {
this.items = [
{
collapsible: false,
region: 'center',
margin: '5 0 0 0',
title: 'Record Event',
id: 'SaveEvent',
bodyPadding: 5,
layout: 'column',
items: [{
xtype: 'fieldset',
title: 'Event Information',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [{
xtype: 'fieldcontainer',
fieldLabel: 'Event',
layout: 'hbox',
defaults: {
hideLabel: 'true'
},
items: [{
xtype: 'combobox',
forceSelection: true,
name: 'eventTypeId',
width: 300,
store: {
type: 'events'
},
valueField: 'eventTypeId',
tpl: Ext.create('Ext.XTemplate',
'<ul class="x-list-plain"><tpl for=".">',
'<li role="option" class="x-boundlist-item">{eventType}/{detail}</li>',
'</tpl></ul>'
),
// template for the content inside text field
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{eventType}/{detail}',
'</tpl>'
),
allowBlank: false
}]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'textfield',
fieldLabel: 'Event Number',
name: 'name',
allowBlank: true
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'datefield',
fieldLabel: 'Date',
format: 'Y-m-d',
name: 'startDate',
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
emptyText: 'Start',
allowBlank: false
},
{
xtype: 'datefield',
format: 'Y-m-d',
name: 'endDate',
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
margin: '0 0 0 6',
emptyText: 'End',
allowBlank: false
},
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'tagfield',
fieldLabel: 'Environment',
name: 'environmentIds',
width: 500,
store: {
type: 'environments'
},
valueField: 'environmentId',
displayField: 'environmentName',
allowBlank: false
}]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'tagfield',
fieldLabel: 'Geographic Location',
name: 'geographicLocationIds',
width: 500,
store: {
type: 'locations'
},
valueField: 'locationId',
tpl: Ext.create('Ext.XTemplate',
'<ul class="x-list-plain"><tpl for=".">',
'<li role="option" class="x-boundlist-item">{region}/Sub region: {subRegion}</li>',
'</tpl></ul>'
),
labelTpl: '{region}/Sub region: {subRegion}',
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'textfield',
fieldLabel: 'Geographic Location (Out of Area)',
name: 'geographicLocationNotes',
width: 400,
emptyText: 'e.g. 30.2500 N, 97.7500 W',
allowBlank: true
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'combobox',
forceSelection: true,
fieldLabel: 'Organization',
name: 'organizationId',
store: {
type: 'organizations'
},
valueField: 'organizationId',
displayField: 'displayName',
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'textarea',
fieldLabel: 'Event Notes',
name: 'eventNotes',
width: 500,
height: 74
}
]
},
{
xtype: 'textarea',
fieldLabel: 'Event ID',
name: 'eventId',
hidden: true
}
]
}],
buttons: [
{
text: 'Save Event',
handler: function() {
var form = this.up('form'); // get the form panel
var formData = form.getValues();
if (form.isValid()) { // make sure the form contains valid data before submitting
Ext.Ajax.request({
url: 'api/events/create',
method:'POST',
headers: { 'Content-Type': 'application/json' },
params : Ext.JSON.encode(formData),
success: function(form, action) {
Ext.Msg.alert('Success', action.result);
},
failure: function(form, action) {
Ext.Msg.alert('Submission failed', 'There was an error.', action.result);
}
});
} else { // display error alert if the data is invalid
Ext.Msg.alert('Submit Failed', 'Please make sure you have made selections for each required field.')
}
}
}
]
},
{
title: 'Created Events',
region: 'east',
floatable: false,
margin: '5 0 0 0',
width: 500,
minWidth: 100,
maxWidth: 1000,
collapsed: true,
xtype: 'gridpanel',
store: {
type: 'createdEvents'
},
columns: [
{
header: 'Database ID',
dataIndex: 'eventId'
},
{
header: 'Event',
dataIndex: 'eventTypeId',
renderer: function(value, p, r) {
{return r.data['eventTypeName'] + '/' + r.data['eventDetail']}
}
},
{
header: 'Event Number',
dataIndex: 'name'
},
{
header: 'Start Date',
//this will be a problem because the form date is formatted as yyyy-mm-dd
dataIndex: 'startDateYear',
renderer: function(value, p, r) {
{return r.data['startDateYear'] + '-' + r.data['startDateMonth'] + '-' + r.data['startDateDay']}
}
},
{
header: 'End Date',
dataIndex: 'endDateYear',
renderer: function(value, p, r) {
{return r.data['endDateYear'] + '-' + r.data['endDateMonth'] + '-' + r.data['endDateDay']}
}
},
{
header: 'environments',
dataIndex: 'environmentIds',
renderer: function(value, p, r) {
{return r.data['environmentNames']}
}
},
{
header: 'Geographic Location',
dataIndex: 'geographicLocationIds',
renderer: function(value, p, r) {
{ return r.data['geographicLocationRegion'] + '/' + r.data['geographicLocationSubregion'] }
}
},
{
header: 'Geographic Location Notes',
dataIndex: 'geographicLocationNotes'
},
{
header: 'Organization',
dataIndex: 'organizationID',
renderer: function(value, p, r) {
{return r.data['organizationDisplayName']}
}
},
{
header: 'Event Notes',
dataIndex: 'eventNotes'
}
],
listeners: {
scope: this,
selectionchange: this.onSelectionChange
}
}
];
this.callParent();
},
onSelectionChange: function(model, records) {
var rec = records[0];
if (rec) {
this.getForm().loadRecord(rec);
}
}
});
I have a form that has comboboxes, tagfields, date pickers, etc., and a grid. Each of these elements has a different store. The user is going to make selections from the comboboxes, etc,. and enter values into the grid. Then the values from the grid and other form elements are all sent on a POST to the server. I know how to POST the data from the comboboxes, tagfields, and date pickers. However, I don't know how to send the data in the grid with the form. Here is the form view:
Ext.define('ExtTestApp.view.main.List', {
extend: 'Ext.form.Panel',
xtype: 'cell-editing',
frame: true,
autoScroll: true,
title: 'Record Event',
bodyPadding: 5,
requires: [
'Ext.selection.CellModel',
'ExtTestApp.store.Personnel'
],
layout: 'column',
initComponent: function(){
this.cellEditing = new Ext.grid.plugin.CellEditing({
clicksToEdit: 1
});
Ext.apply(this, {
//width: 550,
fieldDefaults: {
labelAlign: 'left',
labelWidth: 90,
anchor: '100%',
msgTarget: 'side'
},
items: [{
xtype: 'fieldset',
//width: 400,
title: 'Event Information',
//height: 460,
//defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [{
xtype: 'fieldcontainer',
fieldLabel: 'Event',
layout: 'hbox',
defaults: {
hideLabel: 'true'
},
items: [{
xtype: 'combobox',
name: 'eventTypeId',
width: 300,
//flex: 1,
store: {
type: 'events'
},
valueField: 'eventTypeId',
// Template for the dropdown menu.
// Note the use of the "x-list-plain" and "x-boundlist-item" class,
// this is required to make the items selectable.
allowBlank: false
}
]
},
{
xtype: 'container',
layout: 'hbox',
margin: '0 0 5 0',
items: [
{
xtype: 'datefield',
fieldLabel: 'Date',
format: 'Y-m-d',
name: 'startDate',
//msgTarget: 'under', //location of error message, default is tooltip
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
//flex: 1,
emptyText: 'Start',
allowBlank: false
},
{
xtype: 'datefield',
format: 'Y-m-d',
name: 'endDate',
//msgTarget: 'under', //location of error message
invalidText: '"{0}" is not a valid date. "{1}" would be a valid date.',
//flex: 1,
margin: '0 0 0 6',
emptyText: 'End',
allowBlank: false
}
]
}]
},
{
xtype: 'fieldset',
//height: 460,
title: 'Platform Information',
//defaultType: 'textfield',
layout: 'anchor',
defaults: {
anchor: '100%'
},
items: [
{
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Platform',
//combineErrors: true,
defaults: {
hideLabel: 'true'
},
items: [
{
xtype: 'combobox',
name: 'platformId',
store: {
type: 'platforms'
},
valueField: 'platformId',
allowBlank: false
}
]
}
]
},
{
xtype: 'fieldcontainer',
layout: 'hbox',
fieldLabel: 'Software Type(s)',
//combineErrors: true,
defaults: {
hideLabel: 'true'
},
items: [
{
xtype: 'tagfield',
width: 400,
//height: 50,
fieldLabel: 'Software Type(s)',
name: 'softwareTypeIds',
store: {
type: 'softwareTypes'
},
labelTpl: '{softwareName} - {manufacturer}',
valueField: 'softwareTypeId',
allowBlank: false
}
]
},
{
xtype: 'gridpanel',
layout: 'anchor',
defaults: {
anchor: '100%'
},
width: 1300,
//columnWidth: 0.78,
//title: 'Metrics',
plugins: [this.cellEditing],
title: 'Personnel',
store: {
type: 'personnel'
},
columns: [
{ text: 'Name', dataIndex: 'name', editor: 'textfield' },
{ text: 'Email', dataIndex: 'email', flex: 1 },
{ text: 'Phone', dataIndex: 'phone', flex: 1 }
]
}
],
buttons: [
{
text: 'Save Event',
handler: function() {
var form = this.up('form'); // get the form panel
// if (form.isValid()) { // make sure the form contains valid data before submitting
Ext.Ajax.request({
url: 'api/events/create',
method:'POST',
headers: { 'Content-Type': 'application/json' },
params : Ext.JSON.encode(form.getValues()),
success: function(form, action) {
Ext.Msg.alert('Success', action.result);
},
failure: function(form, action) {
//console.log(form.getForm().getValues());
Ext.Msg.alert('Submission failed', 'Please make sure you selected an item for each required field.', action.result);
}
});
// } else { // display error alert if the data is invalid
// Ext.Msg.alert('Submit Failed', 'Please make sure you have made selections for each required field.')
// }
}
}
]
});
this.callParent();
}
});
var grid = Ext.ComponentQuery.query('grid')[0];
Here is the store for the grid:
Ext.define('ExtTestApp.store.Personnel', {
extend: 'Ext.data.Store',
alias: 'store.personnel',
fields: [
'name', 'email', 'phone'
],
data: { items: [
{ 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: true,
proxy: {
type: 'memory',
api: {
update: 'api/update'
},
reader: {
type: 'json',
rootProperty: 'items'
},
writer: {
type: 'json',
writeAllFields: true,
rootProperty: 'items'
}
}
});
Ideally, you would need to create a custom "grid field" so that the grid data is picked up on form submit like any other field.
You can also use this workaround: in the "Save Event" button handler, dig out the grid store and fish data out of it:
var gridData = [];
form.down('gridpanel').store.each(function(r) {
gridData.push(r.getData());
});
Then get the rest of the form data and put the grid data into it:
var formData = form.getValues();
formData.gridData = gridData;
Finally, include it all in your AJAX call:
params: Ext.JSON.encode(formData)
I had created a demo page using ExtJS for the first time.
I have created the .JS file as below.
Ext.require([
//'Ext.form.*',
//'Ext.layout.container.Column',
//'Ext.tab.Panel'
'*'
]);
Ext.onReady(function() {
Ext.QuickTips.init();
var bd = Ext.getBody();
var required = '<span style="color:red;font-weight:bold" data-qtip="Required">*</span>';
var simple = Ext.widget({
xtype: 'form',
layout: 'form',
collapsible: true,
id: 'userForm',
frame: true,
title: 'User Details',
bodyPadding: '5 5 0',
align: 'center',
width: 350,
buttonAlign: 'center',
fieldDefaults: {
msgTarget: 'side',
labelWidth: 75
},
defaultType: 'textfield',
items: [{
id: 'txtName',
fieldLabel: 'Name',
name: 'name',
afterLabelTextTpl: required,
allowBlank: false
}, {
id: 'dDOJ',
fieldLabel: 'Date Of Joining',
name: 'doj',
xtype: 'datefield',
format: 'd/m/Y',
afterLabelTextTpl: required,
allowBlank: false
}, {
id: 'txtAge',
fieldLabel: 'Age',
name: 'age',
xtype: 'numberfield',
minValue: 0,
maxValue: 100,
afterLabelTextTpl: required,
allowBlank: false
}, {
id: 'chkActive',
xtype: 'checkbox',
boxLabel: 'Active',
name: 'cb'
}],
buttons: [{
text: 'ADD',
listeners: {
click: {
fn: function() {
debugger;
if (Ext.getCmp('txtName').getValue() == "" || Ext.getCmp('dDOJ').getValue() == "" || Ext.getCmp('txtAge').getValue() == "") {
alert("Please Enter All Required Details!");
return false;
}
var reply = confirm("Are You Sure You Want To Save?")
if (reply != false) {
fnShowGrid();
}
}
}
}
}]
});
simple.render(document.body);
});
function fnShowGrid() {
debugger;
var vName = Ext.getCmp('txtName').getValue();
var vDOJ = Ext.Date.format(Ext.getCmp('dDOJ').getValue(), 'd/m/Y');
var vAge = Ext.getCmp('txtAge').getValue();
var vIsActive = "InActive";
if (Ext.getCmp('chkActive').getValue() == true) {
vIsActive = "Active";
}
var store = Ext.create('Ext.data.ArrayStore', {
storeId: 'myStore',
idIndex: 0,
fields: [
{ name: 'name' },
{ name: 'doj' },
{ name: 'age' },
{ name: 'active' }
],
//data: { name: vName, doj: vDOJ, age: vAge, active: vIsActive}
data: [[vName, vDOJ, vAge, vIsActive]]
});
store.load({
params: {
start: 1,
limit: 3
}
});
Ext.create('Ext.grid.Panel', {
title: 'User Details',
store: store,
columns: [
{
header: 'Name',
width: 160,
sortable: true,
dataIndex: 'name'
},
{
header: 'Date Of Join',
width: 75,
sortable: true,
dataIndex: 'doj'
},
{
header: 'Age',
width: 75,
sortable: true,
dataIndex: 'age'
},
{
header: 'Active',
width: 75,
sortable: true,
dataIndex: 'active'
}],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
//detailsGrid.render(document.body);
}
The gridPanel is being displayed. But each time add a new data its creating a new grid!
I want to display GridPanel only once including all before added data.
Here's fiddle: http://jsfiddle.net/pratikhsoni/wc9mD/1/
Here is the working example based on your fiddle!
Ext.require([
'*'
]);
store = Ext.create('Ext.data.ArrayStore', {
storeId: 'myStore',
idIndex: 0,
fields: [
{ name: 'name' },
{ name: 'doj' },
{ name: 'age' },
{ name: 'active' }
],
//data: { name: vName, doj: vDOJ, age: vAge, active: vIsActive}
});
Ext.onReady(function() {
Ext.QuickTips.init();
var bd = Ext.getBody();
var required = '<span style="color:red;font-weight:bold" data-qtip="Required">*</span>';
var simple = Ext.widget({
xtype: 'form',
layout: 'form',
collapsible: true,
id: 'userForm',
frame: true,
title: 'User Details',
bodyPadding: '5 5 0',
align: 'center',
width: 350,
buttonAlign: 'center',
fieldDefaults: {
msgTarget: 'side',
labelWidth: 75
},
defaultType: 'textfield',
items: [{
id: 'txtName',
fieldLabel: 'Name',
name: 'name',
afterLabelTextTpl: required,
allowBlank: false
}, {
id: 'dDOJ',
fieldLabel: 'Date Of Joining',
name: 'doj',
xtype: 'datefield',
format: 'd/m/Y',
afterLabelTextTpl: required,
allowBlank: false
}, {
id: 'txtAge',
fieldLabel: 'Age',
name: 'age',
xtype: 'numberfield',
minValue: 0,
maxValue: 100,
afterLabelTextTpl: required,
allowBlank: false
}, {
id: 'chkActive',
xtype: 'checkbox',
boxLabel: 'Active',
name: 'cb'
}],
buttons: [{
text: 'ADD',
listeners: {
click: {
fn: function() {
debugger;
if (Ext.getCmp('txtName').getValue() == "" || Ext.getCmp('dDOJ').getValue() == "" || Ext.getCmp('txtAge').getValue() == "") {
alert("Please Enter All Required Details!");
return false;
}
var reply = confirm("Are You Sure You Want To Save?")
if (reply != false) {
fnShowGrid();
}
}
}
}
}]
});
simple.render(document.body);
});
function fnShowGrid() {
debugger;
var vName = Ext.getCmp('txtName').getValue();
var vDOJ = Ext.Date.format(Ext.getCmp('dDOJ').getValue(), 'd/m/Y');
var vAge = Ext.getCmp('txtAge').getValue();
var vIsActive = "InActive";
if (Ext.getCmp('chkActive').getValue() == true) {
vIsActive = "Active";
}
if (!Ext.getCmp('sample-grid')) {
store.add({
name: vName,
doj: vDOJ,
age: vAge,
active: vIsActive
});
Ext.create('Ext.grid.Panel', {
title: 'User Details',
store: store,
id: 'sample-grid',
columns: [
{
header: 'Name',
width: 160,
sortable: true,
dataIndex: 'name'
},
{
header: 'Date Of Join',
width: 75,
sortable: true,
dataIndex: 'doj'
},
{
header: 'Age',
width: 75,
sortable: true,
dataIndex: 'age'
},
{
header: 'Active',
width: 75,
sortable: true,
dataIndex: 'active'
}
],
height: 200,
width: 400,
renderTo: Ext.getBody()
});
} else {
store.add({
name: vName,
doj: vDOJ,
age: vAge,
active: vIsActive
});
}
}
First of All.
Its very good to see you getting touch with EXT js. Mistake's i will like to highlight in your code.
1. if (reply != false) {
fnShowGrid();
}
In this you are calling your grid to be created which is being called why you are creating a new grid . you just have to update the store.
Approach: You must call it only once check if it exist and if yes then update the store like this.
if (reply != false) {
if(!Ext.getCmp('hello')) {
fnShowGrid();
} else {
var store=Ext.getCmp('hello').getStore();
store.add ({
name: 'sadad',
doj:'25/01/2015',
age:'26',
active:'false'
});
store.reload();
}
}
So in all you have to update the store add the new records. I have hardcoded right now you can get the values as you have got when creating it.
Please find Updated fiddle.
Fiddle
I am having trouble adding new entries to a store / grid in ExtJS 4.2. The create action runs on the server and returns a generated id for the new record. I can start on edit on the row that does not show up in the grid. The error I get after syncing is: Uncaught TypeError: Cannot read property 'parentNode' of null.
projectStore.js:
var projectStore = Ext.create('Ext.data.Store', {
model: 'ProjectModel',
storeId: 'projectStore',
autoLoad: true,
autoSync: true,
proxy: {
type: 'ajax',
api: {
create: webPath+'server.php?action=createProjectStore',
read: webPath+'server.php?action=readProjectsStore',
update: webPath+'server.php?action=updateProjectStore',
destroy: webPath+'server.php?action=destroyProjectStore'
},
extraParams: {
token: userDetails.token,
userName: userDetails.UserName
},
reader: {
type: 'json',
successProperty: 'success',
idProperty: "ProjectID",
root: 'data',
messageProperty: 'message'
},
writer: {
type: 'json',
writeAllFields: true,
root: 'data',
encode: true,
allowSingle: false
},
listeners: {
exception: function(proxy, response, operation){
// Ext.MessageBox.show({
// title: 'REMOTE EXCEPTION',
// msg: operation.getError(),
// icon: Ext.MessageBox.ERROR,
// buttons: Ext.Msg.OK
// });
operation.records[0].reject();
}
},
onUpdateRecords: function(records, operation, success) {
console.log(records);
}
}
});
projectModel.js:
Ext.define('ProjectModel', {
extend: 'Ext.data.Model',
idProperty: 'ProjectID',
fields: [ {
name: 'ProjectID',
type: 'int'
}, 'AccountName', 'AccountID', 'ProjectName', 'Deleted']
});
userProfileProjects.js
Ext.require([
'Ext.grid.Panel',
'Ext.form.*',
'Ext.window.Window',
'Ext.data.*'
]);
$(document).data('mcal.userAccountFixPopupOpen', false);
$(document).data('mcal.newProjectRecord', false);
var userProfileProjectRowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 1
});
Ext.define('User.Project.Grid', {
extend: 'Ext.grid.Panel',
alias: 'widget.userProjectsGrid',
initComponent: function(){
this.editing = userProfileProjectRowEditing;
this.onRemoveProject = function(grid, rowIndex, colIndex) {
grid.getStore().removeAt(rowIndex);
}
Ext.apply(this, {
dockedItems: [{
xtype: 'toolbar',
items: ['->',
{
text: 'Add Project',
handler : function() {
userProfileProjectRowEditing.cancelEdit();
// Create a model instance
var r = Ext.create('ProjectModel', {
ProjectName: 'New Project'
});
projectStore.insert(0, r);
$(document).data('mcal.newProjectRecord', true);
userProfileProjectRowEditing.startEdit(0, 0);
}
},
{
iconCls: 'icon-refresh',
text: 'Refresh',
scope: this,
handler: this.onRefresh
}]
}],
columns: [
{
text: 'Account',
width: 115,
sortable: true,
hidden: false,
dataIndex: 'AccountID',
renderer: function(value){
var accountID = userAccountTimeLimitedStore.getAt(userAccountTimeLimitedStore.find('key', value));
return accountID.get('AccountName');
},
editor: {
xtype: 'combobox',
valueField: 'key',
displayField: 'AccountName',
triggerAction: 'all',
queryMode: 'local',
store: userAccountTimeLimitedStore
},
flex: 1
},
{
text: 'Project',
width: 115,
sortable: true,
dataIndex: 'ProjectName',
field: {
type: 'textfield'
},
flex: 1,
hidden: false
},
{
xtype:'actioncolumn',
text: 'Delete',
width:45,
align: 'center',
editRenderer: function(){ return ''},
items: [{
icon: webPath+'/images/remove.png', // Use a URL in the icon config
tooltip: 'Edit',
handler: this.onRemoveProject
}]
}
],
selType: 'rowmodel',
plugins: [this.editing]
});
this.callParent();
},
onRefresh: function(){
this.store.reload();
}
});
function initUserProjectGrid(){
window.main = Ext.create('Ext.container.Container', {
padding: '0 0 0 0',
width: 380,
height: 200,
renderTo: Ext.get('userProjectGridDiv'),
layout: {
type: 'vbox',
align: 'stretch'
},
items: [{
itemId: 'userProfileProjectGrid',
xtype: 'userProjectsGrid',
title: 'Projects',
flex: 1,
store: 'projectStore'
}]
});
// main.getComponent('userProfileProjectGrid').editing.editor.form.findField('AccountName').disable();
var localEdit = main.getComponent('userProfileProjectGrid').editing;
localEdit.on('beforeedit', function(editor, context, eOpts){
if($(document).data('mcal.newProjectRecord') != true){
localEdit.editor.form.findField('AccountID').disable();
}else{
localEdit.editor.form.findField('AccountID').enable();
}
});
localEdit.on('afteredit', function(){
$(document).data('mcal.newProjectRecord', false);
});
}
I have this code in my application, but this not load any data. Data is accessible but wont display in my gridpanel, anyone have idea, why?
Ext.onReady(function () {
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = 'side';
var btnAdd = new Ext.Button({
id: 'btnAdd',
text: 'Adicionar',
iconCls: 'application_add',
handler: function (s) {
}
});
var btnEdit = new Ext.Button({
id: 'btnEdit',
text: 'Editar',
iconCls: 'application_edit',
handler: function (s) {
}
});
var btnRemove = new Ext.Button({
id: 'btnRemove',
text: 'Apagar',
iconCls: 'application_delete',
handler: function (s) {
}
});
var tbar = new Ext.Toolbar({
items: [btnAdd, btnEdit, btnRemove]
});
var formFind = new Ext.FormPanel({
height: 100
});
var store = new Ext.data.JsonStore({
remoteSort: true,
idProperty: 'ContentId',
root: 'rows',
totalProperty: 'results',
fields: [
{ name: 'ContentId', type: 'int' },
{ name: 'Name' },
{ name: 'Version' },
{ name: 'State' },
{ name: 'CreatedDateTime' },
{ name: 'PublishedDateTime'},
{ name: 'CreatedByUser' },
{ name: 'PublishedByUser' }
],
proxy: new Ext.data.ScriptTagProxy({
url: '/Admin/ArticleList'
})
});
store.setDefaultSort('ContentId', 'desc');
var paging = new Ext.PagingToolbar({
store: store,
pageSize: 25,
displayInfo: true,
displayMsg: 'Foram encontrados {2} registos. Mostrando {0} de {1}',
emptyMsg: "Nenhum registo encontrado."
});
var grid = new Ext.grid.GridPanel({
id: 'grid',
height: 700,
store: store,
loadMask: true,
loadingText: 'Carregando...',
autoHeight: true,
cm: new Ext.grid.ColumnModel ([
{ id: 'ContentId', dataIndex: 'ContentId', header: 'Identif.', width: 60, sortable: true },
{ id: 'Name', dataIndex: 'Name', header: 'Titulo', width: 75, sortable: true },
{ id: 'Version', dataIndex: 'Version', header: 'Versão', width: 75, sortable: true },
{ id: 'State', dataIndex: 'State', header: 'Estado', width: 75, sortable: true },
{ id: 'CreatedDateTime', dataIndex: 'CreatedDateTime', header: 'Data de Criação', width: 85, sortable: true },
{ id: 'PublishedDateTime', dataIndex: 'PublishedDateTime', header: 'Data de Publicação', width: 75, sortable: true },
{ id: 'CreatedByUser', dataIndex: 'CreatedByUser', header: 'Criado por', width: 75, sortable: true },
{ id: 'PublishedByUser', dataIndex: 'PublishedByUser', header: 'Publicado por', width: 85, sortable: true }
]),
stripeRows: true,
viewConfig: { forceFit: true },
bbar: paging
});
var panel = new Ext.Panel({
id: 'panel',
renderTo: Ext.getBody(),
layout: 'fit',
tbar: tbar,
items: [grid]
});
store.load(); // trigger the data store load
});
You shouldn't be using a ScriptTagProxy. If you read the docs you'll see that it's used only in limited cases to retrieve context from remote server in a particular format.
You want a HttpProxy instead.