@hperchec/scorpion-ui-template-default
Version:
Scorpion UI - Default template
242 lines (235 loc) • 8.49 kB
JavaScript
// tools
// import parseErrorResponse from '#tools/xhr/parseErrorResponse'
// utils
import { utils } from '@hperchec/scorpion-ui'
const { isDef, isNull } = utils
/**
* BaseForm component
*/
export default {
name: 'BaseForm',
data () {
return {
form: {
fields: {},
globalError: null
}
}
},
computed: {
/**
* isFormValid: define if form is valid
*/
isFormValid: function () {
for (const field in this.form.fields) {
const computedFieldIsValidName = this.$h.camelize('is_' + field + '_valid')
if (!this[computedFieldIsValidName]) return false // Break
}
return true
},
/**
* hasChanged method: define if a field has changed
* @returns {Boolean}
*/
hasChanged: function () {
for (const field in this.form.fields) {
const computedFieldChangedName = this.$h.camelize(field + '_changed')
// If '<field>Changed' computed returns true
if (this[computedFieldChangedName]) return true // Break
}
return false
}
},
methods: {
/**
* Is form field in error
*
* @param {string} field - The field name
* @returns {boolean}
*/
isFieldInError: function (field) {
return Boolean(this.form.fields[field].errors)
},
/**
* Get form field error message
*
* @param {string} field - The field name
* @returns {string}
*/
getFieldErrorMessage: function (field) {
let message = ''
const fieldOptions = this.$options.form.fields[field]
if (isDef(this.form.fields[field])) {
const fieldErrors = this.form.fields[field].errors
if (!isNull(fieldErrors)) {
// Get first error
// Does field have 'failed.ruleToErrorCode' map property defined ?
if (isDef(fieldOptions.failed) && isDef(fieldOptions.failed.ruleToErrorCode)) {
const rules = Object.keys(fieldOptions.failed.ruleToErrorCode)
for (const rule of rules) {
const errorCode = fieldOptions.failed.ruleToErrorCode[rule]
// If rule found in field errors keys
if (Object.keys(fieldErrors).indexOf(rule) !== -1) {
message = this.$t(`errors.${errorCode}`)
break
}
}
} else {
message = this.$t('errors.e0051') // This field is invalid
}
}
} else {
this.$root.log('warning', `Warning! Component extending BaseForm: getFieldErrorMessage() method: field '${field}' doesn't exist. Returns empty string...`, { prod: false })
}
return message
},
/**
* Set fields errors & form global error
*
* @param {Object} response - The error response returned by the server
* @returns {void}
*/
setFormErrors (response) {
// const parsedResponse = parseErrorResponse(response)
const parsedResponse = response
// If error => 'e0050' ('A field is invalid')
if (parsedResponse.errorCode === 'e0050' && isDef(parsedResponse.payload.fields)) {
// Set errors for each field
for (const field in parsedResponse.payload.fields) {
this.form.fields[field].errors = parsedResponse.payload.fields[field]
}
}
// Form global error
this.form.globalError = this.$t(`errors.${parsedResponse.errorCode}`)
},
/**
* Reset errors
*
* @returns {void}
*/
resetErrors () {
for (const field in this.form.fields) {
this.form.fields[field].errors = null
}
this.form.globalError = null
},
/**
* Reset form with default values
* @returns {void}
*/
resetForm () {
// Loop on each field and set default value (defined in this.$options.form)
for (const field in this.form.fields) {
this.form.fields[field].value = this.$options.form.fields[field].default.call(this)
}
}
},
beforeCreate () {
// Get data
const dataOptions = this.$options.data()
// Get computed
const computedOptions = this.$options.computed
// Check if form option is defined
const formOptions = this.$options.form
if (!formOptions) {
this.$root.log('error', 'Component extending BaseForm must have \'form\' option.')
} else {
// Get form.fields
if (!formOptions.fields) {
this.$root.log('error', 'Component extending BaseForm: no field properties found in \'form.fields\' option.')
} else {
// Loop on each field
for (const field in formOptions.fields) {
/**
* default
*/
// Check if 'default' property is set
const fieldDefault = formOptions.fields[field].default
// Error if state not defined
if (!isDef(fieldDefault)) this.$root.log('error', `Component extending BaseForm: field '${field}' must have 'default' value.`)
/**
* Add field to data
*/
dataOptions.form.fields[field] = {
value: null, // hydrate value at "created" hook, see below
errors: null
}
/**
* value
*/
// Create name of computed for value
const computedFieldValueName = this.$h.camelize(field + '_value')
// Assign computed
computedOptions[computedFieldValueName] = {
get () {
return this.form.fields[field].value
},
set (value) {
this.form.fields[field].value = value
}
}
/**
* changed
*/
// Create name of computed for changed status
const computedFieldChangedName = this.$h.camelize(field + '_changed')
// Assign computed
computedOptions[computedFieldChangedName] = function () {
if (this.$options.form.fields[field].changed) {
return this.$options.form.fields[field].changed.call(this)
}
return this[computedFieldValueName] !== this.$options.form.fields[field].default.call(this)
}
/**
* state
*/
// Check if 'state' property is set
const fieldState = formOptions.fields[field].state
// Create name of computed for state
const computedFieldStateName = this.$h.camelize(field + '_state')
// Prepare computed
let stateComputed = null
// Warning if state not defined
if (!isDef(fieldState)) {
this.$root.log('warning', `Warning! Component extending BaseForm: field '${field}' doesn't have 'state' property. Generate '${computedFieldStateName}' default computed (returns true).`, { prod: false })
// Default returning true
stateComputed = function () { return true }
} else {
// Else: field defined state function
stateComputed = fieldState
}
// Assign computed
computedOptions[computedFieldStateName] = stateComputed
/**
* isValid
*/
// Check if 'isValid' property is set
const fieldIsValid = formOptions.fields[field].isValid
// Create name of computed for isValid
const computedFieldIsValidName = this.$h.camelize('is_' + field + '_valid')
// Prepare computed
let isValidComputed = null
if (!isDef(fieldIsValid)) {
this.$root.log('warning', `Warning! Component extending BaseForm: field '${field}' doesn't have 'isValid' property. Generate '${computedFieldIsValidName}' default computed (returns true).`, { prod: false })
isValidComputed = function () {
return true
}
} else {
// Else: field defined isValid function
isValidComputed = fieldIsValid
}
computedOptions[computedFieldIsValidName] = isValidComputed
}
}
}
// Assign data
this.$options.data = function () {
return dataOptions
}
// Get computed
this.$options.computed = computedOptions
},
created () {
this.resetForm() // Setup form first time
}
}