1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.FormWithConstraints = void 0;
|
4 | const React = require("react");
|
5 | const prop_types_1 = require("prop-types");
|
6 | const assert_1 = require("./assert");
|
7 | const FieldsStore_1 = require("./FieldsStore");
|
8 | const InputElement_1 = require("./InputElement");
|
9 | const notUndefined_1 = require("./notUndefined");
|
10 | const withFieldDidResetEventEmitter_1 = require("./withFieldDidResetEventEmitter");
|
11 | const withFieldDidValidateEventEmitter_1 = require("./withFieldDidValidateEventEmitter");
|
12 | const withFieldWillValidateEventEmitter_1 = require("./withFieldWillValidateEventEmitter");
|
13 | const withValidateFieldEventEmitter_1 = require("./withValidateFieldEventEmitter");
|
14 | class FormWithConstraintsComponent extends React.PureComponent {
|
15 | }
|
16 | class FormWithConstraints extends (0, withFieldDidResetEventEmitter_1.withFieldDidResetEventEmitter)((0, withFieldWillValidateEventEmitter_1.withFieldWillValidateEventEmitter)((0, withFieldDidValidateEventEmitter_1.withFieldDidValidateEventEmitter)((0, withValidateFieldEventEmitter_1.withValidateFieldEventEmitter)(FormWithConstraintsComponent)))) {
|
17 | constructor() {
|
18 | super(...arguments);
|
19 | this.form = null;
|
20 | this.fieldsStore = new FieldsStore_1.FieldsStore();
|
21 | this.fieldFeedbacksKeyCounter = 0;
|
22 | }
|
23 | getChildContext() {
|
24 | return {
|
25 | form: this
|
26 | };
|
27 | }
|
28 | computeFieldFeedbacksKey() {
|
29 | return `${this.fieldFeedbacksKeyCounter++}`;
|
30 | }
|
31 | validateFields(...inputsOrNames) {
|
32 | return this._validateFields(true, ...inputsOrNames);
|
33 | }
|
34 | validateForm() {
|
35 | return this.validateFieldsWithoutFeedback();
|
36 | }
|
37 | validateFieldsWithoutFeedback(...inputsOrNames) {
|
38 | return this._validateFields(false, ...inputsOrNames);
|
39 | }
|
40 | async _validateFields(forceValidateFields, ...inputsOrNames) {
|
41 | const fields = new Array();
|
42 | const inputs = this.normalizeInputs(...inputsOrNames);
|
43 | for (let i = 0; i < inputs.length; i++) {
|
44 | const input = inputs[i];
|
45 | const field = await this.validateField(forceValidateFields, new InputElement_1.InputElement(input), input);
|
46 | if (field !== undefined)
|
47 | fields.push(field);
|
48 | }
|
49 | return fields;
|
50 | }
|
51 | async validateField(forceValidateFields, input, nativeInput) {
|
52 | const fieldName = input.name;
|
53 | const field = this.fieldsStore.getField(fieldName);
|
54 | if (field === undefined) {
|
55 | }
|
56 | else if (forceValidateFields || !field.hasFeedbacks()) {
|
57 | field.element = nativeInput;
|
58 | field.clearValidations();
|
59 | this.emitFieldWillValidateEvent(fieldName);
|
60 | const arrayOfArrays = await this.emitValidateFieldEvent(input);
|
61 | (0, assert_1.assert)(JSON.stringify(arrayOfArrays.flat(Number.POSITIVE_INFINITY).filter(fieldFeedback => (0, notUndefined_1.notUndefined)(fieldFeedback))) ===
|
62 | JSON.stringify(field.validations), `FieldsStore does not match emitValidateFieldEvent() result, did the user changed the input rapidly?`);
|
63 | this.emitFieldDidValidateEvent(field);
|
64 | }
|
65 | return field;
|
66 | }
|
67 | normalizeInputs(...inputsOrNames) {
|
68 | let inputs;
|
69 | if (inputsOrNames.length === 0) {
|
70 | inputs = Array.from(this.form.querySelectorAll('[name]'));
|
71 | inputs = inputs.filter(input => input.validity !== undefined);
|
72 | inputs
|
73 | .filter(input => input.type !== 'checkbox' && input.type !== 'radio')
|
74 | .map(input => input.name)
|
75 | .forEach((name, index, self) => {
|
76 | if (self.indexOf(name) !== index) {
|
77 | throw new Error(`Multiple elements matching '[name="${name}"]' inside the form`);
|
78 | }
|
79 | });
|
80 | }
|
81 | else {
|
82 | inputs = inputsOrNames.map(input => {
|
83 | if (typeof input === 'string') {
|
84 | const query = `[name="${input}"]`;
|
85 | const elements = Array.from(this.form.querySelectorAll(query));
|
86 | if (elements.some(el => el.validity === undefined)) {
|
87 | throw new Error(`'${query}' should match an <input>, <select> or <textarea>`);
|
88 | }
|
89 | if (elements.filter(el => el.type !== 'checkbox' && el.type !== 'radio').length > 1) {
|
90 | throw new Error(`Multiple elements matching '${query}' inside the form`);
|
91 | }
|
92 | const element = elements[0];
|
93 | if (element === undefined) {
|
94 | throw new Error(`Could not find field '${query}' inside the form`);
|
95 | }
|
96 | return element;
|
97 | }
|
98 | return input;
|
99 | });
|
100 | }
|
101 | return inputs;
|
102 | }
|
103 | isValid() {
|
104 | return this.fieldsStore.isValid();
|
105 | }
|
106 | hasFeedbacks() {
|
107 | return this.fieldsStore.hasFeedbacks();
|
108 | }
|
109 | reset() {
|
110 | return this.resetFields();
|
111 | }
|
112 | resetFields(...inputsOrNames) {
|
113 | const fields = new Array();
|
114 | const inputs = this.normalizeInputs(...inputsOrNames);
|
115 | inputs.forEach(input => {
|
116 | const field = this.resetField(new InputElement_1.InputElement(input));
|
117 | if (field !== undefined)
|
118 | fields.push(field);
|
119 | });
|
120 | return fields;
|
121 | }
|
122 | resetField(input) {
|
123 | const fieldName = input.name;
|
124 | const field = this.fieldsStore.getField(fieldName);
|
125 | if (field === undefined) {
|
126 | }
|
127 | else {
|
128 | field.clearValidations();
|
129 | this.emitFieldDidResetEvent(field);
|
130 | }
|
131 | return field;
|
132 | }
|
133 | render() {
|
134 | return React.createElement("form", { ref: form => (this.form = form), ...this.props });
|
135 | }
|
136 | }
|
137 | exports.FormWithConstraints = FormWithConstraints;
|
138 | FormWithConstraints.childContextTypes = {
|
139 | form: (0, prop_types_1.instanceOf)(FormWithConstraints).isRequired
|
140 | };
|