Custom script freezes browser

I am trying to create a land area converter in Leads form.

Land area is taken as input two formats:

  1. R-A-P-D : ropani - aana - paisa -dam (local unit of Nepal)
  2. sq.ft/sq.m

Feature needed: when user changes one value, others must update accordingly.
Logic is simple:

1 R = 16 A 
1 A = 4 P
1 P = 1 D

1 R = 5476 sqft
1 A = 1R/16 = 5476/16 = 342.25sqft
1 P = 1A/4 = 342.25/4 = 85.5625 sqft
1 D = 1P/4 = 85.5625/4 = 21.3906sqft

Now I put the custom script to handle this on form data changes but it is creating a cyclic loop and browser freezes.

frappe.ui.form.on('Lead', {
    custom_square_meter: function(frm) {
        let square_meter = frm.doc.custom_square_meter || 0;
        let square_feet = (square_meter * 10.7639)
        let ropani = (square_feet / 342.25 / 16)
        let aana = (ropani - Math.floor(ropani))*16
        let paisa = (aana - Math.floor(aana))*4
        let daam = (paisa - Math.floor(paisa))*4
        frm.set_value('custom_square_foot', square_feet);
        frm.set_value('custom_ropani', Math.floor(ropani));
        frm.set_value('custom_aana', Math.floor(aana));
        frm.set_value('custom_paisa', Math.floor(paisa));
        frm.set_value('custom_daam', daam);
    },
    custom_square_foot: function(frm) {
        let square_feet = frm.doc.custom_square_foot || 0;
        let square_meter = (square_feet / 10.7639)
        frm.set_value('custom_square_meter', square_meter);
    },
    custom_ropani: function(frm){
   
            let ropani = frm.doc.custom_ropani || 0;
            let aana = frm.doc.custom_aana || 0;
            let paisa = frm.doc.custom_paisa || 0;
            let daam = frm.doc.custom_daam || 0;
            let custom_sqftrapd = frm.doc.custom_sqftrapd || 0;
            sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
            frm.set_value('custom_square_foot', sqft);
        
    },
    custom_aana: function(frm){
      
            let ropani = frm.doc.custom_ropani || 0;
            let aana = frm.doc.custom_aana || 0;
            let paisa = frm.doc.custom_paisa || 0;
            let daam = frm.doc.custom_daam || 0;
            let custom_sqftrapd = frm.doc.custom_sqftrapd || 0;
            sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
            frm.set_value('custom_square_foot', sqft);
        
    },
    custom_paisa: function(frm){
    
            let ropani = frm.doc.custom_ropani || 0;
            let aana = frm.doc.custom_aana || 0;
            let paisa = frm.doc.custom_paisa || 0;
            let daam = frm.doc.custom_daam || 0;
            let custom_sqftrapd = frm.doc.custom_sqftrapd || 0;
            sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
            frm.set_value('custom_square_foot', sqft);
       
    },
    custom_daam: function(frm){
   
            let ropani = frm.doc.custom_ropani || 0;
            let aana = frm.doc.custom_aana || 0;
            let paisa = frm.doc.custom_paisa || 0;
            let daam = frm.doc.custom_daam || 0;
            let custom_sqftrapd = frm.doc.custom_sqftrapd || 0;
            sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
            frm.set_value('custom_square_foot', sqft);
      
    },
    
   
});

What could be the solution to this ?

May you be able to use some flag to prevent causing a loop?
E.G:

let is_updating = false; // Flag to track values are updating
frappe.ui.form.on('Lead', {

    custom_square_meter: function(frm) {
        if (is_updating) return;

        is_updating = true; // Set flag to true
        let square_meter = frm.doc.custom_square_meter || 0;
        let square_feet = (square_meter * 10.7639);
        let ropani = (square_feet / 342.25 / 16);
        let aana = (ropani - Math.floor(ropani)) * 16;
        let paisa = (aana - Math.floor(aana)) * 4;
        let daam = (paisa - Math.floor(paisa)) * 4;

        frm.set_value('custom_square_foot', square_feet);
        frm.set_value('custom_ropani', Math.floor(ropani));
        frm.set_value('custom_aana', Math.floor(aana));
        frm.set_value('custom_paisa', Math.floor(paisa));
        frm.set_value('custom_daam', daam);
        is_updating = false; // Reset flag
    },

    custom_square_foot: function(frm) {
        if (is_updating) return;

        is_updating = true;
        let square_feet = frm.doc.custom_square_foot || 0;
        let square_meter = (square_feet / 10.7639);
        frm.set_value('custom_square_meter', square_meter);
        is_updating = false;
    },

    custom_ropani: function(frm) {
        if (is_updating) return;

        is_updating = true;
        let ropani = frm.doc.custom_ropani || 0;
        let aana = frm.doc.custom_aana || 0;
        let paisa = frm.doc.custom_paisa || 0;
        let daam = frm.doc.custom_daam || 0;
        let sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
        frm.set_value('custom_square_foot', sqft);
        is_updating = false;
    },

    custom_aana: function(frm) {
        if (is_updating) return;

        is_updating = true;
        let ropani = frm.doc.custom_ropani || 0;
        let aana = frm.doc.custom_aana || 0;
        let paisa = frm.doc.custom_paisa || 0;
        let daam = frm.doc.custom_daam || 0;
        let sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
        frm.set_value('custom_square_foot', sqft);
        is_updating = false;
    },

    custom_paisa: function(frm) {
        if (is_updating) return;

        is_updating = true;
        let ropani = frm.doc.custom_ropani || 0;
        let aana = frm.doc.custom_aana || 0;
        let paisa = frm.doc.custom_paisa || 0;
        let daam = frm.doc.custom_daam || 0;
        let sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
        frm.set_value('custom_square_foot', sqft);
        is_updating = false;
    },

    custom_daam: function(frm) {
        if (is_updating) return;

        frm.is_updating = true;
        let ropani = frm.doc.custom_ropani || 0;
        let aana = frm.doc.custom_aana || 0;
        let paisa = frm.doc.custom_paisa || 0;
        let daam = frm.doc.custom_daam || 0;
        let sqft = ropani * 5476 + aana * 342.25 + paisa * 85.5625 + daam * 21.3906;
        frm.set_value('custom_square_foot', sqft);
        is_updating = false;
    },
});

1 Like

Sounds interesting. Will test this and let you know. Thanks!

Update: Does not work.

This line is causing all the issues because, in custom_square_foot, you are setting the value of custom_square_meter and then the custom_square_meter function is triggered, which is again setting the value of custom_square_foot. So, in my opinion, you should change your logic a little bit.