mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
[wip] Form validation
This commit is contained in:
parent
a268e1a4ef
commit
86042827cc
@ -10,6 +10,7 @@
|
||||
:doc="doc"
|
||||
:fields="meta.fields"
|
||||
:layout="meta.layout"
|
||||
:invalid="invalid"
|
||||
/>
|
||||
<not-found v-if="notFound" />
|
||||
</div>
|
||||
@ -30,7 +31,8 @@ export default {
|
||||
return {
|
||||
docLoaded: false,
|
||||
notFound: false,
|
||||
invalid: false
|
||||
invalid: false,
|
||||
invalidFields: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -52,10 +54,9 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
async save() {
|
||||
if (!this.checkValidity()) {
|
||||
this.invalid = true;
|
||||
return;
|
||||
}
|
||||
this.setValidity();
|
||||
if (this.invalid) return;
|
||||
|
||||
try {
|
||||
if (this.doc._notInserted) {
|
||||
await this.doc.insert();
|
||||
@ -73,8 +74,18 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
checkValidity() {
|
||||
return true;
|
||||
onValidate(fieldname, isValid) {
|
||||
if (!isValid && !this.invalidFields.includes(fieldname)) {
|
||||
this.invalidFields.push(fieldname);
|
||||
} else if (isValid) {
|
||||
this.invalidFields = this.invalidFields.filter(invalidField => invalidField !== fieldname)
|
||||
}
|
||||
},
|
||||
|
||||
setValidity() {
|
||||
const form = this.$el.querySelector('form');
|
||||
let validity = form.checkValidity();
|
||||
this.invalid = !validity;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<form class="frappe-form-layout p-3">
|
||||
<form :class="['frappe-form-layout p-3', { 'was-validated': invalid }]">
|
||||
<div class="row" v-if="layout" v-for="(section, i) in layout" :key="i">
|
||||
<div class="col" v-for="(column, j) in section.columns" :key="j">
|
||||
<frappe-control
|
||||
@ -27,7 +27,7 @@ import FrappeControl from './controls/FrappeControl';
|
||||
|
||||
export default {
|
||||
name: 'FormLayout',
|
||||
props: ['doc', 'fields', 'layout'],
|
||||
props: ['doc', 'fields', 'layout', 'invalid'],
|
||||
data() {
|
||||
const dataObj = {};
|
||||
for (let df of this.fields) {
|
||||
|
@ -85,8 +85,6 @@ export default {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log(this.datatable)
|
||||
},
|
||||
destroyed() {
|
||||
this.datatable.destroy();
|
||||
@ -101,7 +99,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getRowDocs() {
|
||||
return this.rows.map((row, i) => {
|
||||
return (this.rows || []).map((row, i) => {
|
||||
const doc = new Observable();
|
||||
doc.set('idx', i);
|
||||
for (let fieldname in row) {
|
||||
|
@ -21,7 +21,7 @@ export default {
|
||||
this.awesomplete.list = await this.getList(e.target.value);
|
||||
},
|
||||
'awesomplete-select': e => {
|
||||
this.$emit('change', e.text.value);
|
||||
this.handleChange(e.text.value);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -69,13 +69,14 @@ export default {
|
||||
id: this.id,
|
||||
type: 'text',
|
||||
placeholder: '',
|
||||
value: this.value
|
||||
value: this.value,
|
||||
required: this.docfield.required
|
||||
}
|
||||
},
|
||||
getInputListeners() {
|
||||
return {
|
||||
change: (e) => {
|
||||
this.$emit('change', this.parseValue(e.target.value));
|
||||
this.handleChange(e.target.value);
|
||||
}
|
||||
};
|
||||
},
|
||||
@ -85,7 +86,16 @@ export default {
|
||||
getDomProps() {
|
||||
return null;
|
||||
},
|
||||
parseValue(value) {
|
||||
async handleChange(value) {
|
||||
value = this.parse(value);
|
||||
const isValid = await this.validate(value);
|
||||
this.$refs.input.setCustomValidity(isValid === false ? 'error' : '');
|
||||
this.$emit('change', value);
|
||||
},
|
||||
validate() {
|
||||
return true;
|
||||
},
|
||||
parse(value) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@ -12,13 +12,19 @@ export default {
|
||||
getInputListeners() {
|
||||
return {
|
||||
change: e => {
|
||||
this.$emit('change', e.target.value)
|
||||
this.handleChange(e.target.value);
|
||||
},
|
||||
focus: e => {
|
||||
setTimeout(() => this.$refs.input.select(), 100);
|
||||
}
|
||||
};
|
||||
},
|
||||
validate(value) {
|
||||
return !isNaN(value);
|
||||
},
|
||||
parse(value) {
|
||||
return Number(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -8,7 +8,8 @@ export default {
|
||||
},
|
||||
getInputAttrs() {
|
||||
return {
|
||||
id: this.id
|
||||
id: this.id,
|
||||
required: this.docfield.required
|
||||
};
|
||||
},
|
||||
getInputChildren(h) {
|
||||
|
@ -9,6 +9,7 @@ export default {
|
||||
getInputAttrs() {
|
||||
return {
|
||||
id: this.id,
|
||||
required: this.docfield.required,
|
||||
rows: 3
|
||||
};
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user