I'm trying to bind to form's dirty property but, looks like it is processed incorrectly
Please, check fiddle for code example and a description for the bug
https://fiddle.sencha.com/#fiddle/3ovk
// define model
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int', convert: null},
{name: 'phone', type: 'string'},
{name: 'alive', type: 'boolean', defaultValue: true, convert: null}
],
});
// create new record, some filed should have empty string (ex. phone)
var user = Ext.create('User', {
id : 'ABCD12345',
name : 'Conan',
age : 123,
phone: ''
// phone: '123456789' // if the field is not empty, then dirty updated correctly
});
// create basic form
// (viewModel and binding just to check form dirty property)
var form = Ext.create({
xtype: 'formpanel',
viewModel: true,
reference: 'formref',
publishes: ["dirty"],
trackResetOnLoad: true,
items: [
{
xtype: 'textfield',
label: 'id',
name: 'id'
},
{
xtype: 'textfield',
label: 'name',
name: 'name'
},
{
xtype: 'textfield',
label: 'age',
name: 'age'
},
{
xtype: 'textfield',
label: 'phone',
name: 'phone',
},
{
xtype: 'textfield',
bubbleDirty: false,
bind: '{formref.dirty}'
},
]
});
Ext.application({
name : 'Fiddle',
launch : function() {
// render container and lookup for something to reproduce form durty bug
var container = Ext.create({
xtype: 'container',
items: [form]
})
Ext.Viewport.add(container);
// comment next line to check formref.dirty is set correctly
var f = container.lookup('formref');
// lookup will call
// beginSyncChildDirty: function() {
// this._childDirtyState = { counter: 0, ready: false };
// },
// so, it initialize counter
// as phone field value is not changed, it will call adjustChildDirtyCount with false
// childDirtyState.counter += dirty ? 1 : -1;
// now, the childDirtyState.counter is equal to -1
// and !!childDirtyState.counter equal to true
// me.setDirty(!!childDirtyState.counter);
// formref.dirty is now set to true
form.setRecord(user);
}
});
Key to reproduce - call lookup() before setting record to the form panel
I'm looking for the correct fix of the issue
Thanks!
I was discussing the issue with Sencha Support team, and we came up with a quick fix for the issue by adding an override:
Ext.override(Ext.form.Panel, {
adjustChildDirtyCount: function (dirty) {
var me = this,
childDirtyState = me._childDirtyState;
if (childDirtyState) {
if (childDirtyState.ready) {
childDirtyState.counter += dirty ? 1 : -1;
// Fix - Counter should not be less than 0
if(childDirtyState.counter < 0){
childDirtyState.counter = 0
}
me.setDirty(!!childDirtyState.counter);
} else if (dirty) {
childDirtyState.ready = true
++childDirtyState.counter;
}
}
}
})
Looks like it works for me