Handling Conditional Filtering in Script Report

I have three filter fields. My requirement is that if the first field is set, then the other two fields should be optional. However, if the first field is not set, then the other two fields should be required.

Could someone guide me on how to implement this conditional filtering logic in my script report?

You can use set_mandatory().

Eg)

filters: [
	  {
		fieldname: "filter_1",
		label: "Filter One",
		fieldtype: "Link",
		options: "Customer",
		reqd:1,
		on_change: function (query_report) {
		           // your logic according to type of the field
                   let is_filter_1_set = true ? false // your logic

		           query_report.filters[1].set_mandatory(is_filter_1_set ? 0 : 1);
		           query_report.filters[2].set_mandatory(is_filter_1_set ? 0 : 1);
		},
	  },
	  {
		fieldname: "filter_2",
		label: "Filter Two",
		fieldtype: "Data",
	  },
	  {
		fieldname: "filter_3",
		label: "Filter Three",
		fieldtype: "Data",
	  },
	],

Is this code working for you? I’m encountering an issue where the on_change event is not triggering. I’m currently using Frappe version 15.23.0. Here’s my code snippet:

Is there any reference for this code ??

I am also using frappe version 15.

Can you share Error message?

Refrence : [Tutorial] Script Report / Chart

frappe.query_reports["Forum Report"] = {
  filters: [
    {
      fieldname: "filter_1",
      label: "Filter One",
      fieldtype: "Link",
      options: "User",
      reqd: 1,
      on_change: function (query_report) {
        alert("Hello...");
        console.log(query_report);
      },
    },
  ],
};

@Abdeali Thanks for your reply, I’m not sure what the previous problem was, but now the code seems to be working in the on_change event. However, the issue is that even after updating to 0, it still shows an error message indicating that the filter is missing.

I’ve tried two methods, but unfortunately, neither of them is working. Here’s my code snippet

Add at last :

query_report.refresh();

I’ve already tried, but it’s not working

you can try add the logic on the query / script report

Query / Script :

columns = [
your columns here
]

lett = []

filter_1 = filters.get("filter_1")
filter_2 = filters.get("filter_2")
filter_3 = filters.get("filter_3")


sql_2 = """
your query here
"""

sql_2 = """
your query here
    
"""
sql_3 = """
    your query here
"""
###This example for your logic condition for filter
if filter_3 is None and filter_2 is None:
    lett = frappe.db.sql(sql_1, (filter_1), as_dict=True)
elif filter_1 is None:
    lett = frappe.db.sql(sql_2, (filter_2), as_dict=True)
else:
    lett = frappe.db.sql(sql_3, (filter_3), as_dict=True)
data = columns, lett

Client Code / Java Script :

frappe.query_reports["Your Report Name"] = {
    "filters": [
        {
            "fieldname": "filter_1",
            "label": __("Lable_1"),
            "fieldtype": "Date",
            "reqd": 1
        },
        {
            "fieldname": "filter_2",
            "label": __("Lable_2"),
            "fieldtype": "Date",
            "reqd": 1
        },
        {
            "fieldname": "filter_3",
            "label": __("Lable_3"),
            "fieldtype": "Link",
            "options": "Warehouse",
            "reqd": 1
        },
        
    ]
};

You can set it to be required or not by change the "reqd": 1 to "reqd": 0

hope it help

@Gembira_IT_Tech Thanks for your reply. My query is about dynamically changing mandatory fields. For instance, if the first field is filled, then the other two fields should not be mandatory, but if it’s empty, then the other two fields should be mandatory. I need to implement this logic in JavaScript, as handling the logic in Python will be easy for me

frappe.query_reports["Forum Report"] = {
  filters: [
    {
      fieldname: "filter_1",
      label: "Filter One",
      fieldtype: "Link",
      options: "User",
      reqd: 1,
      on_change: function (query_report) {
        const filters = {};
        const url = query_report.get_url_with_filters();
        const params = new URLSearchParams(url.split("?")[1]);

        if (query_report.get_filter_value("filter_1")) {
          query_report.report_settings.filters.slice(1, 3).forEach((filter) => {
            filter.reqd = 0;
          });
        } else {
          query_report.report_settings.filters.slice(1, 3).forEach((filter) => {
            filter.reqd = 1;
          });
        }

        params.forEach((value, key) => {
          filters[key] = value;
        });
        
        query_report.refresh();
        query_report.refresh_report(filters);
      },
    },
    {
      fieldname: "filter_2",
      label: "Filter Two",
      fieldtype: "Data",
      reqd: 1,
    },
    {
      fieldname: "filter_3",
      label: "Filter Three",
      fieldtype: "Data",
      reqd: 1,
    },
  ],
};

Only for filter_1 , same as you can set for other.

Refer :

@Abdeali, thanks for your reply and time. I’m currently running the above exact code, and it automatically sends requests to the backend in a loop. I’ll provide a screenshot for your reference.


I’m debugging the issue, If I discover any leads, I’ll update you here