Files
raven-client/ayanova/src/api/gzvalidate.js
2019-04-08 21:20:48 +00:00

409 lines
11 KiB
JavaScript

/* Xeslint-disable */
///////////////////////////////
// GZVALIDATE
//
// provides form validation services
// and also general error display in forms
//probably should be broken up more
// All locale keys for validation *MUST* be fetched prior to this being used as it assumes all keys are fetched first
// Add any new keys used to the block in locale.js=>commonKeysEditForm
import errorHandler from "./errorhandler";
var triggeringChange = false;
function isEmpty(o) {
if (typeof o == "number" && o == 0) {
return false;
}
return !o;
}
////////////////////////////////////
// isInt value??
//
//FROM HERE: https://stackoverflow.com/a/14794066/8939
//fast test if is an integer:
function isInt(value) {
var x;
if (isNaN(value)) {
return false;
}
x = parseFloat(value);
return (x | 0) === x;
}
////////////////////////////////////
// isNumber
//
//FROM HERE: https://stackoverflow.com/a/1830632/8939
function isNumber(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
////////////////////////////////////
// Get control from ref
//
function getControl(v, ref) {
var ctrl = v.$refs[ref];
return ctrl;
}
////////////////////////////////////
// Get value from control
//
function getControlValue(ctrl) {
var value = ctrl.value;
return value;
}
////////////////////////////////////
// Get field name from control
//
function getControlLabel(ctrl) {
if (errorHandler.developmentModeShowErrorsImmediately) {
if (!ctrl.label) {
throw "GZValidate:getControlLabel - the control has no label " + ctrl;
}
}
return ctrl.label;
}
/////////////////////////////////////////
// Get errors for a particular field
// from server error collection
//
function getErrorsForField(v, ref) {
var ret = [];
if (ref == "errorbox") {
ret = v.$_.filter(v.serverError.details, function(o) {
return !o.target;
});
} else {
ret = v.$_.filter(v.serverError.details, function(o) {
if (!o.target) {
return false;
}
//server error fields are capitalized
return o.target.toLowerCase() == ref;
});
}
return ret;
}
///////////////////////////////
// ERROR BOX ERRORS
// gathers any messages for error box on form which is the generic catch all for non field specific errors from server
// and application itself locally
function GetErrorBoxErrors(v, errs) {
var hasErrors = false;
var ret = "";
if (errs.length > 0) {
hasErrors = true;
//loop array and append each error to a return string
for (var i = 0; i < errs.length; i++) {
ret += errs[i] + "\r\n";
}
}
//any application errors?
if (v.appError) {
hasErrors = true;
ret = v.appError + "\r\n----------\r\n" + ret;
}
if (!hasErrors) {
return null;
} else {
return ret;
}
}
export default {
///////////////////////////////
// REQUIRED
//
Required(v, ref) {
var ctrl = getControl(v, ref);
if (typeof ctrl == "undefined") {
return false;
}
var value = getControlValue(ctrl);
if (!isEmpty(value)) {
return false;
}
// "ErrorRequiredFieldEmpty": "{0} is a required field. Please enter a value for {0}",
var err = v.$gzlocale.get("ErrorRequiredFieldEmpty");
var fieldName = getControlLabel(ctrl);
err = v.$_.replace(err, "{0}", fieldName);
//lodash replace only replaces first instance so need to do it twice
err = v.$_.replace(err, "{0}", fieldName);
return err;
},
///////////////////////////////
// MAXLENGTH
//
MaxLength(v, ref, max) {
var ctrl = getControl(v, ref);
if (typeof ctrl == "undefined") {
return false;
}
var value = getControlValue(ctrl);
if (isEmpty(value)) {
return false;
}
if (value.length > max) {
//get the localized rule text
// "ErrorFieldLengthExceeded": "{0} can not exceed {1} characters.",
var err = v.$gzlocale.get("ErrorFieldLengthExceeded");
var fieldName = getControlLabel(ctrl);
err = v.$_.replace(err, "{0}", fieldName);
err = v.$_.replace(err, "{1}", max);
return err;
} else {
return false;
}
},
///////////////////////////////
// MAX 255
//
Max255(v, ref) {
return this.MaxLength(v, ref, 255);
},
///////////////////////////////
// AFTER
After(v, refStart, refEnd) {
var ctrlStart = getControl(v, refStart);
if (typeof ctrlStart == "undefined") {
return false;
}
var ctrlEnd = getControl(v, refEnd);
if (typeof ctrlEnd == "undefined") {
return false;
}
var valueStart = getControlValue(ctrlStart);
if (isEmpty(valueStart)) {
return false;
}
var valueEnd = getControlValue(ctrlEnd);
if (isEmpty(valueEnd)) {
return false;
}
valueStart = v.$dayjs(valueStart);
valueEnd = v.$dayjs(valueEnd);
// if either is not valid.
if (!valueStart || !valueEnd) {
return false;
}
if (valueStart.isAfter(valueEnd)) {
// "ErrorStartDateAfterEndDate": "Start date must be earlier than stop / end date",
var err = v.$gzlocale.get("ErrorStartDateAfterEndDate");
return err;
} else {
return false;
}
},
///////////////////////////////
// INTEGER
//
Integer(v, ref) {
var ctrl = getControl(v, ref);
if (typeof ctrl == "undefined") {
return false;
}
//DEBUG
//logControl("Integer", ctrl, ref);
var value = getControlValue(ctrl);
if (isEmpty(value)) {
return false;
}
if (isInt(value)) {
return false;
}
// "ErrorFieldValueNotInteger": "Value must be an integer"
var err = v.$gzlocale.get("ErrorFieldValueNotInteger");
return err;
},
///////////////////////////////
// DECIMAL
// Basically anything that can be a number is valid
Decimal(v, ref) {
//TODO: Handle commas and spaces in numbers
//as per v.$gzlocale rules for numbers
var ctrl = getControl(v, ref);
if (typeof ctrl == "undefined") {
return false;
}
//DEBUG
//logControl("Decimal", ctrl, ref);
var value = getControlValue(ctrl);
if (isEmpty(value)) {
return false;
}
if (isNumber(value)) {
return false;
}
// "ErrorFieldValueNotDecimal": "Value must be a number"
var err = v.$gzlocale.get("ErrorFieldValueNotDecimal");
return err;
},
///////////////////////////////
// SERVER ERRORS
// Process and return server errors if any for form and field specified
//
ServerErrors(v, ref) {
//CHECK PREREQUISITES IN DEV MODE TO ENSURE FORM ISN"T MISSING NEEDED DATA ATTRIBUTES ETC
if (v.$gzdevmode()) {
//make sure serverErrors is defined on data
if (!v.$_.has(v, "serverError")) {
throw "DEV ERROR gzvalidate::ServerErrors -> serverError seems to be missing from form's vue data object";
}
//make sure appError is defined on data
if (!v.$_.has(v, "appError")) {
throw "DEV ERROR gzvalidate::ServerErrors -> appError seems to be missing from form's vue data object";
}
//make sure errorBoxMessage is defined on data
if (!v.$_.has(v, "errorBoxMessage")) {
throw "DEV ERROR gzvalidate::ServerErrors -> errorBoxMessage seems to be missing from form's vue data object";
}
//ensure the error returned is in an expected format to catch coding errors at the server end
if (!v.$_.isEmpty(v.serverError)) {
//Make sure there is an error code if there is an error collection
if (!v.serverError.code) {
throw "DEV ERROR gzvalidate::ServerErrors -> server returned error without code";
}
}
}
var ret = [];
//check for errors if we have any errors
if (!v.$_.isEmpty(v.serverError)) {
//debugger;
//First let's get the top level error code
var apiErrorCode = parseInt(v.serverError.code);
//GENERAL ERROR
if (ref == "errorbox") {
//Add any general errors to ret
var err = v.$gzlocale.get("ErrorAPI" + apiErrorCode.toString());
if (v.serverError.message) {
err = err + "\r\n" + v.serverError.message;
}
ret.push(err);
}
//DETAIL ERRORS
//{"error":{"code":"2200","details":[{"message":"Exception: Error converting value \"\" to type 'AyaNova.Biz.AuthorizationRoles'. Path 'roles', line 1, position 141.","target":"roles","error":"2203"}],"message":"Object did not pass validation"}}
//Specific field validation errors are in an array in "details" key
if (!v.$_.isEmpty(v.serverError.details)) {
//See if this key is in the details array
var errorsForField = getErrorsForField(v, ref);
if (errorsForField.length > 0) {
//iterate the errorsForField object and add each to return array of errors
v.$_.each(errorsForField, function(ve) {
var fldErr = "";
var fldErrorCode = parseInt(ve.error);
fldErr =
v.$gzlocale.get("ErrorAPI" + fldErrorCode.toString()) +
" [" +
ve.error +
"]";
if (ve.message) {
fldErr += ' - "' + ve.message + '"';
}
ret.push(fldErr);
});
return ret;
}
}
}
//default if no error message to display
return ret;
},
///////////////////////////////
// ClearServerErrors
// Clear all server errors and app errors and ensure error box doesn't show
//
DeleteAllErrorBoxErrors(v) {
//clear all keys from server error
v.$gzutil.RemoveAllPropertiesFromObject(v.serverError);
//clear app errors
v.appError = null;
//clear out actual message box display
v.errorBoxMessage = null;
},
///////////////////////////////
// SetErrorBoxErrors
// Gather server errors and set the appropriate keys
//
SetErrorBoxErrors(v) {
var errs = this.ServerErrors(v, "errorbox");
var ret = GetErrorBoxErrors(v, errs);
v.errorBoxMessage = ret;
},
///////////////////////////////
// On Change handler
// This is required so that server errors can be cleared when input is changed
//
Change(v, ref) {
if (triggeringChange) {
return;
}
//If ref appears in the servererrors details collection, remove each one
var m = v.$_.remove(v.serverError.details, function(o) {
if (!o.target) {
return false;
}
return o.target.toLowerCase() == ref;
});
//If there are no more errors in details then remove the whole thing as it's no longer required
if (v.serverError.details && v.serverError.details.length < 1) {
if (v.serverError.code == "2200") {
//clear all keys from server error
v.$gzutil.RemoveAllPropertiesFromObject(v.serverError);
}
}
//Clear out old validation display in form by forcing the control's data to change
//I tried calling form validate and reset and all that bullshit but it did nothing
//probably because it has safeguards to prevent excess validation, this works though so far
//I added the triggering change guard but it actually doesn't seem to be required here, more investigation is required
if (m.length > 0) {
triggeringChange = true;
var val = v.obj[ref];
v.obj[ref] = null;
v.obj[ref] = val;
triggeringChange = false;
}
}
};