63
63
this . element . addClass ( 'search' ) ;
64
64
this . bodyContent = $ ( '<div class="body_copy"></div>' ) . appendTo ( this . element ) ;
65
65
66
+ var handleFormUpdated = function ( ) {
67
+ this . removeFocusTrap ( )
68
+ this . setupFocusTrap ( )
69
+ }
70
+
66
71
this . modal = this . bodyContent . bootstrapModal ( { title : 'Search' , size_class :'modal-lg' } ) ;
67
72
if ( typeof CustomSearchManager === 'function' ) {
68
- this . searchManager = new CustomSearchManager ( this . modal )
73
+ this . searchManager = new CustomSearchManager ( this . modal , handleFormUpdated . bind ( this ) )
69
74
} else {
70
- this . searchManager = new SearchManager ( this . modal )
75
+ this . searchManager = new SearchManager ( this . modal , handleFormUpdated . bind ( this ) )
71
76
}
72
77
73
78
this . ontologyMenu = this . searchManager . getOntologyMenu ( ) ;
83
88
ScalarSearch . prototype . showSearch = function ( ) {
84
89
this . modal . modal ( 'show' ) ;
85
90
setTimeout ( ( ) => {
86
- this . searchManager . getFirstFocusable ( ) . focus ( )
91
+ this . searchManager . getInitialFocusable ( ) . focus ( )
92
+ this . setupFocusTrap ( )
87
93
} , 500 )
88
94
}
89
95
97
103
}
98
104
this . searchManager . setSearchField ( query )
99
105
this . showSearch ( )
100
- console . log ( 'do search' )
101
106
setTimeout ( ( ) => {
102
107
this . searchManager . doSearch ( query )
103
- this . setupFocusTrap ( )
104
108
} , 500 )
105
109
}
106
110
107
111
ScalarSearch . prototype . setupFocusTrap = function ( ) {
108
112
109
- var closeBtn = this . modal . find ( '.close' )
110
- var firstFocusable = this . searchManager . getFirstFocusable ( )
111
- var lastFocusable = this . searchManager . getLastFocusable ( )
113
+ this . closeBtn = this . modal . find ( '.close' )
114
+ this . firstFocusable = this . searchManager . getFirstFocusable ( )
115
+ this . lastFocusable = this . searchManager . getLastFocusable ( )
112
116
113
- console . log ( firstFocusable , lastFocusable )
117
+ var me = this
114
118
115
- // tabbing forward from close button brings focus to search field
116
- closeBtn . on ( 'keydown' , ( e ) => {
119
+ // tab from close btn to first/last focusable
120
+ this . closeBtn . on ( 'keydown.focusTrap ' , function ( e ) {
117
121
var keyCode = e . keyCode || e . which ;
118
122
if ( keyCode == 9 ) {
119
123
if ( ! e . shiftKey ) {
120
124
e . preventDefault ( ) ;
121
- firstFocusable . focus ( ) ;
125
+ me . firstFocusable . focus ( ) ;
122
126
} else {
123
127
e . preventDefault ( ) ;
124
- lastFocusable . focus ( )
128
+ me . lastFocusable . focus ( )
125
129
}
126
130
}
127
131
} ) ;
128
132
129
- // tabbing backwards from search field link brings focus to close button
130
- firstFocusable . on ( 'keydown' , ( e ) => {
133
+ // tab back from first focusable to close btn
134
+ this . firstFocusable . on ( 'keydown.focusTrap ' , function ( e ) {
131
135
var keyCode = e . keyCode || e . which ;
132
136
if ( keyCode == 9 ) {
133
137
if ( e . shiftKey ) {
134
138
e . preventDefault ( ) ;
135
- closeBtn . focus ( ) ;
139
+ me . closeBtn . focus ( ) ;
136
140
}
137
141
}
138
142
} ) ;
139
143
140
- lastFocusable . on ( 'keydown' , ( e ) => {
144
+ // tap forward from last focusable to close btn
145
+ this . lastFocusable . on ( 'keydown.focusTrap' , function ( e ) {
141
146
var keyCode = e . keyCode || e . which ;
142
147
if ( keyCode == 9 ) {
143
148
if ( ! e . shiftKey ) {
144
149
e . preventDefault ( ) ;
145
- closeBtn . focus ( ) ;
150
+ me . closeBtn . focus ( ) ;
146
151
}
147
152
}
148
153
} ) ;
149
154
}
150
155
156
+ ScalarSearch . prototype . removeFocusTrap = function ( ) {
157
+ if ( this . closeBtn ) this . closeBtn . off ( 'keydown.focusTrap' )
158
+ if ( this . firstFocusable ) this . firstFocusable . off ( 'keydown.focusTrap' )
159
+ if ( this . lastFocusable ) this . lastFocusable . off ( 'keydown.focusTrap' )
160
+ }
161
+
151
162
ScalarSearch . prototype . getOntologyData = function ( ) {
152
163
let me = this ;
153
164
let newURL = $ ( 'link#approot' ) . attr ( 'href' ) . replace ( 'application' , 'ontologies' ) ;
244
255
} ) ( jQuery , window , document ) ;
245
256
246
257
class SearchManager {
247
- constructor ( modal ) {
258
+ constructor ( modal , onFormUpdated ) {
248
259
this . modal = modal
260
+ this . onFormUpdated = onFormUpdated
249
261
this . bodyContent = this . modal . find ( '.modal-body' )
250
262
this . setup ( )
251
263
}
@@ -299,7 +311,9 @@ class SearchManager {
299
311
this . doSearch ( this . searchField . val ( ) ) ;
300
312
} ) ;
301
313
302
- this . updateForm ( ) ;
314
+ // wait a frame so init has a chance to happen
315
+ setTimeout ( this . updateForm . bind ( this ) , 1 ) ;
316
+
303
317
$ ( '#modal_scope' ) . on ( 'change' , ( event ) => {
304
318
this . updateForm ( ) ;
305
319
} )
@@ -309,12 +323,21 @@ class SearchManager {
309
323
this . searchField . val ( query ) ;
310
324
}
311
325
312
- getFirstFocusable ( ) {
326
+ getInitialFocusable ( ) {
313
327
return this . searchField
314
328
}
315
329
330
+ getFirstFocusable ( ) {
331
+ return this . modal . find ( '#modal_search_term' )
332
+ }
333
+
316
334
getLastFocusable ( ) {
317
- return this . modal . find ( '.vis_footer button' ) . last ( )
335
+ var visFooterBtns = this . modal . find ( '.vis_footer button' )
336
+ if ( visFooterBtns . length > 0 ) {
337
+ return visFooterBtns . last ( )
338
+ } else {
339
+ return this . modal . find ( 'button[type="submit"]' )
340
+ }
318
341
}
319
342
320
343
updateForm ( ) {
@@ -323,6 +346,7 @@ class SearchManager {
323
346
} else {
324
347
$ ( '.search_metadata_option' ) . show ( )
325
348
}
349
+ if ( this . onFormUpdated ) this . onFormUpdated ( )
326
350
}
327
351
328
352
getOntologyMenu ( ) {
@@ -514,6 +538,7 @@ class SearchManager {
514
538
} else {
515
539
this . scalarvis . setOptions ( visOptions )
516
540
}
541
+ if ( this . onFormUpdated ) this . onFormUpdated ( )
517
542
}
518
543
}
519
544
}
0 commit comments