UNPKG

tiny-mobx-form

Version:

Tiny (~2KB) tree-shakable MobX form library

415 lines (346 loc) 12.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tslib = require('tslib'); var mobx = require('mobx'); function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } var error = function error(isError, message) { if (message === void 0) { message = ''; } return isError ? message : undefined; }; var MESSAGES = { required: function required() { return "This field is required."; }, requiredIf: function requiredIf(dependentLabel, label) { return "The " + dependentLabel + " field is required since the " + label + " field is filled out."; }, length: function length(min, max) { return "Must be at least " + min + " and no more than " + max + " characters"; }, match: function match(label, matchingLabel) { return "The " + label + " and " + matchingLabel + " do not match."; }, letters: function letters() { return "Please enter letters only."; }, email: function email() { return "Please enter a valid email address."; }, phone: function phone() { return "Please enter a valid phone number."; }, postal: function postal() { return "Please enter a valid postal number."; }, number: function number() { return "Please enter a valid number."; }, alpha: function alpha() { return "Please do not use special characters."; }, size: function size(min, max) { return "Please enter a number between " + min + " and " + max + "."; }, oneOf: function oneOf(pool) { return "Please choose one of these choices: " + pool.join(', '); } }; var required = function required(field, message) { return error(!field.value, message || MESSAGES.required()); }; var requiredIf = function requiredIf(field, message, dependentFieldName) { return error(!(!!field.value && !!field.form.fields[dependentFieldName]), message || MESSAGES.requiredIf(field.form.fields[dependentFieldName].label, field.label)); }; var length = function length(field, message, min, max) { if (min === void 0) { min = 0; } if (max === void 0) { max = Infinity; } return error(!(!!field.value && field.value.length >= Number(min) && field.value.length <= Number(max)), message || MESSAGES.length(min.toString(10), max.toString(10))); }; var match = function match(field, message, matchingFieldName) { return error(field.value !== field.form.fields[matchingFieldName].value, message || MESSAGES.match(field.label, field.form.fields[matchingFieldName].label)); }; var LETTERS = /^[a-zA-Z\s]*$/; var letters = function letters(_ref, message) { var value = _ref.value; return error(!!value && !LETTERS.test(value), message || MESSAGES.letters()); }; var EMAIL = /^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/; var email = function email(_ref2, message) { var value = _ref2.value; return error(!!value && !EMAIL.test(value), message || MESSAGES.email()); }; var PHONE_NUMBER = /^(\()?[2-9]\d{2}(-|.|\))?\d{3}(-|.)?\d{4}$/; var phone = function phone(_ref3, message) { var value = _ref3.value; return error(!!value && !PHONE_NUMBER.test(value), message || MESSAGES.phone()); }; var POSTAL = /^\d{5}-\d{4}|\d{5}|[A-Z]\d[A-Z] \d[A-Z]\d$/; var postal = function postal(_ref4, message) { var value = _ref4.value; return error(!!value && !POSTAL.test(value), message || MESSAGES.postal()); }; var NUMBER = /^\d+$/; var numbers = function numbers(_ref5, message) { var value = _ref5.value; return error(!!value && !NUMBER.test(value), message || MESSAGES.number()); }; var ALPHA = /^\w+$/; var alpha = function alpha(_ref6, message) { var value = _ref6.value; return error(!!value && !ALPHA.test(value), message || MESSAGES.alpha()); }; var size = function size(_ref7, message, min, max) { var value = _ref7.value; if (min === void 0) { min = 0; } if (max === void 0) { max = Infinity; } return error(!!value && !(Number(value) >= min && Number(value) <= max), message || MESSAGES.size(min.toString(10), max.toString(10))); }; var oneOf = function oneOf(_ref8, message) { var value = _ref8.value; for (var _len = arguments.length, pool = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { pool[_key - 2] = arguments[_key]; } return error(!!value && !pool.includes(value), message || MESSAGES.oneOf(pool)); }; function validate(field, validatorMessages, validators) { if (!field.validation) return []; var validations = field.validation.split('|').filter(Boolean); return validations.map(function (validation) { var _validation$split = validation.split(':'), validator = _validation$split[0], argument = _validation$split[1]; var args = []; if (argument) { // Handle the arguments passed in args = argument.split(','); } if (!(validator in validators)) { throw new Error("There is no validator with the name of " + validator); } var message = validatorMessages && validator in validatorMessages ? validatorMessages[validator] : ''; return validators[validator].apply(validators, [field, message].concat(args)); }).filter(Boolean); } var validators = function validators(additionalValidators) { if (additionalValidators === void 0) { additionalValidators = {}; } return _extends({ required: required, 'required-if': requiredIf, length: length, letters: letters, email: email, match: match, numbers: numbers, phone: phone, postal: postal, alpha: alpha, size: size, 'one-of': oneOf }, additionalValidators); }; var Field = /*#__PURE__*/ function () { function Field(form, _ref, _ref2) { var name = _ref.name, _ref$label = _ref.label, label = _ref$label === void 0 ? '' : _ref$label, _ref$placeholder = _ref.placeholder, placeholder = _ref$placeholder === void 0 ? '' : _ref$placeholder, _ref$validation = _ref.validation, validation = _ref$validation === void 0 ? '' : _ref$validation, _ref$initialValue = _ref.initialValue, initialValue = _ref$initialValue === void 0 ? '' : _ref$initialValue, _ref$validationMessag = _ref.validationMessages, validationMessages = _ref$validationMessag === void 0 ? {} : _ref$validationMessag; var additionalValidators = _ref2.additionalValidators; this.form = form; this.isTouched = false; this.isFocused = false; this.name = name; this.label = label; this.placeholder = placeholder; this.initialValue = initialValue; this._value = initialValue; this.validation = validation; this.validators = additionalValidators; this.validationMessages = validationMessages; } var _proto = Field.prototype; _proto.reset = function reset() { this._value = this.initialValue; this.isTouched = false; this.isFocused = false; }; _createClass(Field, [{ key: "value", get: function get() { return this._value; }, set: function set(value) { this._value = value; this.isTouched = true; } }, { key: "isValid", get: function get() { return this.errors.length === 0; } }, { key: "isDirty", get: function get() { return this.initialValue !== this.value; } }, { key: "errors", get: function get() { return this.validators ? validate(this, this.validationMessages, this.validators) : []; } }, { key: "hasErrors", get: function get() { return this.errors.length > 0; } }]); return Field; }(); tslib.__decorate([mobx.observable], Field.prototype, "initialValue", void 0); tslib.__decorate([mobx.observable], Field.prototype, "isTouched", void 0); tslib.__decorate([mobx.observable], Field.prototype, "isFocused", void 0); tslib.__decorate([mobx.observable], Field.prototype, "validation", void 0); tslib.__decorate([mobx.observable], Field.prototype, "_value", void 0); tslib.__decorate([mobx.computed], Field.prototype, "value", null); tslib.__decorate([mobx.computed], Field.prototype, "isValid", null); tslib.__decorate([mobx.computed], Field.prototype, "isDirty", null); tslib.__decorate([mobx.computed], Field.prototype, "errors", null); tslib.__decorate([mobx.computed], Field.prototype, "hasErrors", null); tslib.__decorate([mobx.action('TinyMobxForm | Field | reset')], Field.prototype, "reset", null); var Form = /*#__PURE__*/ function () { function Form(fields, initialValues, options) { var _this = this; if (initialValues === void 0) { initialValues = {}; } if (options === void 0) { options = {}; } this.fields = {}; this.showErrors = function () { var hasSetFocus = false; _this.fieldNames.forEach(function (name) { _this.fields[name].isTouched = true; // Set the first invalid field we find to isFocused so we can focus on that field if (!_this.fields[name].isValid && !hasSetFocus) { _this.fields[name].isFocused = true; hasSetFocus = true; } }); }; this.reset = function () { _this.fieldNames.forEach(function (name) { return _this.fields[name].reset(); }); }; fields.forEach(function (props) { _this.fieldNames.push(props.name); var initialValue = initialValues[props.name] || props.initialValue; var newProps = _extends({}, props, { initialValue: initialValue }); _this.fields[newProps.name] = new Field(_this, newProps, { additionalValidators: validators(options.additionalValidators || {}) }); }); } _createClass(Form, [{ key: "fieldNames", get: function get() { return Object.keys(this.fields); } }, { key: "isValid", get: function get() { var _this2 = this; return this.fieldNames.filter(function (name) { return !_this2.fields[name].isValid; }).length === 0; } }, { key: "errors", get: function get() { var _this3 = this; return this.fieldNames.flatMap(function (name) { return _this3.fields[name].errors; }); } }, { key: "isDirty", get: function get() { var _this4 = this; return this.fieldNames.some(function (name) { return _this4.fields[name].isDirty; }); } }, { key: "values", get: function get() { var _this5 = this; return this.fieldNames.reduce(function (dataset, name) { var _extends2; return _extends({}, dataset, (_extends2 = {}, _extends2[name] = _this5.fields[name].value, _extends2)); }, {}); } }]); return Form; }(); tslib.__decorate([mobx.observable.struct], Form.prototype, "fields", void 0); tslib.__decorate([mobx.computed], Form.prototype, "fieldNames", null); tslib.__decorate([mobx.computed], Form.prototype, "isValid", null); tslib.__decorate([mobx.computed], Form.prototype, "errors", null); tslib.__decorate([mobx.computed], Form.prototype, "isDirty", null); tslib.__decorate([mobx.computed], Form.prototype, "values", null); tslib.__decorate([mobx.action('TinyMobXForm | showErrors')], Form.prototype, "showErrors", void 0); tslib.__decorate([mobx.action('TinyMobXForm | reset')], Form.prototype, "reset", void 0); exports.Field = Field; exports.Form = Form; //# sourceMappingURL=tiny-mobx-form.cjs.development.js.map