Adds error handling of nested form fields in the API form processing layer

- Muy complejo
- But the results speak for themselves!
 -This will need to be rolled out into the coming refactor...
This commit is contained in:
Oliver 2021-10-04 22:41:59 +11:00
parent 75a35773c6
commit a9d5b776d3

View File

@ -864,6 +864,78 @@ function clearFormErrors(options) {
$(options.modal).find('#non-field-errors').html('');
}
/*
* Display form error messages as returned from the server,
* specifically for errors returned in an array.
*
* We need to know the unique ID of each item in the array,
* and the array length must equal the length of the array returned from the server
*
* arguments:
* - response: The JSON error response from the server
* - parent: The name of the parent field e.g. "items"
* - options: The global options struct
*
* options:
* - nested: A map of nested ID values for the "parent" field
* e.g.
* {
* "items": [
* 1,
* 2,
* 12
* ]
* }
*
*/
function handleNestedErrors(errors, field_name, options) {
var error_list = errors[field_name];
// Ignore null or empty list
if (!error_list) {
return;
}
var nest_list = nest_list = options["nested"][field_name];
// Nest list must be provided!
if (!nest_list) {
console.log(`WARNING: handleNestedErrors missing nesting options for field '${fieldName}'`);
return;
}
for (var idx = 0; idx < error_list.length; idx++) {
var error_item = error_list[idx];
if (idx >= nest_list.length) {
console.log(`WARNING: handleNestedErrors returned greater number of errors (${error_list.length}) than could be handled (${nest_list.length})`);
break;
}
// Extract the particular ID of the nested item
var nest_id = nest_list[idx];
// Here, error_item is a map of field names to error messages
for (sub_field_name in error_item) {
var errors = error_item[sub_field_name];
// Find the target (nested) field
var target = `${field_name}_${sub_field_name}_${nest_id}`;
for (var ii = errors.length-1; ii >= 0; ii--) {
var error_text = errors[ii];
addFieldErrorMessage(target, error_text, ii, options);
}
}
}
}
/*
* Display form error messages as returned from the server.
@ -913,28 +985,30 @@ function handleFormErrors(errors, fields, options) {
for (var field_name in errors) {
// Add the 'has-error' class
$(options.modal).find(`#div_id_${field_name}`).addClass('has-error');
if (field_name in fields) {
var field_dom = $(options.modal).find(`#errors-${field_name}`); // $(options.modal).find(`#id_${field_name}`);
var field = fields[field_name];
var field_errors = errors[field_name];
if ((field.type == "field") && ("child" in field)) {
// This is a "nested" field
handleNestedErrors(errors, field_name, options);
} else {
// This is a "simple" field
if (field_errors && !first_error_field && isFieldVisible(field_name, options)) {
first_error_field = field_name;
}
var field_errors = errors[field_name];
// Add an entry for each returned error message
for (var ii = field_errors.length-1; ii >= 0; ii--) {
if (field_errors && !first_error_field && isFieldVisible(field_name, options)) {
first_error_field = field_name;
}
var error_text = field_errors[ii];
// Add an entry for each returned error message
for (var ii = field_errors.length-1; ii >= 0; ii--) {
var error_html = `
<span id='error_${ii+1}_id_${field_name}' class='help-block form-error-message'>
<strong>${error_text}</strong>
</span>`;
var error_text = field_errors[ii];
field_dom.append(error_html);
addFieldErrorMessage(field_name, error_text, ii, options);
}
}
}
}
@ -952,6 +1026,30 @@ function handleFormErrors(errors, fields, options) {
}
/*
* Add a rendered error message to the provided field
*/
function addFieldErrorMessage(field_name, error_text, error_idx, options) {
// Add the 'has-error' class
$(options.modal).find(`#div_id_${field_name}`).addClass('has-error');
var field_dom = $(options.modal).find(`#errors-${field_name}`);
if (field_dom) {
var error_html = `
<span id='error_${error_idx}_id_${field_name}' class='help-block form-error-message'>
<strong>${error_text}</strong>
</span>`;
field_dom.append(error_html);
} else {
console.log(`WARNING: addFieldErrorMessage could not locate field '${field_name}`);
}
}
function isFieldVisible(field, options) {
return $(options.modal).find(`#div_id_${field}`).is(':visible');