Convert Ext.data.JsonReader from ExtJs 3 to ExtJs 4 - javascript

I'm trying to convert this reader from Ext 3 to Ext 4. JavaScript is throwing an exception. Did I convert this correctly?
JavaScript exception:
Uncaught TypeError: Cannot read property 'prototype' of undefined
Code (converted lines commented):
Ext.onReady(function () {
Ext.Direct.addProvider(Ext.app.REMOTING_API);
//var reader = new Ext.data.JsonReader({ // convert from ext 3 to ext 4
var reader = Ext.create('Ext.data.JsonReader', {
totalProperty: 'results',
successProperty: 'success',
idProperty: 'id',
root: 'data'
}, [{
name: 'id'
}, {
name: 'email',
allowBlank: false
}, {
name: 'first',
allowBlank: false
}, {
name: 'last',
allowBlank: false
}]
);
//var writer = new Ext.data.JsonWriter({ // convert from ext 3 to ext 4
var writer = Ext.create('Ext.data.JsonWriter', {
returnJson: false,
writeAllFields: true
});
//var store = new Ext.data.DirectStore({ // convert from ext 3 to ext 4
var store = Ext.create('Ext.data.DirectStore', {
api: {
read: CRUDSampleMethods2.read,
create: CRUDSampleMethods2.create,
update: CRUDSampleMethods2.update,
destroy: CRUDSampleMethods2.destroy
},
reader: reader,
baseParams: {
dummy: 'blubb'
},
writer: writer,
paramsAsHash: true,
batchSave: false,
batch: false,
prettyUrls: false,
remoteSort: true,
listeners: {
load: function (result) { },
loadexception: function () {
},
scope: this
}
});
// ... code continues
EDIT:
Fixed this:
var reader = Ext.create('Ext.data.JsonReader', {
totalProperty: 'results',
successProperty: 'success',
idProperty: 'id',
root: 'data'
});
And added model:
var store = Ext.create('Ext.data.DirectStore', {
model: 'User',
api: {

JsonReader's constructor accept only one param. So your code doesn't really define the field list. Yet the field list is mandatory, either in the store (if the store doesn't use a model), or the model. And that's the type of error you get when a store is missing fields declaration...

Related

How to read values from multiselector component

I am trying to use multiselector from EXTJS 6.5.2
This is the code that I am using to create multiselector with the values that I need
{
xtype: 'multiselector',
title: 'I caktohet:',
name: 'Caktohen[]',
bind: '{userfullname.value}',
fieldName: 'userfullname',
viewConfig: {
deferEmptyText: false,
emptyText: 'Askush i zgjedhur'
},
search: {
field: 'userfullname',
model: 'InTenders.model.UserModel',
store: {
type: 'users',
sorters: 'userfullname',
// proxy: {
// type: 'rest',
// limitParam: null,
// url: 'api/User'
// }
}
}
}
When I call form = win.down('form') records I can get all values except the multiselector values, they show like this on console.
Anyone can help me or guide me how to get the values?
Thank you.
//Code that I'm trying to get multiselector items and save them
saveTenderForm: function (button, e, eOpts) {
var userMultiSelector = Ext.getCmp('AssignedUsers'); //save assigned users
var selectedUsers = userMultiSelector.getStore().getData(); //get store and put them in array
var me = this,
win = button.up('window'),
form = win.down('form'),
// formApplyUpload = this.getFormApplyUpload(),
// var ko = win.items.items[0].items.items[0].value;
recordtenderUsers = Ext.create('InTenders.model.TenderSaveModel');
// recordtenderUsers = form.getRecord();
// record = form.getRecord(),
values = form.getValues();
// appFile = this.getApplicationFile(),
// callbacks;
recordtenderUsers.set(values);
recordtenderUsers.set('tenderUsers',selectedUsers.items);
// // me.showMask();
// if (form.isValid()) {
recordtenderUsers.save({
success: function (recordtenderUsers, operation) {
win.close();
me.hideMask();
},
failure: function (recordtenderUsers, operation) {
me.hideMask();
}
});
You can get value using multiselector.down('grid') this will return you the grid. And grid have method getSelection().
In this FIDDLE, I have created a demo. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
xtype: 'form',
renderTo: Ext.getBody(),
items: [{
xtype: 'multiselector',
title: 'Multi selector example',
fieldName: 'text',
viewConfig: {
deferEmptyText: false,
emptyText: 'No value selected'
},
search: {
field: 'text',
store: {
fields: [{
name: 'text',
type: 'string'
}],
data: [{
text: 'ABC'
}, {
text: 'ABC 1'
}, {
text: 'ABC 2 '
}, {
text: 'ABC 3'
}, {
text: 'ABC 4'
}]
}
}
}, {
xtype: 'button',
text: 'Get Value',
margin:15,
handler: function (btn) {
var multiselector = btn.up('form').down('multiselector');
if (multiselector.down('grid')) {
multiselector.down('grid').getSelection().forEach(rec => {
console.log(rec.get('text'));
});
}
}
}]
});
}
});

I want to Reorder Rows in an ExtJs grid?

I am using ExtJs 4.2 and I have a Ext.grid.Panel and I have data coming in, but i want them to be ordered upon ingestion based on a boolean flag with things that have true for one field at the top, true for another field next, with false in both fields coming at the bottom. So far I have editing the sorters as prescribed below.
me.requesterListStore = new Ext.create('Ext.data.Store', {
id: 'requesterListStore',
model: 'Connex.Request.Model.RequesterModel',
buffered: true,
pageSize: 100,
leadingBufferZone: 50,
autoLoad: false,
remoteFilter: false,
purgePageCount: 5,
remoteSort: false,
sortOnLoad: true,
sorters: [
{
property: 'isSmartIndexed',
direction: 'DESC'
},
{
property: 'isAutoIndexed',
direction: 'DESC'
}
],
proxy: {
type: 'ajax',
url: $context + 'services/requester/search',
actionMethods: {
read: 'POST'
},
doRequest: function (operation, callback, scope) {
var writer = this.getWriter(),
request = this.buildRequest(operation, callback, scope);
if (operation.allowWrite()) {
request = writer.write(request);
}
Ext.apply(request, {
headers: this.headers,
timeout: this.timeout,
scope: this,
callback: this.createRequestCallback(request, operation, callback, scope),
method: this.getMethod(request),
jsonData: this.jsonData,
disableCaching: false // explicitly set it to false, ServerProxy handles caching
});
Ext.Ajax.request(request);
return request;
},
reader: {
type: 'json',
root: 'content',
totalProperty: 'total',
idProperty: 'id'
},
writer: {
writer: new Ext.data.JsonWriter({
getRecordData: function (record) {
return record.data;
}
})
}
}
});
sorters: [{
property: 'isSmartIndexed',
direction: 'DESC' // or 'ASC'
}, {
property: 'isAutoIndexed',
direction: 'DESC' // or 'ASC'
}]
Add these sorters to your store.
True is always bigger than false ;)
Keep attenction, you can't use sortingFuntions on a bufferedStore like written here:
If the store is buffered, then prefetchData is stored by index, this invalidates all of the prefetchedData.
because in your case you will order only the displayed data on the grid, and not the others that will be loaded.
Test it in this fiddle.

Kendo Grid: how to make datasource trigger update and create events

I am starting to look at how I would get my grid edits back to a service via the datasource.
Following the documentation, I have set a local test data source as follows..
function getDataSource() {
var gridData = [
{
col1: new CellData('1', 'data1-1'),
col2: new CellData('2', 'data1-2')
},
{
col1: new CellData('3', 'data2-1'),
col2: new CellData('4', 'data2-2')
},
];
var dataSrc = new kendo.data.DataSource({
batch: true,
transport: {
read: function (e) {
e.success(gridData);
},
update: function (e) {
// batch is enabled
var updateItems = e.data.models;
// This is not called
// on success
e.success();
},
create: function (e) {
e.success(e.data);
},
destroy: function (e) {
e.success();
}
}
});
return dataSrc;
}
I have a toolbar setup (with the "Save Changes"), and this is calling the SaveChanges configuration event, how ever, just cannot see what else I need to do to get the following to occur..
Have the data sources update called
Mark the grid "on dirty" so that the red "edited" indicators on the edited cells disappear
I am having the same problem with the Add New record (though I can't get the grids "addRow" even to fire here)
I have the running example here
Any help would be great appreciated!
You need to specify the DataSource schema for this to work:
var dataSrc = new kendo.data.DataSource({
batch: false, // true would mean transport functions get multipe models in e.data
transport: {
// ....
},
schema: {
data: function (response) {
return response;
},
model: {
id: "id",
fields: {
id: {
editable: false,
defaultValue: 0 // 0 == new / unsaved row
},
col1: {
editable: true,
// new items would have that using default add button
defaultValue: {
id: 0,
CategoryName: ""
},
fields: { id: { editable: true }, display: { editable: true }
},
col2: {
editable: true,
fields: { id: { editable: true }, display: { editable: true } }
}
}
}
}
});
Also note:
grid.saveChanges will sync the DS, so you don't need to do anything in the event
There is no addRow event.
The default "create" button will try to add an empty object; since you work with nested objects, you need to add the row yourself so you can initialize the properties; thus you need a custom button and bind your action manually
(demo)

Remote Filtering with ListFilter in ExtJS Grid Column Header

I am using ListFilter plugin to filter results on a Grid panel. The column definition is.
{
header: 'Provider',
filter: {
type: 'list',
store: Ext.getStore('MyApp.store.Provider'),
dataIndex: 'provider_id',
labelField: 'name'
}
}
MyApp.store.Provider is created as
Ext.create('Ext.data.Store', {
storeId: 'MyApp.store.Provider',
autoDestroy: true,
autoLoad: {start: 0, limit: 50},
autoSync: true,
model: 'MyApp.model.Provider',
pageSize: 50,
proxy: {
type: 'ajax',
api: {
create: 'proxy/provider/create',
read: 'proxy/provider/read',
update: 'proxy/provider/update',
destroy: 'proxy/provider/destroy'
},
reader: {
type: 'json',
root: 'data',
successProperty: 'success',
messageProperty: 'message',
totalProperty: 'total'
},
writer: {
allowSingle: false,
type: 'json',
writeAllFields: false,
root: 'data'
}
}
});
And lastly model MyApp.model.Provider is defined as
Ext.define('MyApp.model.Provider', {
extend: 'Ext.data.Model',
fields: [
{ name: 'provider_id', type: 'int'},
'name',
{ name: 'create_time', type: 'date', dateFormat: appDateFormat },
{ name: 'status', type: 'int'}
],
idProperty: 'provider_id',
displayProperty: 'name' // A custom property used for dynamically use the property to display
})
Now this code does not show any sub-menu in the filter menu. It just shows loading. See the image.
Update
I have solved it using following filter config. This actually populates options config manually. So no store is used here.
{
type: 'list',
labelField: 'name',
options: (function () {
var opts = [];
fS.load(function (records, operation, success) {
for (var i = 0; i < records.length; i++) {
var ar = {
id: records[i].get('provider_id'),
name: records[i].get('name')
};
opts.push(ar);
}
});
return opts;
})(),
single: true
}
It seems 'id' is hard-coded. id: records[i].get('provider_id'), does not look good. Though it works.
But I am still looking for a proper way to do it.
Note: The expected behavior can be found on ExtJS 4.1.1. See this jsfiddle. I have reproduced it. But this very same thing does not work on ExtJS 4.0.7
I didn't tried this myself but you need to set the ID manually with the idField property [new to ExtJS4.1.3] which is per default set to id. So I guess this will work:
{
header: 'Provider',
filter: {
type: 'list',
idField: 'provider_id',
store: Ext.getStore('MyApp.store.Provider'),
dataIndex: 'provider_id',
labelField: 'name'
}
}
Update
OK, I looked at the source and I can now tell you that this is the answer. So will have to either live with your workarround until 4.2 is out or you can apply the following changes to your Ext.ux.grid.menu.ListMenu to make it run:
add the idField with a default value.
look within the constructor for this lines
case 'object': options.push([value.id, value[this.labelField]]); break;
// some more lines
fields: ['id', this.labelField],
and replace it with
case 'object': options.push([value[me.idField], value[me.labelField]]); break;
// some more lines
fields: [me.idField, me.labelField],
and within the onLoad function look for
itemValue = records[i].get('id');
and replace it with
itemValue = records[i].get(me.idField);
and that pretty much is it.

ExtJS4 Ext.data.Store Load data from a function

Using ExtJS4 Store, I want to execute a Javascript function to return json data, ie. getMyJsonData, to load the data into the store.
function getMyJsonData() {
var myjson = {... };
return myjson;
}
Trawling through the doco, I can't find a way to define a callback function to load the data, all I found was a Memory Store which loads an already defined data object.
How can I call a function instead ?
Ext.define('perhoo.store.Users',
{
extend: 'Ext.data.Store',
model: 'perhoo.model.User',
autoLoad: true,
data : {
users: [
{ id: 1, name: 'joe44', email: 'joe#joe.com'},
{ id: 2, name: 'bloggs44', email: 'bloggs#joe.com'}
]
},
proxy: {
type: 'memory',
data: this.data,
reader: {
type : 'json',
root : 'users'
}
}
EDIT
The reason I want to call a function is because I want to execute LinkedIn API.
And going through Ext JSONP Proxy (as it's cross domain) makes things 10x more complicated as I have to get LinkedIn auth etc etc (which I don't know how to do it yet)
i.e.
var mydata = null;
function onLinkedInAuth() {
// Linked in api to find connections
IN.API.Connections("me").result( function(result) {
mydata = result;
} );
}
ExtJS4's store using proxy to load data, check below:
var myStore = Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : '/users.json',
reader: {
type: 'json',
root: 'users'
}
},
autoLoad: true
});
When executed, it reads data from the url, /users.json, and store into itself.
Also, if you want to process data yourself and load them into store yourself, you can check below:
//this is the model we will be using in the store
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'phone', type: 'string', mapping: 'phoneNumber'}
]
});
//this data does not line up to our model fields - the phone field is called phoneNumber
var data = {
users: [
{
id: 1,
name: 'Ed Spencer',
phoneNumber: '555 1234'
},
{
id: 2,
name: 'Abe Elias',
phoneNumber: '666 1234'
}
]
};
//note how we set the 'root' in the reader to match the data structure above
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
model: 'User',
data : data,
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'users'
}
}
});
And you could easily usesetProxy to change the behavior when you want.
Links:
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.AbstractStore-method-setProxy
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.proxy.Memory

Categories