@@ -8,6 +8,14 @@ $(function() {
8
8
function initSearchAddress ( ) {
9
9
var idTimeoutInputAddress = null ;
10
10
var ajaxObject = null ;
11
+ var selectedSuggestionIndex = - 1 ;
12
+ var isAutocompleteOpen = false ;
13
+
14
+ $ ( document ) . on ( 'click' , function ( event ) {
15
+ if ( ! $ ( event . target ) . closest ( '.fr-autocomplete-list' ) . length && isAutocompleteOpen ) {
16
+ closeSuggestions ( ) ;
17
+ }
18
+ } ) ;
11
19
12
20
$ ( 'input#rechercheAdresse' ) . on ( 'input' , function ( ) {
13
21
if ( idTimeoutInputAddress !== null ) {
@@ -17,7 +25,7 @@ function initSearchAddress() {
17
25
ajaxObject . abort ( ) ;
18
26
}
19
27
20
- $ ( '#rechercheAdresseListe select ' ) . empty ( ) ;
28
+ $ ( '#rechercheAdresseListe' ) . empty ( ) ;
21
29
$ ( '#rechercheAdresseIcon .fr-icon-timer-line' ) . show ( ) ;
22
30
$ ( '#rechercheAdresseIcon .fr-icon-map-pin-2-line' ) . hide ( ) ;
23
31
@@ -30,6 +38,7 @@ function initSearchAddress() {
30
38
ajaxObject = $ . ajax ( {
31
39
url : 'https://api-adresse.data.gouv.fr/search/?q=' + searchField
32
40
} ) . done ( function ( jsonData ) {
41
+ let ariaPosinset = 1 ;
33
42
for ( let feature of jsonData . features ) {
34
43
let adresseLabel = feature . properties . label ;
35
44
let adresseName = feature . properties . name ;
@@ -46,7 +55,23 @@ function initSearchAddress() {
46
55
elementData += ' data-citycode="' + adresseCityCode + '"' ;
47
56
elementData += ' data-geoloclat="' + adresseGeolocLat + '"' ;
48
57
elementData += ' data-geoloclng="' + adresseGeolocLng + '"' ;
49
- $ ( '#rechercheAdresseListe select' ) . append ( '<option ' + elementData + ' class="fr-mb-1v fr-p-1v">' + adresseLabel + '</option>' ) ;
58
+
59
+ const setSize = jsonData . features . length ;
60
+ $ ( '#rechercheAdresseListe' )
61
+ . append (
62
+ '<li '
63
+ + elementData
64
+ + ' class="fr-col-12 fr-p-3v fr-text-label--blue-france fr-autocomplete-suggestion"'
65
+ + ' role="option" tabindex="-1"'
66
+ + ' aria-selected="false"'
67
+ + ' aria-posinset="' + ariaPosinset + '"'
68
+ + ' aria-setsize="' + setSize + '"'
69
+ + '>'
70
+ + adresseLabel
71
+ + '</li>' ) ;
72
+
73
+ ++ ariaPosinset ;
74
+
50
75
$ ( '#rechercheAdresseListe' ) . show ( ) ;
51
76
$ ( '#rechercheAdresseIcon .fr-icon-timer-line' ) . hide ( ) ;
52
77
$ ( '#rechercheAdresseIcon .fr-icon-map-pin-2-line' ) . show ( ) ;
@@ -59,8 +84,10 @@ function initSearchAddress() {
59
84
} ) ;
60
85
}
61
86
62
- $ ( '#rechercheAdresseListe select option' ) . on ( 'click' , function ( ) {
63
- let formPrefix = ( $ ( '#signalement_history_adresse' ) . length > 0 ) ? 'signalement_history' : 'signalement_front' ;
87
+ $ ( '#rechercheAdresseListe li' ) . on ( 'click' , function ( ) {
88
+ let formPrefix = ( $ ( '#signalement_history_adresse' ) . length > 0 )
89
+ ? 'signalement_history'
90
+ : 'signalement_front' ;
64
91
$ ( '#rechercheAdresse' ) . val ( $ ( this ) . data ( 'label' ) ) ;
65
92
$ ( '#' + formPrefix + '_adresse' ) . val ( $ ( this ) . data ( 'name' ) ) ;
66
93
$ ( '#' + formPrefix + '_codePostal' ) . val ( $ ( this ) . data ( 'postcode' ) ) ;
@@ -75,20 +102,27 @@ function initSearchAddress() {
75
102
}
76
103
} ) ;
77
104
}
105
+ isAutocompleteOpen = true ;
78
106
} ) ;
79
107
} ,
80
108
300
81
109
) ;
82
110
} ) ;
83
111
84
- $ ( '#rechercheAdresseListe select' ) . on ( 'keypress' , function ( e ) {
85
- var code = e . keyCode || e . which ;
86
- if ( code == 32 && $ ( '#rechercheAdresseListe' ) . is ( ':visible' ) ) {
87
- $ ( '#rechercheAdresseListe select option:selected' ) . trigger ( 'click' ) ;
88
- }
89
- } ) ;
90
- $ ( '#rechercheAdresseListe select' ) . on ( 'change' , function ( e ) {
91
- $ ( '#rechercheAdresseListe select option:selected' ) . trigger ( 'click' ) ;
112
+
113
+ $ ( 'input#rechercheAdresse' ) . on ( 'keydown' , function ( event ) {
114
+ if ( event . key === 'ArrowDown' ) {
115
+ event . preventDefault ( ) ;
116
+ handleDown ( ) ;
117
+ } else if ( event . key === 'ArrowUp' ) {
118
+ event . preventDefault ( ) ;
119
+ handleUp ( ) ;
120
+ } else if ( event . key === 'Enter' ) {
121
+ event . preventDefault ( ) ;
122
+ handleEnter ( ) ;
123
+ } else if ( event . key === 'Tab' ) {
124
+ closeSuggestions ( ) ;
125
+ }
92
126
} ) ;
93
127
94
128
$ ( '#toggle-skip-search-address' ) . on ( 'click' , function ( ) {
@@ -113,4 +147,68 @@ function initSearchAddress() {
113
147
$ ( '#adresse_afficher_les_champs button' ) . removeClass ( 'fr-icon-eye-off-line' ) ;
114
148
}
115
149
} ) ;
150
+
151
+ function handleDown ( ) {
152
+ const suggestions = $ ( '.fr-autocomplete-suggestion' ) ;
153
+ if ( selectedSuggestionIndex < suggestions . length - 1 ) {
154
+ selectedSuggestionIndex ++ ;
155
+ updateSelectedSuggestion ( ) ;
156
+ }
157
+ }
158
+
159
+ function handleUp ( ) {
160
+ if ( selectedSuggestionIndex > 0 ) {
161
+ selectedSuggestionIndex -- ;
162
+ updateSelectedSuggestion ( ) ;
163
+ }
164
+ }
165
+
166
+ function updateSelectedSuggestion ( ) {
167
+ const suggestions = $ ( '.fr-autocomplete-suggestion' ) ;
168
+ suggestions . each ( function ( index , suggestion ) {
169
+ if ( index === selectedSuggestionIndex ) {
170
+ $ ( suggestion )
171
+ . addClass ( 'fr-autocomplete-suggestion-highlighted' )
172
+ . attr ( 'aria-selected' , 'true' ) ;
173
+ } else {
174
+ $ ( suggestion )
175
+ . removeClass ( 'fr-autocomplete-suggestion-highlighted' )
176
+ . attr ( 'aria-selected' , 'false' ) ;
177
+ }
178
+ } ) ;
179
+ }
180
+
181
+ function handleEnter ( ) {
182
+ const suggestions = $ ( '.fr-autocomplete-suggestion' ) ;
183
+ if ( selectedSuggestionIndex !== - 1 ) {
184
+ let formPrefix = ( $ ( '#signalement_history_adresse' ) . length > 0 )
185
+ ? 'signalement_history'
186
+ : 'signalement_front' ;
187
+
188
+ $ ( '#rechercheAdresse' ) . val ( suggestions . eq ( selectedSuggestionIndex ) . data ( 'label' ) ) ;
189
+ $ ( '#' + formPrefix + '_adresse' ) . val ( suggestions . eq ( selectedSuggestionIndex ) . data ( 'name' ) ) ;
190
+ $ ( '#' + formPrefix + '_codePostal' ) . val ( suggestions . eq ( selectedSuggestionIndex ) . data ( 'postcode' ) ) ;
191
+ $ ( '#' + formPrefix + '_ville' ) . val ( suggestions . eq ( selectedSuggestionIndex ) . data ( 'city' ) ) ;
192
+ $ ( '#' + formPrefix + '_codeInsee' ) . val ( suggestions . eq ( selectedSuggestionIndex ) . data ( 'citycode' ) ) ;
193
+ let geoloc = suggestions . eq ( selectedSuggestionIndex ) . data ( 'geoloclat' )
194
+ + '|'
195
+ + suggestions . eq ( selectedSuggestionIndex ) . data ( 'geoloclng' ) ;
196
+
197
+ $ ( '#' + formPrefix + '_geoloc' ) . val ( geoloc ) ;
198
+
199
+ $ ( '#rechercheAdresseListe' ) . hide ( ) ;
200
+ if ( $ ( '.address-fields' ) . length > 0 ) {
201
+ $ ( '.address-fields' ) . removeClass ( 'fr-hidden' ) ;
202
+ $ ( '.skip-search-address' ) . hide ( ) ;
203
+ }
204
+
205
+ closeSuggestions ( ) ;
206
+ }
207
+ }
208
+
209
+ function closeSuggestions ( ) {
210
+ $ ( '.fr-autocomplete-list' ) . html ( '' ) ;
211
+ selectedSuggestionIndex = - 1 ;
212
+ isAutocompleteOpen = false ;
213
+ }
116
214
}
0 commit comments