In my use case, I want to call the DocType validations when my custom button is clicked. The Save button provided by Frappe will be hidden for my use case. How do I invoke the DocType validations explicitly? I tried the frm.trigger(“validate”), but it executes only the Custom Script validations and not the mandatory field validations. How do I invoke all the client side validations?
Hey, I wanna do the same. Could you find a solution?
Kind regards
anyone find a real solution?
From ChatGPT: -
Excellent and very precise question — this touches a subtle but important distinction inside Frappe’s client-side model handling.
Let’s unpack it carefully:
Problem
You’re hiding Frappe’s default Save button, and instead using your own custom button.
You tried:
frm.trigger("validate");
…but that only runs Custom Script “validate” handlers, not Frappe’s built-in form validations (like mandatory fields, invalid data, link checks, etc.).
Solution
To invoke all client-side validations (the same ones that run when the built-in Save button is clicked), call:
if (!frm.is_dirty()) {
frappe.show_alert({ message: __("No changes to save"), indicator: "orange" });
return;
}
frm.script_manager.trigger("validate").then(() => {
// now call the built-in validation + save pipeline
frappe.ui.form.save(frm);
});
But this alone still saves.
If you want only validation (without saving yet), use the same internal method Frappe uses to check before saving:
Method 1: Run all client-side validations manually (no save)
let validated = true;
try {
// This runs both built-in and custom validations
frm.validate();
} catch (e) {
validated = false;
console.error(e);
}
if (validated) {
frappe.msgprint("All validations passed!");
} else {
frappe.msgprint("Validation failed.");
}
![]()
frm.validate()runs:
Mandatory field checks
Link field validity
Table child validations
Custom Script
validatetriggersStandard Frappe validation hooks
That’s the same function used internally when you press Save.
Method 2: Run validation then manually save
If you want to perform something after validation but before saving, for example:
frappe.ui.form.on('Your Doctype', {
refresh(frm) {
frm.add_custom_button(__('Custom Save'), async function() {
try {
await frm.validate(); // run all client-side validations
frappe.msgprint("All validations passed. Proceeding to save...");
await frm.save(); // now save manually
} catch (e) {
frappe.msgprint("Validation failed: " + e.message);
}
});
}
});
Explanation
-
frm.trigger("validate")→ only runs custom script event hooks. -
frm.validate()→ runs full validation pipeline used by the native Save button. -
frm.save()→ automatically callsfrm.validate()internally, but you can separate them if you need to control the flow.
Summary
| Method | What it Runs | Saves? |
|---|---|---|
frm.trigger("validate") |
Custom script validate only |
|
frm.validate() |
All client-side validations (same as Save) | |
frm.save() |
Validations + actual save |
So for your use case (hidden Save button + custom button):
frm.add_custom_button('Validate & Save', async () => {
try {
await frm.validate(); // full validation
await frm.save(); // save if valid
} catch (e) {
frappe.msgprint(__('Validation failed: ') + e.message);
}
});
That’s the exact behavior of the standard Save button — just under your control.
Would you like me to show you how to integrate this cleanly into a custom_button that performs an action without saving, but still respects validation errors (like a “Submit for Review” action)?