extjs Event to update a Grid - extjs

I need a grid built in extjs designer to add data to the grid on an event.
so I should have a function that when called with receivedMsg as Args, sends the array data to be added as a new record in the grid.
I do not want it to go out and refresh a json file, not very network friendly.
I have written the server backend myself, and implemented websockets to generate the receivedMsg event.
How can I do this?
Here is where the event should go:
/*
* File: app/view/MyGridPanel.js
* Date: Sat Jan 14 2012 14:58:07 GMT-0500 (Eastern Standard Time)
*
* This file was generated by Ext Designer version 1.2.2.
* http://www.sencha.com/products/designer/
*
* This file will be generated the first time you export.
*
* You should implement event handling and custom methods in this
* class.
*/
Ext.define('MyApp.view.MyGridPanel', {
extend: 'MyApp.view.ui.MyGridPanel',
initComponent: function() {
var me = this;
me.callParent(arguments);
}
});
[
["Ace Supplies", "Emma Knauer", "555-3529"],
["Best Goods", "Joseph Kahn", "555-8797"],
["First Choice", "Matthew Willbanks", "555-4954"],
["First Choice", "Matthew Willbanks", "555-4954"]
]

If I understand the question properly, the array that you want to add as a record would first have to be converted into an instance of the same Ext.data.Model that your grid is using. Then you could call your "grid.store.insert()" method. For example, if your grid is using a model called 'Employee' like this:
// Grid data model
Ext.define('Employee', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'int'},
{name: 'email', type: 'string'},
{name: 'start', type: 'date'},
{name: 'salary', type: 'int'},
{name: 'active', type: 'bool'}
]
});
You could create the model instance outside of the function with your data and just pass that as the function args, or if you can only get the data as an array (hopefully you can set the sequence), you can create the model instance inside the function itself, shown here:
// the function you wanted
addRecord: function(myRecordArray) {
// Create a model instance
var r = Ext.create('Employee', {
name: myRecordArray[0],
email: myRecordArray[1],
start: myRecordArray[2],
salary: myRecordArray[3],
active: myRecordArray[4]
});
// get the grid store and the number of records in it
var store = this.getStore();
var maxIndex = store.getCount();
// adds record to the end of the grid (args are: index, Ext.data.Model[])
store.insert(maxIndex, r)
}
You would probably have to tweak this depending on how your store is set-up but that should get it started.

Related

Extjs - How to access/modify the data before the Ext.data.Batch starts

-- Extjs - 6.6.0, Extjs Grid with Cell Editing plugin, record save operation to the server
There is a grid in my application interface with a proper store and model attached to the store. The grid has a date column with a date editor with the render format as 'd-M-Y' and the date value to submit to the server is 'Y-m-d'. During the save operation through a batch start with the session, I am unable to access the data to modify the date format to 'Y-m-d' and is being submitted as 'd-M-Y' which causing an issue.
Can anyone please provide the information on accessing/modifying the data before the Ext.Data.Batch starts.
Note:
I cannot replace the batch with Ajax call.
I already tried dateWriteFormat for the Model class as well.
The date display & submit formats must be 'd-M-Y' & 'Y-m-d'.
I cannot post the code as it is too large.
Any sort of help would be much appreciated.
There are a couple of ways.
FIELD
You might want to edit the Model of the store via serialize.
Ext.define('MyApp.model.Users', {
extend: 'Ciss.data.Model',
fields: [{
name: 'BirthDate',
type: 'date',
dateFormat: 'd m Y', // how the date format comes from the server
serialize: function (val) {
return Ext.Date.format(val, 'Y-m-d');
}
}];
});
WRITER
You can use the writer using the dateFormat
writer: {
type: 'json',
dateFormat: 'Y-m-d',
writeAllFields: true
}
while your field should be of the type date, all the time
If you still need more control you can use the transform method.
Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : 'users.json',
writer: {
type: 'json',
transform: {
fn: function(data, request) {
// do some manipulation of the unserialized data object
return data;
},
scope: this
}
}
},
});
EVENT
You can use the store beforesync event
LAST HOPE
If all this does not work for you you can grab every request before it's send.

How do you create dynamic local store based on record property

I have an integer field on backend. This field is an offset (CPI Index delay) that could takes values from 0 -> N. On frontend I want to display a combo box with this value / label:
{key: 0, label: "0 - 21/06/2020"}
{key: 1, label: "1 - 21/06/2021"}
{key: 2, label: "2 - 21/06/2022"}
{key: 3, label: "3 - ... "}
The number of option is calculated this way: rent_end_date.year - first_due_date.year. Each time the first_due_date change, the options of the combo box must be calculated again.
To achieve this I've initialed a variabile indexOffsetChoices with relative formula to calculate choices each time a first_due_date changes:
viewModel: {
type: 'rentsdetailformmodel',
data: {
hideRentsDetailGrids: false,
indexOffsetChoices: []
},
formulas: {
calculateIndexOffsetChoices: {
bind: '{detailRecord.first_due_date}',
get: function (firstDueDate) {
var detailRecord = this.get('detailRecord'),
indexOffset = detailRecord.get('index_offset'),
rentEndDate = detailRecord.get('end_date');
if (indexOffset !== undefined && rentEndDate !== undefined) {
var choices = [];
for (i = 0; i < (rentEndDate.getFullYear() - firstDueDate.getFullYear()); i++) {
var RawCPIDate = new Date(firstDueDate.setFullYear(firstDueDate.getFullYear() + i)),
CPIDateFmt = Ext.Date.format(new Date(RawCPIDate), 'd/m/Y'),
label = i + ' - ' + CPIDateFmt;
choices.push({"key": i, "label": label});
}
this.indexOffsetChoices = choices;
}
}
}
}
},
Then I added my combo box with an inline local store that point to the viewModel variable indexOffsetChoices:
items: [{
xtype: 'combobox',
name: 'index_offset',
reference: 'index_offset',
fieldLabel: 'CPI Application Delay',
valueField: 'key',
displayField: 'label',
queryMode: 'local',
bind: '{detailRecord.index_offset}',
store: {
type: 'store',
storeId: 'rent__index_offset',
idProperty: 'key',
fields: ['key', 'label'],
data: this.indexOffsetChoices
}
}]
But the data are not loaded. This is the right approach? How do you create local store based on records / dynamic data? What I'm missing?
You did the hardest way sir! The 'data' property in viewModel is actually not used to store large of array data except you will work hard to modify them.
Setting dynamic options in combobox can be achieved by updating (or re-setting) it's options (using yourcombofield.setOptions([/*new array data*/]) like here ) or it's data store (using yourcombofield.getStore().setData([/* new array data*/]) like here) or if you declare your store in viewModel 'stores' property like here and have linked to your combobox's store property, you don't need to access combobox again, just modify the array data of the store and your combobox's options which has been linked to the store will be updated automatically. The important thing, try to give the easiest way to modify you array data inside the store.
Now, let's talk about when and where will you place your code to update this combobox's data? This is about the event's owner which you want to listen (and also affects your case). You said "Each time the first_due_date change". If first_due_date is affected by another field, just put your code inside it's change/keyup/keydown listeners and then re-treat you data by filtering,removing,adding, etc and the last, update the old data with the new data where ever the data has been stored before.

Collection inside a Backbone model

I want to create a Backbone model and store a collection of another model into its property. So, there are parent and child model. Each parent has one or more children stored as an array inside its property.
The JSON will be like this.
Parent = {
name: 'Name',
age: 'Age',
children:
[{name: 'Name', age: 'Age'},
{name: 'Name', age: 'Age'},
{name: 'Name', age: 'Age'}]
}
I've tried to create both model and insert one inside the other but still has no solution. And I don't want to use parse or other server things.
So, is there any solution or better way to achieve that?
As I understand you want to create a model with this data and if there are children inside model to make a collection of same models inside.
var Person = Backbone.Model.extend({
initialize: function(){
this.set('children', new Persons(this.get('children')));
}
});
var Persons = Backbone.Collection.extend({
model: Person
});
On the model creation - initialize: function () {...}
Lets take our children array - this.get('children')
And make a collection - new Persons(...)
Collection will create models itself
And put everything back - this.set('children', ...);
JSFiddle - run and see result in console.

How do I override the url field when extending a base model in Extjs?

I am new to Extjs and am following an Extjs 5 example on creating a model hierarchy:
(http://docs.sencha.com/extjs/5.0/core_concepts/data_package.html)
I created a base model which holds a proxy with a url field. I now want to extend this base model and only override the url part below:
Ext.define('MyPortal.model.Base', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int'
}],
schema: {
namespace: 'MyPortal.model', // generate auto entityName
proxy: {
type: 'ajax'
,url : '/portal-web/{entityName}'
,reader: {
type:'json',
rootProperty:'{entityName:lowercase}',
idProperty: 'id'
}
}
}
});
Here is a child model:
Ext.define('MyPortal.model.Account', {
extend : 'MyPortal.model.Base'
,fields: [
{name: 'accountId', type: 'string'},
{name: 'name', type: 'string'}
]
, //add something here to override the url from the base model above?
});
I tried adding a url field or function to the child model, but these are ignored. Is it possible for a child model to override the parent's url param?
Thanks!
The proxy option in the schema is what Ext5 calls an ObjectTemplate. Simply put, it is used as a default configuration for the models of the schema.
You can override this defaults in the proxy configuration of the model itself (one proxy instance will be created by model class -- not by model instance). Note that the model class itself doesn't accept an url option, it must be set in the proxy.
For you, that would give something like this:
Ext.define('MyPortal.model.Account', {
extend : 'MyPortal.model.Base' // I guess you had a typo here
,fields: [
{name: 'accountId', type: 'string'},
{name: 'name', type: 'string'},
]
// Override proxy URL (the other options of the schema's proxy
// will be used)
,proxy {
url: 'path/to/accounts'
}
});
FYI, the reader doesn't have an idProperty option (so says the docs), it's in the model this time...
I have a slightly different problem: my data model is generated, so i am using override: to extend model classes like this:
Ext.define('app.override.Foo', {
override: 'app.data.Foo',
proxy: {url: 'rest/foo',type: 'rest'}
}
this proxy override does not take effect in extjs 5 (works great in 4.x)

Dynamic json chart

I'm trying to use Sencha Touch Charts with a JSONStore to dynamically display a chart from information provided by JSON, series and data. This was possible with ExtJS 3 with the metaData property.
How can I accomplish the same with Sencha Touch Charts?
// Am using ruby for the webservice calls.
// First u have to create model and store for that
// model
Ext.regModel('samplemodel', {
idProperty: 'name',
fields: [ { name: 'name', type: 'string' },
{ name: 'data', type: 'int' }
]
});
// store
Ext.regStore('SampleStore', {
model: 'samplemodel',
storeId: "sampleStoreID",
sorters: [ {
property: 'name'
}]
});
// and create a variable for the store
var sampleStore = Ext.getStore("SampleStore");
// call the webservice and store it in array,
// bind the response to the store,
// use the store variable in the chart.
http://www.sencha.com/forum/showthread.php?161912-Dynamic-json-chart

Resources