How to filter link field in web form

how to filter link field in web form

frappe.web_form.on('area', (field, value) => {
filterCity(area);
}

function filterCity(area) {
  $.ajax({
    url: `api/resource/City?filters=[["City","area","=","${area}"]]`,
    success: function(result) {
      var options = []
      for (var i = 0; i < result.data.length; i++) {
        options.push({
          'label': result.data[i].name,
          'value': result.data[i].name
        })

      }
      var field = frappe.web_form.field_group.get_field('city');
      field._data = options;
      field.refresh();

    }
  });
};
3 Likes

It’s not working. Could you define the process.

Same here, couldn’t make it work.

Worked. Had to insert below into Custom Script

frappe.web_form.on('area', (field, value) => {
	filterCity(value);
});

function filterCity(area) {
    var myurl = 'api/resource/City%20Doctype?filters=[["City%20Doctype","area","=","' + area + '"]]';
	$.ajax({
		type: 'GET', 
		url: myurl,
		success: function(result) {
			var options = [];
			for (var i = 0; i < result.data.length; i++) {
				options.push({
					'label': result.data[i].name,
					'value': result.data[i].name
				});
			}
			var field = frappe.web_form.get_field("city");
			field._data = options;
			field.refresh();
		}
	});
};

edit: To make code more readable, replaced Blockquote markup with ```

2 Likes

Do we have to always use api to access doctype from webform?

I still can not make it work. The webform field is not changed (not filtered).
But when running it in browser console it shows the intended filtered data. And run the url in the browser also return the intended filtered data.
So i know my code works. But is not picked up by the webform.

@aakvatech, is it Custom Script (in Customization module) or Client Script (in webform) that you use?
Because I can’t choose a webform in Custom Script, only doctype. So the script will start with frappe.ui.form.on() and not frappe.web_form.on()

And what about put it in the js file of the webform?

Thanks for any response.

In Client Script (in webform)

This is where the js is to be put for the webform

This is my code:

frappe.web_form.on('bentuk_usaha', (field, value) => {
filterBentuk(value);
});

function filterBentuk(bentuk_usaha) {
    var myurl = 'api/resource/Jenis%20Organisasi?filters=[["Jenis%20Organisasi","usaha","=","1"]]';
$.ajax({
	type: 'GET', 
	url: myurl,
	success: function(result) {
		var options = [];
		for (var i = 0; i < result.data.length; i++) {
			options.push({
				'name': result.data[i].name,
				'data': result.data[i].name
			});
		}
		var field = frappe.web_form.get_field("bentuk_usaha");
		field._data = options;
		field.refresh();
	}
});
};

bentuk_usaha = the link field in the webform
Jenis Organisasi = the doctype contain the list linked
usaha = checkbox field in Jenis Organisasi

Can you please let me know which is wrong? My guess is in the options.push or the last var field.

1 Like

Hi All,
I was looking to filter city name based on state selection
for Eg: when user selects Karnataka it should only show cities like shimoga, mysuru, manglore etc…
suppose user selects Kerla it should only show the cities belonging to kerla

  1. the Very first thing you need to do is create a doctype for state and city separately
  2. then link to your registration doctype by using “link” as your field type
  3. then create a web form and link the registration doctype and press get fields
  4. under web form there is a option of client script paste the below example code and customise it accordingly

array_data=[]
state_name =frappe.form_dict.state_name
query_data= frappe.db.sql(f""“SELECT tabDistrictCode.name FROM tabDistrictCode WHERE tabDistrictCode.state_name = ‘{state_name}’ “””)
for q in query_data:
array_data.extend(q)
frappe.response[“message”]=array_data

In the below code state is a filed in my registration page
value is where user selected state will be stored
here we are trying to call filterDistrict function
inside that function there is a ajax call
under the URL you will have to paste a customised URL from your project not the URL which is shown in the below code
frappe.web_form.on(‘state’, (field, value) => {
filterDistrict(value);
});

function filterDistrict(state) {
console.log(state)
var myurl = ‘http://’+window.location.host+‘/api/method/getDistrict?state_name=’+state;;
$.ajax({
type: ‘GET’,
url: myurl,
success: function(result) {
var options = [];
for (var i = 0; i < result.message.length; i++) {
options.push({
‘label’: result.message[i],
‘value’: result.message[i]
});
}
console.log(options);
var field = frappe.web_form.get_field(“district”);
field._data = options;
field.refresh();
}
});
};

to get this URL
‘http://’+window.location.host+'/api/method/getDistrict?
first search for server script in erpnext
then create a new server script
script type is API
script method name getDistrict
click on allow guest (to avoid authentication issues)
under script paste the below code

Have you made it, if so please share the code @rahy

any more ideas to make this work?

I dont think I did

You might get permission error if you use the above the api directly if there is no login for the user. Better way is to write your own script in python and call using frappe.call.

eg:

function filterItemGroup(category, form_field) {
    frappe.call({
      method: `path.to.method`,
      type: "GET",
      args: {
        'category': category
      },
      success: function(result) {
        var options = []
        for (var i = 0; i < result.message.length; i++) {
          options.push({
            'label': result.message[i].name,
            'value': result.message[i].name
          })
  
        }
        var field = frappe.web_form.fields_dict[form_field]
        field._data = options;
        field.refresh();
      }
    });
  };

Python

@frappe.whitelist(allow_guest=True)
def filtered_item_group(category):
    vals = frappe.db.get_list(
        "Item Group",
        filters={"item_group_type": category},
        ignore_permissions=True,
    )
    return vals

Please note that item_group_type is a custom field

However, if the user is logged in and does have permission, you can directly call the API.

 function filterItemGroupAJAX() {
    $.ajax({
        url: "/api/resource/Item Group?filters=[[\"item_group_type\", \"=\", \"Super Category\"]]",
      type: "GET",
      success: function(result) {
        var options = []
        for (var i = 0; i < result.data.length; i++) {
          options.push({
            'label': result.data[i].name,
            'value': result.data[i].name
          })
  
        }
      },
      error: function(xhr, status, error) {
    console.log("AJAX request failed:", status, error);
      }
    });
  };
5 Likes