Initializing GridPanel and ArrayStore with empty array does not work - extjs

When I initialize my ArrayStore with some data then I can insert new records and everything displays correctly. However, if I initialize the ArrayStore with an empty array then while the first record inserted works every subsequent insert overwrites the first record in the grid.
This seems a simple problem but I can't find a working way to initialize the grid as empty.
So what am I doing wrong?
Many thanks in advance!
var myData = [
// Initializing with the following element works.
//['Hyannis Connector',3456.9,'Hyannis Connector Bridle Path','Hyannis Connector/Baden Powell'],
// Initializing with this element works but leaves an empty row in the grid..
//[]
];
// create the data store
segmentStore = new Ext.data.ArrayStore({
fields: [
{name: 'trailName'},
{name: 'segmentLength', type: 'float'},
{name: 'startJunction'},
{name: 'endJunction'},
]
});
// manually load local data
segmentStore.loadData(myData);
// create the Grid
segmentGrid = new Ext.grid.GridPanel({
region: 'south',
store: segmentStore,
columns: [
{header: 'Trail Name', width: 140, sortable: true, dataIndex: 'trailName'},
{header: 'Segment Length', width: 75, sortable: true, dataIndex: 'segmentLength'},
{header: 'Start Junction', width: 75, sortable: true, dataIndex: 'startJunction'},
{header: 'End Junction', width: 75, sortable: true, dataIndex: 'endJunction'},
],
stripeRows: true,
height: 150,
width: 600,
title: 'Trail Segments in Route',
layout: 'fit'
});
var defaultData = {
trailName: segment.getTrailName(),
segmentLength: segment.getLength(),
startJunction: '',
endJunction: ''
};
var recId = 3;
var p = new segmentStore.recordType(defaultData, recId);
segmentStore.insert(0, p);

The answer was provided in the ExtJS Forum.
I needed to ensure the record id of the new records was different.

Related

Insert in grid data from two store

Hello i am want output in grid data from two store (store:'book' and store:'price')
i am do this:
Ext.define('TPL.book', {
title: 'Price for Books',
store: 'Book',
header: false,
stripeRows: true,
constructor: function (config) {
this.initConfig(config);
this.callParent(arguments);
},
initComponent: function() {
this.columns = [
{header: 'Id', dataIndex: 'id', flex: 1, hidden: true},
{header: 'Name', dataIndex: 'name', width: 600, hidden: false},
{header: 'Price', dataIndex: '???', width: 100, hidden: false},
];
this.callParent(arguments);
}
});
I am want in column 'Price' output data from store 'Price' where id from store 'Book' equal id from store 'Price'
You would just do a store filter on your click event or load event. Good example here: How to filter a store with multiple values at once?
If you have it in two stores and need to combine it down to one store you could do a Ext.each(array, function(value) {}); and then just push the matched pairs into a new store. I would use the filters and give them filter IDs though and you could then remove filters pretty easily.

EXTJS 3.4 - Grouping gridpanel based on GeoExt.data.WMSCapabilitiesStore

I am trying to implement grouping to the gridpanel using grouping store and grouping view.
Basically I want to modify the example given in this link;
http://api.geoext.org/1.1/examples/wms-capabilities.html
It is using Geoext web mapping library developed on extjs framework.Here GeoExt.data.WMSCapabilitiesStore is the store used for data from a url in XML.
Sample working xml can be viewed here:
url for xml
I am modifying the code to group the resulted records based on for example, 'name'.
Some how I am not able to properly configure the grouping store.
Here is my code sample:
var store;
Ext.onReady(function() {
// create a new WMS capabilities store
store = new GeoExt.data.WMSCapabilitiesStore({
url: "data.xml"
});
// load the store with records derived from the doc at the above url
store.load();
store.on('load',function(store,records,opts){
console.log(store.getRange());
}); //show the array data in firebug console
var reader = new Ext.data.ArrayReader({
fields: [{name: 'title'},
{name: 'name'},
{name: 'queryable'},
{name: 'abstract'}
]});
var grpstore = new Ext.data.GroupingStore({
data: store,
autoLoad: true,
reader: reader,
sortInfo:{field: 'title', direction: "ASC"},
groupField:'name'
});
//SP
// create a grid to display records from the store
var grid = new Ext.grid.GridPanel({
title: "WMS Capabilities",
store: grpstore,
columns: [
{header: "Title", dataIndex: "title", sortable: true},
{header: "Name", dataIndex: "name", sortable: true},
{header: "Queryable", dataIndex: "queryable", sortable: true, width: 70},
{id: "description", header: "Description", dataIndex: "abstract"}
],
view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
}),
frame:true,
width: 700,
height: 450,
collapsible: true,
animCollapse: false,
autoExpandColumn: "description",
listeners: {
rowdblclick: mapPreview
},
iconCls: 'icon-grid',
fbar : ['->', {
text:'Clear Grouping',
iconCls: 'icon-clear-group',
handler : function(){
store.clearGrouping();
}
}],
renderTo: "capgrid"
});
function mapPreview(grid, index) {
var record = grid.getStore().getAt(index);
var layer = record.getLayer().clone();
var win = new Ext.Window({
title: "Preview: " + record.get("title"),
width: 512,
height: 256,
layout: "fit",
items: [{
xtype: "gx_mappanel",
layers: [layer],
extent: record.get("llbbox")
}]
});
win.show();
}
});
I am getting the panel with group options in the columns but the grid is empty. I tried many options in the data input of grouping store, but could not make it work.
Is it good way to get the data from 'store' as array, and then read it again in grouping store? But I couldnt make it working.
store.getRange() is showing all the data in the firebug console, probably as an array. I tried it as per this post. How to then call this array as data in grouping store, if this is a good way of doing it.
Any lead on this would be very helpful
Thanks
Sajid
I was looking to do exactly the same thing. I found two things:
You can use the store.Each function to copy the data from the WMSCapabilitiesStore to the Grouping Store
This was the trouble - the loading of the store is asynchronous, so you have to use store.on to set up a callback function to populate the groupingStore once the WMSCapabilitiesStore is finished loading.
Here's the code:
store = new GeoExt.data.WMSCapabilitiesStore({
url: "data.xml"
});
store.load();
grpStore = new Ext.data.GroupingStore({
groupField: 'name',
sortInfo: {field: 'name', direction: 'ASC'},
groupOnSort: true
});
store.on('load', function(store, records, options)
{
store.each(function(eachItem) {
grpStore.add(eachItem);
});
});
var grid = new Ext.grid.GridPanel({
store: grpStore,
columns: [
{header: "Title", dataIndex: "title", sortable: true},
{header: "Name", dataIndex: "name", sortable: true},
{id: "description", header: "Description", dataIndex: "abstract"}
],
autoExpandColumn: "description",
height: 300,
width: 650,
view: new Ext.grid.GroupingView({
forcefit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
});

Combo box in Extjs editor grid not displaying initally

I am trying to edit an information using editor grid. I have three fields, Interview By (combo), Date (date) and Performance (number), I get the date and the performance column, but the combo is not displaying the value initially. But when I click, then it shows the correct value. I am new to extjs and googled it for a solution, but could not find it. Kindly help me with a solution. Thanks in advance.
MY CODE:
initComponent: function() {
this.createTbar();
this.columns = [
{ xtype:'numbercolumn',
hidden:true,
dataIndex:'interview_id',
hideable:false
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_by_employee_id',
header: 'Interview By',
sortable: true,
width: 290,
editor: {
xtype: 'combo',
store: employee_store,
displayField:'employee_first_name',
valueField: 'employee_id',
hiddenName: 'employee_first_name',
hiddenValue: 'employee_id',
mode: 'remote',
triggerAction: 'all',
forceSelection: true,
allowBlank: false ,
editable: false,
listClass : 'x-combo-list-small',
style: 'font:normal 11px tahoma, arial, helvetica, sans-serif'
},
renderer: function(val){
index = employee_store.findExact('employee_id',val);
if (index != -1){
rs = employee_store.getAt(index).data;
return rs.employee_first_name;
}
}
},
{ xtype: 'gridcolumn',
dataIndex: 'interview_date',
header: 'Date',
sortable: true,
readOnly: true,
width: 100,
editor: {
xtype: 'datefield'
}
},
{ xtype: 'numbercolumn',
header: 'Performance',
format:'0',
sortable: true,
width: 100,
align: 'right',
dataIndex: 'interview_performance',
editor: {
xtype: 'numberfield'
}
}
];
candidate_grid_interview.superclass.initComponent.call(this);
}
and the screen shots,
I faced the same problem and found my solution somewhere. Here is a reduced version of what I'm using. I think the key was the renderer property on the column. If your combo uses remote data, it might be loading its content after the grid is done loading - but I'm not sure it will cause the problem you're describing.
Try this concept:
var myStore = new Ext.data.JsonStore({
autoLoad: false,
...
fields: [
{ name: 'myID', type: 'int' },
{ name: 'myName', type: 'string' }
],
listeners: {
load: function () {
// Load my grid data.
},
scope: this
}
});
var myCombo = new Ext.form.ComboBox({
...
displayField: 'myName',
valueField: 'myID',
store: myStore
});
var grid = new Ext.grid.EditorGridPanel({
store: new Ext.data.ArrayStore({
...
fields: [
...
{ name: 'myID', type: 'int' },
...
]
}),
...
cm: new Ext.grid.ColumnModel({
columns: [
...
{
header: 'Header',
dataIndex: 'myID',
editor: myCombo,
renderer: function (value) {
var record = myCombo.findRecord(myCombo.valueField, value);
return record ? record.get(myCombo.displayField) : myCombo.valueNotFoundText;
}
}]
})
});
myStore.load();
Store loading is asynchronous, so it might be loading itself after rendering the grid. I recommend you render your grid within the store onload event. Also, datatypes can be painfull if you don't pay enough attention. Be sure that your grid store and combo store types match.

How to change the text color of only one row in an ExtJS grid?

I've created the following ExtJS grid.
I want to change the text color of all the cells in the second row.
However, I can only find out how to change the color of all cells in all rows including the header text, as show here:
var myData = [
[4, 'This is a whole bunch of text that is going to be word-wrapped inside this column.', 0.24, 3.0, '2010-11-17 08:31:12'],
[16, 'Computer2-this row should be red', 0.28, 2.7, '2010-11-14 08:31:12'],
[5, 'Network1', 0.02, 2.5, '2010-11-12 08:31:12'],
[1, 'Network2', 0.01, 4.1, '2010-11-11 08:31:12'],
[12, 'Other', 0.42, 5.0, '2010-11-04 08:31:12']
];
var myReader = new Ext.data.ArrayReader({}, [{
name: 'id',
type: 'int'
}, {
name: 'object',
type: 'object'
}, {
name: 'status',
type: 'float'
}, {
name: 'rank',
type: 'float'
}, {
name: 'lastChange',
type: 'date',
dateFormat: 'Y-m-d H:i:s'
}]);
var grid = new Ext.grid.GridPanel({
region: 'center',
style: 'color:red', //makes ALL text in grid red, I only want one row to be red
store: new Ext.data.Store({
data: myData,
reader: myReader
}),
columns: [{
header: 'ID',
width: 50,
sortable: true,
dataIndex: 'id',
hidden: false
}, {
header: 'Object',
width: 120,
sortable: true,
dataIndex: 'object',
renderer: columnWrap
}, {
header: 'Status',
width: 90,
sortable: true,
dataIndex: 'status'
}, {
header: 'Rank',
width: 90,
sortable: true,
dataIndex: 'rank'
}, {
header: 'Last Updated',
width: 120,
sortable: true,
renderer: Ext.util.Format.dateRenderer('Y-m-d H:i:s'),
dataIndex: 'lastChange'
}],
viewConfig: {
forceFit: true
},
title: 'Computer Information',
width: 500,
autoHeight: true,
frame: true,
listeners: {
'rowdblclick': function(grid, index, rec){
var id = grid.getSelectionModel().getSelected().json[0];
go_to_page('edit_item', 'id=' + id);
}
}
});
What do I have to do to change the text color of only the cells in the second row?
You want to override getRowClass, which is passed into the GridPanel's viewConfig. An example is provided in GridPanel's API docs:
viewConfig: {
forceFit: true,
// Return CSS class to apply to rows depending upon data values
getRowClass: function(record, index) {
var c = record.get('change');
if (c < 0) {
return 'price-fall';
} else if (c > 0) {
return 'price-rise';
}
}
},
GridView contains the method, so look there in the API for more information:
getRowClass( Record record, Number index, Object rowParams, Store store )
Override this function to apply custom
CSS classes to rows during rendering.
You can also supply custom parameters
to the row template for the current
row to customize how it is rendered
using the rowParams parameter. This
function should return the CSS class
name (or empty string '' for none)
that will be added to the row's
wrapping div. To apply multiple class
names, simply return them
space-delimited within the string
(e.g., 'my-class another-class').
You can apply the CSS to a certain row by using the index argument.
not sure if this helps, but you can try. I tried locally, it does change the color of all the characters in 2nd row.
Add listener to the grid:
listeners:{
viewready: function(g){
g.getView().getRow(1).style.color="#f30";
}
}
"When viewready, you can get the row's div by using getRow() method from GridView. After that is normal Javascript of assigning colors (or adding extra class, if you want)
Cheers
EDIT
I realize it's not working if your store is retrieving data remotely. View is ready but data is not ready. This method would fail.

Configuring an Ext.data.XmlStore to obtain custom tags from response

Hi I have the following xml returned from the server:
Code:
link text
I couldn''t seem to get the xml store configuration right. Especially, I want to be able to obtain the custom tags: name, intra and referrals which are properties of the result set returned.
Many thanks!
Try this code (replace test.xml with your xml source)
// create the Data Store
var store = new Ext.data.Store({
// load using HTTP
url: 'test.xml',
// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// records will have an "customer" tag
record: 'customer',
}, ['id','field1', 'field2', 'field3'])
});
// create the grid
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{header: "id", width: 120, dataIndex: 'id', sortable: true},
{header: "field1", width: 180, dataIndex: 'field1', sortable: true},
{header: "field2", width: 115, dataIndex: 'field2', sortable: true},
{header: "field3", width: 100, dataIndex: 'field3', sortable: true}
],
renderTo:'example-grid',
width:540,
height:200
});
store.load();
in order to obtain the tags: name, intra and referrals i used Ext.DomQuery which enables you to parse to xml (try it for intra and referrals )
Ext.Ajax.request({
url: 'test.xml',
success: function(response){
console.debug(response);
if (Ext.DomQuery.selectNode("/rootNode/name", response.responseXML)) {
var name = Ext.DomQuery.selectValue("/rootNode/name", response.responseXML);
console.debug(name);
}
},
failure: function () { console.log('failure');}
});

Resources