|  | 
| 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