|
1 | 1 | // Patterns validate - Form vlidation
|
2 | 2 | import "../../core/polyfills"; // SubmitEvent.submitter for Safari < 15.4 and jsDOM
|
3 |
| -import $ from "jquery"; |
4 | 3 | import { BasePattern } from "../../core/basepattern";
|
5 | 4 | import Parser from "../../core/parser";
|
6 | 5 | import dom from "../../core/dom";
|
@@ -63,10 +62,56 @@ class Pattern extends BasePattern {
|
63 | 62 | { capture: true }
|
64 | 63 | );
|
65 | 64 |
|
66 |
| - this.initialize_inputs(); |
67 |
| - $(this.form).on("pat-update", () => { |
68 |
| - this.initialize_inputs(); |
69 |
| - }); |
| 65 | + // Input debouncer map: |
| 66 | + // - key: input element |
| 67 | + // - value: debouncer function |
| 68 | + // 1) We want do debounce the validation checks to avoid validating |
| 69 | + // while typing. |
| 70 | + // 2) We want to debounce the input events individually, so that we can |
| 71 | + // do multiple checks in parallel and show multiple errors at once. |
| 72 | + const input_debouncer_map = new Map(); |
| 73 | + const debounce_filter = (e) => { |
| 74 | + const input = e.target; |
| 75 | + if (input?.form !== this.form || ! this.inputs.includes(input)) { |
| 76 | + // Ignore events from other forms or from elements which are |
| 77 | + // not inputs. |
| 78 | + return; |
| 79 | + } |
| 80 | + |
| 81 | + if (! input_debouncer_map.has(input)) { |
| 82 | + // Create a new cancelable debouncer for this input. |
| 83 | + input_debouncer_map.set(input, utils.debounce((e) => { |
| 84 | + logger.debug("Checking input for event", input, e); |
| 85 | + this.check_input({ input: input, event: e }); |
| 86 | + }, this.options.delay)); |
| 87 | + } |
| 88 | + |
| 89 | + // Get the debouncer for this input. |
| 90 | + const debouncer = input_debouncer_map.get(input); |
| 91 | + // Debounce the validation check. |
| 92 | + debouncer(input, e); |
| 93 | + }; |
| 94 | + |
| 95 | + events.add_event_listener( |
| 96 | + document, |
| 97 | + "input", |
| 98 | + `pat-validation--${this.uuid}--input--validator`, |
| 99 | + (e) => debounce_filter(e) |
| 100 | + ); |
| 101 | + |
| 102 | + events.add_event_listener( |
| 103 | + document, |
| 104 | + "change", |
| 105 | + `pat-validation--${this.uuid}--change--validator`, |
| 106 | + (e) => debounce_filter(e) |
| 107 | + ); |
| 108 | + |
| 109 | + events.add_event_listener( |
| 110 | + document, |
| 111 | + "focusout", |
| 112 | + `pat-validation--${this.uuid}--focusout--validator`, |
| 113 | + (e) => debounce_filter(e) |
| 114 | + ); |
70 | 115 |
|
71 | 116 | // Set ``novalidate`` attribute to disable the browser's validation
|
72 | 117 | // bubbles but not disable the validation API.
|
@@ -94,35 +139,6 @@ class Pattern extends BasePattern {
|
94 | 139 | }
|
95 | 140 | }
|
96 | 141 |
|
97 |
| - initialize_inputs() { |
98 |
| - for (const [cnt, input] of this.inputs.entries()) { |
99 |
| - // Cancelable debouncer. |
100 |
| - const debouncer = utils.debounce((e) => { |
101 |
| - logger.debug("Checking input for event", input, e); |
102 |
| - this.check_input({ input: input, event: e }); |
103 |
| - }, this.options.delay); |
104 |
| - |
105 |
| - events.add_event_listener( |
106 |
| - input, |
107 |
| - "input", |
108 |
| - `pat-validation--input-${input.name}--${cnt}--validator`, |
109 |
| - (e) => debouncer(e) |
110 |
| - ); |
111 |
| - events.add_event_listener( |
112 |
| - input, |
113 |
| - "change", |
114 |
| - `pat-validation--change-${input.name}--${cnt}--validator`, |
115 |
| - (e) => debouncer(e) |
116 |
| - ); |
117 |
| - events.add_event_listener( |
118 |
| - input, |
119 |
| - "blur", |
120 |
| - `pat-validation--blur-${input.name}--${cnt}--validator`, |
121 |
| - (e) => debouncer(e) |
122 |
| - ); |
123 |
| - } |
124 |
| - } |
125 |
| - |
126 | 142 | check_input({
|
127 | 143 | input, // Input to check.
|
128 | 144 | event = null, // Optional event which triggered the check.
|
|
0 commit comments