PDA

View Full Version : Tracking dirty fields in form with RED TRIANGLE



genio
22 Jan 2010, 5:04 AM
Made alteration to use this in EXT 3.0 on this historycal 1.0 extension http://www.extjs.com/forum/showthread.php?p=429924#post429924



Ext.override(Ext.form.Field, {
initEvents: function () {
this.el.on(Ext.isIE ? "keydown" : "keypress", this.fireKey, this);
this.el.on("focus", this.onFocus, this);
this.el.on("blur", this.onBlur, this);
this.el.on("change", this.markDirty, this);
// reference to original value for reset
this.originalValue = this.getValue();
},
markDirty: function () {
if (this.isDirty() && this.originalValue != this.getValue()) {
if (!this.dirtyIcon) {
var elp = this.el.parent('.x-form-element');
this.dirtyIcon = elp.createChild({
cls: 'x-grid3-dirty-cell'
});
this.dirtyIcon.position("absolute",0,0,0);
this.dirtyIcon.setSize(10, 10);
}
this.alignDirtyIcon();
this.dirtyIcon.show();
this.on('resize', this.alignDirtyIcon, this);
} else {
if (this.dirtyIcon) {
this.dirtyIcon.hide();
}
}
},
alignDirtyIcon: function () {
this.dirtyIcon.alignTo(this.el, 'tl', [0, 0]);
}
});
Seems to work nicely on my form that now with the trackResetOnLoad: true is quite happly setting the dirty triangle when the users changes the form from its original value!

I suggest this could be part of a future extension on the Basic Form so that an option "showDirtyFields" could import this functionality

Hope this helps!

genio
22 Jan 2010, 7:56 AM
Ext.override(Ext.form.BasicForm, {
clearDirty: function() {
var i, it = this.items.items, l = it.length, c;
for (i = 0; i < l; i++) {
it[i].markDirty();
}
}
});


This also heps to clear out the form manually

supercharge2
22 Jan 2010, 8:34 AM
This is very useful, thanks for posting. As usual, it works great in Firefox and seems to have issues in IE. I am using IE8, the red triangle is not aligning in the form field properly. It is indented about a tabs width in. I will try to play with it and see what I can find. Thanks again for a cool post!

genio
22 Jan 2010, 9:16 AM
Baaah! Stupid IE!

Ok So to make it compatible with IE I had to inverse the init and dirty function in the extensions (ie6 engine will complain about mark dirty not being define prior to assignin it to the change event)

I also added a little tweek to the position of the icon if its IE (Bah!)



Ext.override(Ext.form.Field, {
markDirty: function () {
if (this.isDirty() && this.originalValue != this.getValue()) {
if (!this.dirtyIcon) {
var elp = this.el.parent('.x-form-element');
this.dirtyIcon = elp.createChild({
cls: 'x-grid3-dirty-cell'
});
if (Ext.isIE) {
this.dirtyIcon.position("absolute", 0, -5, 0);
} else {
this.dirtyIcon.position("absolute", 0, 0, 0);
}
this.dirtyIcon.setSize(10, 10);
}
this.alignDirtyIcon();
this.dirtyIcon.show();
this.on('resize', this.alignDirtyIcon, this);
} else {
if (this.dirtyIcon) {
this.dirtyIcon.hide();
}
}
},
initEvents: function () {
this.el.on(Ext.isIE ? "keydown" : "keypress", this.fireKey, this);
this.el.on("focus", this.onFocus, this);
this.el.on("blur", this.onBlur, this);
this.el.on("change", this.markDirty, this);
// reference to original value for reset
this.originalValue = this.getValue();
},

alignDirtyIcon: function () {
this.dirtyIcon.alignTo(this.el, 'tl', [0, 0]);
}
});

Ext.override(Ext.form.BasicForm, {
clearDirty: function () {
var i, it = this.items.items,
l = it.length,
c;
for (i = 0; i < l; i++) {
it[i].markDirty();
}
}
});

supercharge2
22 Jan 2010, 9:25 AM
Works perfectly now in my not so perfect IE! Thanks again.

supercharge2
22 Jan 2010, 9:37 AM
I need the dirty to truly clear vs just the visual reset of the dirty flag. I do isDirty checking that continues to trigger on the posted clearDirty function. This slightly modifies the clearDirty function to provide a true dirty clear:



//a clearDirty overide to give dirty reset ability
Ext.override(Ext.form.BasicForm, {
clearDirty: function () {
var i, it = this.items.items,
l = it.length,
c;
for (i = 0; i < l; i++) {
it[i].markDirty();
c = it[i];
c.originalValue = String(c.getValue());
}
}
});


I am digging this, thanks again.

DerSalz
27 Jan 2010, 7:25 AM
Hello,

It's seems not to work with ComboBox, CheckBox or DatePicker.

In fact the markDirty method will never be called on the change event.

I changed the initEvents function a little bit:



initEvents: function () {
this.el.on(Ext.isIE ? 'keydown' : 'keypress', this.fireKey, this);
this.el.on('focus', this.onFocus, this);
this.el.on('blur', this.onBlur, this);
this.on('change', this.markDirty);
//this.el.on('change', this.markDirty, this);
// reference to original value for reset
this.originalValue = this.getValue();
}

This worked but I don't know why...

Can anybody help? What am I doing wrong? I would love to use this change tracking on form fields but it has to work with all field types.

Another thing I'm wondering: When using an editable Grid the red triangle appears when changing a value but it doesn't hide when the value is changed back to the original value. Is this the "normal" behaviour? I would like it to hide the red triangle when the original value is set again in the field. This is perfectly working on this form field solution in the markDirty function.

Thanks

DerSalz
27 Jan 2010, 8:34 AM
I forgot to mention that I'm using ExtJS 3.1.0

genio
29 Jan 2010, 2:34 AM
Have you set track on load on the form?

when i set back the original value for me its removing the triangle

DerSalz
29 Jan 2010, 4:14 AM
yes, I used:

trackResetOnLoad : true

on the form.

Does it work with DatePicker and ComboBox with you?
Maybe it is a problem using ExtJS 3.1? I get the error with IE and Firefox.

If I set:

this.on('change', this.markDirty);

in the initEvent function. It works but then you have a problem with the EditorGridPanel asvar elp = this.el.parent('.x-form-element'); is null when editing a Date cell or ComboBox cell.

Changing your markDirty function to:



markDirty: function () {
if (this.isDirty() && this.originalValue != this.getValue()) {
if (!this.dirtyIcon) {
var elp = this.el.parent('.x-form-element');
if(elp != null) {
this.dirtyIcon = elp.createChild({
cls: 'x-grid3-dirty-cell'
});
if (Ext.isIE) {
this.dirtyIcon.position("absolute", 0, -5, 0);
} else {
this.dirtyIcon.position("absolute", 0, 0, 0);
}
this.dirtyIcon.setSize(10, 10);
}
else {
// do nothing. otherwise the grid tracking is not working anymore...
//Ext.Msg.alert('this.el.parent is null!');
}
}
if(this.dirtyIcon) {
this.alignDirtyIcon();
this.dirtyIcon.show();
this.on('resize', this.alignDirtyIcon, this);
}
} else {
if (this.dirtyIcon) {
this.dirtyIcon.hide();
}
}
},


it works with form fields and editable grid cells. But that can't be the solution

Any ideas?

jmariani
5 Feb 2010, 3:45 PM
Hey, nice override.
Can you develop a similar one, but with the functionality of putting the red triangle (or something else) on the top right corner of the field when the field is required? I'll appreciate that.

TIA.

ashraffsdpak
6 Feb 2010, 1:00 AM
Works perfectly now in my not so perfect IE! Thanks again.
This is so much easy and useful, thanks for this it works great in Firefox and seems to have issues in IE. the red triangle is not aligning in the form field properly. I will try to enjoy to play with it and see its digits what I can find. Thanks again for this posting.

catnipper
28 Feb 2010, 11:32 AM
Thank's - it works fine for me too.

1. I added a function "markClean":

function markClean (item) {
if (item.dirtyIcon) {
item.dirtyIcon.hide();
}
}

2. Added a "Reset" button (working fine):

buttons: [{
text: 'Save'
},{
text: 'Reset',
handler: function () {
// Empty the form input
gridForm.getForm().reset();
// Reset the markDirty
gridForm.getForm().items.each(markClean);
}
}]

3. Added a grid with row selection to populate the form:

sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
rowselect: function(sm, row, rec, id) {
LayoutContactGrid = Ext.getCmp("contact_grid_"+rec.get('account_id'));
LayoutContactForm = Ext.getCmp("contact_form_"+rec.get('account_id'));
if(LayoutContactForm && LayoutContactGrid) {
gridForm.getForm().items.each(markClean);
gridForm.getForm().reset();
LayoutContactGrid.getForm().loadRecord(rec);
LayoutContactForm.setVisible(true);
} else {
alert('Could not find \'contact_form_'+rec.get('account_id')+'\'');
}
}
}
}),


When I put the cursor in one of the form fields and select a new record from the grid, this field is getting "dirty" - although I explicitly reset the form. If the current focus is not in on a field in this form everything works as expected.

Any ideas (or better solutions)?