Entering a value not in Link Field

In a Frappe doctype we can set Link Field filters using functions like “frm.set_query” to override the query.

However there is an issue when entering a value in the Link Field. If the entered value does not exists in the doctype and does not satisfy the filter criteria

it gets cleared when the focus leaves the field
but if the value exists in the doctype but does not match the filter it remains in the field and can be saved to the doctype.

My question is
how handling this event if values not in the filter
needs to be done case-by-case or if there is an option in Frappe to automatically clear the field if the value does not match the specified filters

Hi @Isadang,

If you haven’t checked then please check the documentation of Overriding Link Query By Custom Script.

You have the opportunity to delve into the document, where you will find various examples.

I hope this helps.

Thank You!

Yeah this is an issue we found out as well, when you use query filters to filter out the link options you can still type out other options that are supposed to be hidden.

Maybe run a custom script that clears the field if the value is not in the filtered list?

1 Like

Example

In DocType : Main DocType
Have Link field to User

DocType : User is Custom query to filter out Website User

@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def user_query(doctype, txt, searchfield, start, page_len, filters):
	from frappe.desk.reportview import get_filters_cond, get_match_cond

	doctype = "User"
	conditions = []

	user_type_condition = "and user_type != 'Website User'"
	if filters and filters.get("ignore_user_type") and frappe.session.data.user_type == "System User":
		user_type_condition = ""
	filters and filters.pop("ignore_user_type", None)

	txt = f"%{txt}%"
	return frappe.db.sql(
		"""SELECT `name`, CONCAT_WS(' ', first_name, middle_name, last_name)
		FROM `tabUser`
		WHERE `enabled`=1
			{user_type_condition}
			AND `docstatus` < 2
			AND `name` NOT IN ({standard_users})
			AND ({key} LIKE %(txt)s
				OR CONCAT_WS(' ', first_name, middle_name, last_name) LIKE %(txt)s)
			{fcond} {mcond}
		ORDER BY
			CASE WHEN `name` LIKE %(txt)s THEN 0 ELSE 1 END,
			CASE WHEN concat_ws(' ', first_name, middle_name, last_name) LIKE %(txt)s
				THEN 0 ELSE 1 END,
			NAME asc
		LIMIT %(page_len)s OFFSET %(start)s
	""".format(
			user_type_condition=user_type_condition,
			standard_users=", ".join(frappe.db.escape(u) for u in STANDARD_USERS),
			key=searchfield,
			fcond=get_filters_cond(doctype, filters, conditions),
			mcond=get_match_cond(doctype),
		),
		dict(start=start, page_len=page_len, txt=txt),
	)

So in Main DocType will show only System User “show_user@example.com
if type User not in User DocType Value will be clear

but if Type User in User DocType but not in filter out query Value still in box and can save that Value

Is it not bug right?
Have to be handle case-by-case for link field?

Hi @Isadang,

Please apply the client script for Main DocType.

frappe.ui.form.on("Main DocType", {
    refresh:function(frm) {
        frm.set_query("user", function() {
            return {
                "filters": {
                    'user_type': ['Not In', ['Website User']]
                }
            };
        });
    }
});

Please set your field and filter according to the scenario.

Thank You!

This will filter out the website users in a link field (they won’t show in the drop-down), but if you know a website user’s ID, you can paste it in and it will accept that value. There is no “validation” against the queried link options.
(Atleast not in version 14)

1 Like

Yes i’m apply this solution already
but still the same as @Void_Moon said

(i’m test frappe-14)