What is the equivalent of "refresh(frm) ()" for a child table?

When I load, the DocType I’m creating …

frappe.ui.form.on('My Main Form', {
	refresh(frm) {
        console.log("Message from main form");
	}
});

frappe.ui.form.on('My Child Table', {
	refresh(frm) {
        console.log("Message from child table");
	}
});

… I see …

Message from main form

… but I do not see “Message from child table”.

I would be grateful for some help in understanding what I might be doing wrong?

@MartinHBramwell I think the best event is on_form_rendered and it can be acessed from the parent or children instances using diferent methods!

Let’s think about Quotation and Quotation Item doctypes, so you can build that

frappe.ui.form.on("Quotation", {
    items_on_form_rendered(frm){
       alert("Called from parent!");
    }
});

frappe.ui.form.on("Quotation Item", {
    on_form_rendered(frm, cdt, cdn){
       alert(`Called from children ${cdt} ${cdn}`)
    }
});

Those are not frappe standard form events, are they?

Aren’t they ones you have specified?

@MartinHBramwell They are!

There’s hundreds of events in frappe that aren’t documented!

1 Like

@MartinHBramwell okay, i think it is only triggered when you open the form!

The alternative is to listen a change event on the table wrapper

frappe.ui.form.on('Route Planner', {
    onload_post_render(frm){
        frm.fields_dict.stop_addr.wrapper.on('change', evt => {
           // your event code goes here!
        })
    }
})
1 Like

This is driving me crazy.

I gave up on my own DocType and went with Quotation, using exactly your code, as you suggested it.

No alerts were called.

I changed it to …

frappe.ui.form.on("Quotation", {
    onload(frm){
       console.log("Called from parent!");
    }
});

frappe.ui.form.on('Quotation Item', {
	refresh(frm) {
       console.log(`Called from children ${cdt} ${cdn} (refresh)`);
	},
    onload(frm, cdt, cdn){
       console.log(`Called from children ${cdt} ${cdn} (onload)`);
    }
});

The result was …

Called from parent!

… and nothing else.

If I click on the [Add script for Child Table] button, these lines get added to my script …

frappe.ui.form.on('Quotation Item', {
	refresh(frm) {
		// your code here
	}
})

… which is exactly what I have above, and it does nothing.

What the hell? What am I missing?

(Very grateful for your help, by the way. Thank you!!!)


Specs

admin@lenh:~/frappe-bench-LENH$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy

admin@lenh:~/frappe-bench-LENH$ bench version
ecommerce_integrations 1.15.2
erpnext 14.16.1
frappe 14.25.4
hrms 14.0.2
payments 0.0.1

admin@lenh:~/frappe-bench-LENH$ bench --version
5.16.1

So I tried :

frappe.ui.form.on("Quotation", {
    onload(frm){
       console.log("Called from parent!");
    },
    onload_post_render(frm){
        console.log("Called from parent! (onload_post_render)");

        console.dir(frm.fields_dict.items.wrapper);

        frm.fields_dict.items.wrapper.on('change', evt => {
          console.log("Called from child table wrapper!");
        });
    }
});

frappe.ui.form.on('Quotation Item', {
	refresh(frm) {
       console.log(`Called from children ${cdt} ${cdn} (refesh)`);
	},
    onload(frm, cdt, cdn){
       console.log(`Called from children ${cdt} ${cdn}(onload)`);
    }
});

Got the result :

Called from parent!
Called from parent! (onload_post_render)
Uncaught (in promise) TypeError: frm.fields_dict.items.wrapper.on is not a function
    at onload_post_render (quotation__custom_js:11:39)
    at _handler (script_manager.js:30:12)
    at runner (script_manager.js:109:16)
    at script_manager.js:127:22

The line …

console.dir(frm.fields_dict.items.wrapper);

… produced a …

div.frappe-control.form-group

Exploring that with dev tools I could find no function “on

@MartinHBramwell a little change so!

frappe.ui.form.on('Route Planner', {
    onload_post_render(frm){
        $(frm.fields_dict.stop_addr.wrapper).on('change', evt => {
           // your event code goes here!
        })
    }
})
2 Likes

At last!

Some progress!

Thank you so much Max.

I wonder … do you have any explanation for why the Client Script editor page offers a menu button to “Add script for Child Table” THAT DOES NOT WORK?!?!?!

It’s incredible.

(Or does it work for everyone else, but not in my configuration?)

@MartinHBramwell the add script for Child table works, but some events, are undocumented, or hard to track!

I must not be explaining myself well.

Using your minimalist example with Quotation I did this…

frappe.ui.form.on("Quotation", {
	refresh(frm) {
        console.log("Called from Quotation parent!");
});

… getting me the result …

Called from Quotation parent!

I then click on the menu button, “Add script for Child Table" and see my script augmented with a second event handler, like this …

frappe.ui.form.on("Quotation", {
	refresh(frm) {
        console.log("Called from Quotation parent!");
});

frappe.ui.form.on('Quotation Item', {
	refresh(frm) {
		// your code here
        console.log("Called from child table!");  // Added by me
	}
})

… which gets me the following result in the console …

Called from Quotation parent!

Are you saying you DO get a “Called from child table!” message while I do not?

@MartinHBramwell I dont get on “refresh” cuz there’s no refresh event on the child table!

On the child table, you can listen for the form_rendered when you click to open the form to edit the table, or you can watch to a change event that the “refresh” method of the table will trigger inside it’s wrapper

That’s what I find to be so careless and offensive.

It’s offered as a quick start!

Most novice users exploring how to develop a Client Script will fall for it, waste hours on it, wrack their brains on what they might be doing wrong, give up, go away and never come back.

I already have years of ERPNext experience, but left it for a few months.

Nevertheless, I also fell for it! I wasted most of a day, and your time too, trying to figure out what the hell I’ve forgotten – but, nah it’s just another ERPNext booby trap.

per this code in grid.js

we can add the following code simulating child table refresh in parent doctype as below

setup(frm){
        frm.grids[0].wrapper.onchange = function(evt){
            console.log('child table event trigger')
        }  
    },
2 Likes

Excellent!

That should be the code added to a Client Script, when one hits the “Add script for Child Table” button.

Thank you, very much.