An easy way determine if a form is dirty (user has changed something)

This has been asked my previosly by myself: A way to tell if form fields in the app are dirty? - #8 by Funkdaddy and I remember this coming up in other places.

Well I just figure out a way to do this easily.

  1. All of the components you want to check for dirty are in a form component. A simple container won't do.
  2. Assign the form a default value that is the object of the data the user may edit. This is most commonly selected row in a table so it would be simply: {{table.selectedRow}}. I also use an object passed to a module that holds the editing functionality.
  3. You need to make sure the Form data key property has the same object property names as your Initial data. If you used Generate Form to add your components, this is is done for you.
  4. Make this transformer:
// trIsFormDirty
const keys = Object.keys({{form1.data}})
return !keys.every(key => {
  if ({{form1.initialData}}.hasOwnProperty(key)) {
    return (({{form1.data}}[key] || null) === ({{form1.initialData}}[key] || null))
  } else {
    return true
  }
})

You can double check if it is all set up correctly by going to Debug Tools and expanding .data and .intitalData on your form to make sure the field names all match. You do not need to have all of your fields in the form, just the ones you want to edit.

Now you just need to check trIsFormDirty.value to see if the user has change anything!

Yo can add/remove components form the form without changing anything else in the app making maintenance much easier then previous techniques.

Let me explain the function in case you are interested:

const keys = Object.keys({{form1.data}})
This gets all of the Form data key values we set up that are also the same names as your initialData object properties.

return !keys.every(key => {
Now we loop through all of them. every will return true if all of its lambda functions return true. If any one of the me returns false, it will stop and return a false. We return the not (!) of its value as we asking if dirty, not if clean.

if ({{form1.initialData}}.hasOwnProperty(key)) {
This is a safety check for an apparent bug (Form.data property has an extra item that does not belong) that allows random values in the form's .data array.

return (({{form1.data}}[key] || null) === ({{form1.initialData}}[key] || null))
This checks to see if the form1.data value is the same as its intitialData. A component's value will often be an empty string or a 0 if the intitalData's value was null. This accounts for that so 0 === null and "" === null'.

  } else {
    return true
  }

This is the bottom half the the safety check, we must return true if there is a rogue value or else .every assume it is false and fails the entire thing.