PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 3.1.6
JetFormBuilder — Dynamic Blocks Form Builder v3.1.6
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / assets / src / frontend / main / reporting / ReportingInterface.js
jetformbuilder / assets / src / frontend / main / reporting Last commit date
restrictions 2 years ago BrowserReporting.js 2 years ago ReportingContext.js 2 years ago ReportingInterface.js 2 years ago RestrictionError.js 2 years ago functions.js 2 years ago
ReportingInterface.js
261 lines
1 /**
2 * Validation logic: on change input value we run
3 * @see ReportingInterface.validateOnChange
4 *
5 * In that function we clear stored errors
6 * @see ReportingInterface.errors
7 * check all restrictions again and save errors
8 * to the same property.
9 *
10 * When user tries to submit form we run
11 * @see ReportingInterface.validate
12 * If there was stored errors - it will return them.
13 * Otherwise we check all and save errors.
14 *
15 * In the case when we run the validation through the
16 * @see ReportingInterface.isValid
17 * We "block the form" through the "test" property.
18 * This property is reactive, and when it changes,
19 * the state of the button for submitting the form
20 * and the navigation buttons between pages changes.
21 *
22 */
23 import RestrictionError from './RestrictionError';
24 import ReactiveVar from '../reactive/ReactiveVar';
25
26 function ReportingInterface() {
27 /**
28 * @type {InputData}
29 */
30 this.input = null;
31 this.isRequired = false;
32 /**
33 * @type {array|null}
34 */
35 this.errors = null;
36 this.restrictions = [];
37
38 this.valuePrev = null;
39 this.validityState = null;
40 this.promisesCount = 0;
41 }
42
43 ReportingInterface.prototype = {
44 /**
45 * @type {Restriction[]}
46 */
47 restrictions: [],
48 valuePrev: null,
49 /**
50 * @type {ReactiveVar}
51 */
52 validityState: null,
53 promisesCount: 0,
54 /**
55 * Runs on changing value in the field
56 * @see InputData.onChange
57 */
58 validateOnChange: function () {
59 },
60 validateOnBlur: function () {
61 },
62 /**
63 * Runs on trying to submit form
64 * @see Observable.inputsAreValid
65 *
66 * Runs on changing value, if this field inside page
67 * @see InputData.setPage
68 * @see PageState.updateState
69 *
70 * @returns {Promise<boolean>}
71 */
72 validate: async function () {
73 const errors = await this.getErrors();
74
75 this.validityState.current = !Boolean( errors.length );
76
77 if ( !errors.length ) {
78 this.clearReport();
79
80 return true;
81 }
82
83 !this.input.root.getContext().silence && this.report( errors );
84
85 throw new RestrictionError( errors[ 0 ].name );
86 },
87 /**
88 * @param promises {Function[]}
89 * @return {Promise<array|null>}
90 */
91 getErrorsRaw: async function ( promises ) {
92 throw new Error( 'getError must return a Promise' );
93 },
94
95 /**
96 * @return {Promise<array|*[]|null>}
97 */
98 getErrors: async function () {
99 if (
100 this.input.loading.current ||
101 this.input?.callable?.lock?.current ||
102 !this.input.isVisible()
103 ) {
104 return [];
105 }
106
107 const promises = this.getPromises();
108
109 if (
110 !this.hasChangedValue() &&
111 this.promisesCount === promises.length
112 ) {
113 return this.errors ?? [];
114 }
115
116 this.promisesCount = promises.length;
117 this.errors = [];
118
119 if ( !promises.length ) {
120 return this.errors;
121 }
122
123 this.errors = await this.getErrorsRaw( promises );
124
125 return this.errors;
126 },
127 report: function ( validationErrors ) {
128 if ( this.input.getContext().reportedFirst ) {
129 this.reportRaw( validationErrors );
130
131 return;
132 }
133
134 this.input.getContext().reportFirst();
135
136 this.reportFirst( validationErrors );
137 },
138 /**
139 * @param validationErrors {Restriction[]}
140 * @return void
141 */
142 reportRaw: function ( validationErrors ) {
143 throw new Error( 'report is empty' );
144 },
145 reportFirst: function ( validationErrors ) {
146 this.report( validationErrors );
147 },
148 clearReport: function () {
149 throw new Error( 'clearReport is empty' );
150 },
151 getPromises: function () {
152 const promises = [];
153
154 for ( const restriction of this.restrictions ) {
155 if ( !this.canProcessRestriction( restriction ) ) {
156 continue;
157 }
158 this.beforeProcessRestriction( restriction );
159
160 promises.push( ( resolve, reject ) => {
161 restriction.validatePromise().
162 then( () => resolve( restriction ) ).
163 catch( error => reject( [ restriction, error ] ) );
164 } );
165 }
166
167 return promises;
168 },
169 /**
170 * @param restriction {Restriction}
171 * @return {Boolean}
172 */
173 canProcessRestriction: function ( restriction ) {
174 return true;
175 },
176
177 /**
178 * @param restriction {Restriction}
179 */
180 beforeProcessRestriction: function ( restriction ) {
181 },
182 /**
183 * @param node
184 * @param input
185 *
186 * @return {boolean}
187 */
188 isSupported: function ( node, input ) {
189 throw new Error( 'isSupported is empty' );
190 },
191 /**
192 * @param input {InputData}
193 */
194 setInput: function ( input ) {
195 this.validityState = new ReactiveVar();
196 this.validityState.make();
197
198 this.input = input;
199 this.setRestrictions();
200 this.filterRestrictions();
201 },
202 setRestrictions: function () {
203 },
204 /**
205 * @return {HTMLInputElement|HTMLElement}
206 */
207 getNode: function () {
208 return this.input.nodes[ 0 ];
209 },
210
211 hasChangedValue: function () {
212 return this.valuePrev !== this.input.getValue();
213 },
214 /**
215 * @returns {Promise<*>}
216 */
217 checkValidity: function () {
218 const isSilence = this.input.getContext().silence;
219
220 if ( null === this.validityState.current ) {
221 return this.validateOnChangeState();
222 }
223 if ( this.validityState.current ) {
224 return Promise.resolve();
225 }
226
227 if ( isSilence ) {
228 return Promise.reject();
229 }
230
231 !isSilence && this.report( this.errors || [] );
232
233 return Promise.reject();
234 },
235 /**
236 * @since 3.0.1
237 *
238 * @return {boolean}
239 */
240 hasAutoScroll: function () {
241 return false;
242 },
243 /**
244 * With the help of filters that add new restrictions,
245 * you can overwrite a particular restriction
246 * if the "type" property is defined in it
247 */
248 filterRestrictions: function() {
249 const map = {};
250
251 for ( let [ index, restriction ] of Object.entries( this.restrictions ) ) {
252 index = restriction.getType() ? restriction.getType() : index;
253
254 map[ index ] = restriction;
255 }
256
257 this.restrictions = Object.values( map );
258 }
259 };
260
261 export default ReportingInterface;