For some time I have a problem with my Shopware plugin. I extended article listWindow, added a column with checkbox. When customer clicks on checkbox I need to get article number that is in another column.
The way I first did it seems unreliable because it depends on position of a columns that can change.
//{block name="backend/article_list/view/main/grid"}
//{$smarty.block.parent}
//{namespace name=backend/article_list/main}
Ext.define('Shopware.apps.ArticleList.view.main.etsy_attribute.Grid', {
override: 'Shopware.apps.ArticleList.view.main.Grid',
...
getToolbar: function () {
var me = this, buttons;
buttons = me.callParent();
me.equaliseEtsyBtn = Ext.create('Ext.button.Button', {
text: 'Etsy equalise',
iconCls: 'sprite-drive-upload',
onClick: function () {
var i,
recPerPage = me.items.items[0].all.elements,
for (i = 0; i < recPerPage.length; i++) {
var productNumber = recPerPage[i].children[2].innerText;
if( recPerPage[i].children[numOfChildren].children[0].children[0].checked === true) {
Ext.Ajax.request({
method: 'POST',
url: '{url controller="someController" action="someAction"}',
params: Object.assign({
productNumber: productNumber
}),
success: function (res) {
//var parsed = JSON.parse(res.responseText);
},
failure: function () {
}
});
} else {
});
}
}
}
});
buttons.add(me.equaliseEtsyBtn);
return buttons;
},
})
What is bad here is this:
recPerPage[i].children[numOfChildren].children[0].children[0].checked === true
And similar lines. How to get value I need in some smarter and more accurate way?
Alse tried with .down and .up
Please give me some direction!
How do I remove a newly added row from a gridpanel? The gridpanel is bound to a store.
I use:
store.remove(record);
store.sync();
It works fine on existing records in the grid, the record is removed from the grid directly, but when I add a record and want to remove it right away, it isn't 'removed' form the grid.
The api is called, so the record is 'removed from the database' and the record is indeed gone when I do e.g. a browser refresh.
Does anyone knows how this works? Thanks in advance.
Store configurations
Ext.define('Iziezie.store.animal.doggywood.animal', {
extend: 'Iziezie.store.animal.animal',
model: 'Iziezie.model.animal.doggywood.animal',
proxy: {
type: 'baseProxy',
api: {
create: '../php/api/doggywood_animals.php?request=create',
read: '../php/api/doggywood_animals.php?request=read',
update: '../php/api/doggywood_animals.php?request=update',
destroy: '../php/api/doggywood_animals.php?request=destroy'
}
}
});
New records is added by form:
var store = gridpanel.getStore();
var model = Ext.ModelMgr.getModel(store.model);
var record = model.create();
store.insert(0, record);
...
frm.loadRecord(record);
On form submit
frm.updateRecord();
var record = frm.getRecord();
record.save();
On remove:
var sm = gridpanel.getSelectionModel();
var record = sm.getLastSelected();
var store = gridpanel.getStore();
store.remove(record);
store.sync();
To force a visual refresh on the grid, you can just call
myGridPanel.getView().refresh();
But this shouldn't be required, the grid should just show whatever is in your store. Can you post a full code sample of what you are doing?
try this to create a new record to grid panel using row editing:
createRecord: function() {
var model = Ext.ModelMgr.getModel('EKOJS.model.m_yourmodel');
var r = Ext.ModelManager.create({
id: '',
text: ''
}, model);
this.getYourgridaliasview().getStore().insert(0, r);
this.getYourgridaliasview().rowEditing.startEdit(0, 0);
},
and to remove the selected record in your grid panel :
deleteRecord: function(dataview, selections) {
var getstore = this.getYourgridaliasview().getStore();
var selection = this.getYourgridaliasview().getSelectionModel().getSelection()[
0];
if (selection) {
Ext.Msg.confirm('Confirmation',
'Are you sure to delete this data: id = "' + selection.data
.id + '"?', function(btn) {
if (btn == 'yes') {
getstore.remove(selection);
getstore.sync();
}
});
}
},
and, the important thing always reload your store after creating record like this :
Ext.Ajax.request({
method: 'POST',
url: '../php/api/doggywood_animals.php?request=create',
params: {
data: jsonData
},
success: function(response) {
e.store.reload({
callback: function() {
var newRecordIndex = e.store.findBy(
function(record, id) {
if (record.get('id') === e.record
.data.id) {
return true;
}
return false;
});
/* me.grid.getView().select(recordIndex); */
me.grid.getSelectionModel().select(
newRecordIndex);
}
});
}
});
The listener of after edit in rowediting plugin i use is like this below :
'afteredit': function(editor, e) {
var me = this;
if ((/^\s*$/).test(e.record.data.id)) {
Ext.Msg.alert('Peringatan', 'Kolom "id" tidak boleh kosong.');
return false;
}
/* e.store.sync();
return true; */
var jsonData = Ext.encode(e.record.data);
Ext.Ajax.request({
method: 'POST',
url: '../php/api/doggywood_animals.php?request=create',
params: {
data: jsonData
},
success: function(response) {
e.store.reload({
callback: function() {
var newRecordIndex = e.store.findBy(
function(record, id) {
if (record.get('id') ===
e.record.data.id
) {
return true;
}
return false;
});
/* me.grid.getView().select(recordIndex); */
me.grid.getSelectionModel().select(
newRecordIndex);
}
});
}
});
return true;
}
May be a little help for you.
Below is a renderer for an Ext.grid.Panel column. Suppose contactStore has 2,000 values in it and all I care about is the name of the record based on the id (value parameter in this case), and my grid only has 25 rows/records in it for the page I'm on. How can I dynamically get the store so that I grab the relevant associated records (based on the foreign key) of the id of my grid column, rather than loading all 2,000 records? Is there a way to load the store and then in the callback, somehow have this "renderer" function display the values after the callback succeeded?
columns: [{
...
}, {
header: 'Contact Name',
flex: 1,
sortable: true,
dataIndex: 'contact_id',
renderer: function(value) {
var contactStore = Ext.StoreManager.lookup('Contacts');
return contactStore.getById(value).get('full_name');
}
}, {
You can adjust the collectData(records, startIndex) in the viewConfig for that:
Ext.create('Ext.grid.Panel', {
(...)
viewConfig: {
//this method needs to be adjusted
collectData: function(records, startIndex) {
var me = this;
//we can use a custom function for this
if (me.onBeforeCollectData) {
me.onBeforeCollectData(records);
}
var data = me.superclass.collectData.call(me, records, startIndex);
return data;
},
onBeforeCollectData: function(records) {
var newExtraParams = [];
var oldExtraParams;
var needToLoadStore = false;
var contactStore = Ext.StoreManager.lookup('Contacts');
if (contactStore) {
oldExtraParams = contactStore.oldExtraParams;
} else {
//don't use autLoad: true, this will be a local store
contactStore = Ext.create('Ext.data.Store', {
storeId:'Contacts',
(...)
});
needToLoadStore = true;
}
for (var x in records) {
//contact_id is read out here
var param = records[x].get('contact_id');
if (param) {
if (needToLoadStore == false && Ext.Array.contains(oldExtraParams, param) == false) {
needToLoadStore = true;
}
newExtraParams.push(param);
}
}
if (needToLoadStore == true) {
//we use this to load the store data => because of async: false property
Ext.Ajax.request({
scope: this,
//this is for synchronous calls
async: false,
url: (...),
method: (...),
params: newExtraParams,
success: function (res, opt) {
var responseObj = Ext.decode(res.responseText, false);
contactStore.loadData(responseObj); //or deeper in the responseObj if needed
contactStore.oldExtraParams = newExtraParams;
}
});
}
}
}
});
Using ExtJs 4.2 with MVC pattern
I am trying to make a custom model, store, proxy, reader, writer but am having problems getting it to work in the MVC pattern. I followed this example to extend a model and I can see it working only if it is not used in the MVC way.
My store refers to a model such as Contacts defined in the model property, then Contacts refers to custom model WakandaModel using the model property. But when I create my store which refers to Contacts none of the model properties or proxy defined in the custom WakandaModel is brought over to the stores model.
Here is my code, I have left comments in so you can see what I have attempted to try. Thanks for any help!
App Code
Ext.Loader.setConfig({
enabled : true,
paths : {
'Ext.ux' : "lib/extux",
'Wakanda' : "lib/extux/wakanda"
}
});
Ext.application({
name : 'SimplyFundraising',
autoCreateViewport : true,
requires : ['Ext.ux.Router', // Require the UX
'Ext.window.MessageBox'],
controllers : ['Contacts'],
});
Custom Model
Ext.define('Wakanda.Model', {
extend: 'Ext.data.Model',
idProperty: '__KEY',
stampProperty: '__STAMP',
defaultProxyType: 'wakanda',
onClassExtended: function(cls, data) {
// debugger;
// cls.apply(this)
// var parts = data.$className.split('.');
// var entity = parts[2]
// var catalog = this.prototype.getCatalog(entity),
// attributes = catalog.attributes;
// for (var i = 0, l = attributes.length; i < l; i++) {
// if (attributes[i].name === 'ID') {
// attributes[i].persist = false;
// }
// }
// attributes.push({name: this.prototype.idProperty});
// attributes.push({name: this.prototype.stampProperty});
// // data.fields = attributes;
// // debugger;
// //this.setFields(data.fields)
// // var mymodel = Ext.ModelManager.getModel(data.$className);
// debugger;
// Ext.appy(this);
// //this.superclass.superclass.$onExtended.apply(this, arguments);
},
getCatalog: function(className) {
var catalog;
Ext.Ajax.request({
async: false,
url: 'http://127.0.0.1:8081/cors/$catalog/' + className,
success: function(response) {
catalog = Ext.decode(response.responseText);
}
});
return catalog;
}
});
Custom proxy
Ext.define('Wakanda.Proxy', {
extend: 'Ext.data.proxy.Rest',
// alternateClassName: 'SimplyFundraising.data.WakandaProxy',
alias : 'proxy.wakanda',
sortParam: '$orderby',
filterParam: '$filter',
startParam: '$skip',
limitParam: '$top',
// groupersParam: '$group',
reader: 'wakanda',
writer: 'wakanda',
actionMethods: {
create : 'POST',
read : 'GET',
update : 'POST',
destroy: 'POST'
},
buildUrl: function(request) {
debugger;
var modelName = this.model.modelName,
operation = request.operation,
records = operation.records || [],
record = records[0],
id = record ? record.getId() : operation.id,
url = '/cors/' + modelName,
action = request.action;
if (this.appendId && id && (action === 'read' || action === 'destroy')) {
url += '(' + id + ')';
}
request.url = url;
// console.log("buildUrl", this, arguments, request.url);
if (action !== 'read') {
if (action === 'create') action = 'update';
else if (action === 'destroy') action = 'delete';
url = Ext.urlAppend(url, '$method=' + action);
}
if (this.noCache) {
url = Ext.urlAppend(url, Ext.String.format("{0}={1}", this.cacheString, Ext.Date.now()));
}
return url;
},
encodeSorters: function(sorters) {
var min = [],
length = sorters.length,
i = 0, sort = '';
for (; i < length; i++) {
sort += sorters[i].property + ' ' + sorters[i].direction + ' ';
}
return sort;
},
encodeFilters: function(filters) {
var min = [],
length = filters.length,
i = 0, filter = '';
for (; i < length; i++) {
filter += filters[i].property + ' eq ' + filters[i].value + '# ';
}
return filter;
}
});
Custom reader
Ext.define('Wakanda.reader', {
extend: 'Ext.data.reader.Json',
//alternateClassName: 'SimplyFundraising.data.WakandaReader',
alias : 'reader.wakanda',
root: '__ENTITIES',
totalProperty: '__COUNT',
getData: function(data) {
if (Ext.isObject(data) && !data[this.root]) {
data = [data];
}
return data;
}
});
Custom writer
Ext.define('Wakanda.writer', {
extend: 'Ext.data.writer.Json',
// alternateClassName: 'SimplyFundraising.data.WakandaWriter',
alias: 'writer.wakanda',
writeAllFields: false,
getRecordData: function(record) {
var isPhantom = record.phantom === true,
writeAll = this.writeAllFields || isPhantom,
nameProperty = this.nameProperty,
fields = record.fields,
data = {},
changes,
name,
field,
key;
if (writeAll) {
// console.log("getRecordData1", this, arguments);
fields.each(function(field){
if (field.persist) {
name = field[nameProperty] || field.name;
data[name] = record.get(field.name);
} else {
}
});
} else {
changes = record.getChanges();
// console.log("getRecordData2", this, arguments, changes);
for (key in changes) {
if (changes.hasOwnProperty(key)) {
field = fields.get(key);
name = field[nameProperty] || field.name;
data[name] = changes[key];
}
}
if (!isPhantom) {
data[record.idProperty] = record.getId();
data[record.stampProperty] = record.get(record.stampProperty);
}
}
return {'__ENTITIES': [data]};
}
});
Contacts Model
Ext.define('SimplyFundraising.model.Contact', {
extend : 'Wakanda.Model' ,
//constructor: function() {
//alert(“Going to call parent’s overriden constructor…”);
// this.callParent(arguments);
// return this;
// }
});
Contacts Store
Ext.define('SimplyFundraising.store.Contacts', {
extend : 'Ext.data.Store',
model : 'SimplyFundraising.model.Contact',
autoLoad : true,
autoSync : true,
// constructor: function() {
// this.model = Ext.create('SimplyFundraising.model.Contact')
//alert(“Going to call parent’s overriden constructor…”);
// this.callParent(arguments);
return this;
// }
});
Contacts Controller
Ext.define('SimplyFundraising.controller.Contacts', {
extend : 'Ext.app.Controller',
models : ['Contact'],
views : ['contacts.List', 'contacts.Edit'],
init : function() {
this.control({
'contactslist' : {
itemdblclick : this.editContact,
removeitem : this.removeContact
},
'contactslist > toolbar > button[action=create]' : {
click : this.onCreateContact
},
// 'contactsadd button[action=save]': {
// click: this.doCreateContact
// },
'contactsedit button[action=save]' : {
click : this.updateContact
}
});
},
list : function() {
// var mystore = Ext.StoreMgr.lookup('Contacts');
// var myContact = this.getModel('Contact')
// var User = this.getModel('User');
//debugger;
// var mystore = Ext.create('SimplyFundraising.store.Contacts')
// var myContact = this.getModel('Contact').create()
// var bb = myContact.create()
// var rr = Ext.create('SimplyFundraising.model.Contact')
var mystore = Ext.create('SimplyFundraising.store.Contacts')
debugger;
// mystore.proxy.api.read = users.proxy.api.read + '(17)'
//mystore.proxy.extraParams = { $expand: 'ContactType'};
mystore.load();
//var test = Ext.ModelManager.getModel('Contact');
// //var User = this.getContactModel();
// User.load(258, {
// success: function(user) {
// console.log("Loaded user 258: " + user.get('lastName'));
// }
// });
},
editContact : function(grid, record) {
var view = Ext.widget('contactsedit');
view.down('form').loadRecord(record);
this.addnew = false
},
removeContact : function(Contact) {
Ext.Msg.confirm('Remove Contact ' + Contact.data.lastName, 'Are you sure?', function(button) {
if (button == 'yes') {
this.getContactsStore().remove(Contact);
}
}, this);
},
onCreateContact : function() {
var view = Ext.widget('contactsedit');
this.addnew = true
},
// doCreateContact: function (button) {
// var win = button.up('window'),
// form = win.down('form'),
// values = form.getValues(),
// store = this.getContactsStore();
// if (form.getForm().isValid()) {
// store.add(values);
// win.close();
// }
// },
updateContact : function(button) {
var win = button.up('window'), form = win.down('form'), record = form.getRecord(), values = form.getValues(), store = this.getContactsStore();
if (form.getForm().isValid()) {
if (this.addnew == true) {
store.add(values);
} else {
record.set(values);
}
win.close();
}
}
});
I got this working now:
It looks like my custom wakanda model,proxy,reader,writer where not loading. Still a bit confused on how MVC references classes and loads files and instantiates classes, which I asked in other question.
Any way the fix was to add a requires to the custom wakanda model and proxy
For the Wakanda model add requires: ['Wakanda.proxy'],
For Wakanda proxy add requires: ['Wakanda.reader', 'Wakanda.writer'],
now the inheritance is working as expected.
/**
* Rajan Y. Rawal
* application.js
* This file is sample file for learing Extjs
*/
// reference local blank image
Ext.BLANK_IMAGE_URL = '../extjs/resources/images/default/s.gif';
// create namespace
Ext.namespace('myNameSpace');
// Just to allow this tutorial to work for 1.1 and 2.
//Ext.Ext2 = (Ext.version && (Ext.version.indexOf("2") == 0));
// create application
myNameSpace.app = function() {
var btn1;
var privVar1 = 11;
var btn1Handler = function(button, event) {
alert('privVar1=' + privVar1);
alert('this.btn1Text=' + this.btn1Text);
};
return {
// public properties, e.g. strings to translate
btn1Text: 'Button 1',
// public methods
init: function() {
btn1 = new Ext.Button('btn1-ct', {
text: this.btn1Text,
handler: btn1Handler,
scope:this
});
}
};
}();
Ext.apply(myNameSpace.app, {
btn1Text:'Taste 1',
init: function() {
try {
btn1 = new Ext.Button('btn1-ct', {
text: this.btn1Text,
handler: btn1Handler,
scope: this
});
}
catch(e) {
alert('Error: "' + e.message + '" at line: ' + e.lineNumber);
}
}
});
Where is my fault?
Your script is working. What exactly are you expecting it to do?
You're creating an Ext.button with a handler, but there it is not being told to render anywhere on the page. You should provide a renderTo config option which will tell ExtJS to render the button to a given element...
btn1 = new Ext.Button('btn1-ct', {
text: this.btn1Text,
handler: btn1Handler,
scope: this,
renderTo: 'element-of-html-div'
});
Also, you're defining and then overriding everything in myNameSpace.app, this is pointless.