How to prevent web_form.on() from triggering when web_form.set_value() is used

Hello

Framework v15.32

I’m trying to prevent the web_form.on() event handler from triggering when I supply the field it’s value programmatically with web_form.set_value().

On a DocType Form View that is possible with skip_dirty_trigger=true, but I cannot figure out how to do the same for a Web Form.

Any ideas?

Further to my original question above:

Note that according to the documentation at Customization to reset a value, we need to invoke frappe.web_form.set_value(). However, if this is done within the event handler, as is indicated in the documentation, then this leads to an infinite loop, for specific values such as null, undefined, “”, NaN, etc. This freezes the browser :angry:

What we really need is the ability to not trigger the event handler as is the case with frm.set_value() for DocType Form Views. This function has an argument skip_dirty_trigger=true which the web_form.set_value() does not have.

Is there any workaround for this behaviour?

Hi @EugeneP:

You can “disable” the event before assign the value for special cases… and “restore” it after.

function enableEvent() {
    frappe.web_form.on('subject', (field, value) =>  {
    console.log("enabled");
    })
}


function disableEvent() {
    frappe.web_form.on('subject', (field, value) =>  {
    console.log("disabled");
  dis()
    })
}

// Your code
disableEvent()
frappe.web_form.set_value("subject", "Hello")
enableEvent()

Hope this helps.

But maybe I’m not understanding your use case :sweat_smile:

1 Like

Hi @avc
Good to hear from you again

This is an event handler associated with the Web Form field “subject”. My dilemma is that it triggers when I update the very same field (aka “subject”) with field.set_value(). I don’t want the event handler to trigger on all occasions, especially when set_value() is called from within the event handler, as below.

frappe.ready(function() {
	frappe.web_form.on('subject', (field,value) => {
		field.set_value(undefined);
	});
});

The above code causes an infinite loop you cannot escape from. The browser freezes and your best option is the kill the process.

This happens because I cannot declare not to trigger the event handler with something such as

field.set_value(undefined, skip_dirty_trigger=true)

Hi @EugeneP:

Nice to hear from you too :slight_smile:
I’m afraid that I don’t catch your point yet :joy:

How can this be?
field.set_value(undefined)
Maybe you are making a call and value can be undefined?

Check this:

frappe.web_form.on('subject', (field, value) =>  {
    enableSubjectEvent(value)
})

function enableSubjectEvent(value) {
    frappe.web_form.on('subject', (field, value) =>  {
       undefinedPrevention(value)
    })
}

function disableSubjectEvent() {
    frappe.web_form.on('subject', (field, value) =>  {
        console.log("action on disableEvent");
    })
}

function undefinedPrevention(value){
    if (value === "somestring"){
        console.log("undefined detected!");
        disableSubjectEvent()
        frappe.web_form.set_value("subject", "undefined prevention system!")
        enableSubjectEvent()
    }
}

I’m sure that there are many ways to do it better and cleaner, but, I think it will works.

Hope this helps.

What I mean with field.set_value(undefined) is to reset it’s value to nothing, which is very much fieldtype dependent.

  • If it’s a Data, Small Text, Phone, etc then you can reset it’s value to any one of “”, null, undefined, etc
  • If it’s Int, Currency, etc then you can reset to 0, null, undefined, etc

In essence how do you remove any value currently in the field, ie clear it.

This is based directly on the example from the documentation at Customization wich I copy here for convenience.

frappe.web_form.on('amount', (field, value) => {
    if (value < 1000) {
        frappe.msgprint('Value must be more than 1000');
        field.set_value(0);
    }
});

Note that in this case field.set_value(0) will still trigger the frappe.web_form.on() event handler but only once, as the second call to field.set_value(0) will deem the field not to be dirty. BUT, this is not always the case and in the event of field.set_value(undefined) or field.set_value(“”) it keeps triggering the event handler. It creates an infinite loop.

Copy and paste my 5 lines of JS into the .js file of a Web Form and execute it. Your browser freezes up!!!

Hi EugeneP:

Ok, sorry, I see now … It’s pretty strange.
I’m not JS expert … but maybe related with execution workflow …