This commit is contained in:
2019-04-03 22:07:40 +00:00
parent 4f9bb570c3
commit b16f8d1a66
4 changed files with 167 additions and 99 deletions

View File

@@ -28,8 +28,8 @@ FIX:
Scenarios:
- DONE: Local form validation errors display correctly and are cleared when edited
- Server form validation errors displayed correctly
- control ones under control where local form validation errors show
- whole object ones at top
- DONE control ones under control where local form validation errors show
- DONE whole object ones at top
- Server form validation errors cleared in individual inputs upon any change to them (but form overall ones stay until submitted)
- On submit:
- Doesn't happen if any local validation errors
@@ -39,6 +39,9 @@ FIX:
DIRTY CHECKING to short circuit rule checks
inernalChange does get set to true but only on the very first actual change, later it can be false again, however this is enough for me to detect a change and remove the server rule
direct control properties when control was changed / is dirty:
=-=-=-=-
hasColor: true

View File

@@ -74,6 +74,54 @@ function getControlLabel(ctrl) {
return ctrl.label;
}
////////////////////////////////////
// DEBUG / DEVELOPMENT LOGGING
//
function logControl(caller, ctrl, ref) {
if (ref != "xcount") {
return;
}
var hasChanged = false;
if (ctrl.internalChange) {
hasChanged = true;
} else {
if (ctrl.initialValue && ctrl.lazyValue) {
if (ctrl.initialValue != ctrl.lazyValue) {
hasChange = true;
}
}
}
var v =
"CTRL=" +
ref +
", CALLER [" +
caller +
"], " +
", internalChange=" +
ctrl.internalChange +
", lazyValue=" +
ctrl.lazyValue +
", initialValue=" +
ctrl.initialValue +
", loading=" +
ctrl.loading +
", isDirty=" +
ctrl.isDirty +
", isResetting=" +
ctrl.isResetting +
", HAS CHANGED =" +
hasChanged;
console.log(v);
}
export default {
///////////////////////////////
// REQUIRED
@@ -84,6 +132,9 @@ export default {
return false;
}
//DEBUG
logControl("Required", ctrl, ref);
var value = getControlValue(ctrl);
if (!isEmpty(value)) {
return false;
@@ -106,6 +157,9 @@ export default {
return false;
}
//DEBUG
logControl("MaxLength", ctrl, ref);
var value = getControlValue(ctrl);
if (isEmpty(value)) {
return false;
@@ -142,6 +196,10 @@ export default {
return false;
}
//DEBUG
logControl("After", ctrlStart, refStart);
logControl("After", ctrlEnd, refEnd);
var valueStart = getControlValue(ctrlStart);
if (isEmpty(valueStart)) {
return false;
@@ -177,6 +235,9 @@ export default {
return false;
}
//DEBUG
logControl("Integer", ctrl, ref);
var value = getControlValue(ctrl);
if (isEmpty(value)) {
return false;
@@ -203,6 +264,9 @@ export default {
return false;
}
//DEBUG
logControl("Decimal", ctrl, ref);
var value = getControlValue(ctrl);
if (isEmpty(value)) {
return false;
@@ -236,6 +300,78 @@ export default {
}
}
}
var ret = [];
//return 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);
//TODO: This logic is faulty, there could be overall errors that are not field specific, however there are also field ones that trigger overall errors.
//Keep top part if statement for gathering all overall errors, but then also run the field errors block and check for field errors where "target" is empty and add them in to the return as well
//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 = [];
if (ref == "errorbox") {
errorsForField = v.$_.filter(v.serverError.details, function(o) {
return !o.target;
});
} else {
errorsForField = v.$_.filter(v.serverError.details, {
target: ref
});
}
if (errorsForField.length > 0) {
//DEBUG
logControl("ServerErrors", getControl(v, ref), ref);
//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;
}
} else {
if (v.$gzdevmode()) {
throw "DEV ERROR gzvalidate::ServerErrors -> on field validation error no 'details' key was found to show which field had the error";
}
}
}
//default if no error message to display
return ret;
//OK, this is sketchy a bit but seems to work
//If it returns a value that is displayed as an error in the field (hides any rule errors but whatever)
//Tested and confirmed that If I make a change to the underlying data property that is housing the data used here to determine if a field has an error, and remove that error then it instantly resolves in the UI and removes the message so that's good!
@@ -317,102 +453,18 @@ Here are all the API level error codes that can be returned by the API server:
| NotChangeable | Indicates the attempted property change is invalid because the value is fixed and cannot be changed |
*/
var ret = [];
//return 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);
//TODO: This logic is faulty, there could be overall errors that are not field specific, however there are also field ones that trigger overall errors.
//Keep top part if statement for gathering all overall errors, but then also run the field errors block and check for field errors where "target" is empty and add them in to the return as well
//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 = [];
if (ref == "errorbox") {
errorsForField = v.$_.filter(v.serverError.details, function(o) {
return !o.target;
});
} else {
errorsForField = v.$_.filter(v.serverError.details, {
target: 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;
}
} else {
if (v.$gzdevmode()) {
throw "DEV ERROR gzvalidate::ServerErrors -> on field validation error no 'details' key was found to show which field had the error";
}
}
}
//default if no error message to display
return ret;
// var ctrl = getControl(v, ref);
// if (typeof ctrl == "undefined") {
// return false;
// }
// 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;
},
///////////////////////////////
// ERROR BOX ERRORS
// displays any messages for error box on form which is the generic catch all for non field specific errors from server
ErrorBoxErrors(v) {
console.log("gzvalidate::ErrorBoxErrors called...");
console.log(v);
//console.log("gzvalidate::ErrorBoxErrors called...");
var errs = this.ServerErrors(v, "errorbox");
if (errs.length < 1) {
console.log("gzvalidate::ErrorBoxErrors - RETURN NO ERRORS, short circuit return");
// console.log(
// "gzvalidate::ErrorBoxErrors - RETURN NO ERRORS, short circuit return"
// );
return null;
}
@@ -421,8 +473,8 @@ Here are all the API level error codes that can be returned by the API server:
for (var i = 0; i < errs.length; i++) {
ret += errs[i] + "\r\n";
}
// ret=ret.replace("\r\n"," <br/> ");
console.log("gzvalidate::ErrorBoxErrors - RETURN WITH ERRORS");
// console.log("gzvalidate::ErrorBoxErrors - RETURN WITH ERRORS");
return ret;
}
};

View File

@@ -79,6 +79,7 @@ export default {
watch: {
date() {
this.$emit("input", this.date); //always in UTC
this.$emit("change", this.date); //always in UTC
},
value() {
this.date = this.value; //always in UTC

View File

@@ -14,7 +14,7 @@
>
{{someerror}}
</v-alert>
</v-flex> -->
</v-flex>-->
<v-flex xs12 mt-1 mb-2>
<v-alert
ref="errorbox"
@@ -25,8 +25,7 @@
transition="scale-transition"
class="multi-line"
outline
>{{this.$gzv.ErrorBoxErrors(this)}}
</v-alert>
>{{this.$gzv.ErrorBoxErrors(this)}}</v-alert>
</v-flex>
<v-flex xs12 sm6 lg4 xl3 px-2>
<v-text-field
@@ -36,6 +35,7 @@
:rules="[this.$gzv.Max255(this,'name')]"
:error-messages="this.$gzv.ServerErrors(this,'name')"
ref="name"
@change="test('name')"
></v-text-field>
</v-flex>
<v-flex xs12 sm6 lg4 xl3 px-2>
@@ -46,6 +46,7 @@
:rules="[this.$gzv.MaxLength(this,'serial',10)]"
:error-messages="this.$gzv.ServerErrors(this,'count')"
ref="serial"
@change="test('serial')"
></v-text-field>
</v-flex>
<v-flex xs12 sm6 lg4 xl3 px-2>
@@ -57,6 +58,7 @@
:rules="[this.$gzv.Integer(this,'count'),this.$gzv.Required(this,'count')]"
:error-messages="this.$gzv.ServerErrors(this,'count')"
required
@change="test('count')"
></v-text-field>
</v-flex>
@@ -69,6 +71,7 @@
required
:rules="[this.$gzv.Decimal(this,'dollarAmount'),this.$gzv.Required(this,'dollarAmount')]"
:error-messages="this.$gzv.ServerErrors(this,'dollarAmount')"
@change="test('dollarAmount')"
></v-text-field>
</v-flex>
@@ -78,6 +81,7 @@
v-model="obj.startDate"
ref="startDate"
:error-messages="this.$gzv.ServerErrors(this,'startDate')"
@change="test('startDate')"
></gz-date-time-picker>
</v-flex>
@@ -88,6 +92,7 @@
:error-messages="this.$gzv.ServerErrors(this,'endDate')"
v-model="obj.endDate"
ref="endDate"
@change="test('endDate')"
></gz-date-time-picker>
</v-flex>
<v-flex xs12 sm6 lg4 xl3 px-2>
@@ -97,6 +102,7 @@
ref="active"
:error-messages="this.$gzv.ServerErrors(this,'active')"
required
@change="test('active')"
></v-checkbox>
</v-flex>
<v-flex xs12 sm6 lg4 xl3 px-2>
@@ -107,6 +113,7 @@
:rules="[this.$gzv.Integer(this,'roles'),this.$gzv.Required(this,'roles')]"
:error-messages="this.$gzv.ServerErrors(this,'roles')"
required
@change="test('roles')"
></v-text-field>
</v-flex>
</v-layout>
@@ -177,10 +184,15 @@ export default {
obj: {},
serverError: {},
formReady: false,
someerror: "blah blahv <br/> blah blah" + "\n test line 3" + "\r\n Test line 4"
someerror:
"blah blahv <br/> blah blah" + "\n test line 3" + "\r\n Test line 4"
};
},
methods: {
},
methods: {
test(ref){
//debugger;
console.log("CHANGE - " + ref);
} ,
getDataFromApi() {
var url = "Widget/" + this.$route.params.id;
this.$gzapi.get(url).then(res => {