PDA

View Full Version : Problem with binding a form to a store and writeAllFields==false



JacobGu
16 Mar 2011, 12:02 PM
I am binding a form with the loadRecord method, and saving back by using updateRecord and store.save(). My store's writer has writeAllFields set to false. However, it is sending back to the server fields that did not really change, including displayfields which modify the original value to something more user friendly and datetimefields. It's no mystery to me why this is happening, as updateRecord writes back displayfields. And datetimefield's problem is that if called with setValue(null), getValue() returns an empty string; and also it removes the timezone.

Any advice on a clean way to deal with a displayfield with changed value, and with datetimefield that is null or has a timezone? I suppose I could override BasicForm.updateRecord method to ignore displayfields and do extra dirty check for datetimefields, but thought I'd gather a focus group and get everybody's opinion.

walldorff
16 Mar 2011, 9:28 PM
If I understand your questions correctly, then displayFields should not be getting updated to the server.
If - in that case - you omit the name config property, then the field will not be included during submit().

JacobGu
17 Mar 2011, 3:22 AM
When calling BasicForm.updateRecord, all fields in the form (including DisplayField) getting written back to the record if they are different than record's prior value. I do need to keep 'name' property on the DisplayField in order to have loadRecord bind the field and populate the value from the record. I just don't want the value written back to the record when calling updateRecord.

I wrote an override of updateRecord to accomplish the following:
1) do not update disabled field to record (even if it changed)
2) do not update DisplayField to record (even if it changed programmatically)
3) set an empty combo box value to null (since original value in record is null)
4) set an empty date value to null (since original value in record is null)
5) do not update a date value if only difference is seconds (since date/time fields zero out seconds)

This is the override:

Ext.override(Ext.form.BasicForm, {

//
// Use custom bindConfig values to control when
// field updates are applied. Available options
// are: noUpdateDisplayField, noUpdateDisabledField,
// ignoreDateSeconds, emptyComboIsNull, emptyDateIsNull,
//
//
updateRecord : function(record){

record.beginEdit();
var fs = record.fields,
field,
value;
fs.each(function(f){
field = this.findField(f.name);
if(field){

var bindConfig = this.bindConfig || {};

if( (bindConfig.noUpdateDisabledField && field.disabled) ||
(bindConfig.noUpdateDisplayField && field.xtype == 'displayfield')){
return true;
}

value = field.getValue();

if(field.xtype == 'combo'){
if(bindConfig.emptyComboIsNull && value == ''){
value = null;
}
} else if(f.type.type == 'date'){
if(bindConfig.emptyDateIsNull && value == ''){
value = null;
} else if(bindConfig.ignoreDateSeconds){

var origValue = record.get(f.name);
if(value instanceof Date && origValue instanceof Date){

if(value.format('Y-m-d H:i') == origValue.format('Y-m-d H:i')){
return true;
}
}
}
} else if (typeof value != undefined && value.getGroupValue) {
value = value.getGroupValue();
} else if ( field.eachItem ) {
value = [];
field.eachItem(function(item){
value.push(item.getValue());
});
}

record.set(f.name, value);
}
}, this);
record.endEdit();
return this;
}
});

And the following code was added to my FormPanel subclass initComponent method:

Ext.apply(this.initialConfig, {
// bindConfig is used by a custom override of BasicForm.updateRecord
bindConfig: {
noUpdateDisabledField: true,
noUpdateDisplayField: true,
ignoreDateSeconds: true,
emptyComboIsNull: true,
emptyDateIsNull: true
}
});