Search code examples
javascriptformsextjsextjs4extjs4.2

ExtJS4.2 - Fields inside of FieldContainer is always marked dirty.


Good day. I have a web application where a user fills out several forms. These forms can then be edited and I want to log the edits in my database as well in a form of an audit trail by getting all the dirty fields in the form and logging the name and value in the database.

Initially, I had a problem with Radio Buttons that had the same name since they were marked as dirty but I eventually managed to solve that. My issue now, however, are the fields inside a FieldContainer. Even if I unmark them as dirty, when I run the code that checks for dirty fields, the fields inside the FieldContainer are marked as dirty.

Here's the code that I run on preloading of the form to make my buttons clean:

form.items.filterBy(function(c){

    if(c.getXType()==='radiofield'){
        c.originalValue = c.getValue();
        c.checkDirty();
    }
    else{
    }
    if(c.getXType()==='fieldcontainer'){
        c.items.filterBy(function(d){
            if(d.getXType()==='checkboxfield' || d.getXType()==='textfield' ||
               d.getXType()==='combobox'){

                console.log("itemID of field in fieldContainer = " + d.getItemId());

                d.originalValue = d.getValue();
                d.checkDirty();

                console.log("component dirty state = " + d.isDirty());
            }
        });
    }

});

What my function does is it iterates through every child view element of the form. As you can see, I have two if conditions. My first if condition checks if the element is a radio button, if so, I just mark it as clean. The second if statement checks if the element is a field container. If so, I check all the children view elements in the field container and I look for check boxes, text fields, and combo boxes, then mark them as clean. Here's the console log that I got from that:

itemID of field in fieldContainer = amountFinanced
component dirty state = false
itemID of field in fieldContainer = unitTerm
component dirty state = false

I counter checked with my View and those are the right itemIDs and they are marked as clean.

Now, I create my audit trail records on button click. The general idea is that I get the active form, go through the fields and check which ones are dirty. Here's my code:

form2.items.filterBy(function(c){
    if(c.getXType()==='radiofield' || c.getXType() ==='combobox' ||
       c.getXType()==='radiogroup' || c.getXType() ==='textfield' ||
       c.getXType()==='datefield' || c.getXType() ==='fieldset' ||
       c.getXType()==='fieldcontainer' || c.getXType() ==='checkbox' ){

        if(c.getXType()!='fieldcontainer'){
            if(c.isDirty()){
                var entry = '';
                if(c.getXType()==='radiofield'){
                    entry = c.getName() + ": " + c.getSubmitValue();
                }
                else{
                    entry = c.getName() + ": " + c.getRawValue();
                }

                changes.push(entry);
            }
        }
        else{
            c.items.filterBy(function(d){
                if(d.getXType()==='radiofield' || d.getXType() ==='combobox' ||
                   d.getXType()==='radiogroup' || d.getXType() ==='textfield' ||
                   d.getXType()==='datefield' || d.getXType() ==='fieldset' ||
                   d.getXType()==='fieldcontainer' || d.getXType() ==='checkbox' ){

                    if(d.getXType()!='fieldcontainer' && d.getXType()!='label'){
                        console.log("item id = " + d.getItemId());
                        console.log("item name = " + d.getName());
                        console.log("component dirty state = " + d.isDirty());

                        if(d.isDirty()){

                            var entry = '';
                            if(d.getXType()==='radiofield'){
                                entry = d.getName() + ": " + d.getSubmitValue();
                            }
                            else{
                                entry = d.getName() + ": " + d.getRawValue();
                            }
                            changes.push(entry);
                        }
                    }
                }
            });
        }
    }
});

This is a bit lengthier than the previous one. I start by going through all the view elements inside the form and I filter through all the element XTypes that I used. If I come across something that's not a field container, I check if it's dirty, if it's dirty, I take the name and value of the field and put it in an array (that I will later on save to my database). However, if it's a field container, I check the elements in that field container to check if those are dirty then I'll save them.

Now. I also log the item IDs as well as the name of the fields inside the fieldcontainer. I checked if marking the fields inside the fieldset as clean (as I did when I loaded the forms) would help. However, upon checking the console for logs, I saw that the fields inside the fieldcontainer was marked as dirty even if I didn't change them. Here is my log:

item id = amountField
item id = amountFinanced
item name = AMOUNT_FINANCED
component dirty state = true
item id = termField
item id = unitTerm 
item name = TERM
component dirty state = true

As you can see, I am able to go through the field container (amountField and termField respectively), navigate to the field (amountFinanced - textfield, and unitTerm - comboBox), get their names, and see if they're dirty.

Now I'm confused, I was able to mark those fields as clean earlier, why is it that when I proceed to checking all the dirty fields, they're now marked as dirty even if I didn't change anything?

Is there a better way to check if the fields inside a field container (and a field set) are dirty? I've been stuck with this problem for several hours now and the frustration is getting to me.

Thanks for any help.


Solution

  • Okay I'm an idiot. The said fieldsets are initialized from another controller since the values are taken from another store/database table. I had to run the code below in the controller where I get the values from my store and load them into the form.

    However, in my other form that contain fieldsets, it seems that you have to run this code to make sure they aren't marked as dirty every time even if no changes were made:

    form.items.filterBy(function(c){
    
        if(c.getXType()==='radiofield'){
            c.originalValue = c.getValue();
            c.checkDirty();
        }
        if(c.getXType()==='fieldcontainer'){
            c.items.filterBy(function(d){
                if(d.getXType()==='checkboxfield' || d.getXType()==='textfield' ||
                   d.getXType()==='combobox'){ //add whatever XType you have inside
    
                    console.log("itemID of field in fieldContainer = " + d.getItemId());
                    console.log("component dirty state before = " + d.isDirty());
    
                    console.log("original value = " + d.originalValue);
                    console.log("get value = " + d.getValue());
                    console.log("get raw value = " + d.getRawValue());
    
    
                    d.originalValue = d.getValue();
                    d.checkDirty();
    
                    console.log("component dirty state after = " + d.isDirty());
    
    
                }
            });
        }
    
    });
    

    Of course you can remove the console logs.