PDA

View Full Version : Form.isDirty() with trackResetOnLoad: true



mohaaron
26 Jun 2009, 3:19 PM
Even with trackResetOnLoad: true I am still getting a isDirty value of true through the lifecycle of the page loading. I need isDirty to be false on load so that I can test it for true later when I have changes data in the form fields.

My intent is to check the isDirty value when a grid row is selected and if it's true cancel the row select in the beforerowselect event.

Why in the form render event isDirty is false but then in the grid render event it's true?

I have a feeling my problem is that I'm using the selectRow(0) method to select the first row in the grid, causing the row selection events to fire, then the beforerowselect event is fired, then rowselect, then the form is loaded. It seem like the only way to make this work is to make the form load before the beforerowselect event. I can't do this because I need the id from the row to know what record to load into the form.

What I need to do is on page load render the grid load it's data and select the first row in the grid without the row selection events from fires. Once thing the docs don't mention is that the selectRow() method caues the row selection events to fire which is causing my problem now. I don't want them to fire the first time the page is rendered.

Below is the FireBug output using console.log in the different events as the page loads. Can anyone tell me how to make this work?

mainForm.render
isDirty: false
Grid.Render
isDirty: true
POST http://localhost:3294/Bugs/GetBugs
Grid.Render.Store.Load
isDirty: true
grid.render.selectRow(0)
isDirty: true
grid.beforerowselect
isDirty: true
grid.rowselect
isDirty: true
loadForm(gridRecord)
isDirty: true
POST http://localhost:3294/Bugs/GetBug/
mainForm.load
isDirty: false

mohaaron
26 Jun 2009, 4:00 PM
Let me try and explain this a little more clearly.

I first load the grid with data in the grid render event with loadGridStore().
In the grid.Store.load event I select the first row in the grid.
The beforerowselect and rowselect events fire.
I'm currently calling the loadForm function in the rowselect event because I want the form to get loaded when a new row is selected. So I'm using this for the inital load as well because I can't select the first row without firing the rowselect event.

I think what I should be doing is loading the grid, somehow not firing the rowselect even or either calling the loadForm in the rowselect. Instead loading the grid, selecting the first row of grid, loading the form after the grid has loaded and somehow making the rowselect event not load the form on the initial page load.

I feel like I'm having a hard time explaining this. I hope it helps or maybe just talking about it will help me. This feels like a design problem to me.

Here is the related code with comments and all.


function loadGridStore(pageNumber, pageSize, searchValue, searchField) {
var grid = Ext.getCmp('summaryGrid');

if (searchValue == null || searchValue == '')
{
// load params are a name:value pair.
grid.getStore().load({ params: {start: pageNumber, limit: pageSize} });
}
else
{
//console.log('start:' + pageNumber + ', limit:' + pageSize+ ', searchValue:' + searchValue + ', searchField:' + searchField);
grid.getStore().load({ params: {start: pageNumber, limit: pageSize, searchValue: searchValue, searchField: searchField} });
}
}

var summaryGrid = new Ext.grid.GridPanel({
id: 'summaryGrid',
region: 'north',
border: true,
//width: 300,
height: 600,
loadMask: true,
store: summaryGridStore,
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
beforerowselect: function(sm, rowIndex, keepExisting, gridRecord) {
console.log('grid.beforerowselect');
console.log('isDirty: ' + Ext.getCmp('mainForm').getForm().isDirty());
// This is always true on form load. We need to find out why
// and fix it. When the form first loads it should be false
// until a field is changed.
// if (Ext.getCmp('mainForm').getForm().isDirty())
// alert('dirty form');
//
// return false;

// if (formDataChanged) {
// showDirtyFormMsg();
// }
},
rowselect: function(sm, rowIndex, gridRecord) {
console.log('grid.rowselect');
console.log('isDirty: ' + Ext.getCmp('mainForm').getForm().isDirty());
// Load form with currently selected record.
loadForm(gridRecord);
}
}
}),
columns: [
{ header: 'FixNoteId', width: 80, sortable: true, dataIndex: 'FixNoteId' },
{ header: 'Summary', width: 300, sortable: true, dataIndex: 'Summary' }
],
bbar: new Ext.PagingToolbar({
pageSize: 100,
displayInfo: true,
displayMsg: 'Bugs {0} - {1} of {2}',
emptyMsg: 'No data found',
store: summaryGridStore
}),
listeners: {
render: function(grid) {
console.log('Grid.Render');
console.log('isDirty: ' + Ext.getCmp('mainForm').getForm().isDirty());

//g.getStore().load({ params: { start: 0, limit: 100} });
loadGridStore(0, 100, '');

// Load the grid store here so we can set focus and select the first row on grid load.
grid.getStore().on('load', function() {
console.log('Grid.Render.Store.Load');
console.log('isDirty: ' + Ext.getCmp('mainForm').getForm().isDirty());

// Set focus to the grid to allow navigating the rows.
grid.getView().focusEl.focus();

console.log('grid.render.selectRow(0)');
console.log('isDirty: ' + Ext.getCmp('mainForm').getForm().isDirty());

// The selectRow(0) and selectFirstRow() methods causes the 'rowselect' event to be fired.
//grid.getSelectionModel().selectFirstRow();
grid.getSelectionModel().selectRow(0);

// // selected record.
// gridRecord = grid.getSelectionModel().getSelected();
// // Load form with currently selected record.
// loadForm(gridRecord);
});
},
delay: 10
}
});

function loadForm(gridRecord)
{
console.log('loadForm(gridRecord)');

var mainForm = Ext.getCmp('mainForm'); // FormPanel
var jsonData = null;

mainForm.load({
url: appRoot + '/Bugs/GetBug/',
params: { FixNoteId: gridRecord.id },
method: 'post',
// waitTitle: 'Processing...',
// waitMsg: 'Loading data...',
success: function(form, action) {
console.log('mainForm.load');
console.log('isDirty: ' + Ext.getCmp('mainForm').getForm().isDirty());

jsonData = Ext.util.JSON.decode(action.response.responseText);

// Manually load data into Summary Panel fields (non-editable fields).
// This can't be automatically bound to the form fields because only one form field
// can be bound at a time.
Ext.getCmp('mainForm').getForm().findField('txtFixNoteId').setValue(jsonData.data.FixNoteId);
Ext.getCmp('mainForm').getForm().findField('txtSummary').setValue(jsonData.data.Summary);
Ext.getCmp('mainForm').getForm().findField('txtDateEntered').setValue(jsonData.data.DateEntered);
Ext.getCmp('mainForm').getForm().findField('txtPvVersion').setValue(jsonData.data.PvVersion);

// This doesn't work very well. The waitTitle/waitMsg is causing the grid to lose focus.
//Ext.getCmp('summaryGrid').getView().focusEl.focus();

// Why don't I have access to the variable myForm here?
//mainForm.getForm().findField('prdCombo').setValue(jsonData.data.PrdClass);
}
});

// Why can't I set the value of jsonData in the success function and then access it here?
////console.log(jsonData.data.PrdClass); // returns error: jsonData is null.
}

mohaaron
26 Jun 2009, 4:07 PM
I thought I had this fixed for a minute.

I did this in store.load which helped by stopping the rowselect event from fires on load. This allowed me to load the form earlier and the first selected grid record.


grid.getSelectionModel().suspendEvents();
grid.getSelectionModel().selectRow(0);
grid.getSelectionModel().resumeEvents();

// selected record.
gridRecord = grid.getSelectionModel().getSelected();
// Load form with currently selected record.
loadForm(gridRecord);
Now for some reason after the page has loaded when I go to click on a different grid row the form.isDirty flag is somehow set to true even though I have not changed anything.

After clicking on a different row I get this sequence.

grid.beforerowselect
isDirty: true
grid.rowselect
isDirty: true
loadForm(gridRecord)
POST http://localhost:3294/Bugs/GetBug/
mainForm.load
isDirty: true

mohaaron
26 Jun 2009, 4:10 PM
The reason why I'm doing all this is so I can cancel the selection of a new row in the grid if the form is dirty.

mohaaron
26 Jun 2009, 4:22 PM
OK, now this was helpful. I just added the following code to the grid.render event to see what fields were causing the problem. It seems to be all checkbox fields. I happen to be using the xcheckbox extension and am now wondering if this is my problem.



Ext.getCmp('mainForm').getForm().items.each(function(field) {
// Why is the form dirty.
if (field.isDirty()) {
console.log('Dirty Field: ' + field.fieldLabel);
}
});

mohaaron
26 Jun 2009, 4:45 PM
It seems as though different fields are dirty at different times. I commented all the checkboxes for the moment and now I have a dirty htmlEditor in the grid.store.load event and I have no idea why.

JAnderson
5 Oct 2009, 11:29 AM
Did you ever resolve this issue? Your exact same situation is currently driving me insane!

JAnderson
5 Oct 2009, 11:31 AM
It definitely has to do with CheckBoxes. I'm not using any user extensions on this page, and when I remove my RadioGroup object from the form isDirty() functions as intended.

JAnderson
5 Oct 2009, 11:36 AM
I seem to have resolved the issue. If you set the name at both the group and item level isDirty() doesn't function properly, but if you set the name at just the item level isDirty() works just fine. Maybe setting the name at the group level recursively sets the name on each item and somehow flags them as dirty (even if the name is identical)?

JAnderson
5 Oct 2009, 2:59 PM
I seem to have resolved the issue. If you set the name at both the group and item level isDirty() doesn't function properly, but if you set the name at just the item level isDirty() works just fine. Maybe setting the name at the group level recursively sets the name on each item and somehow flags them as dirty (even if the name is identical)?
Nevermind, isDirty() works in that situation but the RadioGroup no longers functions properly.

froggman2k
18 Mar 2010, 2:48 PM
I am having the same issue, and have forms that are nothing BUT radio groups... I am going to try doing them as individual radios, but unfortunately there doesn't seem to be a way to get a radio value based on the "name"... Which means I have to check each radio individually... So I'd really like to see if someone has found a way to make checkbox and radio button groups work with the setValues, isDirty stuff.

fermo111
7 Jul 2010, 5:06 AM
This bug is still present in version 3.2.1

fermo111
21 Sep 2010, 6:12 AM
Bump

picofaradpjf
4 Nov 2010, 9:50 AM
Seems to still be a problem in 3.3

Here's a fix for RadioGroups that is working for me.


Ext.override(Ext.form.RadioGroup, {

isDirty: function(){
//skip the disabled or not rendered
if (this.disabled || !this.rendered) {
return false;
}
//override the behaviour to check sub items.
var dirty = true;
if( this.getValue().inputValue == this.originalValue.inputValue )
{
dirty = false;
}

return dirty;
}
});

DerSalz
21 Nov 2010, 11:00 AM
I'm having the same problem with 3.3.0! In my opinion this is a bug! Someone from ExtJS should look at it!

frrogoy
10 Jan 2011, 10:42 AM
I use the same form for initial data entry (new record) and can load an existing record into the form via double-click on a grid record. I need to reset (clear) the form between records as hidden fields may have been set as a result of user actions. Hidden fields include keys for combo boxes that are displaying text. (This is a related problem when using a form this way - both manually entering data and updating after loading data from a grid - you can't get it to work the same way in both cases.)
I can't use trackResetOnLoad because I need to be able to clear the form. I can't use isDirty because the fields become dirty when I load a record. So I end up using additional hidden fields when I need to track that a textfield or combo box has been changed.
I never had these problems with html forms. I think the timing is different in ExtJS (when the data gets put in the field) from initializing field content via a PHP module, and that is what is resulting in these problems.