UNPKG

react-form-with-constraints

Version:
141 lines (140 loc) 6.02 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FormWithConstraints = void 0; const React = require("react"); const prop_types_1 = require("prop-types"); const assert_1 = require("./assert"); const FieldsStore_1 = require("./FieldsStore"); const InputElement_1 = require("./InputElement"); const notUndefined_1 = require("./notUndefined"); const withFieldDidResetEventEmitter_1 = require("./withFieldDidResetEventEmitter"); const withFieldDidValidateEventEmitter_1 = require("./withFieldDidValidateEventEmitter"); const withFieldWillValidateEventEmitter_1 = require("./withFieldWillValidateEventEmitter"); const withValidateFieldEventEmitter_1 = require("./withValidateFieldEventEmitter"); class FormWithConstraintsComponent extends React.PureComponent { } class FormWithConstraints extends (0, withFieldDidResetEventEmitter_1.withFieldDidResetEventEmitter)((0, withFieldWillValidateEventEmitter_1.withFieldWillValidateEventEmitter)((0, withFieldDidValidateEventEmitter_1.withFieldDidValidateEventEmitter)((0, withValidateFieldEventEmitter_1.withValidateFieldEventEmitter)(FormWithConstraintsComponent)))) { constructor() { super(...arguments); this.form = null; this.fieldsStore = new FieldsStore_1.FieldsStore(); this.fieldFeedbacksKeyCounter = 0; } getChildContext() { return { form: this }; } computeFieldFeedbacksKey() { return `${this.fieldFeedbacksKeyCounter++}`; } validateFields(...inputsOrNames) { return this._validateFields(true, ...inputsOrNames); } validateForm() { return this.validateFieldsWithoutFeedback(); } validateFieldsWithoutFeedback(...inputsOrNames) { return this._validateFields(false, ...inputsOrNames); } async _validateFields(forceValidateFields, ...inputsOrNames) { const fields = new Array(); const inputs = this.normalizeInputs(...inputsOrNames); for (let i = 0; i < inputs.length; i++) { const input = inputs[i]; const field = await this.validateField(forceValidateFields, new InputElement_1.InputElement(input), input); if (field !== undefined) fields.push(field); } return fields; } async validateField(forceValidateFields, input, nativeInput) { const fieldName = input.name; const field = this.fieldsStore.getField(fieldName); if (field === undefined) { } else if (forceValidateFields || !field.hasFeedbacks()) { field.element = nativeInput; field.clearValidations(); this.emitFieldWillValidateEvent(fieldName); const arrayOfArrays = await this.emitValidateFieldEvent(input); (0, assert_1.assert)(JSON.stringify(arrayOfArrays.flat(Number.POSITIVE_INFINITY).filter(fieldFeedback => (0, notUndefined_1.notUndefined)(fieldFeedback))) === JSON.stringify(field.validations), `FieldsStore does not match emitValidateFieldEvent() result, did the user changed the input rapidly?`); this.emitFieldDidValidateEvent(field); } return field; } normalizeInputs(...inputsOrNames) { let inputs; if (inputsOrNames.length === 0) { inputs = Array.from(this.form.querySelectorAll('[name]')); inputs = inputs.filter(input => input.validity !== undefined); inputs .filter(input => input.type !== 'checkbox' && input.type !== 'radio') .map(input => input.name) .forEach((name, index, self) => { if (self.indexOf(name) !== index) { throw new Error(`Multiple elements matching '[name="${name}"]' inside the form`); } }); } else { inputs = inputsOrNames.map(input => { if (typeof input === 'string') { const query = `[name="${input}"]`; const elements = Array.from(this.form.querySelectorAll(query)); if (elements.some(el => el.validity === undefined)) { throw new Error(`'${query}' should match an <input>, <select> or <textarea>`); } if (elements.filter(el => el.type !== 'checkbox' && el.type !== 'radio').length > 1) { throw new Error(`Multiple elements matching '${query}' inside the form`); } const element = elements[0]; if (element === undefined) { throw new Error(`Could not find field '${query}' inside the form`); } return element; } return input; }); } return inputs; } isValid() { return this.fieldsStore.isValid(); } hasFeedbacks() { return this.fieldsStore.hasFeedbacks(); } reset() { return this.resetFields(); } resetFields(...inputsOrNames) { const fields = new Array(); const inputs = this.normalizeInputs(...inputsOrNames); inputs.forEach(input => { const field = this.resetField(new InputElement_1.InputElement(input)); if (field !== undefined) fields.push(field); }); return fields; } resetField(input) { const fieldName = input.name; const field = this.fieldsStore.getField(fieldName); if (field === undefined) { } else { field.clearValidations(); this.emitFieldDidResetEvent(field); } return field; } render() { return React.createElement("form", { ref: form => (this.form = form), ...this.props }); } } exports.FormWithConstraints = FormWithConstraints; FormWithConstraints.childContextTypes = { form: (0, prop_types_1.instanceOf)(FormWithConstraints).isRequired };