PDA

View Full Version : RowEditor ComboBox - on update showing value instead of display



iwarner
24 Mar 2010, 2:53 AM
Hi

Ok so when I edit my row in the grid with Roweditor - the combobox immediately shows the valuefield - which is simply an ID and not the display field the user selected from

I have done quite a bit of searching - either the topics are very general or there are no signs of guidance

I was also looking to see if the ExtJS support a kind of callback - ie the JSON is submitted in the Success message there is JSON to overwrite the fields with fresh data. I though I read something that this was possible but see no help on this anywhere

The last thing to try I suppose would be to capture the update listener of the row editor and force the correct text into the row instead of the valuefield ID number.

Open to suggestions please

Included the code for this



Ext.BLANK_IMAGE_URL = 'http://extjs.cachefly.net/ext-3.0.0/resources/images/default/s.gif';

Ext.onReady(function()
{
// Instantiate the quick tips
Ext.QuickTips.init();

var xg = Ext.grid;

// Use RowEditor for editing
var rowEditor = new Ext.ux.grid.RowEditor({
errorSummary : false,
saveText : 'Update'
});

var msg = function(title, msg) {
Ext.Msg.show({
buttons : Ext.Msg.OK,
icon : Ext.Msg.INFO,
msg : msg,
minWidth : 200,
modal : true,
msg : msg,
title : title
});
};

// Display or bring forth the form
function uploadFormWindow()
{
if (!uploadCreateWindow.isVisible()) {
uploadCreateWindow.show();
} else {
uploadCreateWindow.toFront();
}
}

// Method to display negative numbers in a different colour
function renderNegativeAmount(val)
{
if (val < 0) {
var className = 'style="color: red"';
} else {
var className = 'style="font-weight: bold"';
}

return '<span ' + className + '>' + val + '</span>';
}

function renderVatLink(val, p, record)
{
return('<a id="myClickableField" href="/restaccounts/data/vatID/' + record.data.id + '" title="VAT Records">' + val + '</a>');
}

function reload()
{
store.baseParams.vatID = null;
store.reload({
params: {
start:0, limit:50, sort:'date', dir:'DESC'
}
});
}

// The DataWriter component.
var writer = new Ext.data.JsonWriter({
encode : false,
writeAllFields : true
});

// Create the data store
var store = new Ext.data.JsonStore({
fields : [
{ name: 'id', type: 'int' },
{ name: 'date', type: 'string' },
{ name: 'description', type: 'string' },
{ name: 'reference', type: 'string' },
{ name: 'invoice', type: 'string' },
{ name: 'payment', type: 'string' },
{ name: 'vat', type: 'int' }
],
idProperty : 'id',
messageProperty : 'data',
remoteSort : true,
restful : true,
root : 'data',
successProperty : 'success',
totalProperty : 'totalCount',
url : '/restaccounts',
writer : writer
});

// Create the Reference data store
var storeReference = new Ext.data.JsonStore({
fields : [
{ name : 'id', type: 'int' },
{ name : 'reference', type: 'string' }
],
root : 'data',
url : '/accounts/reference'
});

store.setDefaultSort('date', 'DESC');
store.load({params:{start:0, limit:50, sort:'date', dir:'DESC'}});

// Row expander
var expander = new Ext.grid.RowExpander({
expandOnDblClick : false,
tpl : new Ext.Template(
'<p style="margin-left: 50px; width: 99%; padding: 10px;"><b>Notes:</b> {description}</p>'
)
});

// create the column model
var columns = [
new xg.RowNumberer(),
expander,
{ header: 'Date', sortable: true, dataIndex: 'date' },
{ header: 'Reference', sortable: true, dataIndex: 'reference',
editor : {
allowBlank : false,
displayField : 'reference',
emptyText : 'Select Reference',
fieldLabel : 'Reference',
forceSelection : true,
lazyRender : true,
mode : 'remote',
name : 'reference',
store : storeReference,
typeAhead : true,
triggerAction : 'all',
valueField : 'id',
xtype : 'combo'
}
},
{ header: 'Invoice', sortable: true, dataIndex: 'invoice',
editor: {
xtype : 'textfield'
}
},
{ header: 'Payment', sortable: true, dataIndex: 'payment', renderer: renderNegativeAmount },
{ header: 'VAT', sortable: true, dataIndex: 'vat', renderer: renderVatLink,
editor : {
maxValue : 100,
minValue : 1,
xtype : 'numberfield'
}
}
];

// Create the pager
var pagingBar = new Ext.PagingToolbar({
displayInfo : true,
displayMsg : '{0} - {1} of {2}',
emptyMsg : 'No Data',
pageSize : 50,
store : store
});

// Create the Grid Panel
var grid = new xg.GridPanel({
bbar : pagingBar,
columns : columns,
height : 500,
iconCls : 'icon-grid',
loadMask : {msg: 'Loading data.', enabled: true},
plugins : [expander, rowEditor],
renderTo : 'dbGrid',
sm : new Ext.grid.RowSelectionModel({singleSelect:true}),
store : store,
stripeRows : true,
tbar : [
'->', {
text : 'Upload Accounts',
tooltip : 'Upload Accounts',
iconCls : 'icon-add',
handler : uploadFormWindow
},
'->', {
handler : reload,
iconCls : 'icon-tableRefresh',
text : 'Show All',
tooltip : 'Show all records.'
},
],
title : 'Accounts',
viewConfig : {
forceFit : true
}
});

// Create the Uplaod Form
var uploadItems = new Ext.FormPanel({
autoHeight : true,
bodyStyle : 'padding: 10px;',
buttons: [{
text : 'Save',
handler : function() {

if (uploadItems.getForm().isValid()) {
uploadCreateWindow.hide();
uploadItems.getForm().submit({
waitMsg : 'Uploading your accounts',
failure : function(uploadItems, data) {
msg('Failure', data.result.message);
},
success : function(uploadItems, data) {
msg('Success', data.result.message);
store.reload();
},
url : '/accounts/upload'
});
}
}
},{
text : 'Reset',
handler : function() {
uploadItems.getForm().reset();
}
},{
text : 'Close',
handler : function() {
uploadCreateWindow.hide();
}
}],
defaults : {
anchor : '90%',
allowBlank : false,
msgTarget : 'side'
},
fileUpload : true,
frame : true,
items : [{
height : 28,
xtype : 'fileuploadfield',
id : 'uploadFile',
emptyText : 'Select a file',
fieldLabel : 'Select File',
name : 'uploadFile',
buttonCfg : {
text : '',
iconCls : 'icon-add'
}
},
new Ext.form.ComboBox({
allowBlank : false,
displayField : 'bankName',
emptyText : 'Bank Name',
fieldLabel : 'Bank',
forceSelection : true,
mode : 'local',
store : new Ext.data.SimpleStore({
fields : ['bankValue', 'bankName'], data: [['Natwest','Natwest']]
}),
triggerAction : 'all',
valueField : 'bankValue'
}),
],
labelWidth : 75,
width : 400
});

// Create the Panel to hold the Upload Form
var uploadCreateWindow = new Ext.Window({
autoHeight : true,
closable : true,
closeAction : 'hide',
height : 150,
iconCls : 'icon-grid',
items : uploadItems,
layout : 'fit',
title : 'Upload Accounts',
width : 450
});

// Create an event handler for the company selection
grid.on('cellclick', function(grid, row, col, e) {
var tgt = e.getTarget();
var rec = grid.getStore().getAt(row);
var field = grid.getColumnModel().getDataIndex(col);

if (field == 'vat') {
if (tgt.tagName.toLowerCase() == 'a') {
grid.getStore().load({params: { 'vatID': rec.get('vat'), 'limit': 50, 'start': 0 } } );
store.baseParams.vatID = rec.get('vat');
e.stopEvent();
}
}
});
});

iwarner
24 Mar 2010, 6:01 PM
This must be quite a common problem - but I cant seem to find any direction on it - a little bump to see if anyone else can.

frrogoy
15 Apr 2010, 12:50 PM
I coded around the hidden field problem. I added two fields to my record for the key (srid and delegate for 2 comboboxes).
var rid = 0; // global var
var delid = 0; // global var var delgt = Ext.data.Record.create([{
name: 'srid',
type: 'int'
}, {
name: 'delegate',
type: 'int'
}, {
name: 'repname',
type: 'string'
},{
name: 'delname',
type: 'string'
},{
name: 'allquotes',
type: 'string'
}]);
var writer = new Ext.data.JsonWriter({
encode: true ,
writeAllFields: true // write all fields, not just those that changed
});

var preader = new Ext.data.JsonReader({
idProperty:'id',
fields: [
{name: 'id', type: 'int'},
{name: 'srid', type: 'int'},
{name: 'delegate', type: 'int'},
{name: 'repname', type: 'string', filterable: true},
{name: 'delname', type: 'string', filterable: true},
{name: 'allquotes', type: 'string', filterable: true}
],
root:'data'
});

In validateedit I checked for the presence of changes to my two comboboxes and set the key fields in the record.

var editor = new Ext.ux.grid.RowEditor({
saveText: 'Update',
listeners: {
validateedit: function(re,chgs,rec){
var err = 0;
if(typeof chgs.repname == "undefined"){
}else if(chgs.repname != ''){
rec.data.srid = rid;
}else { err=1;}
if(typeof chgs.delname == "undefined"){
}else if(chgs.delname != ''){
rec.data.delegate = delid;
}else { err=1;}
if(rec.data.repname == 'New Rep' || rec.data.delname == 'Delegate' ){ err=1;}
if(err=1){
Ext.Msg.alert("Update cancelled - Missing Field","'Rep Name' and 'Delegate For' are both required.");
return false;
}
}
}
});
var rep2rdr = new Ext.data.JsonReader({
fields: [
{name: 'srid', type: 'int'},
{name: 'repname', type: 'string'} ],
root: 'data',
remoteSort: true
})
var dsrep2 = new Ext.data.Store({
reader: rep2rdr,
baseParams: {q: 'ALL',delegates: 'Yes'},
proxy : new Ext.data.HttpProxy({
url: 'getrepext.php',
method: 'GET'
})
});
var sr2Combo = new Ext.form.ComboBox({
name: 'sr2name',
triggerAction: 'all',
lazyRender:true,
allowBlank: true,
typeAhead: true,
mode: 'local',
store: dsrep2,
forceSelection: true,
displayField: 'repname'
});
sr2Combo.on('select', function(cmb,rec,idx) {
rid =rec.data.srid;
});
Similar code for the 2nd combobox. It uses the same store and reader.

The php update module looks for the default data to ignore the phantom record. The create and update code ignore the names. The delete code uses the ID.

Rangi
15 Apr 2010, 1:11 PM
From the API documentation:

ComboBox in Grid
If using a ComboBox in an Editor Grid (http://www.extjs.com/deploy/dev/docs/output/Ext.grid.EditorGridPanel.html) a renderer (http://www.extjs.com/deploy/dev/docs/output/Ext.grid.Column.html#Ext.grid.Column-renderer) will be needed to show the displayField when the editor is not active. Set up the renderer manually, or implement a reusable render, for example:


// create reusable renderer
Ext.util.Format.comboRenderer = function(combo){
return function(value){
var record = combo.findRecord(combo.valueField (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-valueField), value);
return record ? record.get(combo.displayField (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-displayField)) : combo.valueNotFoundText (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-valueNotFoundText);
}
}

// create the combo instance
var combo = new Ext.form.ComboBox({
typeAhead (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-typeAhead): true,
triggerAction (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-triggerAction): 'all',
lazyRender (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-lazyRender):true,
mode (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-mode): 'local',
store (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-store): new Ext.data.ArrayStore({
id: 0,
fields: [
'myId',
'displayText'
],
data: [[1, 'item1'], [2, 'item2']]
}),
valueField (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-valueField): 'myId',
displayField (http://www.extjs.com/deploy/dev/docs/output/Ext.form.ComboBox.html#Ext.form.ComboBox-displayField): 'displayText'
});

// snippet of column model used within grid
var cm = new Ext.grid.ColumnModel([{
...
},{
header: "Some Header",
dataIndex: 'whatever',
width: 130,
editor: combo, // specify reference to combo instance
renderer: Ext.util.Format.comboRenderer(combo) // pass combo instance to reusable renderer
},
...
]);

kiminox
21 May 2010, 1:28 AM
I think you have and will have the same problem than me...
http://www.extjs.com/forum/showthread.php?99605-EXTJS-3.2.1-Editorgridpanel-combobox-using-JSON-store

Yoong

mond
3 May 2011, 10:36 PM
@Rangi Cant see the Display Field once render the grid. what would be possible problem?