[HOW TO] - A technique to evaluate 2 or more fields on change

Hey guys, I just sharing how I do it in case someone else stack on this.

The scenario:

Assume that in DocType Item we have added Custom Fields (Setup > Customize Form):
– 1. customer, that is a Link to DocType Customer, ex. Stavros
– 2. customer_type, that is a Select with options “From Space”, “From Outter Space”

So, we need when User creates an Item and if he selects ‘customer’ or ‘customer_type’ then ‘item_code’ to auto-generate like ‘ST-FOS’ → ‘Stavros From Outter Space’

So we need to detect on two fields the on change state and also we need only if customer is set to generate the code.

And all this must be exported to our version control.

LET DO THIS :slight_smile:


in Setup > Custom Script select DocType Item:

frappe.ui.form.on("Item", 
  customer: function(frm) {
    updateItemCode(frm)
  },
  customer_type: function(frm) {
   updateItemCode(frm) 
 }

function updateItemCode(frm) {
   form_data = {
    customer: frm.doc.customer,
    customer: frm.doc.customer_type,
  }
 
frappe.call({
      method: "myapp.myapp,mynewapi.mywhitelistdecoratorfuction",
      args : { "form_data": form_data },
      callback: function(response) {
        frm.set_value("item_code", response.message)
      }
 });
}

So, what I have done ?

I just calling updateIteCode function everytime a change is made and passing the frm object, in order to get frm.doc.customer and frm.doc.customer_type to a json obj called variable form_data. The updateItemCode function is just a api call to the backend (@frappe.whitelist() decorated function) where we handle our data.
This way we can version control ‘Custom Script’ by updating hooks.py and export-fixtures and we can version control our custom backend code as it lives to our app (myapp/myapp/mynewapi.py).

Now on the backend

import frappe
import json 

@frappe.whitelist()
def mywhitelistdecoratorfuction(form_data):
   form_data =  json.data(form_data)
   # your awesome code here
   # validate form_data like 
   # if 'customer' in form_data.keys():
   # or if form_data['customer']: 
     if #Some of your validation with form_data:
         return 'ST-FOS'  #A string with an new Item Code
   return ''   # in all other case return a empty string

As you can tell from the above code, I don’t write the whole code but only the important lines.

So, import json will let us deserialize the Custom Script json form_data we sent with json.loads(form_data) as a python dictonary. Also keep in mind to use the same name between your client function and the whitelisted function, in my case I named it form_data.

That’s it,
Hope you liked it

This is a simplication and an minor example example not official docs. Also, some things might broke due ERPnext updates- I using bench version 4.0.0, erpnext 7… Always check Topics date :slight_smile:

4 Likes