ExtJS 4 remoteSort asDate - javascript

For my remote-sort i use in ExtJS 3 the keyword asDate which was sent in direction-part of request:
sort:my_date
dir:asDate ASC
In ExtJS 4 i miss the sortType information in Request:
sort:[{"property":"my_date","direction":"DESC"}]
is there any way to get the sortType information on server side?

You can the override encodeSorters function. I'll make you an example :)
http://jsfiddle.net/Vandeplas/xLz5C/1/
var store = Ext.create('Ext.data.Store', {
model: 'User',
sorters: [{
property: 'age',
direction: 'DESC',
sortType: 'asDate'
}, {
property: 'firstName',
direction: 'ASC'
}],
proxy: {
type: 'ajax',
url: '/echo/json/',
reader: {
type: 'json',
root: 'users'
},
encodeSorters: function (sorters) {
var min = [],
length = sorters.length,
i = 0;
for (; i < length; i++) {
min[i] = {
property: sorters[i].property,
direction: sorters[i].direction,
sortType: sorters[i].sortType
};
}
return this.applyEncoding(min);
}
}
});

Related

Creating dependent extjs grids

I just started to study extjs 6.
How it is possible to implement dependent grids when the main displays data from the table, when clicked on, in the second grid, the dependent entries from the second table are displayed.
What I realized at the moment:
I created a grid, I get the records from the "Operation" table, I call it using the CRUD. In the "Operation" table, all entries are associated with the second table (numoperation) in the code field.
It is required to me that at pressing on record of the main grid which is already created, to receive dependent records from the table numoperation in the second grid.
How can this be implemented in general?
I would be glad if you share useful links, tips or examples.
Thank you in advance.
Below is the code for the client part of the application:
Ext.onReady(function () {
Ext.define('Operation', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
'date_op',
'code',
'status',
'type'
]
});
var urlRoot = 'data?model=Operation&method=';
var registrStore = Ext.create('Ext.data.Store', {
model: 'Operation',
pageSize: 10,
proxy: {
type: 'jsonp',
noCache: false,
api: {
create: urlRoot + 'Create',
read: urlRoot + 'Read',
update: urlRoot + 'Update',
destroy: urlRoot + 'Destroy'
},
reader: {
type: 'json',
metaProperty: 'meta',
root: 'data',
idProperty: 'id',
totalProperty: 'meta.total',
successProperty: 'meta.success'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data',
allowSingle: false,
}
}
});
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToEdit: 2,
autoCancel: false,
listeners: {
edit: function (editor, context) {
var emp = registrStore.getProxy();
var con = context.record;
emp.setExtraParam("id", con.data['id']);
emp.setExtraParam("date_operation", con.data['date_operation']);
emp.setExtraParam("code", con.data['code']);
emp.setExtraParam("status", con.data['status']);
emp.setExtraParam("type", con.data['type']);
}
}
});
var textField = {
xtype: 'textfield'
};
// Определение столбцов
var columns = [
{
header: 'ID',
dataIndex: 'id',
sortable: true,
width: 35
},
{
header: 'Дата',
dataIndex: 'date_op',
sortable: true,
editor: textField
},
{
header: 'Код',
dataIndex: 'code',
sortable: true,
editor: textField
},
{
header: 'Статус',
dataIndex: 'status',
sortable: true,
editor: textField
},
{
header: 'Тип',
dataIndex: 'type',
sortable: true,
editor: textField
}
];
var pagingToolbar = {
xtype: 'pagingtoolbar',
store: registrStore,
displayInfo: true,
items: [
'-',
{
text: 'Save Changes',
handler: function () {
registrStore.sync();
}
},
'-',
{
text: 'Reject Changes',
handler: function () {
// Отмена изменений в stoe
registrStore.rejectChanges();
}
},
'-'
]
};
var onDelete = function () {
var selected = grid.selModel.getSelection();
Ext.MessageBox.confirm(
'Confirm delete',
'Are you sure?',
function (btn) {
if (btn == 'yes') {
var nn = selected[0].get('id')
var emp = registrStore.getProxy();
emp.setExtraParam("id", nn)
grid.store.remove(selected);
grid.store.sync();
}
}
);
};
var onInsertRecord = function () {
var selected = grid.selModel.getSelection();
rowEditing.cancelEdit();
var newEmployee = Ext.create("Operation");
registrStore.insert(selected[0].index, newEmployee);
rowEditing.startEdit(selected[0].index, 0);
};
var doRowCtxMenu = function (view, record, item, index, e) {
e.stopEvent();
if (!grid.rowCtxMenu) {
grid.rowCtxMenu = new Ext.menu.Menu({
items: [
{
text: 'Insert Operation',
handler: onInsertRecord
},
{
text: 'Delete Operation',
handler: onDelete
}
]
});
}
grid.selModel.select(record);
grid.rowCtxMenu.showAt(e.getXY());
};
var grid = Ext.create('Ext.grid.Panel', {
title: 'Таблица операций',
items: grid,
columns: columns,
store: registrStore,
loadMask: true,
bbar: pagingToolbar,
plugins: [rowEditing],
stripeRows: true,
selType: 'rowmodel',
viewConfig: {
forceFit: true
},
listeners: {
itemcontextmenu: doRowCtxMenu,
destroy: function (thisGrid) {
if (thisGrid.rowCtxMenu) {
thisGrid.rowCtxMenu.destroy();
}
}
},
renderTo: Ext.getBody()
});
registrStore.load();
});
What you probably want to do is to add a listener on the main grid that listens for the event: select.
https://docs.sencha.com/extjs/6.5.3/modern/Ext.grid.Grid.html#event-select
listeners: {
select: "onSelectMainGrid",
},
then you want to have a function called onSelectMainGrid or something similar
var onSelectMainGrid : function(grid, selectedItem) {
. . .
}
and in this function, you want to get the store from the dependent grids and you want to call the .load() function on them. For your dependent grid's store's proxy, use the config extraParams: {}
https://docs.sencha.com/extjs/6.5.3/modern/Ext.data.Connection.html#cfg-extraParams and bind the selection from the main grid to the extraParams of the dependent grids. Then call the method .load() on the dependent grid's store. The store of your dependent grid will look something like
var dependentGridStore = Ext.create('Ext.data.Store', {
model: 'OperationDependent',
pageSize: 10,
proxy: {
type: 'jsonp',
noCache: false,
extraParams: { // <==THIS IS NEW
valueFromMainGrid: '{selectedValueFromMainGrid}'
}
api: {
create: urlRoot + 'Create',
read: urlRoot + 'Read',
update: urlRoot + 'Update',
destroy: urlRoot + 'Destroy'
},
reader: {
type: 'json',
. . .
. . .
});
I noticed that you have all the code in the same file. It is strongly advised that you separate your code into views, viewModels, and viewControllers.
One last thing, If you don't make use of a viewModel for databinding, alternatively in the onSelectMainGrid function, since you are passing the selectedItem parameter, you can just get the dependent grid, then get its store, then get its proxy, and then set the extraParams to the selectedItem passed as parameter to the function.
Let me know if you need any clarification.
I did so (shortened the code for better perception):
Ext.define('Operation', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
'date_operation',
'code',
'status',
'type',
'mesto_hraneniya',
'contragent',
'sum_operation',
'rezerv',
'cnt_doc',
'stellag'
]
});
var urlRoot = 'data?model=Operation&method=';
// Хранилище для данных таблицы Registr
var registrStore = Ext.create('Ext.data.Store', {
model: 'Operation',
pageSize: 10,
proxy: {
type: 'jsonp',
noCache: false,
api: {
create: urlRoot + 'Create',
read: urlRoot + 'Read',
update: urlRoot + 'Update',
destroy: urlRoot + 'Destroy'
},
reader: {
type: 'json',
metaProperty: 'meta',
root: 'data',
idProperty: 'id',
totalProperty: 'meta.total',
successProperty: 'meta.success'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data',
allowSingle: false,
}
}
});
Ext.define('Tovary', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' },
'name',
'code',
'prise',
'unit'
]
});
var urlRootTv = 'data?model=Tovary&method=';
var TovaryGridStore = Ext.create('Ext.data.Store', {
model: 'Tovary',
pageSize: 10,
proxy: {
type: 'jsonp',
noCache: false,
extraParams: {
inclProps: '{code_tv}'
},
api: {
create: urlRootTv + 'Create',
read: urlRootTv + 'Read',
update: urlRootTv + 'Update',
destroy: urlRootTv + 'Destroy'
},
reader: {
type: 'json',
metaProperty: 'meta',
root: 'data',
idProperty: 'id',
totalProperty: 'meta.total',
successProperty: 'meta.success'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data',
allowSingle: false,
}
}
});
......
// Grid панель
var grid = Ext.create('Ext.grid.Panel', {
title: 'Таблица операций',
items: grid,
columns: columns,
store: registrStore,
loadMask: true,
bbar: pagingToolbar,
plugins: [rowEditing],
stripeRows: true,
selType: 'rowmodel',
viewConfig: {
forceFit: true
},
listeners: {
itemcontextmenu: doRowCtxMenu,
destroy: function (thisGrid) {
if (thisGrid.rowCtxMenu) {
thisGrid.rowCtxMenu.destroy();
}
},
select: function(grid, selectedItem) {
TovaryGridStore.proxy.extraParams = {'code_tv' : selectedItem.id.code};
TovaryGridStore.load();
}
},
renderTo: Ext.getBody()
});
registrStore.load();
When I click on a row in the grid, the browser console displays an error:
GET http://127.0.0.1:8000/hello_extjs/data?model=Tovary&method=Read&code_tv=&page=1&start=0&limit=10&callback=Ext.data.JsonP.callback2 500 (Internal Server Error)
What is the cause of this error? Whether correctly I understand that now I need to deduce the second Ext.grid.Panel what to display in it the data of model "Tovary"?

ext js 6 pass dynamic id from grid panel to model

How to passing id from gridpanel to model ?
here my grid panel code:
{
text : 'Tindakan',
xtype: 'actioncolumn',
minWidth: 130,
sortable: false,
menuDisabled: true,
items: [{
icon: 'images/view.png', // Use a URL in the icon config
tooltip: 'Lihat',
handler : function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
alert("Lihat - " + rec.get('id'));
}]
}
Here is my model code:
Ext.define('Kds.model.ProfilView', {
extend: 'Ext.data.Store',
alias: 'model.profilView',
fields: [
'name',
'ic_no',
'address',
],
pageSize : 20,
proxy: {
type: 'rest',
url : 'http://localhost/kds-rest/web/index.php/people/view/'+id,
useDefaultXhrHeader : false,
withCredentials: false,
reader: {
type: 'json',
rootProperty: 'data',
//totalProperty: 'totalItems'
}
},
autoLoad: 'true',
});
How do you use that model? If you create or use that each time, you can try this:
handler : function(grid, rowIndex, colIndex) {
var rec = grid.getStore().getAt(rowIndex);
//Create or get model to use
var model = Ext.create('Kds.model.ProfilView', {
// then give the record id to model
recordId: rec.get('id') // edited
});
}
// to use in model
Ext.define('Kds.model.ProfilView', {
extend: 'Ext.data.Store',
alias: 'model.profilView',
fields: [
'name',
'ic_no',
'address'
],
pageSize : 20,
autoLoad: 'true',
initComponent: function() {
var me = this;
me.proxy = {
type: 'rest',
url : 'http://localhost/kdsrest/web/index.php/people/view/'+me.recordId, // or this.up().recordId,
................
} // iniComponent
me.callParent();
Edit: How to load model dynamically: fiddle: https://fiddle.sencha.com/#fiddle/11g9
Ext.define('model.instance', {
extend: 'Ext.data.Model',
fields: ['name', 'city', 'country'],
proxy: {
type: 'ajax',
url: 'info',
reader: {
type: 'json',
rootProperty: 'records'
}
}
});
var fn = function getSelectedRow(gridView, rowIndex, colIndex, column, e,direction) {
var me = this;
var store = gridView.getStore();
var record = store.getAt(rowIndex);
var inst = Ext.create('model.instance', {
name: record.get('name')
});
inst.load({
scope: this,
success: function(rec) {
console.log(rec);
}
});
}
var store1 = Ext.create('Ext.data.Store', {
fields: ['name', 'surname'],
data: [{
name: 'Rick',
surname: 'Donohoe'
}, {
name: 'Jane',
surname: 'Cat'
}]
});
var grid = Ext.create('Ext.grid.Panel', {
columns: [{
dataIndex: 'name'
}, {
dataIndex: 'surname'
}, {
xtype: 'actioncolumn',
text: 'Select',
icon: '/image',
handler: Ext.bind(fn, this)
}],
store: store1,
renderTo: Ext.getBody()
});

Getting a string on an update request in KendoUI datasource

I have a pretty simple grid with data source that retrieves data correctly
For that cause I have a schema.parse function defined
The problem is that when I try to update/create new row the schema.parse() called again and the parameter that is passed to it is a string that contains the HTML of my page. cannot really get what the hell is going on there.
thanks
var _dataSource = new kendo.data.DataSource({
transport: {
read: {
dataType: "json",
url: layerDefProvider.getLayerUrlById("surveys") + "/query",
data: {
f: "json",
//token: token,
outFields: "*",
//outSR: 3857,
where: "1=1"
},
type: "POST"
},
create: function (options) {
console.debug("called");//never gets called
},
update: function (options) {
console.debug("called");//never gets called
},
destroy: function (options) {
console.debug("called");//never gets called
}
},
filter: {
field: "OBJECTID", operator: "eq", value: 0
},
schema: {
data:function(response) {
},
parse: function (data) {//on loading it is fine, on updating the data param is a string of my HTML of the page
var rows = [];
var features = data.features;
if (!features) {
return [];
}
for (var i = 0; i < features.length; i++) {
var dataRow = {};
dataRow.OBJECTID = features[i].attributes.OBJECTID;
dataRow.Name = features[i].attributes.Name;
dataRow.Date = features[i].attributes.Date;
dataRow.Comment = features[i].attributes.Comment;
rows.push(dataRow);
}
return rows;
},
model: {
id: "OBJECTID",
fields: {
OBJECTID: { type: "number", editable: false },
Name: { type: "string" },
Date: { type: "string" },
Comment: { type: "string" }
}
}
}
});
var _surveysPicker = $(config.table).kendoGrid({
toolbar: ["create","save"],
editable: true,
dataSource: _dataSource,
height: 300,
sortable: true,
selectable: "multiple",
columnMenu: true,
resizable: true,
columns: [{
field: "OBJECTID",
width: 40
}, {
field: "Name",
width: 40
}, {
field: "Date",
width: 40
}, {
field: "Comment",
width: 100
}]
});
You need to move your parse function inside read event if you need to parse data only on read action.

ExtJS Record with auto id Property

i have following problem with my ExtJS 5.1.0 Store.
When i want to create a new empty model with var m = new (store.model)(); and set Values with record.set(values); ( Which come from a Ext.form.Panel) the record has next to the normal Id, a second id. The Second one looks like that: "AM.namespace.model.ServiceContract-2".
Is it able to prevent a auto generated id?
To Create I use:
onAddServiceContract: function (item) {
this.__form = item.up('form');
var values = this.__form.getValues();
var store = this.getStore('ServiceContract');
var record = new (store.model)();
record.set('Id', 0000);
record.set(values);
record.phantom = true;
var rec = store.add(record);
}
The Store is defined as:
Ext.define('AM.####.store.ServiceContract',{
extend: 'AM.####.data.Store',
requires: ['Ext.data.proxy.Direct'],
model: 'AM.####.model.ServiceContract',
remoteGroup: true,
autoLoad: true,
//buffered: true,
pageSize: 1000,
leadingBufferZone: 500,
trailingBufferZone: 500,
autoSync: true,
constructor: function (config) {
config = Ext.apply({}, config);
if (!config.proxy) {
var proxy = {
type: 'direct',
reader: {
idProperty: 'Id',
rootProperty: 'data',
type: 'json'
},
writer: {
allowSingle: true,
writeAllFields: false // Note: Changed in ExtJS 5 to be default false
},
api: {
read: AM.####.ServiceContract.List,
create: AM.####.ServiceContract.Create,
update: AM.####.ServiceContract.BulkUpdate,
destroy: AM.####.ServiceContract.BulkDelete
}
};
config.proxy = proxy;
}
this.callParent([config]);
this.proxy.on('exception', this.onProxyException, this);
}
});
Thanks for your help!
You can mod the idProperty of the model to some other name.
For instance:
Ext.define('App.model.rssSoaFeed_m', {
extend: 'Ext.data.Model',
idProperty:'extIdProperty',//renaming the extjs id property
fields: [
{ name: 'title', type: 'auto' },
{ name: 'id', type: 'auto' }, //my custom id property
],
proxy:
{
type: 'ajax',
url: '/someurl.service',
extraParams: {
},
reader: {
type: 'json',
root: 'query.results.item'
}
}
});
And here is more info in sencha docs
Also, please note from the docs
the idProperty may be configured as null which will mean that no identifying field will be generated.

Extjs model array of string mapping

It seems to be very basic question, but happens to kill lot of my time.
How can I map following in to Ext.data.Model?
<Principal>STEMMED CORP.</Principal>
<BusinessDefinitions>
<value>NY CLIENTS CORE</value>
<value>US LISTED DERIVS- STOCK,ADR,ETF</value>
<value>US CLIENT SITE TRADING</value>
<value>SYNDICATES - ADRS AND CBS</value>
<value>GWM CAPITAL MARKETS</value>
</BusinessDefinitions>
<countryOfResidence>USA</countryOfResidence>
Problem is, I unable to figure out how to get array of string for BusinessDefinitions against each value.
The following field is what I have added to Model.fields:
// Business Definition(s)
{
name: 'BusinessDefinitions',
type: 'auto',
mapping: 'value',
convert: function(n, record) {
console.log('BusinessDefinition: ' + n);
return n;
}
}
I have tried other combinations as well, but nothing seem to work.
The following was fabricated to fit your data from the example below.
Here is a Sencha Fiddle of the answer I have provided. It is 4.2.1.883 compliant. I have yet to try this with version 5.1.0.
Data
<BusinessArray>
<BusinessItem>
<Principal>STEMMED CORP.</Principal>
<BusinessDefinitions>
<value>NY CLIENTS CORE</value>
<value>US LISTED DERIVS- STOCK,ADR,ETF</value>
<value>US CLIENT SITE TRADING</value>
<value>SYNDICATES - ADRS AND CBS</value>
<value>GWM CAPITAL MARKETS</value>
</BusinessDefinitions>
<countryOfResidence>USA</countryOfResidence>
</BusinessItem>
</BusinessArray>
Application
Ext.define('App.model.Business', {
requires: [ 'Ext.data.reader.Xml' ],
extend: 'Ext.data.Model',
fields: [{
name: 'principal',
mapping: 'Principal',
type: 'string'
}, {
name: 'country',
mapping: 'countryOfResidence',
type: 'string'
}, {
name: 'businessDefs',
type : 'auto',
convert: function(value, record) {
var nodes = record.raw.querySelectorAll('BusinessDefinitions value');
var items = [];
for (var i = 0; i < nodes.length; i++) {
items.push(nodes[i].textContent);
}
return items;
}
}]
});
Ext.application({
name : 'Fiddle',
launch : function() {
var store = Ext.create('Ext.data.Store', {
model: 'App.model.Business',
proxy: {
type: 'ajax',
url: 'business.xml',
reader: {
type: 'xml',
record: 'BusinessItem'
}
},
autoLoad : true
});
Ext.create('Ext.panel.Panel', {
title : 'XML Model Example',
layout : 'hbox',
items : [{
xtype: 'combo',
fieldLabel: 'Business',
emptyText: 'select',
editable: false,
queryMode: 'local',
store: store,
displayField: 'principal',
valueField: 'businessDefs',
listeners : {
select: function (combo, record, index) {
Ext.Msg.alert('Business Definitions', combo.getValue().join('<br />'));
}
}
}],
renderTo: Ext.getBody()
});
}
});
Example
The example below is from the accepted solution from Sencha Forums: How do I parse a XML node to an array of strings? Also handing XML attributes?.
XML Data
<jobs>
<job>
<id>1</id>
<name audioSrc="audio/jobs/names/electrician.mp3">Electrician</name>
<attributes>
<attributeID>sitting</attributeID>
<attributeID>individual</attributeID>
<attributeID>lightEquip</attributeID>
<attributeID>doer</attributeID>
<attributeID>physical</attributeID>
<attributeID>repair</attributeID>
</attributes>
</job>
</jobs>
Store
Ext.create('Ext.data.Store', {
model: 'App.model.JobData',
proxy: {
type: 'ajax',
url: dataURL,
reader: {
type: 'xml',
record: 'job'
}
}
});
Model
Ext.define('App.model.JobData', {
requires: [ 'Ext.data.reader.Xml' ],
extend: 'Ext.data.Model',
config: {
fields: [{
name: 'id',
mapping: 'id',
type: 'int'
}, {
name: 'title',
mapping: 'name',
type: 'string'
}, {
name: 'attributeList',
mapping : 'attributes',
convert: function(value, record) {
var nodes = record.raw.querySelectorAll('attributes attributeID');
var arrayItem = [];
var l = nodes.length;
for (var i = 0; i < l; i++) {
var node = nodes[i];
arrayItem.push(nodes[i].textContent);
console.log(nodes[i].textContent);
}
return arrayItem;
}
}]
}
});
Following is what worked for me:
No need to add requires: [ 'Ext.data.reader.Xml' ],
With that, following is the final field
},{
//Business Definition/s
name: 'BusinessDefinitions',
type: 'auto',
mapping: function(data){
return data.children[2].children[10];
},
convert: function(value, record) {
var items = [];
var nodes = record.data.BusinessDefinitions.querySelectorAll('BusinessDefinitions value');
for (var i = 0; i < nodes.length; i++) {
items.push(nodes[i].textContent);
}
return items;
}
},

Categories

Resources