Repository URL to install this package:
|
Version:
0.3.0 ▾
|
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
var _createClass = (function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var _immutable = require('immutable');
var _immutable2 = _interopRequireDefault(_immutable);
var _invariant = require('invariant');
var _invariant2 = _interopRequireDefault(_invariant);
var _typecheckTypecheck = require('../typecheck/typecheck');
var _typecheckTypecheck2 = _interopRequireDefault(_typecheckTypecheck);
var _eventemitter2 = require('eventemitter2');
var _eventemitter22 = _interopRequireDefault(_eventemitter2);
var _lodashAssign = require('lodash.assign');
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
var Emit = _eventemitter22['default'].EventEmitter2 || _eventemitter22['default'];
var ValidatorStore = (function () {
/**
* In earlier iterations of validators, we used to require
* that blank validators also include the substantive
* validators. We improve (fix) this by now allowing blank
* validators to be specified separately.
*
* @param actions
* @param {Validator} validator: an object of class Validator that produces
* validations.
* @param {Object.<string, boolean>} options: options for when to validate things.
*/
function ValidatorStore(actions, validator, options) {
_classCallCheck(this, ValidatorStore);
options = options || {};
var defaultOptions = {
recomputeOnAllBlurs: true,
recomputeOnBlurIfKeyExists: true,
recomputeOnAllChanges: false,
recomputeOnChangeIfKeyExists: true,
recomputeOnFormSubmission: true
};
options = (0, _lodashAssign2['default'])(defaultOptions, options);
this.recomputeOnAllBlurs = options.recomputeOnAllBlurs;
this.recomputeOnBlurIfKeyExists = options.recomputeOnBlurIfKeyExists;
this.recomputeOnAllChanges = options.recomputeOnAllChanges;
this.recomputeOnChangeIfKeyExists = options.recomputeOnChangeIfKeyExists;
this.recomputeOnFormSubmission = options.recomputeOnFormSubmission;
// Model.
// We set the list of _errors directly so that we do
// not trigger the setter.
this._messages = _immutable2['default'].List();
this.formData = _immutable2['default'].Map();
this.validateBlankFields = false;
// Validator!
this.validator = validator;
actions.emitters.formFieldChanged.onAny(this.handleFormFieldChanged.bind(this));
actions.emitters.formFieldBlurred.onAny(this.handleFormFieldBlurred.bind(this));
actions.emitters.formFieldDeleted.onAny(this.handleFormFieldDeleted.bind(this));
actions.emitters.formSubmitted.onAny(this.handleFormSubmitted.bind(this));
actions.emitters.externalErrorsReceived.onAny(this.handleExternalErrorsReceived.bind(this));
this.changeEmitter = new Emit({
maxListeners: 1
});
}
// The pseudoproperty errors is a wrapped version
// of _errors.
_createClass(ValidatorStore, [{
key: 'handleExternalErrorsReceived',
/**
* External errors can only be received when
* there are no internal errors, because there
* must be no internal errors when the form
* is submitted. Recall that the setter takes care
* of sending the message.
*
* Also, note that external errors will persist until
* the field update satisfies the internal errors
* condition.
*
* @param errors
*/
value: function handleExternalErrorsReceived(errors) {
(0, _invariant2['default'])(_typecheckTypecheck2['default'].checkErrorsFormat(errors), 'External errors must be provided\n in the form Immutable.Map<string, Immutable.List<string>>. Instead,\n ' + errors + ' was received.');
this.messages = errors;
}
/* We only want to validate on change if the field being
changed exists as a key in the errors map. This allows
users to fill out an empty form (while changing form
fields) without triggering errors.
If the key exists, then we can assume that the user has
already triggered a validation of the field (through
blurring or otherwise) so we are safe to validate it. This
also allows instant auto-correction of errors. If an
error is fixed while the user is typing, they are
immediately informed.
*/
}, {
key: 'handleFormFieldChanged',
value: function handleFormFieldChanged(name, value) {
this.formData = this.formData.set(name, value);
if (this.recomputeOnAllChanges || this.recomputeOnChangeIfKeyExists && this.messages.has(name)) {
this.messages = this.validate();
}
}
}, {
key: 'handleFormFieldDeleted',
value: function handleFormFieldDeleted(name) {
this.formData = this.formData['delete'](name);
if (this.recomputeOnAllChanges || this.recomputeOnChangeIfKeyExists && this.messages.has(name)) {
this.messages = this.validate();
}
}
// But we always want to validate on blur, because we can
// reasonably assume that the user has completed the input
// for that field at that point.
}, {
key: 'handleFormFieldBlurred',
value: function handleFormFieldBlurred(name) {
if (this.recomputeOnAllBlurs || this.recomputeOnBlurIfKeyExists && this.messages.has(name)) {
this.messages = this.validate();
}
}
}, {
key: 'handleFormSubmitted',
value: function handleFormSubmitted() {
this.validateBlankFields = true;
if (this.recomputeOnFormSubmission) {
this.messages = this.validate();
}
}
}, {
key: 'validate',
value: function validate() {
return this.validator.validate(this.formData, this.validateBlankFields);
}
}, {
key: 'messages',
get: function get() {
return this._messages;
},
/**
* This setter does three things.
* 1. Checks that the errors are in the right format
* 2. Sets the errors
* 3. Fires an event noting that the errors are changed.
* @param listOfMessages
*/
set: function set(listOfMessages) {
(0, _invariant2['default'])(_typecheckTypecheck2['default'].checkErrorsFormat(listOfMessages), 'Messages must be provided\n in the form Immutable.Map<string, Immutable.List<string>>. Instead,\n ' + listOfMessages + ' was received.');
this._messages = listOfMessages;
this.changeEmitter.emit('', this._messages);
}
}]);
return ValidatorStore;
})();
exports['default'] = ValidatorStore;
module.exports = exports['default'];