vant
Version:
Mobile UI Components built on Vue
200 lines (184 loc) • 4.89 kB
JavaScript
import { createNamespace } from '../utils';
import { sortChildren } from '../utils/vnodes';
var _createNamespace = createNamespace('form'),
createComponent = _createNamespace[0],
bem = _createNamespace[1];
export default createComponent({
props: {
colon: Boolean,
disabled: Boolean,
readonly: Boolean,
labelWidth: [Number, String],
labelAlign: String,
inputAlign: String,
scrollToError: Boolean,
validateFirst: Boolean,
errorMessageAlign: String,
submitOnEnter: {
type: Boolean,
default: true
},
validateTrigger: {
type: String,
default: 'onBlur'
},
showError: {
type: Boolean,
default: true
},
showErrorMessage: {
type: Boolean,
default: true
}
},
provide: function provide() {
return {
vanForm: this
};
},
data: function data() {
return {
fields: []
};
},
methods: {
getFieldsByNames: function getFieldsByNames(names) {
if (names) {
return this.fields.filter(function (field) {
return names.indexOf(field.name) !== -1;
});
}
return this.fields;
},
validateSeq: function validateSeq(names) {
var _this = this;
return new Promise(function (resolve, reject) {
var errors = [];
var fields = _this.getFieldsByNames(names);
fields.reduce(function (promise, field) {
return promise.then(function () {
if (!errors.length) {
return field.validate().then(function (error) {
if (error) {
errors.push(error);
}
});
}
});
}, Promise.resolve()).then(function () {
if (errors.length) {
reject(errors);
} else {
resolve();
}
});
});
},
validateFields: function validateFields(names) {
var _this2 = this;
return new Promise(function (resolve, reject) {
var fields = _this2.getFieldsByNames(names);
Promise.all(fields.map(function (item) {
return item.validate();
})).then(function (errors) {
errors = errors.filter(function (item) {
return item;
});
if (errors.length) {
reject(errors);
} else {
resolve();
}
});
});
},
// @exposed-api
validate: function validate(name) {
if (name && !Array.isArray(name)) {
return this.validateField(name);
}
return this.validateFirst ? this.validateSeq(name) : this.validateFields(name);
},
validateField: function validateField(name) {
var matched = this.fields.filter(function (item) {
return item.name === name;
});
if (matched.length) {
return new Promise(function (resolve, reject) {
matched[0].validate().then(function (error) {
if (error) {
reject(error);
} else {
resolve();
}
});
});
}
return Promise.reject();
},
// @exposed-api
resetValidation: function resetValidation(name) {
if (name && !Array.isArray(name)) {
name = [name];
}
var fields = this.getFieldsByNames(name);
fields.forEach(function (item) {
item.resetValidation();
});
},
// @exposed-api
scrollToField: function scrollToField(name, options) {
this.fields.some(function (item) {
if (item.name === name) {
item.$el.scrollIntoView(options);
return true;
}
return false;
});
},
addField: function addField(field) {
this.fields.push(field);
sortChildren(this.fields, this);
},
removeField: function removeField(field) {
this.fields = this.fields.filter(function (item) {
return item !== field;
});
},
getValues: function getValues() {
return this.fields.reduce(function (form, field) {
form[field.name] = field.formValue;
return form;
}, {});
},
onSubmit: function onSubmit(event) {
event.preventDefault();
this.submit();
},
// @exposed-api
submit: function submit() {
var _this3 = this;
var values = this.getValues();
this.validate().then(function () {
_this3.$emit('submit', values);
}).catch(function (errors) {
_this3.$emit('failed', {
values: values,
errors: errors
});
if (_this3.scrollToError) {
_this3.scrollToField(errors[0].name);
}
});
}
},
render: function render() {
var h = arguments[0];
return h("form", {
"class": bem(),
"on": {
"submit": this.onSubmit
}
}, [this.slots()]);
}
});