[Tutorial] set_df_property | Parent Table & Child Table | 2023

New Project (1)

Summary

Learn how to use the set_df_property function in ERPNext to dynamically modify properties of DocField (fields) in your custom applications. This powerful feature allows you to customize field behavior, such as making fields read-only, hiding them conditionally, or setting default values. Enhance your ERPNext application with this tutorial!

Reference Documentation

Get Started

Syntax

frm.set_df_property(fieldname, property, value, docname, table_field, table_row_name)

fieldname - Parent Doctype Field Name
property - read_only, reqd, hidden …etc
value - 1 or 0 or characters
docname - Name of the current doctype | frm.docname
table_field - Field Inside the child table
table_row_name - name of the row | child.name

Parent Doctype

I’m creating a parent doctype with the name of School you can use custom doctype or core doctype

Child Table

Student List

Lets Explore

Parent

I hope you all get some ideas going to change the school_name field as Mandatory

frm.set_df_property('school_name', 'read_only', 1)

This a sample example for parent doctype its applicable to any fields in parent doctype

Child Table
Change the roll_no as Mandatory

frm.set_df_property('students', 'reqd', 1, frm.docname, 'roll_no', child.name)

How to add these feature in school.js

school.js

// Parent Doctype
frappe.ui.form.on('School', {
   refresh: function(frm){
   frm.set_df_property('school_name', 'read_only', 1)
   }
});

// Child Table
frappe.ui.form.on('Student List', { 
   students_add: function(frm, cdt, cdn){
     var child = locals[cdt][cdn]
     frm.set_df_property('students', 'reqd', 1, frm.docname, 'roll_no', child.name)
   }
})

You can change and play with this single syntax in any of your fields property

List of property

There is lot of options is there i listed some of them frequently used.

Property Value Description
read_only 1 or 0 Make the field as read only
reqd 1 or 0 Make the field as Mandatory
bold 1 or 0 Make the field as bold
hidden 1 or 0 Make the field as Hidden
options List of Values or link Doctype Can Link Any Doctype Dynamicaly if its a select field we can change the options
default Any Value Set Default value for the field

Please Support with you likes and comments

Github: Antony-M1 · GitHub
Linkedin: Antony

14 Likes

I have tried it but no success I wanted to set uom link field in purchase invoice item to the one set in item uoms table , so I have created server script of type api which response with list of uom for that item and call it get_uoms,

/ Parent Doctype
frappe.ui.form.on('Purchase Invoice', {
   refresh: function(frm){
   
   }
});

// Child Table
frappe.ui.form.on('Purchase Invoice Item', { 
   item_code: function(frm, cdt, cdn){
     var child = locals[cdt][cdn];
frappe.call("get_uoms", {message:child.item_code}).then(r=<
     frm.set_df_property('students', 'reqd', 1, frm.docname, 'roll_no', child.name)
   }
})

You can change and play

This tutorial assumes your access to Child Table fields is obtained through:

var child = locals[cdt][cdn]

If you are coding in the parent DocType context (refresh(), setup(), after_save(), onload(), etc) you cannot use that to get at fields in the child table.

Elsewhere in this forum you will find explanations of how to set_df_property for a specific field in all child table rows at once.

In my case I am :

  • coding in the parent DocType context
  • setting single fields in specific rows to read_only

I have found these are all viable ways to get at a specific field in a specific row …

	    let student;
	    let aRow = 22;

	    student = frm.fields_dict['students'].grid.grid_rows[aRow].doc;
	    console.dir(student);
	    frm.set_df_property('students', 'read_only', 1, frm.docname, 'roll_no', student.name)

	    student = frm.get_field("students").grid.data[aRow];
	    console.dir(student);
	    frm.set_df_property('students', 'read_only', 1, frm.docname, 'roll_no', student.name)

        student = frm.doc.students[aRow];
	    console.dir(student);
	    frm.set_df_property('students', 'read_only', 1, frm.docname, 'roll_no', student.name)

5 Likes

Thanks For Your Contribution. its really great

1 Like

Can we set these properties using python?

No you should use in the Js file

Goated tutorial, this should be in the official documentation. Please Frappe devs add this, this is such an important concept, that should be accessible to everyone without searching google for this forum post.

2 Likes

Hi,

I am using this same function on filtering the data from another doctype as below

// scripting to automate fetching or populating these fields based on user input
frappe.ui.form.on(‘Sample’, {
branch_type: function(frm) {
// frappe.msgprint(__(‘Invalid value for field: field_name’));
frappe.call({
method: “frappe.client.get_list”,
args: {
doctype: “branchtype”,
filters: {
branch_type: frm.doc.branch_type
},
fields: [“zone”]
},
callback: function(r) {
var zone_options = r.message.map(function(d) { return d.zone; });
frm.set_df_property(‘zone’, ‘options’, zone_options.join(‘\n’));
console.log(zone_options);
}
});
}
});

I successfully able to filter the data and able to select the data but the issue is once it gets saved the data not getting appeared in the field but the list showing the data which i have selected and saved.

Is there any solution…
List showing the value saved in the field

but the doctype contains nothing

please help!!!

Try the functionality in the refresh event

frappe.ui.form.on(‘Sample’, {
  refresh: function(frm) {
    // frappe.msgprint(__(‘Invalid value for field: field_name’));
    if Boolean(frm.doc.branch_type){
         frappe.call({
          method: “frappe.client.get_list”,
          args: {
          doctype: “branchtype”,
          filters: {
            branch_type: frm.doc.branch_type
            },
      fields: [“zone”]
      },
      callback: function(r) {
        var zone_options = r.message.map(function(d) { return d.zone; });
        frm.set_df_property(‘zone’, ‘options’, zone_options.join(‘\n’));
        console.log(zone_options);
      }
      });
    }
    
  }
});
1 Like

Thks it is working now

1 Like