How to avoid duplicated selection model specification in ExtJS grids? - extjs3

We have recently switched from ExtJS 3.2 to 3.4 and found that grids with check box selection model stop working. It turns out that such configuration is not allowed any more:
var gridConfig = {
xtype: 'grid',
store: myStore,
columns:[
new Ext.grid.CheckboxSelectionModel(),
{
id: 'Name',
header: 'Inland Carrier',
dataIndex: 'Name'
}],
sm: new Ext.grid.CheckboxSelectionModel({
checkOnly: true
})
};
Instead selection model object must be created once and then passed both to column collection and sm property.
The problem now is that we have a very long configuration object with multitude of grids. Previously selection model was specified locally as per the sample above. But now we have to allot a variable for each selection model object, invent unique name for it, and keep these variables far away from the place where they are used. It's extremely inconvenient.
Is it possible somehow to specify selection model in one place? Or maybe to create it in one property initializer and reference this object in the second place?

you can add sm to cm after initialization of grid.
ie:
var gridConfig = {
xtype: 'grid',
store: myStore,
columns:[{
id: 'Name',
header: 'Inland Carrier',
dataIndex: 'Name'
}],
sm: new Ext.grid.CheckboxSelectionModel({
checkOnly: true
})
};
var grid = new Ext.grid.GridPanel( gridConfig );
grid.getColumnModel().config.unshift( grid.getSelectionModel() );

Related

Ag-grid column definition and `__metadata__` property

I need to introduce object with my own properties in columnDefs object.
After, I did it, I see in dev console
So, here has been written, that I could mean __metadata__ property. Does this property suit to mine purpose?
I've not found any information in types and docs about this property
ColDef has no custom state property that you could use. Certainly do not touch __metadata__. The name sounds like some internal implementation detail.
You can store your metadata in a separate object, for example using colId as a key:
columnDefs: ColDef[] = [
{
colId: 'id',
field: 'id'
},
{
colId: 'name',
field: 'name'
}
];
columnMetadata: {
id: 'something custom',
name: 'custom data'
}
private getColumnMetadata(column: Column) {
return this.columnMetadata[column.getColId()];
}

Ag-Grid Server Side Row Group Key Creator

When using Ag-Grid's server side row model, I am unable to send a custom group key to the server in order to do proper group by queries.
My row data is a simple JSON structure but with one composite object.
row = {
athlete: '',
age: '',
country: {
name: 'Ireland',
code: 'IRE'
},
...
}
I am using the server side row model. To get the grid to display the country name is simple enough as I use the following column definition.
{
headerName: "Country",
colId: "country",
valueGetter: "data.country.name",
enableRowGroup: true
}
However, when I group by the Country column ag-grid sends the groupKey as 'Ireland' from my example above. But I need the group key to be the country code, 'IRE'. I cannot figure out how to generate a groupKey when using the server-side row model.
I have seen the keyCreator method, but this only works for client-side row model. In addition, I have seen the Tree Data Mode which has a callback for getServerSideGroupKey(dataItem) but then callback only gets used when gridOptions.treeData = true and when the treeData option is set to true, a "Group" column is always displayed regardless if a grouping is happening or not. I tested this out by setting isServerSideGroup: function(dataItem) {return false;}
Any help would be appreciated.
I was able to solve this issue by using the dot notation for the column definition's field attribute and a custom cellRenderer.
{
headerName: "Country",
colId: "country",
field: "country.code",
enableRowGroup: true,
cellRenderer: function (params) {
return params.data.country.name;
}
}
This allowed me to display the correct data point from the custom object and when doing server side actions, ag-grid will send the datapoint contained within the field attribute.

Posting limited fields with ExtJS 4.2.x REST on store update

We are trying to use ExtJS grid/forms and bind them with Store to perform REST operations.
Now as I was playing with extjs examples for restful api, I came across http://docs.sencha.com/extjs/4.2.1/#!/example/restful/restful.html and tried editing a model to add a new field 'phone' in the list like below:
Ext.define('Person', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'int',
useNull: true
}, 'email', 'first', 'last','phone'],
validations: [{
type: 'length',
field: 'email',
min: 1
}, {
type: 'length',
field: 'first',
min: 1
}, {
type: 'length',
field: 'last',
min: 1
}]
});
As you can see "phone" is a new field added in fields list of a model and after adding that field while I was trying to perform any of the rest operation (PUT/POST) it was posting that field along with rest of the visible fields in grid. This is something I have not expected.
Is there anyway by which I can just post dirty fields (which are modified) and not all those exist in model with default store/rest manipulation way that ExtJS has provided?
In the proxy writer definition you would want to use the writeAllFields param which will work for updates. New model instances will send all fields.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.writer.Writer-cfg-writeAllFields

Node, Mongoose, problems saving multiple-depths of nested schema

I'm having trouble working out how to insert multiple-depths of nested schema in MongoDB, via Mongoose and node.js.
The example below is a bit contrived but should hopefully explain my problem. As for why each schema is defined as a full model but not used in the example, that's just because in my real-world problem, they are actual, usable models and I wanted this example to be realistic in case it's relevant.
So here are the example schema definitions in reverse order, ie. smallest Russian-doll first:
// Define pen model
var PenSchema = new Schema({
color: String // black, blue or red
});
var Pen = mongoose.model('Pen', PenSchema);
// Define ruler model
var RulerSchema = new Schema({
units: String // inches or millimetres
});
var Ruler = mongoose.model('Ruler', RulerSchema);
// --------
// Define drawing tools model
var DrawingToolsSchema = new Schema({
label: String,
pens: [Pen]
});
var DrawingTools = mongoose.model('DrawingTools', DrawingToolsSchema);
// Define measuring tools model
var MeasuringToolsSchema = new Schema({
label: String,
ruler: [Ruler]
});
var MeasuringTools = mongoose.model('MeasuringTools', MeasuringToolsSchema);
// --------
// Define stationery box model
// It has a label and two compartments - tools for drawing and measuring
var StationeryBoxSchema = new Schema({
label: String,
drawingTools: [DrawingToolsSchema],
measuringTools: [MeasuringToolsSchema]
});
var StationeryBox = mongoose.model('StationeryBox', StationeryBoxSchema);
Hopefully you can tell from this that there is a main model, StationeryBox, which has a label and contains two compartments for DrawingTools and MeasuringTools which are nested schema. They in turn have their own labels and contain nested schemas for Pens and Rulers. The problem I'm having is inserted the 2nd level nesting, ie. pens/rulers. So based on the mongoose docs, creating the top level model, and pushing in the first nested objects works fine, then trouble strikes. For example:
// To create my stationery box - this works
var stationery = new StationeryBox({ label: 'My Stationery Box' });
// To add the nested compartments - this works
stationery.drawingTools.push({ label: 'My Pens' });
stationery.measuringTools.push({ label: 'My Rulers' });
// But this is wrong as 'stationery.drawingTools.pens' is undefined
stationery.drawingTools.pens.push({ color: 'red' });
stationery.drawingTools.pens.push({ color: 'black' });
And if I go back one step and try to insert the pens at the same time as the drawing tools:
// Also wrong - presumably the second level of nesting is the problem
stationery.drawingTools.push({
label: 'My Pens',
pens: [ // These object represent second levels of nested schema
{ color: 'red' },
{ color: 'black' }
]
});
I know this isn't a super-realistic example, but it's a simplified example of a real-world system I'm building and this was a easiest way to illustrate that.
The actual saving happens after this of course and I've left that out, but do I need to add these next levels in the save callback perhaps?
If anyone can tell me where I'm going wrong on this or point me in the right direction I'll buy you a nice cake (imaginary cake only I'm afraid, unless you live near me).
You are extremely close, the problem is actually in your Schema definitions. It all comes down to the difference between a Schema object and a Model object. When specifying mongoose Schema with embedded documents, you can only point to other Schema.
var DrawingToolsSchema = new Schema({
label: String,
pens: [Pen] // uh-oh, broken! Pen is a Model.
});
However, you do have this correct for your first level of embedded documents defined in StationeryBoxSchema.
var StationeryBoxSchema = new Schema({
label: String,
drawingTools: [DrawingToolsSchema], // yes! DrawingToolsSchema is a Schema
measuringTools: [MeasuringToolsSchema] // this one too.
});
This difference accounts for all of your unexpected behaviour later on.

Why does Ext.form.ComboBox remove all the values automatically when selected any item in the list?

I've made a combo box and its working fine except when I select one of the items in the combobox, it removes all other values in it. Here is a piece of code:
var comboitemarray = new Array();
for(var comboitems=0;comboitems<listitems.length;comboitems++){
comboitemarray[comboitems] = listitems[comboitems].item;
}
dynamicformfield = new Ext.form.ComboBox({
id: fieldname,
fieldLabel: fieldlabel,
name: fieldname,
editable: false,
autoSelect : true,
store: comboitemarray,
queryMode: 'local',
});
Any idea? Or am I missing anything here?
You gave an Array as store :
store: comboitemarray
Where it expects an Ext.data.Store. Implement an Ext.data.ArrayStore() from that comboitemarray array . Check the documentation of ArrayStore and always test in firebug for the errors.
I behaves that way because it's not a select-box, it's a combo-box.
If you had the following items:
a
aa
aaa
and you selected "aa", there would then be two options in the box: 'aa', and 'aaa'.
If you think carefully about how you'd like it to work, you'll realize that to get what you want will break ability to have any sort of meaningful type-ahead functionality.