Need Help with Dynamic Filtering of Link Fields in Frappe Framework

Hello everyone,

I recently encountered a strange issue while creating my app using the Frappe framework.

I created a DocType called “Product,” which contains a child table named “bom_product.” This child table has two fields: “item” and “specs,” both of which are of Link type (linking to Item DocType and Variants DocType, respectively). The Item DocType also has a child table, which includes a Link type field called “variants_name” that corresponds to its related Variants DocType.

I want to achieve the effect where, upon selecting an Item, the Specs field automatically filters to show the relevant Variants DocType associated with that Item.

Currently, I am able to filter the content displayed in Specs using custom scripts, but I cannot update it on the page. I have to click the Edit button or add a new row to see the filtered content in the newly appeared Specs field. I have tried using frm.refresh(); and other methods to refresh the table, but the issue persists.
How can I solve this problem? Thank you!
Here is my code and an image for reference.

frappe.ui.form.on("Bill of Materials ChildTable", {
	item: function(frm, cdt, cdn) {
        const row = frappe.get_doc(cdt, cdn);
        if (row.item) {
            frappe.call({
                method: 'frappe.client.get_list',
                args: {
                    doctype: 'Variants ChildTable',
                    parent: 'Item',
                    filters:{
                        parent: row.item
                    },
                    fields: ['variants_name']
                },
                callback: function(r) {
                    let variants_id = r.message.map(d => d.variants_name);
                    variants_id = variants_id.join(',')
                    frm.fields_dict['bom_product'].grid.get_field('specs').get_query = function(doc, cdt, cdn){
                        return {
                            filters: [
                                ['name','in',variants_id]
                            ]
                        }
                    };

                    frm.refresh();
                }
            })
        }
	},
});

PixPin_2024-10-31_14-30-14-min

frappe.ui.form.on("Parent table", {
	setup: function(frm) {
        frm.fields_dict['bom_product'].grid.get_field("specs").get_query = function(doc, cdt, cdn) {
			let row = locals[cdt][cdn];
            if (row.item) {
                frappe.call({
                    method: 'frappe.client.get_list',
                    args: {
                        doctype: 'Variants ChildTable',
                        parent: 'Item',
                        filters:{
                            parent: row.item
                        },
                        fields: ['variants_name']
                    },
                    callback: function(r) {
                        let variants_id = r.message.map(d => d.variants_name);
                        variants_id = variants_id.join(',')
                        frm.fields_dict['bom_product'].grid.get_field('specs').get_query = function(doc, cdt, cdn){
                            return {
                                filters: [
                                    ['name','in',variants_id]
                                ]
                            }
                        };
                    }
                })
            }
        }
	},
});

use above code, setup event of Parent doctype

Thank you, but the code still didn’t work.

However, I just solved the issue by directly accessing the specs field in the current child table and modifying the link_filters property. This approach is effective, and each row is independent, so they won’t interfere with each other.

Here is the complete code:

frappe.ui.form.on("Bill of Materials ChildTable", {
	item: function(frm, cdt, cdn) {
        const row = frappe.get_doc(cdt, cdn);
        if (row.item) {
            frappe.call({
                method: 'frappe.client.get_list',
                args: {
                    doctype: 'Variants ChildTable',
                    parent: 'Item',
                    filters:{
                        parent: row.item
                    },
                    fields: ['variants_name']
                },
                callback: function(r) {
                    const variants_id = r.message.map(d => d.variants_name);
                    let link_filters = JSON.stringify([['Variants','name','in',variants_id]])
                    const cur_row = locals[cdt][cdn]
                    const cur_child_table = cur_row.parentfield
                    const cur_row_index = cur_row.idx - 1
                    
                    frm.get_field(cur_child_table).grid.grid_rows[cur_row_index].get_field('specs').df.link_filters=link_filters;
                }
            })
        } else {
        }
	},
});