How to Filter a Child Table Link Field Based on Another Field in the Same Row (Frappe / ERPNext Guide)

When customizing forms in Frappe / ERPNext, one of the most common UI requirements is:

Filter a Link field inside a child table based on another field from the same child-table row.

For example:

Inside a child table row, a user selects a Item Group, and the next field Item should show only items belonging to that selected Item Group — but only for that row.

This improves data accuracy and makes the form more intelligent.

In this blog, we’ll cover exactly how to implement this using frm.set_query() with proper usage of cdt and cdn.


🔍 Understanding the Scenario

Let’s assume your child table has fields:

FieldnameLabelType
item_groupItem GroupLink (Item Group)
itemItemLink (Item)

Goal:

When the user selects category in a row, the item field dropdown should show only items under that category — but only for that specific row.

This is done using dynamic filtering inside the child table.


✅ Correct Script: Filtering Child Table Field Based on Another Field in Same Row

frappe.ui.form.on("Parent Doctype", {
  setup(frm) {
    frm.set_query("item(child_table_field_to_filter)", "items(child_table_field_name)", function (doc, cdt, cdn) {
      let row = frappe.get_doc(cdt, cdn);
      return {
        filters: {
          item_group: row.item_group
        }
      };
    });
  },
});
✔ What this script does:
	•	"item" → the field to filter
	•	"items" → child table fieldname
	•	row = frappe.get_doc(cdt, cdn) → fetches the current child row
	•	row.item_group → gets the user-selected item group in the same row
	•	Filters the Item dropdown based on this category

This ensures each row behaves independently.


🧠 How It Works (Simplified)

  1. User selects a Category in that row
  2. ERPNext triggers the query for the Item field
  3. The script fetches the same row data
  4. Link field shows only filtered items

This is row-level filtering, not table-level.


🧪 Example Use Case

A manufacturing BOM child table:

  • Select Raw Material Type
  • Show only materials of that type in Material field
  • Avoids wrong selections
  • Reduces validation errors
  • Makes user experience cleaner

This is widely used in:

  • Textile weaving Bill of Materials
  • Diamond planning & assorting
  • Inventory classification
  • Manufacturing inputs selection

⚠ Common Mistakes to Avoid

❌ Using frm.doc.items[row.idx]

This fails because indexing changes when rows are reordered.

❌ Using refresh

Filtering should be inside setup, not refresh.

❌ Applying query at parent level without cdt and cdn

This won’t work for child-table dynamic values.


🏁 Final Thoughts

Filtering a child-table Link field based on another field in the same row is one of the most powerful customisations in Frappe. With only a few lines of code, you create a dynamic, intelligent child table that reduces user mistakes and improves data quality.

This technique is essential for anyone building ERPNext custom apps, scripts, or advanced forms — especially in manufacturing and inventory workflows.