2323 searchPosition ,
2424 scrollValue = 0 ;
2525
26- // Makes sure the browser doesn't already support the list attribute
27- // todo: I couldn't figure out how to make an opposite `if statement` without Safari acting up
28- if ( ! Modernizr . input . list || ( parseInt ( $ . browser . version ) > 400 ) ) {
29-
30- // Insert home for new fake datalist
31- $ ( "<ul />" , {
32- "class" : "datalist" ,
33- "id" : list_id
34- } ) . appendTo ( "body" ) ;
35-
36- // Remove old datalist
37- $datalist . remove ( ) ;
38-
39- // Update pointer
40- var $datalist = $ ( "#" + list_id ) ;
41-
42- // Fill new fake datalist
43- datalistItems . each ( function ( ) {
44- $ ( "<li />" , {
45- // .val is required here, not .text or .html
46- // HTML *needs* to be <option value="xxx"> not <option>xxx</option> (IE)
47- "text" : $ ( this ) . val ( )
48- } ) . appendTo ( $datalist ) ;
49- } ) ;
50-
51- // Update pointer
52- datalistItems = $datalist . find ( "li" ) ;
53-
54- // Typey type type
55- $input
56- . on ( "focus" , function ( ) {
57- // Reset scroll
58- $datalist . scrollTop ( 0 ) ;
59- scrollValue = 0 ;
60- } )
61- . on ( "blur" , function ( ) {
62- // If this fires immediately, it prevents click-to-select from working
63- setTimeout ( function ( ) {
64- $datalist . fadeOut ( options . fadeOutSpeed ) ;
65- datalistItems . removeClass ( "active" ) ;
66- } , 500 ) ;
67- } )
68- . on ( "keyup focus" , function ( e ) {
69- searchPosition = $input . position ( ) ;
70- // Build datalist
71- $datalist
72- . show ( )
73- . css ( {
74- top : searchPosition . top + $ ( this ) . outerHeight ( ) ,
75- left : searchPosition . left ,
76- width : $input . outerWidth ( )
77- } ) ;
78-
79- datalistItems . hide ( ) ;
80- $datalist . find ( "li:RD_contains('" + $input . val ( ) + "')" ) . show ( ) ;
81- } ) ;
82-
83- // Don't want to use :hover in CSS so doing this instead
84- // really helps with arrow key navigation
85- datalistItems
86- . on ( "mouseenter" , function ( ) {
87- $ ( this ) . addClass ( "active" ) . siblings ( ) . removeClass ( "active" ) ;
88- } )
89- . on ( "mouseleave" , function ( ) {
90- $ ( this ) . removeClass ( "active" ) ;
91- } ) ;
92-
93- // Window resize
94- $ ( window ) . resize ( function ( ) {
26+ // Insert home for new fake datalist
27+ $ ( "<ul />" , {
28+ "class" : "datalist" ,
29+ "id" : list_id
30+ } ) . appendTo ( "body" ) ;
31+
32+ // Remove old datalist
33+ $datalist . remove ( ) ;
34+
35+ // Update pointer
36+ var $datalist = $ ( "#" + list_id ) ;
37+
38+ // Fill new fake datalist
39+ datalistItems . each ( function ( ) {
40+ $ ( "<li />" , {
41+ // .val is required here, not .text or .html
42+ // HTML *needs* to be <option value="xxx"> not <option>xxx</option> (IE)
43+ "text" : $ ( this ) . val ( )
44+ } ) . appendTo ( $datalist ) ;
45+ } ) ;
46+
47+ // Update pointer
48+ datalistItems = $datalist . find ( "li" ) ;
49+
50+ // Typey type type
51+ $input
52+ . on ( "focus" , function ( ) {
53+ // Reset scroll
54+ $datalist . scrollTop ( 0 ) ;
55+ scrollValue = 0 ;
56+ } )
57+ . on ( "blur" , function ( ) {
58+ // If this fires immediately, it prevents click-to-select from working
59+ setTimeout ( function ( ) {
60+ $datalist . fadeOut ( options . fadeOutSpeed ) ;
61+ datalistItems . removeClass ( "active" ) ;
62+ } , 500 ) ;
63+ } )
64+ . on ( "keyup focus" , function ( e ) {
9565 searchPosition = $input . position ( ) ;
66+ // Build datalist
9667 $datalist
68+ . show ( )
9769 . css ( {
9870 top : searchPosition . top + $ ( this ) . outerHeight ( ) ,
9971 left : searchPosition . left ,
10072 width : $input . outerWidth ( )
10173 } ) ;
102- } ) ;
103-
104- // Watch arrow keys for up and down
105- $input . on ( "keydown" , function ( e ) {
106-
107- var active = $ ( "li.active" ) ,
108- datalistHeight = $datalist . outerHeight ( ) ,
109- datalistItemsHeight = datalistItems . outerHeight ( ) ;
110-
111- // up arrow
112- if ( e . keyCode == 38 ) {
113- if ( active . length ) {
114- prevAll = active . prevAll ( "li:visible" ) ;
115- if ( prevAll . length > 0 ) {
116- active . removeClass ( "active" ) ;
117- prevAll . eq ( 0 ) . addClass ( "active" ) ;
118- }
119-
120- if ( prevAll . length && prevAll . position ( ) . top < 0 && scrollValue > 0 ) {
121- $datalist . scrollTop ( scrollValue -= datalistItemsHeight ) ;
122- }
123- }
124- }
12574
126- // down arrow
127- if ( e . keyCode == 40 ) {
128- if ( active . length ) {
129- var nextAll = active . nextAll ( "li:visible" ) ;
130- if ( nextAll . length > 0 ) {
131- active . removeClass ( "active" ) ;
132- nextAll . eq ( 0 ) . addClass ( "active" ) ;
133- }
134-
135- if ( nextAll . length && ( nextAll . position ( ) . top + datalistItemsHeight ) >= datalistHeight ) {
136- $datalist . stop ( ) . animate ( {
137- scrollTop : scrollValue += datalistItemsHeight
138- } , 200 ) ;
139- }
140- } else {
141- datalistItems . removeClass ( "active" ) ;
142- $datalist . find ( "li:visible:first" ) . addClass ( "active" ) ;
143- }
144- }
75+ datalistItems . hide ( ) ;
76+ $datalist . find ( "li:RD_contains('" + $input . val ( ) + "')" ) . show ( ) ;
77+ } ) ;
14578
146- // return or tab key
147- if ( e . keyCode == 13 || e . keyCode == 9 ) {
148- if ( active . length ) {
149- $input . val ( active . text ( ) ) ;
150- item_selected ( active . text ( ) ) ;
151- }
152- $datalist . fadeOut ( options . fadeOutSpeed ) ;
153- datalistItems . removeClass ( "active" ) ;
154- }
79+ // Don't want to use :hover in CSS so doing this instead
80+ // really helps with arrow key navigation
81+ datalistItems
82+ . on ( "mouseenter" , function ( ) {
83+ $ ( this ) . addClass ( " active" ) . siblings ( ) . removeClass ( "active" ) ;
84+ } )
85+ . on ( "mouseleave" , function ( ) {
86+ $ ( this ) . removeClass ( "active" ) ;
87+ } ) ;
15588
156- // keys
157- if ( e . keyCode != 13 && e . keyCode != 38 && e . keyCode != 40 ) {
158- // Reset active class
159- datalistItems . removeClass ( "active" ) ;
160- $datalist . find ( "li:visible:first" ) . addClass ( "active" ) ;
89+ // Window resize
90+ $ ( window ) . resize ( function ( ) {
91+ searchPosition = $input . position ( ) ;
92+ $datalist
93+ . css ( {
94+ top : searchPosition . top + $ ( this ) . outerHeight ( ) ,
95+ left : searchPosition . left ,
96+ width : $input . outerWidth ( )
97+ } ) ;
98+ } ) ;
16199
162- // Reset scroll
163- $datalist . scrollTop ( 0 ) ;
164- scrollValue = 0 ;
100+ // Watch arrow keys for up and down
101+ $input . on ( "keydown" , function ( e ) {
102+
103+ var active = $ ( "li.active" ) ,
104+ datalistHeight = $datalist . outerHeight ( ) ,
105+ datalistItemsHeight = datalistItems . outerHeight ( ) ;
106+
107+ // up arrow
108+ if ( e . keyCode == 38 ) {
109+ if ( active . length ) {
110+ prevAll = active . prevAll ( "li:visible" ) ;
111+ if ( prevAll . length > 0 ) {
112+ active . removeClass ( "active" ) ;
113+ prevAll . eq ( 0 ) . addClass ( "active" ) ;
114+ }
115+
116+ if ( prevAll . length && prevAll . position ( ) . top < 0 && scrollValue > 0 ) {
117+ $datalist . scrollTop ( scrollValue -= datalistItemsHeight ) ;
118+ }
165119 }
120+ }
166121
167- } ) ;
122+ // down arrow
123+ if ( e . keyCode == 40 ) {
124+ if ( active . length ) {
125+ var nextAll = active . nextAll ( "li:visible" ) ;
126+ if ( nextAll . length > 0 ) {
127+ active . removeClass ( "active" ) ;
128+ nextAll . eq ( 0 ) . addClass ( "active" ) ;
129+ }
130+
131+ if ( nextAll . length && ( nextAll . position ( ) . top + datalistItemsHeight ) >= datalistHeight ) {
132+ $datalist . stop ( ) . animate ( {
133+ scrollTop : scrollValue += datalistItemsHeight
134+ } , 200 ) ;
135+ }
136+ } else {
137+ datalistItems . removeClass ( "active" ) ;
138+ $datalist . find ( "li:visible:first" ) . addClass ( "active" ) ;
139+ }
140+ }
168141
169- // When choosing from dropdown
170- datalistItems . on ( "click" , function ( ) {
171- var active = $ ( "li.active" ) ;
142+ // return or tab key
143+ if ( e . keyCode == 13 || e . keyCode == 9 ) {
172144 if ( active . length ) {
173- $input . val ( $ ( this ) . text ( ) ) ;
145+ $input . val ( active . text ( ) ) ;
146+ item_selected ( active . text ( ) ) ;
174147 }
175148 $datalist . fadeOut ( options . fadeOutSpeed ) ;
176149 datalistItems . removeClass ( "active" ) ;
177- item_selected ( $ ( this ) . text ( ) ) ;
178- } ) ;
179-
180- function item_selected ( new_text ) {
181- if ( typeof options . change === 'function' )
182- options . change . call ( this , new_text ) ;
183150 }
184151
185- } // end if
152+ // keys
153+ if ( e . keyCode != 13 && e . keyCode != 38 && e . keyCode != 40 ) {
154+ // Reset active class
155+ datalistItems . removeClass ( "active" ) ;
156+ $datalist . find ( "li:visible:first" ) . addClass ( "active" ) ;
157+
158+ // Reset scroll
159+ $datalist . scrollTop ( 0 ) ;
160+ scrollValue = 0 ;
161+ }
162+
163+ } ) ;
164+
165+ // When choosing from dropdown
166+ datalistItems . on ( "click" , function ( ) {
167+ var active = $ ( "li.active" ) ;
168+ if ( active . length ) {
169+ $input . val ( $ ( this ) . text ( ) ) ;
170+ }
171+ $datalist . fadeOut ( options . fadeOutSpeed ) ;
172+ datalistItems . removeClass ( "active" ) ;
173+ item_selected ( $ ( this ) . text ( ) ) ;
174+ } ) ;
175+
176+ function item_selected ( new_text ) {
177+ if ( typeof options . change === 'function' )
178+ options . change . call ( this , new_text ) ;
179+ }
180+
186181 } ) ;
187182 } ;
188183} ) ( jQuery ) ;
0 commit comments