This commit is contained in:
2019-04-23 18:34:37 +00:00
parent d6e6b006ae
commit aab019d797
4 changed files with 119 additions and 78 deletions

View File

@@ -30,7 +30,7 @@ function dealWithError(msg, form) {
} }
} }
form.appError = msg; form.appError = msg;
form.$gzv.setErrorBoxErrors(form); form.$gzform.setErrorBoxErrors(form);
} }
} }
export default { export default {

View File

@@ -1,8 +1,10 @@
/* Xeslint-disable */ /* Xeslint-disable */
/////////////////////////////// ///////////////////////////////
// GZVALIDATE // gzform
// //
// provides form validation services // provides form services and utilities
// validation services
// dirty and change tracking
// and also general error display in forms // and also general error display in forms
//probably should be broken up more //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 // All locale keys for validation *MUST* be fetched prior to this being used as it assumes all keys are fetched first
@@ -12,24 +14,6 @@ import errorHandler from "./errorhandler";
var triggeringChange = false; var triggeringChange = false;
////////////////////////////////////
// set calling form Dirty state
//
function setFormDirty(vm, isDirty) {
Vue.nextTick(function() {
vm.formDirty = isDirty;
});
}
////////////////////////////////////
// set calling form Valid state
//
function setFormValid(vm, isValid) {
Vue.nextTick(function() {
vm.formValid = isValid;
});
}
function isEmpty(o) { function isEmpty(o) {
if (typeof o == "number" && o == 0) { if (typeof o == "number" && o == 0) {
return false; return false;
@@ -82,7 +66,7 @@ function getControlValue(ctrl) {
function getControlLabel(ctrl) { function getControlLabel(ctrl) {
if (errorHandler.developmentModeShowErrorsImmediately) { if (errorHandler.developmentModeShowErrorsImmediately) {
if (!ctrl.label) { if (!ctrl.label) {
throw "GZValidate:getControlLabel - the control has no label " + ctrl; throw "gzform:getControlLabel - the control has no label " + ctrl;
} }
} }
return ctrl.label; return ctrl.label;
@@ -162,7 +146,11 @@ export default {
err = vm.$_.replace(err, "{0}", fieldName); err = vm.$_.replace(err, "{0}", fieldName);
//lodash replace only replaces first instance so need to do it twice //lodash replace only replaces first instance so need to do it twice
err = vm.$_.replace(err, "{0}", fieldName); err = vm.$_.replace(err, "{0}", fieldName);
setFormValid(vm, false); //Update the form status
this.setFormState({
vm: vm,
formValid: false
});
return err; return err;
}, },
/////////////////////////////// ///////////////////////////////
@@ -189,7 +177,11 @@ export default {
var fieldName = getControlLabel(ctrl); var fieldName = getControlLabel(ctrl);
err = vm.$_.replace(err, "{0}", fieldName); err = vm.$_.replace(err, "{0}", fieldName);
err = vm.$_.replace(err, "{1}", max); err = vm.$_.replace(err, "{1}", max);
setFormValid(vm, false); //Update the form status
this.setFormState({
vm: vm,
formValid: false
});
return err; return err;
} else { } else {
return false; return false;
@@ -243,7 +235,11 @@ export default {
if (valueStart.isAfter(valueEnd)) { if (valueStart.isAfter(valueEnd)) {
// "ErrorStartDateAfterEndDate": "Start date must be earlier than stop / end date", // "ErrorStartDateAfterEndDate": "Start date must be earlier than stop / end date",
var err = vm.$gzlocale.get("ErrorStartDateAfterEndDate"); var err = vm.$gzlocale.get("ErrorStartDateAfterEndDate");
setFormValid(vm, false); //Update the form status
this.setFormState({
vm: vm,
formValid: false
});
return err; return err;
} else { } else {
return false; return false;
@@ -275,7 +271,11 @@ export default {
// "ErrorFieldValueNotInteger": "Value must be an integer" // "ErrorFieldValueNotInteger": "Value must be an integer"
var err = vm.$gzlocale.get("ErrorFieldValueNotInteger"); var err = vm.$gzlocale.get("ErrorFieldValueNotInteger");
setFormValid(vm, false); //Update the form status
this.setFormState({
vm: vm,
formValid: false
});
return err; return err;
}, },
/////////////////////////////// ///////////////////////////////
@@ -308,7 +308,11 @@ export default {
// "ErrorFieldValueNotDecimal": "Value must be a number" // "ErrorFieldValueNotDecimal": "Value must be a number"
var err = vm.$gzlocale.get("ErrorFieldValueNotDecimal"); var err = vm.$gzlocale.get("ErrorFieldValueNotDecimal");
setFormValid(vm, false); //Update the form status
this.setFormState({
vm: vm,
formValid: false
});
return err; return err;
}, },
/////////////////////////////// ///////////////////////////////
@@ -320,24 +324,24 @@ export default {
if (vm.$gzdevmode()) { if (vm.$gzdevmode()) {
//make sure serverErrors is defined on data //make sure serverErrors is defined on data
if (!vm.$_.has(vm, "serverError")) { if (!vm.$_.has(vm, "serverError")) {
throw "DEV ERROR gzvalidate::serverErrors -> serverError seems to be missing from form's vue data object"; throw "DEV ERROR gzform::serverErrors -> serverError seems to be missing from form's vue data object";
} }
//make sure appError is defined on data //make sure appError is defined on data
if (!vm.$_.has(vm, "appError")) { if (!vm.$_.has(vm, "appError")) {
throw "DEV ERROR gzvalidate::serverErrors -> appError seems to be missing from form's vue data object"; throw "DEV ERROR gzform::serverErrors -> appError seems to be missing from form's vue data object";
} }
//make sure errorBoxMessage is defined on data //make sure errorBoxMessage is defined on data
if (!vm.$_.has(vm, "errorBoxMessage")) { if (!vm.$_.has(vm, "errorBoxMessage")) {
throw "DEV ERROR gzvalidate::serverErrors -> errorBoxMessage seems to be missing from form's vue data object"; throw "DEV ERROR gzform::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 //ensure the error returned is in an expected format to catch coding errors at the server end
if (!vm.$_.isEmpty(vm.serverError)) { if (!vm.$_.isEmpty(vm.serverError)) {
//Make sure there is an error code if there is an error collection //Make sure there is an error code if there is an error collection
if (!vm.serverError.code) { if (!vm.serverError.code) {
throw "DEV ERROR gzvalidate::serverErrors -> server returned error without code"; throw "DEV ERROR gzform::serverErrors -> server returned error without code";
} }
} }
} }
@@ -357,7 +361,11 @@ export default {
if (vm.serverError.message) { if (vm.serverError.message) {
err = err + "\r\n" + vm.serverError.message; err = err + "\r\n" + vm.serverError.message;
} }
setFormValid(vm, false); //Update the form status
this.setFormState({
vm: vm,
formValid: false
});
ret.push(err); ret.push(err);
} }
//DETAIL ERRORS //DETAIL ERRORS
@@ -382,7 +390,12 @@ export default {
} }
ret.push(fldErr); ret.push(fldErr);
}); });
setFormValid(vm, false);
//Update the form status
this.setFormState({
vm: vm,
formValid: false
});
return ret; return ret;
} }
} }
@@ -403,7 +416,11 @@ export default {
vm.appError = null; vm.appError = null;
//clear out actual message box display //clear out actual message box display
vm.errorBoxMessage = null; vm.errorBoxMessage = null;
setFormValid(vm, true); //Update the form status
this.setFormState({
vm: vm,
formValid: true
});
}, },
/////////////////////////////// ///////////////////////////////
// setErrorBoxErrors // setErrorBoxErrors
@@ -449,8 +466,34 @@ export default {
vm.obj[ref] = val; vm.obj[ref] = val;
triggeringChange = false; triggeringChange = false;
} }
setFormDirty(vm, true);
setFormValid(vm, vm.$refs.form.validate()); //Update the form status
//TODO: shouldn't it check for any dirty here and set the isdirty to false if none since each rule can set it dirty this.setFormState({
vm: vm,
formDirty: true,
formValid: vm.$refs.form.validate()
});
},
////////////////////////////////////
// set calling form Valid state
//
// {vm:vm,formDirty:bool | undefined,
// formValid:bool | undefined,
// formLoading:bool | undefined}
//
setFormState(theState) {
Vue.nextTick(function() {
if (theState.formValid != undefined) {
theState.vm.formValid = theState.formValid;
}
if (theState.formDirty != undefined) {
theState.vm.formDirty = theState.formDirty;
}
if (theState.formLoading != undefined) {
theState.vm.formLoading = theState.formLoading;
}
});
} }
}; };

View File

@@ -18,7 +18,7 @@ import gzmenu from "./api/gzmenu";
import gzutil from "./api/gzutil"; import gzutil from "./api/gzutil";
import locale from "./api/locale"; import locale from "./api/locale";
import gzapi from "./api/gzapi"; import gzapi from "./api/gzapi";
import gzvalidate from "./api/gzvalidate"; import gzform from "./api/gzform";
import "@/assets/css/main.css"; import "@/assets/css/main.css";
import gzdateandtimepicker from "./components/gzdateandtimepicker.vue"; import gzdateandtimepicker from "./components/gzdateandtimepicker.vue";
@@ -34,7 +34,7 @@ Object.defineProperty(Vue.prototype, "$dayjs", { value: dayjs });
Object.defineProperty(Vue.prototype, "$_", { value: lodash }); Object.defineProperty(Vue.prototype, "$_", { value: lodash });
Object.defineProperty(Vue.prototype, "$gzlocale", { value: locale }); Object.defineProperty(Vue.prototype, "$gzlocale", { value: locale });
Object.defineProperty(Vue.prototype, "$gzapi", { value: gzapi }); Object.defineProperty(Vue.prototype, "$gzapi", { value: gzapi });
Object.defineProperty(Vue.prototype, "$gzv", { value: gzvalidate }); Object.defineProperty(Vue.prototype, "$gzform", { value: gzform });
Object.defineProperty(Vue.prototype, "$gzHandleFormError", { Object.defineProperty(Vue.prototype, "$gzHandleFormError", {
value: errorHandler.handleFormError value: errorHandler.handleFormError
}); });

View File

@@ -22,8 +22,8 @@
@click:clear="onChange('name')" @click:clear="onChange('name')"
:counter="255" :counter="255"
:label="this.$gzlocale.get('WidgetName')" :label="this.$gzlocale.get('WidgetName')"
:rules="[this.$gzv.max255(this,'name'),this.$gzv.required(this,'name')]" :rules="[this.$gzform.max255(this,'name'),this.$gzform.required(this,'name')]"
:error-messages="this.$gzv.serverErrors(this,'name')" :error-messages="this.$gzform.serverErrors(this,'name')"
ref="name" ref="name"
@change="onChange('name')" @change="onChange('name')"
></v-text-field> ></v-text-field>
@@ -35,8 +35,8 @@
@click:clear="onChange('serial')" @click:clear="onChange('serial')"
:counter="10" :counter="10"
:label="this.$gzlocale.get('WidgetSerial')" :label="this.$gzlocale.get('WidgetSerial')"
:rules="[this.$gzv.maxLength(this,'serial',10)]" :rules="[this.$gzform.maxLength(this,'serial',10)]"
:error-messages="this.$gzv.serverErrors(this,'serial')" :error-messages="this.$gzform.serverErrors(this,'serial')"
ref="serial" ref="serial"
@change="onChange('serial')" @change="onChange('serial')"
></v-text-field> ></v-text-field>
@@ -49,8 +49,8 @@
:counter="10" :counter="10"
:label="this.$gzlocale.get('WidgetCount')" :label="this.$gzlocale.get('WidgetCount')"
ref="count" ref="count"
:rules="[this.$gzv.integerValid(this,'count'),this.$gzv.required(this,'count')]" :rules="[this.$gzform.integerValid(this,'count'),this.$gzform.required(this,'count')]"
:error-messages="this.$gzv.serverErrors(this,'count')" :error-messages="this.$gzform.serverErrors(this,'count')"
required required
@change="onChange('count')" @change="onChange('count')"
type="number" type="number"
@@ -64,8 +64,8 @@
:label="this.$gzlocale.get('WidgetDollarAmount')" :label="this.$gzlocale.get('WidgetDollarAmount')"
ref="dollarAmount" ref="dollarAmount"
required required
:rules="[this.$gzv.decimalValid(this,'dollarAmount'),this.$gzv.required(this,'dollarAmount')]" :rules="[this.$gzform.decimalValid(this,'dollarAmount'),this.$gzform.required(this,'dollarAmount')]"
:error-messages="this.$gzv.serverErrors(this,'dollarAmount')" :error-messages="this.$gzform.serverErrors(this,'dollarAmount')"
@change="onChange('dollarAmount')" @change="onChange('dollarAmount')"
type="number" type="number"
></v-text-field> ></v-text-field>
@@ -76,7 +76,7 @@
:label="this.$gzlocale.get('WidgetStartDate')" :label="this.$gzlocale.get('WidgetStartDate')"
v-model="obj.startDate" v-model="obj.startDate"
ref="startDate" ref="startDate"
:error-messages="this.$gzv.serverErrors(this,'startDate')" :error-messages="this.$gzform.serverErrors(this,'startDate')"
@change="onChange('startDate')" @change="onChange('startDate')"
></gz-date-time-picker> ></gz-date-time-picker>
</v-flex> </v-flex>
@@ -84,8 +84,8 @@
<v-flex xs12 sm6 lg4 xl3 px-2> <v-flex xs12 sm6 lg4 xl3 px-2>
<gz-date-time-picker <gz-date-time-picker
:label="this.$gzlocale.get('WidgetEndDate')" :label="this.$gzlocale.get('WidgetEndDate')"
:rules="[this.$gzv.datePrecedence(this,'startDate','endDate')]" :rules="[this.$gzform.datePrecedence(this,'startDate','endDate')]"
:error-messages="this.$gzv.serverErrors(this,'endDate')" :error-messages="this.$gzform.serverErrors(this,'endDate')"
v-model="obj.endDate" v-model="obj.endDate"
ref="endDate" ref="endDate"
@change="onChange('endDate')" @change="onChange('endDate')"
@@ -96,7 +96,7 @@
v-model="obj.active" v-model="obj.active"
:label="this.$gzlocale.get('Active')" :label="this.$gzlocale.get('Active')"
ref="active" ref="active"
:error-messages="this.$gzv.serverErrors(this,'active')" :error-messages="this.$gzform.serverErrors(this,'active')"
required required
@change="onChange('active')" @change="onChange('active')"
></v-checkbox> ></v-checkbox>
@@ -106,8 +106,8 @@
v-model="obj.roles" v-model="obj.roles"
:label="this.$gzlocale.get('WidgetRoles')" :label="this.$gzlocale.get('WidgetRoles')"
ref="roles" ref="roles"
:rules="[this.$gzv.integerValid(this,'roles'),this.$gzv.required(this,'roles')]" :rules="[this.$gzform.integerValid(this,'roles'),this.$gzform.required(this,'roles')]"
:error-messages="this.$gzv.serverErrors(this,'roles')" :error-messages="this.$gzform.serverErrors(this,'roles')"
required required
@change="onChange('roles')" @change="onChange('roles')"
type="number" type="number"
@@ -146,8 +146,7 @@
</template> </template>
<script> <script>
/* eslint-disable */ /* XXeslint-disable */
import Vue from "vue";
function clickHandler(menuItem) { function clickHandler(menuItem) {
if (!menuItem) { if (!menuItem) {
@@ -262,60 +261,60 @@ export default {
formLoading: true formLoading: true
}; };
}, },
watch: { watch: {
formValid: { formValid: {
handler: function(newObj, oldObj) { handler: function(newObj, oldObj) {
console.log("Valid CHANGED, was " + oldObj + " Now is " + newObj); //todo: change the save button state here
//console.log("Valid CHANGED, was " + oldObj + " Now is " + newObj);
} }
} }
}, },
methods: { methods: {
onChange(ref) { onChange(ref) {
if (!this.formLoading) { if (!this.formLoading) {
console.log("onChange:" + ref); this.$gzform.onChange(this, ref);
this.$gzv.onChange(this, ref);
} }
}, },
getDataFromApi() { getDataFromApi() {
this.formLoading = true; this.formLoading = true;
var url = "Widget/" + this.$route.params.id; var url = "Widget/" + this.$route.params.id;
var vm = this; var vm = this;
this.$gzv.deleteAllErrorBoxErrors(this); this.$gzform.deleteAllErrorBoxErrors(this);
this.$gzapi this.$gzapi
.get(url) .get(url)
.then(res => { .then(res => {
if (res.error) { if (res.error) {
vm.serverError = res.error; vm.serverError = res.error;
vm.$gzv.setErrorBoxErrors(vm); vm.$gzform.setErrorBoxErrors(vm);
} else { } else {
vm.obj = res.data; vm.obj = res.data;
//WTF? Can't seem to set this to valid after the data has loaded, it seems to validate outside of here //Update the form status
//tried to set nexttick as latest attempt, but it's not working vm.$gzform.setFormState({
//tried to defer validation until form is loaded but that's also not working for some reason vm: vm,
//wtf is going on here??? formDirty: false,
Vue.nextTick(function() { formValid: true,
vm.formValid = true; formLoading: false
vm.formDirty = false;
vm.formLoading = false;
}); });
} }
}) })
.catch(function handleGetDataFromAPIError(error) { .catch(function handleGetDataFromAPIError(error) {
vm.formLoading = false; //Update the form status
vm.$gzform.setFormState({
vm: vm,
formLoading: false
});
vm.$gzHandleFormError(error, vm); vm.$gzHandleFormError(error, vm);
}); });
}, },
submit() { submit() {
//check if form is valid, as far as I know this is the way you're supposed to do it and in testing it does not force all fields to revalidate individually //check if form is valid, as far as I know this is the way you're supposed to do it and in testing it does not force all fields to revalidate individually
if (this.$refs.form.validate()) { if (this.formValid && this.formDirty) {
this.formLoading = true; this.formLoading = true;
var vm = this; var vm = this;
var url = "Widget/" + this.$route.params.id; var url = "Widget/" + this.$route.params.id;
//clear any errors vm might be around from previous submit //clear any errors vm might be around from previous submit
this.$gzv.deleteAllErrorBoxErrors(this); this.$gzform.deleteAllErrorBoxErrors(this);
this.$gzapi this.$gzapi
.upsert(url, this.obj) .upsert(url, this.obj)
@@ -323,12 +322,11 @@ export default {
this.formLoading = false; this.formLoading = false;
if (res.error) { if (res.error) {
vm.serverError = res.error; vm.serverError = res.error;
vm.$gzv.setErrorBoxErrors(vm); vm.$gzform.setErrorBoxErrors(vm);
} else { } else {
//It's ok, form is saved vm.setFormState({
Vue.nextTick(function() { vm: vm,
// vm.formValid = true; formDirty: false
vm.formDirty = false;
}); });
//Logic for detecting if a post or put: if id then it was a post, if no id then it was a put //Logic for detecting if a post or put: if id then it was a post, if no id then it was a put