@@ -21,6 +21,8 @@ export default class AutoCheckElement extends HTMLElement {
21
21
const state = { check : checker , controller : null , previousValue : null }
22
22
states . set ( this , state )
23
23
24
+ input . addEventListener ( 'change' , setLoadingState )
25
+ input . addEventListener ( 'input' , setLoadingState )
24
26
input . addEventListener ( 'change' , checker )
25
27
input . addEventListener ( 'input' , checker )
26
28
input . autocomplete = 'off'
@@ -35,6 +37,8 @@ export default class AutoCheckElement extends HTMLElement {
35
37
if ( ! state ) return
36
38
states . delete ( this )
37
39
40
+ input . removeEventListener ( 'change' , setLoadingState )
41
+ input . removeEventListener ( 'input' , setLoadingState )
38
42
input . removeEventListener ( 'change' , state . check )
39
43
input . removeEventListener ( 'input' , state . check )
40
44
input . setCustomValidity ( '' )
@@ -91,6 +95,36 @@ export default class AutoCheckElement extends HTMLElement {
91
95
}
92
96
}
93
97
98
+ function setLoadingState ( event : Event ) {
99
+ const input = event . currentTarget
100
+ if ( ! ( input instanceof HTMLInputElement ) ) return
101
+
102
+ const autoCheckElement = input . closest ( 'auto-check' )
103
+ if ( ! ( autoCheckElement instanceof AutoCheckElement ) ) return
104
+
105
+ const src = autoCheckElement . src
106
+ const csrf = autoCheckElement . csrf
107
+ const state = states . get ( autoCheckElement )
108
+
109
+ // If some attributes are missing we want to exit early and make sure that the element is valid.
110
+ if ( ! src || ! csrf || ! state ) {
111
+ return
112
+ }
113
+
114
+ let message = 'Verifying…'
115
+ const setValidity = text => ( message = text )
116
+ input . dispatchEvent (
117
+ new CustomEvent ( 'auto-check-start' , {
118
+ bubbles : true ,
119
+ detail : { setValidity}
120
+ } )
121
+ )
122
+
123
+ if ( autoCheckElement . required ) {
124
+ input . setCustomValidity ( message )
125
+ }
126
+ }
127
+
94
128
function makeAbortController ( ) {
95
129
if ( 'AbortController' in window ) {
96
130
return new AbortController ( )
@@ -114,19 +148,22 @@ async function fetchWithNetworkEvents(el: Element, url: string, options: Request
114
148
}
115
149
116
150
async function check ( autoCheckElement : AutoCheckElement ) {
117
- const src = autoCheckElement . src
118
- if ( ! src ) {
119
- throw new Error ( 'missing src' )
120
- }
121
- const csrf = autoCheckElement . csrf
122
- if ( ! csrf ) {
123
- throw new Error ( 'missing csrf' )
124
- }
125
151
const input = autoCheckElement . input
126
- if ( ! input ) return
152
+ if ( ! input ) {
153
+ return
154
+ }
127
155
156
+ const src = autoCheckElement . src
157
+ const csrf = autoCheckElement . csrf
128
158
const state = states . get ( autoCheckElement )
129
- if ( ! state ) return
159
+
160
+ // If some attributes are missing we want to exit early and make sure that the element is valid.
161
+ if ( ! src || ! csrf || ! state ) {
162
+ if ( autoCheckElement . required ) {
163
+ input . setCustomValidity ( '' )
164
+ }
165
+ return
166
+ }
130
167
131
168
const body = new FormData ( )
132
169
body . append ( 'authenticity_token' , csrf )
@@ -136,24 +173,20 @@ async function check(autoCheckElement: AutoCheckElement) {
136
173
if ( id && id === state . previousValue ) return
137
174
state . previousValue = id
138
175
139
- let message = 'Verifying…'
140
- const setValidity = text => ( message = text )
176
+ if ( ! input . value . trim ( ) ) {
177
+ if ( autoCheckElement . required ) {
178
+ input . setCustomValidity ( '' )
179
+ }
180
+ return
181
+ }
182
+
141
183
input . dispatchEvent (
142
184
new CustomEvent ( 'auto-check-send' , {
143
185
bubbles : true ,
144
- detail : { body, setValidity }
186
+ detail : { body}
145
187
} )
146
188
)
147
189
148
- if ( ! input . value . trim ( ) ) {
149
- input . dispatchEvent ( new CustomEvent ( 'auto-check-complete' , { bubbles : true } ) )
150
- return
151
- }
152
-
153
- if ( autoCheckElement . required ) {
154
- input . setCustomValidity ( message )
155
- }
156
-
157
190
if ( state . controller ) {
158
191
state . controller . abort ( )
159
192
} else {
0 commit comments