140 lines
3.3 KiB
JavaScript
140 lines
3.3 KiB
JavaScript
import Modifier from 'ember-modifier';
|
|
import { action } from '@ember/object';
|
|
|
|
class ValidationError extends Error {}
|
|
|
|
export default class ValidateModifier extends Modifier {
|
|
|
|
item = null;
|
|
hash = null;
|
|
|
|
validate(value, validations = {}) {
|
|
if(Object.keys(validations).length === 0) {
|
|
return;
|
|
}
|
|
const errors = {};
|
|
Object.entries(this.hash.validations)
|
|
// filter out strings, for now these are helps, but ain't great if someone has a item.help
|
|
.filter(([key, value]) => typeof value !== 'string')
|
|
.forEach(([key, item]) => {
|
|
// optionally set things for you
|
|
if(this.item) {
|
|
this.item[key] = value;
|
|
}
|
|
(item || []).forEach((validation) => {
|
|
const re = new RegExp(validation.test);
|
|
if(!re.test(value)) {
|
|
errors[key] = new ValidationError(validation.error);
|
|
}
|
|
});
|
|
});
|
|
const state = this.hash.chart.state;
|
|
if(state.context == null) {
|
|
state.context = {};
|
|
}
|
|
if(Object.keys(errors).length > 0) {
|
|
state.context.errors = errors;
|
|
this.hash.chart.dispatch("ERROR", state.context);
|
|
} else {
|
|
state.context.errors = null;
|
|
this.hash.chart.dispatch("RESET", state.context);
|
|
}
|
|
}
|
|
|
|
@action
|
|
reset(e) {
|
|
if(e.target.value.length === 0) {
|
|
const state = this.hash.chart.state;
|
|
if(!state.context) {
|
|
state.context = {};
|
|
}
|
|
if(!state.context.errors) {
|
|
state.context.errors = {};
|
|
}
|
|
Object.entries(this.hash.validations)
|
|
// filter out strings, for now these are helps, but ain't great if someone has a item.help
|
|
.filter(([key, value]) => typeof value !== 'string')
|
|
.forEach(([key, item]) => {
|
|
if(typeof state.context.errors[key] !== 'undefined') {
|
|
delete state.context.errors[key];
|
|
}
|
|
});
|
|
if(Object.keys(state.context.errors).length === 0) {
|
|
state.context.errors = null;
|
|
this.hash.chart.dispatch("RESET", state.context);
|
|
}
|
|
}
|
|
}
|
|
|
|
async connect([value], _hash) {
|
|
this.element.addEventListener(
|
|
'input',
|
|
this.listen
|
|
);
|
|
this.element.addEventListener(
|
|
'blur',
|
|
this.reset
|
|
);
|
|
if(this.element.value.length > 0) {
|
|
await Promise.resolve();
|
|
if(this && this.element) {
|
|
this.validate(this.element.value, this.hash.validations);
|
|
}
|
|
}
|
|
}
|
|
|
|
@action
|
|
listen(e) {
|
|
this.validate(e.target.value, this.hash.validations);
|
|
}
|
|
|
|
disconnect() {
|
|
this.item = null;
|
|
this.hash = null;
|
|
this.element.removeEventListener(
|
|
'input',
|
|
this.listen
|
|
)
|
|
this.element.removeEventListener(
|
|
'blur',
|
|
this.reset
|
|
)
|
|
}
|
|
|
|
|
|
didReceiveArguments() {
|
|
const [value] = this.args.positional;
|
|
const _hash = this.args.named;
|
|
|
|
this.item = value;
|
|
this.hash = _hash;
|
|
|
|
if(typeof _hash.chart === 'undefined') {
|
|
this.hash.chart = {
|
|
state: {
|
|
context: {}
|
|
},
|
|
dispatch: (state) => {
|
|
switch(state) {
|
|
case 'ERROR':
|
|
_hash.onchange(this.hash.chart.state.context.errors);
|
|
break;
|
|
case 'RESET':
|
|
_hash.onchange();
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
didInstall() {
|
|
this.connect(this.args.positional, this.args.named);
|
|
}
|
|
|
|
willRemove() {
|
|
this.disconnect();
|
|
}
|
|
}
|