Files
raven-client/ayanova/src/components/custom-fields-control.vue
2020-02-28 23:10:57 +00:00

447 lines
13 KiB
Vue

<template>
<div v-if="templateHasVisibleCustomFields()">
<span class="v-label v-label--active theme--light">
{{ lt("ObjectCustomFieldCustomGrid") }}
</span>
<div>
<v-row align-center justify-left row wrap>
<template v-for="item in this.$store.state.formCustomTemplate[formKey]">
<v-col
v-if="item.type"
:key="item.fld"
cols="12"
sm="6"
lg="4"
xl="3"
px-2
>
<!-- CURRENCY -->
<div v-if="item.type === 8">
<gz-currency
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
></gz-currency>
</div>
<!-- DATE -->
<div v-else-if="item.type === 2">
<gz-date-picker
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
></gz-date-picker>
</div>
<!-- TIME -->
<div v-else-if="item.type === 3">
<gz-time-picker
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
></gz-time-picker>
</div>
<!-- DATETIME -->
<div v-else-if="item.type === 1">
<gz-date-time-picker
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
></gz-date-time-picker>
</div>
<!-- TEXT -->
<div v-else-if="item.type === 4">
<v-textarea
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
auto-grow
clearable
></v-textarea>
</div>
<!-- INTEGER -->
<div v-else-if="item.type === 5">
<v-text-field
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
clearable
:counter="10"
type="number"
step="none"
></v-text-field>
</div>
<!-- DECIMAL -->
<div v-else-if="item.type === 7">
<gz-decimal
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
></gz-decimal>
</div>
<!-- BOOL -->
<div v-else-if="item.type === 6">
<v-checkbox
v-model="_self[item.dataKey]"
:readonly="readOnly"
:label="lt(item.fld)"
:ref="item.fld"
:error-messages="form().serverErrors(parentVM, item.fld)"
:rules="[
form().customFieldsCheck(parentVM, item, _self, lt(item.fld))
]"
></v-checkbox>
</div>
<div v-else>
<span class="error"
>UNKNOWN CUSTOM CONTROL TYPE: {{ item.type }}</span
>
</div>
</v-col>
</template>
</v-row>
</div>
</div>
</template>
<script>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* XXXeslint-disable */
////////////////////////////////////////////////////////////////////////////////////////////////////////////
export default {
data() {
return {};
},
props: {
value: {
default: "{}",
type: String
},
formKey: String, //used to grab template from store
readOnly: Boolean,
parentVM: Object
},
methods: {
lt: function(ltkey) {
return window.$gz.locale.get(ltkey);
},
form() {
//nothing
return window.$gz.form;
},
onChange(ref) {
if (
!this.parentVM.formState.loading &&
!this.parentVM.formState.readOnly
) {
window.$gz.form.onChange(this.parentVM, ref);
}
},
templateHasVisibleCustomFields() {
var template = this.$store.state.formCustomTemplate[this.formKey];
if (template == undefined) {
return false;
}
//iterate template and see if it has any custom fields set to display
return window.$gz._.find(template, "type") != undefined;
},
GetValueForField: function(dataKey) {
if (!this.value) {
return null;
}
//get the data out of the JSON string value
var cData = JSON.parse(this.value);
//Custom field types can be changed by the user and cause old entered data to be invalid for that field type
//Here we need to take action if the data is of an incompatible type for the control field type and attempt to coerce or simply nullify if not co-ercable the data
// - CURRENT TEXT fields could handle any data so they don't need to be changed
// - CURRENT BOOL fields can only handle empty or true false so they would need to be set null
// - CURRENT TIME, DATE, DATETIME are pretty specific but all use a datetime string so any value not datetime like should be nulled
// - CURRENT NUMBER, CURRENCY are also pretty specific but easy to identify if not fully numeric and then sb nulled or attempt to convert then null if not
//Get the field data type
//https://lodash.com/docs#find
var ctrlType = window.$gz._.find(
this.$store.state.formCustomTemplate[this.formKey],
["dataKey", dataKey]
).type;
//First get current value for the data that came from the server
var ret = cData[dataKey];
//Only process if value is non-null since all control types can handle null
if (ret != null) {
//check types that matter
/*thes are all types, not necessarily all custom field types
NoType = 0,
DateTime = 1,
Date = 2,
Time = 3,
Text = 4,
Integer = 5,
Bool = 6,
Decimal = 7,
Currency = 8,
Tags = 9,
Enum = 10,
EmailAddress = 11,
HTTP = 12,
InternalId = 13
*/
switch (ctrlType) {
//DateLike?
case 1:
case 2:
case 3:
//can it be parsed into a date using the same library as the components use?
if (!window.$gz.DateTime.fromISO(ret).isValid) {
ret = null;
}
break;
case 6:
//if it's not already a boolean
if (!window.$gz._.isBoolean(ret)) {
//it's not a bool and it's not null, it came from some other data type,
//perhaps though, it's a truthy string so check for that before giving up and nulling
if (window.$gz._.isString(ret)) {
ret = window.$gz.util.stringToBoolean(ret);
break;
}
//The number 1?
if (ret === 1) {
ret = true;
break;
}
//The number 0?
if (ret === 0) {
ret = false;
break;
}
}
break;
case 8:
case 7:
if (!window.$gz._.isNumber(ret)) {
ret = window.$gz.util.stringToFloat(ret);
break;
}
break;
}
}
return ret;
},
SetValueForField: function(dataKey, newValue) {
//Get the current data out of the json string value
//
var cData = JSON.parse(this.value);
if (!window.$gz._.has(cData, dataKey)) {
cData[dataKey] = null;
}
//handle null or undefined
if (newValue === null || newValue === undefined) {
cData[dataKey] = null;
} else {
//then set item in the cData
cData[dataKey] = newValue.toString();
}
//emit the new data so it syncs with the parent source
var ret = JSON.stringify(cData);
//THis is absolutely required or it won't save any changes, no idea why though
this.$emit("update:value", ret);
//this.$emit("input", ret); //always in UTC
//this triggers the onchange routine in the parent form
//so that the dirty checking works
this.$emit("change", ret);
}
},
computed: {
c1: {
get: function() {
return this.GetValueForField("c1");
},
set: function(newValue) {
this.SetValueForField("c1", newValue);
}
},
c2: {
get: function() {
return this.GetValueForField("c2");
},
set: function(newValue) {
this.SetValueForField("c2", newValue);
}
},
c3: {
get: function() {
return this.GetValueForField("c3");
},
set: function(newValue) {
this.SetValueForField("c3", newValue);
}
},
c4: {
get: function() {
return this.GetValueForField("c4");
},
set: function(newValue) {
this.SetValueForField("c4", newValue);
}
},
c5: {
get: function() {
return this.GetValueForField("c5");
},
set: function(newValue) {
this.SetValueForField("c5", newValue);
}
},
c6: {
get: function() {
return this.GetValueForField("c6");
},
set: function(newValue) {
this.SetValueForField("c6", newValue);
}
},
c7: {
get: function() {
return this.GetValueForField("c7");
},
set: function(newValue) {
this.SetValueForField("c7", newValue);
}
},
c8: {
get: function() {
return this.GetValueForField("c8");
},
set: function(newValue) {
this.SetValueForField("c8", newValue);
}
},
c9: {
get: function() {
return this.GetValueForField("c9");
},
set: function(newValue) {
this.SetValueForField("c9", newValue);
}
},
c10: {
get: function() {
return this.GetValueForField("c10");
},
set: function(newValue) {
this.SetValueForField("c10", newValue);
}
},
c11: {
get: function() {
return this.GetValueForField("c11");
},
set: function(newValue) {
this.SetValueForField("c11", newValue);
}
},
c12: {
get: function() {
return this.GetValueForField("c12");
},
set: function(newValue) {
this.SetValueForField("c12", newValue);
}
},
c13: {
get: function() {
return this.GetValueForField("c13");
},
set: function(newValue) {
this.SetValueForField("c13", newValue);
}
},
c14: {
get: function() {
return this.GetValueForField("c14");
},
set: function(newValue) {
this.SetValueForField("c14", newValue);
}
},
c15: {
get: function() {
return this.GetValueForField("c15");
},
set: function(newValue) {
this.SetValueForField("c15", newValue);
}
},
c16: {
get: function() {
return this.GetValueForField("c16");
},
set: function(newValue) {
this.SetValueForField("c16", newValue);
}
}
},
beforeCreate() {
//check pre-requisites exist just in case
if (window.$gz.errorHandler.devMode()) {
if (!window.$gz._) {
throw "custom-fields-control: $gz._ (lodash) is required and missing";
}
if (!window.$gz.locale) {
throw "custom-fields-control: $gz.locale is required and missing";
}
}
},
created() {
if (window.$gz.errorHandler.devMode()) {
//debugger;
if (!this.formKey) {
throw "custom-fields-control: formKey property is required and missing";
}
}
}
};
</script>