mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-13 22:51:49 +00:00
fix(item): error on uncommitted input and escape values in variant dialog
Address review feedback:
- A typed-but-not-selected value passed validation yet was dropped by
get_selected_attributes (reads committed pills only). Treat any pending
input as an error so it is never silently omitted from creation.
- Escape pill / pending values before interpolating them into the HTML
error message.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit d4da9a3d7d)
This commit is contained in:
@@ -856,34 +856,40 @@ $.extend(erpnext.item, {
|
|||||||
return Math.abs(Math.round(steps) - steps) <= 1e-6;
|
return Math.abs(Math.round(steps) - steps) <= 1e-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block variant creation if ANY value is invalid. Checks both the committed
|
// Block variant creation if anything is wrong: an invalid committed pill, or
|
||||||
// pills and any text still sitting in the input box (typed but not selected),
|
// text typed but not added as a pill (which get_selected_attributes would
|
||||||
// so garbage like "00A" can never slip through to creation.
|
// otherwise drop silently). The user must fix each before creation proceeds.
|
||||||
function validate_selected_attributes() {
|
function validate_selected_attributes() {
|
||||||
let invalid = [];
|
let errors = [];
|
||||||
frm.doc.attributes.forEach((row) => {
|
frm.doc.attributes.forEach((row) => {
|
||||||
if (row.disabled) return;
|
if (row.disabled) return;
|
||||||
let field = me.multiple_variant_dialog.get_field(frappe.scrub(row.attribute));
|
let field = me.multiple_variant_dialog.get_field(frappe.scrub(row.attribute));
|
||||||
if (!field) return;
|
if (!field) return;
|
||||||
|
|
||||||
|
let attribute = frappe.utils.escape_html(row.attribute);
|
||||||
let spec = attr_val_fields[row.attribute];
|
let spec = attr_val_fields[row.attribute];
|
||||||
let values = (field.get_value() || []).slice();
|
|
||||||
let pending = (field.$input?.val() || "").trim();
|
|
||||||
if (pending) values.push(pending);
|
|
||||||
|
|
||||||
let bad = [...new Set(values.filter((v) => !is_valid_attribute_value(spec, v)))];
|
let invalid = [
|
||||||
if (bad.length) {
|
...new Set((field.get_value() || []).filter((v) => !is_valid_attribute_value(spec, v))),
|
||||||
invalid.push(`<b>${frappe.utils.escape_html(row.attribute)}</b>: ${bad.join(", ")}`);
|
];
|
||||||
|
if (invalid.length) {
|
||||||
|
let values = invalid.map(frappe.utils.escape_html).join(", ");
|
||||||
|
errors.push(__("{0}: remove invalid value(s) {1}", [attribute, values]));
|
||||||
|
}
|
||||||
|
|
||||||
|
let pending = (field.$input?.val() || "").trim();
|
||||||
|
if (pending) {
|
||||||
|
let value = frappe.utils.escape_html(pending);
|
||||||
|
errors.push(
|
||||||
|
__("{0}: select the typed value {1} from the list or clear it", [attribute, value])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (invalid.length) {
|
if (errors.length) {
|
||||||
frappe.throw({
|
frappe.throw({
|
||||||
title: __("Invalid Attribute Values"),
|
title: __("Invalid Attribute Values"),
|
||||||
message:
|
message: errors.join("<br>"),
|
||||||
__("Please remove the following invalid values before creating variants:") +
|
|
||||||
"<br><br>" +
|
|
||||||
invalid.join("<br>"),
|
|
||||||
indicator: "red",
|
indicator: "red",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user