I can not add new record in EditorGridPanel - extjs

I currently teach EditorGridPanel in Ext JS 3.1.0. I managed to create a grid that shows a list of cities. However, I have a problem when I try to add a new record into the database. When I click the button 'Add City' nothing happens and Firebug shows an error:
Uncaught ReferenceError: newCity is not defined
Ext.grid.EditorGridPanel.tbar.handlereg02.html: 96
Ext.Button.Ext.extend.onClickext-all-debug.js: 27083
h
This is my code:
Ext.onReady(function(){
//===== Data Store ================================================== (2)
var store = new Ext.data.Store({
url: 'city_for_eg01.php',
reader: new Ext.data.JsonReader({
root:'rows',
id:'zip'
}, [
'zip',
'city'
]),
api: {
create : 'city_for_eg01.php?action=create',
read : 'city_for_eg01.php?action=read',
update: 'city_for_eg01.php?action=update',
destroy: 'city_for_eg01.php?action=destroy'
},
writer: new Ext.data.JsonWriter({
writeAllFields: true
}),
autoSave: false,
});
store.load();
//=================================================================== end (2)
var editor = new Ext.form.TextField();
var grid = new Ext.grid.EditorGridPanel({
renderTo: document.body,
frame:true,
title: 'City',
height:200,
width:520,
clickstoEdit: 1,
store: store,
columns: [
{header: "ZIP", dataIndex: 'zip', editor: editor},
{header: "CITY", dataIndex: 'city', editor: editor},
],
listeners: {
afteredit: function(e){e.record.commit();}
},
tbar: [{
text: 'Add City',
icon: 'images/table_add.png',
cls: 'x-btn-text-icon',
handler: function() {
Ext.Ajax.request({
url: 'city-update.php',
params: {
action: 'create',
zip: 'zip'
},
success: function(resp,opt) {
grid.getStore().insert(0,
new newCity{
zip: 'New Zip',
city: 'New City'
})
);
grid.startEditing(0,0);
},
failure: function(resp,opt) {
Ext.Msg.alert('Error','Unable to add city');
}
});
}
}]
});
});

This is because there is no newCity function defined.
You should be able to make it work with:
new store.recordType(/* values */)
The recordType holds the constructor for a new Record for that store.

Related

ExtJS Drag & Drop gives "TypeError: path is undefined" on drop

I'm using ExtJS 6.0.1 and want to drag items from a grid over a tree so I can change some category values into the grid records.
But on drop event I get this error: "TypeError: path is undefined". The error is returned by the function ensureVisible from Ext.tree Panel class, first line.
var foldersStore = Ext.create("Ext.data.TreeStore",{
storeId: 'foldersTreeStore',
proxy: {
type: 'ajax',
url: 'categories/tree.json'
},
autoLoad: true
});
var foldersTree = Ext.create("Ext.tree.Panel",{
title: 'Categories',
hideHeaders: true,
renderTo: 'folders-tree',
rootVisible: false,
allowDeselect: true,
store: foldersStore,
droppedRecords: undefined,
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
dragText: 'Drag and drop to reorganize',
dropGroup: 'bkmDDGroup',
appendOnly: true
},
listeners: {
beforedrop: function(node, data, overModel, dropPos, opts) {
this.droppedRecords = data.records;
data.records = [];
console.log(this.droppedRecords);
},
drop: function(node, data, overModel, dropPos, opts) {
console.log(arguments);
}
}
}
});
var filesStore = Ext.create("Ext.data.Store",{
storeId:'filesTableStore',
fields:[
{name: 'eid', type:'string'},
{name: 'fileName', type:'string'},
{name: 'createdAt', type:'string'},
{name: 'mimeType', type:'string'},
{name: 'version', type:'string'},
{name: 'size', type:'int'},
{name: 'creator', type:'string'},
{name: 'modifier', type:'string'},
{name: 'status', type:'string'},
{name: 'tmpId'}
],
proxy: {
type: 'ajax',
url: 'documents/list.json',
reader: {
type: 'json',
rootProperty: "list"
}
},
autoLoad: true
});
var filesTable = Ext.create("Ext.grid.Panel",{
store: filesStore,
title:'Files',
selModel: {
mode: "MULTI",
allowDeselect: true
},
columns:[
{
text:'File Name',
flex:1,
dataIndex:'fileName'
},{
text:'Created By',
flex:1,
dataIndex:'creator'
},{
text:'Mime Type',
width: 150,
dataIndex:'mimeType'
},{
text:'Size',
width: 100,
dataIndex:'size'
},{
text:'Version',
width: 80,
dataIndex: 'version'
},{
text:'Status',
width: 100,
dataIndex:'status'
},{
text:'Created At',
width:150,
dataIndex:'createdAt'
}],
renderTo:'files-table',
height:UI.getContentHeight("#files-table"),
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragText: 'Drag and drop to reorganize',
dragGroup: 'bkmDDGroup'
}
}
});
From my point of view looks like I've forgot some config, still don't have any idea yet. Even if I have a single console.log line in drop event, the error remains the same.
Any clues will be much appreciated.
Thanks
In the beforedrop listener you are deleting the records you've selected:
data.records = []
Instead you must prepare that records to drop into TreePanel where data model differs from the grid.
Link to the realization

ExtJS combobox: the values loaded but doesn't show

This my code to add combobox in extjs version 2.2 ..... the data is loaded and showed empty rows and when select any row it get the right item and i want to align the label to left
Thanks in advance
Ext.onReady(function(){
var relationValues = new Ext.data.Store({
reader: new Ext.data.JsonReader({
fields: ['DKEY', 'NAME_AR', 'NAME_EN'],
root: 'rows'
}),
proxy: new Ext.data.HttpProxy({
url: 'LoadRelation'
}),
autoLoad: true
});
var userForm = new Ext.form.FormPanel({
standardSubmit: true,
frame:true,
title: 'User Information',
width: 350,
defaults: {width: 230},
defaultType: 'textfield',
items: [
{
xtype: 'combo',
name: 'relation',
fieldLabel: 'Relation',
mode: 'local',
store: relationValues,
displayField:'NAME_EN',
valueField: 'DKEY',
//anchor: '100%',
listeners: {
select: function(f,r,i){
console.log(r);
}
}
}
],
buttons: [{
text: 'Insert',
handler: function() {
userForm.getForm().getEl().dom.action = 'login';
userForm.getForm().getEl().dom.method = 'POST';
userForm.getForm().submit();
}
},{
text: 'Reset',
handler: function() {
userForm.getForm().reset();
}
}]
});
userForm.render('mydiv');
});

how to call an addRow view method from an ExtJS4 controller

I have a controller and a view and want to push a line from a controller when item is selected.
Where it says onItemSelect: that's where I need to make a call, and don't know how...
Thank you.
controller is this:
Ext.define('Application.controller.ItemController', {
// Extend basic controller object
extend: 'Ext.app.Controller',
// Attach store classes to this controller
stores: ['Items'],
// Attach model classes to this controller
models: ['Item'],
// ..and last but not least - the view classes
views: ['item.List', 'item.Show'],
// Refs parameter defines references to certain
// instances of components pointed by selector
refs: [
{
// Ref determines the name of the automagic
// this.get[ref-goes-here] method that returns
// instance of certain component
ref : 'itemShowDesc',
// Select #item-description component in
// item.Show view
selector: 'itemShow > #item-description'
}
],
// when including the controllers in your application,
// the framework will automatically load the controller
// and call the init method on it
init: function() {
this.control({
'itemList' : {
// Action to be performed on select
select: this.onItemSelect
}
});
},
onItemSelect: function (selModel, selection) {
// Executed only when selection is a leaf
(selection.data.leaf) ? this.getItemShowDesc().addRow(selection.raw.description,'','','','','','') : null;
}
});
and the view is this:
Ext.define('Application.view.item.Show', {
extend: 'Ext.grid.Panel',
alias : 'widget.itemShow',
requires: [
'Ext.selection.CellModel',
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.form.*',
'Application.model.Item'
],
xtype: 'cell-editing',
title: 'Favorite Books',
frame: true,
initComponent: function() {
this.cellEditing = new Ext.grid.plugin.CellEditing({
clicksToEdit: 1
});
Ext.apply(this, {
width: 680,
height: 350,
plugins: [this.cellEditing],
store: new Ext.data.Store({
// destroy the store if the grid is destroyed
autoDestroy: true,
model: Application.model.Item,
proxy: {
type: 'ajax',
// load remote data using HTTP
url: 'resources/data/grid/books.xml',
// specify a XmlReader (coincides with the XML format of the returned data)
reader: {
type: 'xml',
// records will have a 'plant' tag
record: 'book'
}
},
sorters: [{
property: 'common',
direction:'ASC'
}]
}),
columns: [{
header: 'Book Id',
dataIndex: 'item_id',
width: 100
}, {
header: 'Author',
dataIndex: 'author',
width: 100
}, {
header: 'Title',
dataIndex: 'title',
width: 250
},{
header: 'Description',
dataIndex: 'description',
width: 495
},{
header: 'Price',
dataIndex: 'price',
width: 70,
align: 'right',
renderer: 'usMoney'
},{
xtype: 'actioncolumn',
width: 30,
sortable: false,
menuDisabled: true,
items: [{
icon: 'resources/images/icons/delete.gif',
tooltip: 'Delete Plant',
scope: this,
handler: this.onRemoveClick
}]
}],
selModel: {
selType: 'cellmodel'
}
});
this.callParent();
this.on('afterlayout', this.loadStore, this, {
delay: 1,
single: true
})
},
addRow: function(inItemID,inDisplay,inSex,inAuthor,inTitle,inDescription,inPrice){
// Create a record instance through the ModelManager
var r = Ext.ModelManager.create({
item_id: inItemID,
display: inDisplay,
sex: inSex,
author: inAuthor,
title: inTitle,
description: inDescription,
price: inPrice
}, 'Item');
store.insert(0, r);
cellEditing.startEditByPosition({row: 0, column: 0});
}
,
loadStore: function() {
this.getStore().load({
// store loading is asynchronous, use a load listener or callback to handle results
callback: this.onStoreLoad
});
},
onStoreLoad: function(){
Ext.Msg.show({
title: 'Store Load Callback',
msg: 'Favorites were loaded, data available for processing',
icon: Ext.Msg.INFO,
buttons: Ext.Msg.OK
});
},
onRemoveClick: function(grid, rowIndex){
this.getStore().removeAt(rowIndex);
}
})
Your ref for itemShowDesc is selecting a child component of itemShow. So when you do this.getItemShowDesc().addRow(), you're calling a method on whatever #item-description is, not on the Application.view.item.Show class.

ExtJS PagingToolbar trouble

I novice in extJS.
I have trouble with PagingToolbar and Store. When I click to 'next page' PagingToolbar works correctly , but the gride don't update. Why is this happening? Help me please.
This's my code:
`
getJsonReader: function(){
this.JsonReader = new Ext.data.JsonReader({
totalProperty: 'results',
root: 'data',
idProperty: 'id',
fields: [
{name:'id', type: 'int', allowBlank: false},
{name: 'firstName', allowBlank: false},
{name: 'lastName', allowBlank: false},
{name: 'middleName',allowBlank: false},
{name: 'fotoTeacher',allowBlank: false}
]
});
return this.JsonReader;
},
getStore: function(){
this.store = new Ext.data.Store({
id: 'store-teachers',
reader: this.getJsonReader(),
proxy: new Ext.data.HttpProxy({
method: 'POST',
url: 'admin/get_teachers'
}),
autoLoad: {params:{start:0, limit:3}},
listeners: {
load: function()
{
if(jQuery('#panel-editTeacherHtml').length)
{
//remove attention
jQuery('#panel-editTeacherHtml').remove();
}
Ext.getCmp('grid-editTeacher').show();
},
exception: function()
{
Ext.getCmp('grid-editTeacher').hide();
if(!document.getElementById('panel-editTeacherHtml'))
{
Ext.DomHelper.insertAfter('panel-editTeacher-refreshButton',{
id: 'panel-editTeacherHtml',
html:'Увы, но нет ни одного преподавателя =('
});
}
}
}
});
return this.store;
},
titleTeacherfoto: function(val)
{
return '<img src="'+val+'" />';
},
getGrid: function(){
this.grid = new Ext.grid.GridPanel({
frame : true,
autoHeight:true,
id:'grid-editTeacher',
loadMask: true,
store: this.getStore(),
sm: new Ext.grid.CheckboxSelectionModel({
singleSelect: false,
checkOnly: true
}),
cm: new Ext.grid.ColumnModel({
{header: 'Фамилия', dataIndex: 'lastName'},
{header: 'Имя', dataIndex: 'firstName', sortable: false},
{header: 'Отчество', dataIndex: 'middleName', sortable: false},
{header: 'Фотография', dataIndex: 'fotoTeacher', renderer: this.titleTeacherfoto}
],
defaultSortable: true
}),
viewConfig: {
forceFit:true
},
bbar: new Ext.PagingToolbar({
id:'pager-editTeacher',
displayInfo: true,
displayMsg: 'Преподаватели {0} - {1} из {2}',
beforePageText: 'Страница',
afterPageText: 'из {0}',
prependButtons: true,
pageSize: 3,
store: this.getStore()
})
})
return this.grid;
},
getPanel: function(){
return new Ext.Panel({
frame: true,
bodyStyle: 'padding:5px;',
id: 'panel-editTeacher',
autoScroll: true,
title: 'Панель редактирования преподавателей',
items: [{
xtype: 'button',
text: 'Обновить',
iconCls: 'refresh',
id:'panel-editTeacher-refreshButton',
style: 'margin-bottom:10px',
listeners:{
click: function(){
grid = Ext.getCmp('grid-editTeacher');
grid.getStore().reload();
Ext.getCmp('pager-editTeacher').doRefresh();
}
}
},
this.getGrid()
]
});
}
Ajax responce
{success:true,
results:5,
data:[{"id":"1","firstName":"","lastName":"","middleName":"","fotoTeacher":"\/modules\/admin\/design\/img\/default\/teacher_thumb.jpg"},{"id":"2","firstName":"","lastName":"","middleName":"","fotoTeacher":"\/modules\/admin\/design\/img\/default\/teacher_thumb.jpg"},{"id":"3","firstName":"","lastName":"","middleName":"","fotoTeacher":"\/modules\/admin\/design\/img\/default\/teacher_thumb.jpg"}]}
P.s: Sorry for my english =)
I think your problem is that every time you click the button, a new store is created, and in the process a new Reader object.
getStore: function(){
this.store = new Ext.data.Store({
....
So if you click the button, what happens is:
grid.getStore().reload();
//GridInstance.createANewStoreForMe(andCreateANewReaderForYourself).reload
So, the newly created store fetches the exact same result as the original one.
What you should be doing is creating the store in the objects namespace (this) during initialization, and not afterwards:
MyApp.MyClass = Ext.extend(Ext.grid.Grid, {
initComponent: function () {
this.store = new Ext.data.Store({
...
});
// create config object
var config = {
store : store,
...
};
// apply config
Ext.apply(this, Ext.apply(this.initialConfig, config));
// call parent
MyApp.MyClass.superclass.initComponent.call(this);
} // eo function initComponent
,getStore: function() {
return this.store;
// Or this.getStore(); in the case of this class (Grid which is always able to return it's own store)
}
}); // eo extend
var myGrid = new MyApp.MyClass({});
Good luck,
Rob

problem with JsonStore and JsonReader

In my ExtJS application I use EditorGridPanel to show data from server.
var applicationsGrid = new Ext.grid.EditorGridPanel({
region: 'west',
layout: 'fit',
title: '<img src="../../Content/img/app.png" /> Приложения',
collapsible: true,
margins: '0 0 5 5',
split: true,
width: '30%',
listeners: { 'viewready': { fn: function() { applicationsGridStatusBar.setText('Приложений: ' + applicationsStore.getTotalCount()); } } },
store: applicationsStore,
loadMask: { msg: 'Загрузка...' },
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: { 'rowselect': { fn: applicationsGrid_onRowSelect} }
}),
viewConfig: { forceFit: true },
tbar: [{
icon: '../../Content/img/add.gif',
text: 'Добавить'
}, '-', {
icon: '../../Content/img/delete.gif',
text: 'Удалить'
}, '-'],
bbar: applicationsGridStatusBar,
columns: [{
header: 'Приложения',
dataIndex: 'ApplicationName',
tooltip: 'Наименование приложения',
sortable: true,
editor: {
xtype: 'textfield',
allowBlank: false
}
}, {
header: '<img src="../../Content/img/user.png" />',
dataIndex: 'UsersCount',
align: 'center',
fixed: true,
width: 50,
tooltip: 'Количество пользователей приложения',
sortable: true
}, {
header: '<img src="../../Content/img/role.gif" />',
dataIndex: 'RolesCount',
align: 'center',
fixed: true,
width: 50,
tooltip: 'Количество ролей приложения',
sortable: true}]
});
When I use JsonStore without reader it works, but when I try to update any field it uses my 'create' url instead of 'update'.
var applicationsStore = new Ext.data.JsonStore({
root: 'applications',
totalProperty: 'total',
idProperty: 'ApplicationId',
messageProperty: 'message',
fields: [{ name: 'ApplicationId' }, { name: 'ApplicationName', allowBlank: false }, { name: 'UsersCount', allowBlank: false }, { name: 'RolesCount', allowBlank: false}],
id: 'app1234',
proxy: new Ext.data.HttpProxy({
api: {
create: '/api/applications/getapplicationslist1',
read: '/api/applications/getapplicationslist',
update: '/api/applications/getapplicationslist2',
destroy: '/api/applications/getapplicationslist3'
}
}),
autoSave: true,
autoLoad: true,
writer: new Ext.data.JsonWriter({
encode: false,
listful: false,
writeAllFields: false
})
});
I believe that the problem is that I don't use reader, but when I use JsonReader grid stops showing any data at all.
var applicationReader = new Ext.data.JsonReader({
root: 'applications',
totalProperty: 'total',
idProperty: 'ApplicationId',
messageProperty: 'message',
fields: [{ name: 'ApplicationId' }, { name: 'ApplicationName', allowBlank: false }, { name: 'UsersCount', allowBlank: false }, { name: 'RolesCount', allowBlank: false}]
});
var applicationsStore = new Ext.data.JsonStore({
id: 'app1234',
proxy: new Ext.data.HttpProxy({
api: {
create: '/api/applications/getapplicationslist1',
read: '/api/applications/getapplicationslist',
update: '/api/applications/getapplicationslist2',
destroy: '/api/applications/getapplicationslist3'
}
}),
reader: applicationReader,
autoSave: true,
autoLoad: true,
writer: new Ext.data.JsonWriter({
encode: false,
listful: false,
writeAllFields: false
})
});
So, does anyone know what the problem might be and how to solve it. The data returned from my server is Json-formated and seams to be ok
{"message":"test","total":2,"applications":[{"ApplicationId":"f82dc920-17e7-45b5-98ab-03416fdf52b2","ApplicationName":"Archivist","UsersCount":6,"RolesCount":3},{"ApplicationId":"054e2e78-e15f-4609-a9b2-81c04aa570c8","ApplicationName":"Test","UsersCount":1,"RolesCount":0}]}
I had the same problem.. I solved it establishing Success Property in the json store and returning success true in the response from my create Method.. here is my code. Hope it helps
var EStore = new Ext.data.JsonStore
({
api: { read: 'getAssignedJobs',
create: 'createAssignedJobs',
update: 'updateAssignedJobs',
destroy: 'destroyAssignedJobs'},
root: 'jobData',
idProperty: 'Id',
autoSave: false,
autoLoad: true,
batch: true,
successProperty: 'success',
writer: new Ext.data.JsonWriter({ encode: true, writeAllFields: true }),
fields: [
{ name: 'Id', type: 'int', mapping: 'Id' },
{ name: 'ResourceId', type: 'int', mapping: 'fitter_id' },
{ name: 'StartDate', type: 'date', dateFormat: "Y-m-d\\TH:i:s" },
{ name: 'EndDate', type: 'date', dateFormat: "Y-m-d\\TH:i:s" },
{ name: 'status', type: 'int' },
{ name: 'job_id', type: 'int' }
]
});
and this is my Create method from Server Side..
public JsonResult createAssignedJobs(string jobData)
{
var Jsondata = (JobfitterToScheduler)new JavaScriptSerializer().Deserialize<JobfitterToScheduler>(jobData);
JobToFitterRepo jobtofitter = new JobToFitterRepo();
if (Jsondata != null)
{
jobtofitter.insertJobToFitter(13, Jsondata.fitter_id, 0, DateTime.Now, DateTime.Now);
return this.Json(new { success = true, jobData = Jsondata });
}
return null;
}
Looking at the source for Ext.data.Api I would say that the verbs are screwed up:
restActions : {
create : 'POST',
read : 'GET',
update : 'PUT',
destroy : 'DELETE'
},
For me the create should be a PUT and the update should be a POST. But I guess the Sencha guys have a different idea.
Btw, the source is taken from Ext 3.3.1
I guess you could override the restActions object to work as you would expect:
Ext.data.Api.restActions = {
create : 'PUT',
read : 'GET',
update : 'POST',
destroy : 'DELETE' };
As I've managed to know the Store 'id' config option is depricated.
I think the JsonStore keys off the record id on whether to do a POST vs PUT. So if the id is non-user generated the it will issue a POST, and a PUT otherwise. I am referring to record.id not record.data.id.
Not sure about the first part (my stores make the correct calls with similar code) but I can shed light on the 2nd part of your question.
Ext.data.JsonStore does NOT accept a reader object - it only takes fields and always makes its own reader, as you can see from the source
Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
constructor: function(config){
Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
reader: new Ext.data.JsonReader(config)
}));
}
});
and is confirmed as being "as per docs" in Ext 2.x
http://www.sencha.com/forum/showthread.php?57189-2.x-Closed-Bug-in-Ext.data.JsonStore-cconstructor
So if you supply your own reader you must, in this case, make an Ext.data.Store instead (this caught me out too)

Resources