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
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?
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),
)
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)