Dirty Form Checker Functions - JS

UPDATE: 2021-11-16

I was having trouble with accessing the global object with AppConnect (I assume this is because NodeJS being server side and all), so I have cleaned up the code and added “global” variables to dmx.app.data instead. Now any buttons etc with dynamic attributes will respond to changes in pd_dirtyFormCheck.dirty.


So it took me quite a while to get this just the way I wanted it, (removeEventListener is to blame for THAT!), but I finally managed it. Below is my JS to check whether a form is dirty or not. I just use the “Run Javascript” in the flow editor and plug in the ID of my form and I’m away.

There is also a destroy function here to remove the global variable holding the form ID, remove the 3 global arrays checking the form inputs and also removing those elements custom attributes, plus removing all event listeners on the form elements.

Don’t shoot me if the code isn’t pretty :stuck_out_tongue:

const pddfc = function pd_dirtyFormChecker(input) {
    input = input.currentTarget;
    let fid = dmx.app.data.g_formid;
    let dfc = dmx.app.data.pd_dirtyFormCheck[fid]['els'];
    let dfcc = dmx.app.data.pd_dirtyFormCheck[fid]['els_changed'];
    dmx.app.data.pd_dirtyFormCheck[fid]['els_changed'][input.getAttribute('pddfc')] = input.value;
    for(let i=0;i<dfc.length;i++) {
        if(dfc[i] !== dfcc[i]) {
            dmx.app.data.pd_dirtyFormCheck[fid].dirty = true;
            break;
         } else {
            continue;
         }
    }
}
function pd_dirtyFormCheck_init(formid) {
    let el = document.getElementById(formid).elements;
    dmx.app.data.g_formid = formid;
    const formel = ['input', 'select', 'textarea'];
    dmx.app.data.pd_dirtyFormCheck = {};
    dmx.app.data.pd_dirtyFormCheck[formid] = {
        'dirty': false,
        'els': [],
        'els_changed': [],
        'eventlisteners': []
    };
    let dfc = dmx.app.data.pd_dirtyFormCheck[formid].els, dfcc = dmx.app.data.pd_dirtyFormCheck[formid].els_changed;
    let count = 0;
    for(let i=0;i<el.length;i++) {
        let e = el[i];
        if(formel.includes(e.nodeName.toLowerCase())) {
            dfc.push(e.value || null);
            dmx.app.data.pd_dirtyFormCheck[formid].eventlisteners.push(e);
            e.setAttribute('pddfc', count);
            e.addEventListener('change',pddfc);
            count += 1;
        }
    }
    dfcc.push(...dfc);
}
function pd_dirtyFormCheck_destroy() {
    let dfd = dmx.app.data.pd_dirtyFormCheck[dmx.app.data.g_formid];
    for(const el of dfd.eventlisteners) {
        el.removeEventListener('change', pddfc);
        el.removeAttribute('pddfc');
    }
    delete dmx.app.data.pd_dirtyFormCheck[dmx.app.data.g_formid];
    delete dmx.app.data.g_formid;
}

I use this for a form in a modal for on Shown (making sure the inputs have their dynamic values added before calling the function), and on Hidden (to destroy the function).

Enjoy ladies and gents. :slight_smile:

Community Page
Last updated: