I have a grid panel with one grid model. How can I set primary key to that grid store so that I can prevent duplicate values. My model is:
Ext.define('product',{
extend : 'Ext.data.Model',
fields: [{name: 'name',type: 'string'},
{name: 'column1', type: 'int'},
{name: 'column2', type: 'int'}]
associations: [{type: 'belongsTo',model: 'product',primaryKey: 'column1'}]
});
How can I use this primary key to prevent entry of same record twice?!
You can't 'set' a primary key on a model with Extjs. The concept itself does not exist in the library. The ID of the record needs to be unique, but there is really nothing that enforces it to be so. My question for you is, what do you even want done when a duplicate record is added? Do you want the values of the record to overwrite based on the key? Do you want an exception?
The best suggestion I can have for you is to use the 'add' event on the store and fill it with code something like this:
var myStore = Ext.create("Ext.data.Store", {
listeners: {
add: function(store, records){
var checkRecords = store.getRange();//get the records to check against
//clean out the records from the set that were just added
for(var i = 0; i < records.length; i++)
Ext.Array.remove(checkRecords, records[i]);
for(var i = 0; i < checkRecords.length; i++)
{
for( var j = 0; j < records.length; j++)
{
if(checkRecords[i].get("primary_key") == records[j].get("primary_key"))
throw "Duplicate primary key: " + records[j].get("primary_key");
}
}
}
}
});
That code will throw an exception but not stop the record for being added.
what about idProperty??
if you set an idProperty on your model it acts as a primary key.
Related
I'm trying to create a custom grid with columns for Feature Predecessors and Successors.
I've managed to extract the data and display the relevant formatted IDs of the pre+suc in clear text. Now I would like to format these as "standard" FormattedIDs with QDP/click options.
My display looks like this, is this the right path, what should I return in order to have correct formatting?
var myGrid = Ext.create('Ext.Container', {
items: [
{
xtype: 'rallygrid',
columnCfgs: [
'FormattedID',
'Name',
{ // Column 'Successors'
xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
dataIndex: 'Successors',
renderer: function(value, metaData, record) {
//console.log('Display in renderer: ', record.successorStore);
var mFieldOutputSuc = '';
var i;
var mDependency;
for (i = 0; i < record.successorStore.getCount(); i++) {
mDependency = record.successorStore.getAt(i);
console.log('mDependency = ', mDependency);
mFieldOutputSuc = mFieldOutputSuc + mDependency.get('FormattedID') + '<br>'; // Correct return value?
}
return mFieldOutputSuc;
}, //renderer: function(value, metaData, record) {
}, // Column 'Successors'
I'd check out this utility method: https://help.rallydev.com/apps/2.1/doc/#!/api/Rally.nav.DetailLink-method-getLink
You should be able to just put that in there where you have your //Correct return value? comment:
mFieldOutputSuc += Rally.nav.DetailLink.getLink({
record: mDependency
});
There are some more config options you can pass as well, to customize the link further, but I think that should get you started...
I have a rally grid that shows defects. I want do add a column that shows the number of days a defect has been open.
I know can do that by adding a custom renderer in the column configs, but I would also like to sort on this column. Unfortunately, the renderer does not change the sorting of the column.
I think I might be able to use the convert() function on the store instead to create a new virtual column (in this case openAgeDays), but I'm not sure how to do this from the constructor--I presume I make some changes to storeConfig?
Does anyone have an example of how to use a convert function (assuming that this is the right way to do it) to add a new virtual, sortable column to a rally grid?
this.grid = this.add({
xtype: 'rallygrid',
model: model,
disableColumnMenus: false,
storeConfig: [...]
As is the answer in the duplicate, you can add a doSort to the column:
{dataIndex: 'Parent', name: 'Parent',
doSort: function(state) {
var ds = this.up('grid').getStore();
var field = this.getSortParam();
console.log('field',field);
ds.sort({
property: field,
direction: state,
sorterFn: function(v1, v2){
console.log('v1',v1);
console.log('v2',v2);
if (v1.raw.Parent) {
v1 = v1.raw.Parent.Name;
} else {
v1 = v1.data.Name;
}
if (v2.raw.Parent) {
v2 = v2.raw.Parent.Name;
} else {
v2 = v2.data.Name;
}
return v1.localeCompare(v2);
}
});
},
renderer: function(value, meta, record) {
var ret = record.raw.Parent;
if (ret) {
return ret.Name;
} else {
meta.tdCls = 'invisible';
return record.data.Name;
}
}
},
The add method adds the menuPoint to the end of the store, how can I add it to the beginning instead?
Have gone through all methods in the store documentation, but cant find a method putting the element to the beginning of the store.
http://docs.sencha.com/touch/2-0/#!/api/Ext.data.Store
var store = Ext.getStore('AdultMenuStore');//adultmenulist.getStore();
for(var i=0; i < adultObj.children.length; i++){
var child = adultObj.children[i];
var menuPoint = Ext.create('Sencha.model.MenuPoint',
{
id: child.childId,
name: child.firstName,
icon_url: 'http://kidsparent.no/images/adultMenu/bkids-home-profile.png', xtype: 'childmenu'
});
store.add(menuPoint);
}
Just use insert method instead:
insert( Number index, Ext.data.Model[] records )
I am new to sencha touch. I have a datastore and i want to empty the datastore when the back button is clicked. Is there any method like refresh used to empty the datastore? Can anyone show me a bit of code on it?
This is not working in my case:
{
text: 'Back',
ui: 'back',
width: 50,
handler: function() {
var records = iPolis.journalListStore.getRange();
iPolis.journalListStore.remove(records);
iPolis.Viewport.setActiveItem('journalPanel', {
type: 'slide',
direction:'right'
});
}
}
you can use store.getRange(); to get all records of an Ext.data.Store and then pass those records to store.remove(); function to remove it form store
var records = store.getRange();
store.remove(records);
Ok, i found a solution to my question, i will post it here maby it will help someone.
the problem is that the store was not loaded so i have to getRange after the store load, here is the code :
StoreTrajectoire.on('load',function(store,records,opts){
var points = [];
points =StoreTrajectoire.getRange();
}
this will return an array of objects, to read the array data :
for(var i = 0; i < store.getCount(); i++ ) {
var record = store.getAt(i);
var data = record.get('your attribue')
points.push(p);
console.log(points[i]);
}
wish that can help you.
So I have a ExtJs 4 Grid Panel that has two columns.
Column ONE is a ComboBox with a custom renderer
Ext.ux.comboBoxRenderer = function(combo) {
return function(value) {
var idx = combo.store.find(combo.valueField, value);
var rec = combo.store.getAt(idx);
return (rec == null ? '<img src="/js/extjs4/resources/themes/images/default/grid/loading.gif" />' : rec.get(combo.displayField) );
};
}
Column TWO is a numeric column
{
allowBlank: false,
header: 'Time',
dataIndex: 'tedPaidTime',
align: 'right',
field: {
xtype: 'numberfield',
allowBlank: false,
minValue: 0,
maxValue: 100000
},
flex: 0.20,
selectOnFocus:true
}
Now, when I load the DataStore, I want the FIRST column to be read only. Which is easy if I set the ReadOnly flag.
However, I have a button that adds a NEW record to store and I want that new record to NOT have the readonly flag.
So basically, once you change column one and save, you can not alter it. Only able to alter new records before they are saved.
The business rules here require them to delete the old record if it's incorrect.
Thanks.
I was able to solve this myself.
Basically, I recorded the combo on the selectionchange event.
Then, in the focus event, I checked to see if it had a required data key from the store. If not, then I assume a new row and ran the following:
focus: function(combo) {
var cb = combo;
if(newTEDetailRecord) {
if(newTEDetailRecord.data["activityKey"] == "") {
console.log("newTEDetailRecord", newTEDetailRecord);
cb.setEditable(true);
cb.setReadOnly(false);
cb.focus();
cb.selectText();
} else {
cb.setReadOnly(true);
}
}
},