uber_select_rails 0.4.4 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/uber_select_rails/version.rb +1 -1
- data/vendor/assets/javascript/uber_select/README.md +67 -1
- data/vendor/assets/javascript/uber_select/javascript/jquery.uber-select.js +5 -5
- data/vendor/assets/javascript/uber_select/javascript/list.js +4 -3
- data/vendor/assets/javascript/uber_select/javascript/output_container.js +1 -1
- data/vendor/assets/javascript/uber_select/javascript/pane.js +32 -26
- data/vendor/assets/javascript/uber_select/javascript/search_field.js +5 -1
- data/vendor/assets/javascript/uber_select/javascript/uber_search.js +53 -16
- data/vendor/assets/javascript/uber_select/test.html +12 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e37c667b8e66ed1dda23bb261ff4afd711edd8ada1158a6eee77a44aae2573e
|
4
|
+
data.tar.gz: f51b530782b7e0ea3cd97934de9fe06f91c8fbe1fdb1cfee49ac75867770eb7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba59b1dee8c43c50a6a1df171cddc362ba5b4297f0cbaa58bd0e9d306ab19ae138f121171067be89187cf29d152115db114bfe870ebda34300f5ef73b9508d65
|
7
|
+
data.tar.gz: 64924a5caf7106dc0005a2d93f7fa105f9b00e10a2629c0bced95e833a72554a553db0eb029c32ad1cba71aa78d82d272c21eb89619a80ccfe762f48aae1b80c
|
@@ -3,13 +3,16 @@
|
|
3
3
|
UberSelect is a fancy UI on top of a regular `<select>` element.
|
4
4
|
|
5
5
|
## Requirements
|
6
|
+
|
6
7
|
Tested on jQuery 1.11.x to 3.3.x
|
7
8
|
|
8
9
|
## Parts
|
10
|
+
|
9
11
|
UberSelect is composed of two main parts, an UberSearch that does all the of searching and UI, and an UberSelect which
|
10
12
|
is used to connect an UberSearch to a `<select>` element.
|
11
13
|
|
12
14
|
### UberSelect
|
15
|
+
|
13
16
|
This is the object that allows an UberSearch and a `<select>` element to work together. The select element can be used
|
14
17
|
to control the state of the UberSearch, and vice-versa. This means you can programmatically change the state of the
|
15
18
|
select, and UberSearch will update. Users can interact with the UberSearch, and the select will update. This also means
|
@@ -22,38 +25,46 @@ $('.my_selects').uberSelect(options);
|
|
22
25
|
```
|
23
26
|
|
24
27
|
#### Attributes <a name="UberSearch attributes"></a>
|
28
|
+
|
25
29
|
Attribtes on the outermost element can be specified by setting the `data-uber-attributes` attribute on the `<select>` element. Values should be passed
|
26
30
|
as a JSON string of key/value pairs where the key is the attribute name and the value is the attribute value.
|
27
31
|
|
28
32
|
#### Options
|
33
|
+
|
29
34
|
Options can be specified by setting the `data-uber-options` attribute on the `<select>` element. Values should be passed
|
30
35
|
as a JSON string. All options on the are passed to the underlying UberSearch, see [UberSearch options](#UberSearchOptions).
|
31
36
|
|
32
37
|
- ##### prepopulateSearchOnOpen
|
38
|
+
|
33
39
|
Determines whether the search input starts with the selected value in it when the pane is opened.
|
34
40
|
|
35
41
|
Default: `false`
|
36
42
|
|
37
43
|
- ##### clearSearchClearsSelect
|
44
|
+
|
38
45
|
Determines whether the select value should be cleared when the search is cleared.
|
39
46
|
|
40
47
|
Default: `false`
|
41
48
|
|
42
49
|
- ##### placeholder
|
50
|
+
|
43
51
|
Placeholder to show in the selected text area.
|
44
52
|
|
45
53
|
Default: `<select>` element attributes `<select placeholder="my placeholder" data-placeholder="my placeholder">`
|
46
54
|
|
47
55
|
- ##### dataUrl
|
56
|
+
|
48
57
|
A url to pre-fetch select options from. JSON response should be of the form
|
49
58
|
`[{text:'option with explicit value', value: 'some value'}, {text:'option with implicit value'}]`. For a custom JSON response, use in conjunction with optionFromDatum.
|
50
59
|
|
51
60
|
Default: `null`
|
52
61
|
|
53
62
|
- ##### optionFromDatum
|
63
|
+
|
54
64
|
A function that is used to customize the options value and text built from a JSON response. `datum` is a single result returned from the JSON response.
|
55
65
|
|
56
66
|
The function signature is as follows:
|
67
|
+
|
57
68
|
```js
|
58
69
|
function(datum) {
|
59
70
|
return // a <option> element to represent the select
|
@@ -63,25 +74,36 @@ as a JSON string. All options on the are passed to the underlying UberSearch, se
|
|
63
74
|
Default: `datum.value` populates the `<option>` value, `datum.text` populates the `<option>` text.
|
64
75
|
|
65
76
|
- ##### value
|
77
|
+
|
66
78
|
Initialize the UberSearch with this selected value
|
67
79
|
|
68
80
|
Default: `<select>` element `value` property
|
69
81
|
|
82
|
+
- ##### ariaLabel
|
83
|
+
|
84
|
+
Add an aria-label attribute with this value to the uber_select element.
|
85
|
+
|
70
86
|
#### Events Triggered
|
87
|
+
|
71
88
|
- ##### uber-select:ready
|
89
|
+
|
72
90
|
This fires when the UberSelect has initialized and is ready for user interaction
|
73
91
|
|
74
92
|
#### Events Observed
|
93
|
+
|
75
94
|
The `<select>` element observes the following events:
|
76
95
|
|
77
96
|
- ##### uber-select:refreshOptions
|
97
|
+
|
78
98
|
The UberSearch options list will be updated to match the `<select>` element's `<option>` list.
|
79
99
|
|
80
100
|
- ##### uber-select:refresh
|
101
|
+
|
81
102
|
The UberSearch will update its selected value to match the `<select>` element's. This handler also runs when the
|
82
103
|
`<select>` element triggers a `change` event.
|
83
104
|
|
84
105
|
### UberSearch
|
106
|
+
|
85
107
|
The UberSearch performs all of the heavy lifting. It creates the UI views, maintains state, and performs the searching.
|
86
108
|
It can be instantiated without the use of an UberSelect, which can be useful for situations where the selected value is
|
87
109
|
being used in purely in JS, and not being linked to a `<select>` element in a form.
|
@@ -93,114 +115,143 @@ new UberSearch(data, options);
|
|
93
115
|
```
|
94
116
|
|
95
117
|
#### Data
|
118
|
+
|
96
119
|
Data is an array of objects. Each object may have the following properties:
|
97
120
|
|
98
121
|
- ##### text
|
122
|
+
|
99
123
|
String shown to the user in the list of results. This value is required if *value* is not provided.
|
100
124
|
|
101
125
|
- ##### selectedText
|
126
|
+
|
102
127
|
String shown to the user in the output container when this option is selected. *optional*
|
103
128
|
|
104
129
|
- ##### title
|
130
|
+
|
105
131
|
Title text shown to the user when hovering over the result. *optional*
|
106
132
|
|
107
133
|
- ##### value
|
134
|
+
|
108
135
|
This is matched against the *value* option passed UberSearch and will appear selected if it matches. It is also used to match against search input text when the user searches. This value is required if *text* is not provided.
|
109
136
|
|
110
137
|
- ##### matchValue
|
138
|
+
|
111
139
|
This overrides the value used to match against search input text when the user searches. *optional*
|
112
140
|
|
113
141
|
- ##### visibility
|
142
|
+
|
114
143
|
This is used to determine whether the option appears only when searching or only when not searching. Values accepted: `query`, `no-query`. *optional*
|
115
144
|
|
116
145
|
- ##### disabled
|
146
|
+
|
117
147
|
This is used to determine whether the option appears disabled. *optional*
|
118
148
|
|
119
149
|
- ##### group
|
150
|
+
|
120
151
|
This is used to visually group options. All options with the same group will appear together. *optional*
|
121
152
|
|
122
153
|
#### Methods
|
123
154
|
|
124
155
|
- ##### setData(data)
|
125
|
-
Sets the data. `data` should be an Array conforming to the specifications described in <a href="#data">Data</a>
|
126
156
|
|
157
|
+
Sets the data. `data` should be an Array conforming to the specifications described in <a href="#data">Data</a>
|
127
158
|
|
128
159
|
#### Options <a name="UberSearch options"></a>
|
160
|
+
|
129
161
|
Options can be specified by setting the `data-uber-options` attribute on the `<select>` element. Values should be passed
|
130
162
|
as a JSON string.
|
131
163
|
|
132
164
|
- ##### value
|
165
|
+
|
133
166
|
Sets the initially selected value of the UberSearch. This value should match the `value` property of the desired
|
134
167
|
option data.
|
135
168
|
|
136
169
|
Default: `null`
|
137
170
|
|
138
171
|
- ##### search
|
172
|
+
|
139
173
|
Determines whether the search input be shown.
|
140
174
|
|
141
175
|
Default: `true`
|
142
176
|
|
143
177
|
- ##### clearSearchButton
|
178
|
+
|
144
179
|
Sets the text content of clear search button.
|
145
180
|
|
146
181
|
Default: `✕`
|
147
182
|
|
148
183
|
- ##### selectCaret
|
184
|
+
|
149
185
|
Sets the text content of clear select caret.
|
150
186
|
|
151
187
|
Default: `⌄`
|
152
188
|
|
153
189
|
- ##### hideBlankOption
|
190
|
+
|
154
191
|
Sets whether blank options should be hidden automatically.
|
155
192
|
|
156
193
|
Default: `false`
|
157
194
|
|
158
195
|
- ##### treatBlankOptionAsPlaceholder
|
196
|
+
|
159
197
|
Determines whether the `text` property of an option with a blank `value` property should be used as the placeholder
|
160
198
|
text if no placeholder is specified.
|
161
199
|
|
162
200
|
Default: `false`
|
163
201
|
|
164
202
|
- ##### highlightByDefault
|
203
|
+
|
165
204
|
Determines whether the first search result be auto-highlighted.
|
166
205
|
|
167
206
|
Default: `true`
|
168
207
|
|
169
208
|
- ##### minQueryLength
|
209
|
+
|
170
210
|
Sets minimum number of characters the user must type before a search will be performed.
|
171
211
|
|
172
212
|
Default: `0`
|
173
213
|
|
174
214
|
- ##### minQueryMessage
|
215
|
+
|
175
216
|
Sets the message shown to the user when the query doesn't exceed the minimum length. `true` for a default message,
|
176
217
|
`false` for none, or provide a string to set a custom message.
|
177
218
|
|
178
219
|
Default: `true`
|
179
220
|
|
180
221
|
- ##### placeholder
|
222
|
+
|
181
223
|
Sets the placeholder shown in the selected text area.
|
182
224
|
|
183
225
|
Default: `null`
|
184
226
|
|
185
227
|
- ##### searchPlaceholder
|
228
|
+
|
186
229
|
Sets the placeholder shown in the search input.
|
187
230
|
|
188
231
|
Default: `'Type to search'`
|
189
232
|
|
190
233
|
- ##### noResultsText
|
234
|
+
|
191
235
|
Sets the message shown when there are no results.
|
192
236
|
|
193
237
|
Default: `'No Matches Found'`
|
194
238
|
|
195
239
|
- ##### noDataText
|
240
|
+
|
196
241
|
Sets the text to show when the results list is empty and no search is in progress
|
197
242
|
|
198
243
|
Default: `'No options'`
|
244
|
+
|
245
|
+
- ##### searchInputAttributes
|
246
|
+
|
247
|
+
An Object containing attributes to add to the search input element.
|
199
248
|
|
200
249
|
- ##### buildResult
|
250
|
+
|
201
251
|
A function that is used to build result elements.
|
202
252
|
|
203
253
|
The function signature is as follows:
|
254
|
+
|
204
255
|
```js
|
205
256
|
function(listOptionData) {
|
206
257
|
return // HTML/element to insert into the the results list
|
@@ -208,10 +259,12 @@ as a JSON string.
|
|
208
259
|
```
|
209
260
|
|
210
261
|
- ##### resultPostprocessor
|
262
|
+
|
211
263
|
A function that is run after a result is built and can be used to decorate it. This can be useful when extending the
|
212
264
|
functionality of an existing UberSearch implementation.
|
213
265
|
|
214
266
|
The function signature is as follows:
|
267
|
+
|
215
268
|
```js
|
216
269
|
function(resultsListElement, listOptionData) { }
|
217
270
|
```
|
@@ -219,50 +272,63 @@ as a JSON string.
|
|
219
272
|
Default: No-op
|
220
273
|
|
221
274
|
- ##### onRender
|
275
|
+
|
222
276
|
A function to run when the results container is rendered. If the result returns false, the default `select` event
|
223
277
|
handler is not run and the event is cancelled.
|
224
278
|
|
225
279
|
The function signature is as follows:
|
280
|
+
|
226
281
|
```js
|
227
282
|
function(resultsContainer, searchResultsHTML) { }
|
228
283
|
```
|
229
284
|
|
230
285
|
- ##### onSelect
|
286
|
+
|
231
287
|
A function to run when a result is selected. If the result returns false, the default `select` event handler is not
|
232
288
|
run and the event is cancelled.
|
233
289
|
|
234
290
|
The function signature is as follows:
|
291
|
+
|
235
292
|
```js
|
236
293
|
function(listOptionData, resultsListElement, clickEvent) { }
|
237
294
|
```
|
238
295
|
|
239
296
|
- ##### onNoHighlightSubmit
|
297
|
+
|
240
298
|
A function to run when a user presses enter without selecting a result.
|
241
299
|
Should be used in combination with `highlightByDefault: false`.
|
242
300
|
|
243
301
|
The function signature is as follows:
|
302
|
+
|
244
303
|
```js
|
245
304
|
function(value) { }
|
246
305
|
```
|
247
306
|
|
248
307
|
- ##### outputContainer (Deprecated)
|
308
|
+
|
249
309
|
An object that receives the output once a result is selected. Must respond to `setValue(value)` and `view()`. This object serves to
|
250
310
|
attach the result list to the DOM at the desired location.
|
251
311
|
|
252
312
|
#### Events Triggered
|
313
|
+
|
253
314
|
- ##### shown
|
315
|
+
|
254
316
|
This fires when the UberSearch pane is opened.
|
255
317
|
|
256
318
|
- ##### renderedResults
|
319
|
+
|
257
320
|
This fires each time the list of results is updated.
|
258
321
|
|
259
322
|
- ##### clear
|
323
|
+
|
260
324
|
This fires when the user clicks the clear search button.
|
261
325
|
|
262
326
|
- ##### select
|
327
|
+
|
263
328
|
This fires when the user selects a result.
|
264
329
|
|
265
330
|
The handler function signature is as follows:
|
331
|
+
|
266
332
|
```js
|
267
333
|
function(event, [listOptionData, resultsContainer, originalEvent]) { }
|
268
334
|
```
|
@@ -44,7 +44,7 @@
|
|
44
44
|
$(select).on(eventsObserved.refreshOptions, refreshOptionsList)
|
45
45
|
|
46
46
|
// When the select value changes
|
47
|
-
$(select).on(eventsObserved.refresh,
|
47
|
+
$(select).on(eventsObserved.refresh, refresh)
|
48
48
|
|
49
49
|
// When a result is selected
|
50
50
|
$(uberSearch).on('select', function(_, datum){
|
@@ -139,20 +139,20 @@
|
|
139
139
|
}
|
140
140
|
|
141
141
|
function refreshOptionsList(){
|
142
|
-
uberSearch.setDisabled($(select).is(':disabled'))
|
143
142
|
uberSearch.setData(dataFromSelect(select))
|
144
143
|
updateSelectValue($(select).find('option[selected]').attr('value')) // Read the value of the option that is selected because the <select> element's value is defunct now that we've updated the <option> elements
|
145
144
|
}
|
146
145
|
|
147
|
-
|
148
|
-
|
146
|
+
function refresh(){
|
147
|
+
uberSearch.setDisabled($(select).is(':disabled'))
|
149
148
|
uberSearch.setValue($(select).val())
|
150
149
|
}
|
151
150
|
|
152
151
|
function updateSelectValue(value){
|
153
152
|
var before = $(select).val()
|
154
153
|
$(select).val(value)
|
155
|
-
|
154
|
+
var after = $(select).val() // Read value the same way instead of comparing to `value` so the same coercion is applied
|
155
|
+
if (before != after) { $(select).trigger('change') } // Only trigger a change if the value has actually changed
|
156
156
|
}
|
157
157
|
|
158
158
|
// Selects the option with an emptystring value, or the first option if there is no blank option
|
@@ -7,7 +7,7 @@ function List(options) {
|
|
7
7
|
// BEHAVIOUR
|
8
8
|
|
9
9
|
// Handle up and down arrow key presses
|
10
|
-
$(options.keypressInput).on('keydown', function(event){
|
10
|
+
$(options.keypressInput || view).on('keydown', function(event){
|
11
11
|
switch (event.which) {
|
12
12
|
case 38: // Up Arrow
|
13
13
|
stepHighlight(-1, true)
|
@@ -50,7 +50,7 @@ function List(options) {
|
|
50
50
|
|
51
51
|
// Can be overridden to format how results are built
|
52
52
|
this.buildResult = function(datum){
|
53
|
-
return $('<li></li>').html(datum)
|
53
|
+
return $('<li role="option" class="result" tabindex="0"></li>').html(datum)
|
54
54
|
}
|
55
55
|
|
56
56
|
this.unhighlightResults = unhighlightResults
|
@@ -73,6 +73,7 @@ function List(options) {
|
|
73
73
|
if (!result.length) { return }
|
74
74
|
|
75
75
|
result.addClass('highlighted')
|
76
|
+
result.attr("aria-selected", true)
|
76
77
|
|
77
78
|
if (options.scroll){
|
78
79
|
scrollResultIntoView(result)
|
@@ -80,7 +81,7 @@ function List(options) {
|
|
80
81
|
}
|
81
82
|
|
82
83
|
function unhighlightResults(){
|
83
|
-
highlightedResult().removeClass('highlighted')
|
84
|
+
highlightedResult().removeClass('highlighted').attr("aria-selected", false)
|
84
85
|
}
|
85
86
|
|
86
87
|
function highlightedResult(){
|
@@ -1,6 +1,6 @@
|
|
1
1
|
var OutputContainer = function(options){
|
2
2
|
options = $.extend({}, options)
|
3
|
-
var view = $('<span class="selected_text_container" tabindex=0
|
3
|
+
var view = $('<span class="selected_text_container" tabindex="0"></span>')
|
4
4
|
var selectedText = $('<span class="selected_text"></span>').appendTo(view)
|
5
5
|
var selectCaret = $('<span class="select_caret"></span>').appendTo(view).html(options.selectCaret)
|
6
6
|
|
@@ -3,40 +3,31 @@ function Pane(options){
|
|
3
3
|
trigger: null
|
4
4
|
}, options)
|
5
5
|
|
6
|
-
var context
|
7
|
-
var model
|
8
|
-
var isOpen
|
9
|
-
var view
|
6
|
+
var context = this
|
7
|
+
var model = {}
|
8
|
+
var isOpen = false
|
9
|
+
var view = $('<div class="pane"></div>').toggle(isOpen)
|
10
10
|
var innerPane = $('<div class="pane_inner"></div>').appendTo(view)
|
11
11
|
|
12
12
|
|
13
13
|
// PUBLIC INTERFACE
|
14
14
|
|
15
|
-
$.extend(this, {
|
15
|
+
$.extend(this, {
|
16
|
+
model: model,
|
17
|
+
view: view,
|
18
|
+
addContent: addContent,
|
19
|
+
removeContent: removeContent,
|
20
|
+
show: show,
|
21
|
+
hide: hide,
|
22
|
+
toggle: toggle,
|
23
|
+
isOpen: paneIsOpen,
|
24
|
+
isClosed: paneIsClosed
|
25
|
+
})
|
16
26
|
|
17
27
|
|
18
28
|
// BEHAVIOUR
|
19
29
|
|
20
|
-
|
21
|
-
// Show the pane when the select element is clicked
|
22
|
-
$(options.trigger).on('click', function(event){
|
23
|
-
if ($(options.trigger).hasClass('disabled')) { return }
|
24
|
-
|
25
|
-
context.show()
|
26
|
-
})
|
27
|
-
|
28
|
-
// Show the pane if the user was tabbed onto the trigger and pressed enter or space
|
29
|
-
$(options.trigger).on('keyup', function(event){
|
30
|
-
if ($(options.trigger).hasClass('disabled')) { return }
|
31
|
-
|
32
|
-
if (event.which == 13 || event.which == 32){
|
33
|
-
context.show()
|
34
|
-
return false
|
35
|
-
}
|
36
|
-
})
|
37
|
-
}
|
38
|
-
|
39
|
-
// Hide the pane when clicked out
|
30
|
+
// Hide the pane when clicked out
|
40
31
|
$(document).on('mousedown', function(event){
|
41
32
|
if (isEventOutsidePane(event) && isEventOutsideTrigger(event)){
|
42
33
|
context.hide()
|
@@ -52,13 +43,21 @@ function Pane(options){
|
|
52
43
|
$(document).on('keyup', function(event){
|
53
44
|
if (event.which == 27 && isOpen){
|
54
45
|
context.hide()
|
55
|
-
|
46
|
+
return false
|
56
47
|
}
|
57
48
|
})
|
58
49
|
|
59
50
|
|
60
51
|
// HELPER FUNCTIONS
|
61
52
|
|
53
|
+
function paneIsOpen(){
|
54
|
+
return isOpen
|
55
|
+
}
|
56
|
+
|
57
|
+
function paneIsClosed(){
|
58
|
+
return !isOpen
|
59
|
+
}
|
60
|
+
|
62
61
|
function addContent(name, content){
|
63
62
|
model[name] = content
|
64
63
|
innerPane.append(content)
|
@@ -81,6 +80,13 @@ function Pane(options){
|
|
81
80
|
view.hide()
|
82
81
|
$(context).trigger('hidden')
|
83
82
|
}
|
83
|
+
function toggle(){
|
84
|
+
if (isOpen) {
|
85
|
+
context.hide()
|
86
|
+
} else {
|
87
|
+
context.show()
|
88
|
+
}
|
89
|
+
}
|
84
90
|
|
85
91
|
// returns true if the event originated outside the pane
|
86
92
|
function isEventOutsidePane(event){
|
@@ -1,11 +1,15 @@
|
|
1
1
|
function SearchField(options){
|
2
2
|
options = $.extend({
|
3
3
|
placeholder: 'Type to Search',
|
4
|
+
searchInputAttributes: { 'aria-label': "Type to Search" },
|
4
5
|
clearButton:'✕' // Text content of clear search button
|
5
6
|
}, options)
|
6
7
|
|
8
|
+
var inputAttrs = {}
|
9
|
+
$.extend(inputAttrs, { placeholder: options.placeholder }, options.searchInputAttributes)
|
10
|
+
|
7
11
|
var context = this
|
8
|
-
var input = this.input = $('<input type="search" class="search_input">').attr(
|
12
|
+
var input = this.input = $('<input type="search" class="search_input">').attr(inputAttrs)
|
9
13
|
var value = input.val()
|
10
14
|
var clearButton = this.clearButton = $('<span class="clear_search_button"></span>').html(options.clearButton)
|
11
15
|
var view = this.view = $('<span class="search_field_container"></span>').append(input).append(clearButton)
|
@@ -7,6 +7,7 @@ var UberSearch = function(data, options){
|
|
7
7
|
}
|
8
8
|
|
9
9
|
options = $.extend({
|
10
|
+
ariaLabel: null,
|
10
11
|
value: null, // Initialize with this selectedValue
|
11
12
|
disabled: false, // Initialize with this disabled value
|
12
13
|
search: true, // Show the search input
|
@@ -30,14 +31,22 @@ var UberSearch = function(data, options){
|
|
30
31
|
}, options)
|
31
32
|
|
32
33
|
var context = this
|
33
|
-
var view = $('<span class="uber_select"></span>')
|
34
|
+
var view = $('<span class="uber_select" role="listbox"></span>')
|
34
35
|
var selectedValue = options.value // Internally selected value
|
35
36
|
var outputContainer = options.outputContainer || new OutputContainer({selectCaret: options.selectCaret})
|
36
|
-
var searchField = new SearchField({placeholder: options.searchPlaceholder, clearButton: options.clearSearchButton})
|
37
37
|
var resultsContainer = $('<div class="results_container"></div>')
|
38
38
|
var messages = $('<div class="messages"></div>')
|
39
|
-
var pane = new Pane(
|
40
|
-
|
39
|
+
var pane = new Pane()
|
40
|
+
|
41
|
+
if (options.ariaLabel) { view.attr("aria-label", options.ariaLabel) }
|
42
|
+
|
43
|
+
var searchField = new SearchField({
|
44
|
+
placeholder: options.searchPlaceholder,
|
45
|
+
clearButton: options.clearSearchButton,
|
46
|
+
searchInputAttributes: options.searchInputAttributes
|
47
|
+
})
|
48
|
+
|
49
|
+
var search = new Search(searchField.input, resultsContainer, {
|
41
50
|
model: {
|
42
51
|
dataForMatching: dataForMatching,
|
43
52
|
minQueryLength: options.minQueryLength,
|
@@ -48,23 +57,56 @@ var UberSearch = function(data, options){
|
|
48
57
|
view: {
|
49
58
|
renderResults: renderResults,
|
50
59
|
buildResult: options.buildResult || buildResult,
|
51
|
-
keypressInput: searchField.input
|
60
|
+
keypressInput: options.search ? searchField.input : null
|
52
61
|
}
|
53
62
|
})
|
54
63
|
|
55
64
|
|
56
65
|
// BEHAVIOUR
|
57
66
|
|
67
|
+
// Show the pane when the select element is clicked
|
68
|
+
$(outputContainer.view).on('click', function(event){
|
69
|
+
if (outputContainer.view.hasClass('disabled')) { return }
|
70
|
+
|
71
|
+
pane.show()
|
72
|
+
})
|
73
|
+
|
74
|
+
// Show the pane if the user was tabbed onto the trigger and pressed enter, space, or down arrow
|
75
|
+
$(outputContainer.view).on('keyup', function(event){
|
76
|
+
if (outputContainer.view.hasClass('disabled')) { return }
|
77
|
+
|
78
|
+
if (event.which === 32 || event.which === 40 && pane.isClosed()){
|
79
|
+
pane.show()
|
80
|
+
return false
|
81
|
+
}
|
82
|
+
else if (event.which === 13){ // toggle pane when enter is pressed
|
83
|
+
pane.toggle()
|
84
|
+
return false
|
85
|
+
}
|
86
|
+
})
|
87
|
+
|
58
88
|
// When the pane is opened
|
59
89
|
$(pane).on('shown', function(){
|
60
90
|
search.clear()
|
61
|
-
markSelected()
|
62
|
-
$(searchField.input).focus()
|
91
|
+
markSelected()
|
63
92
|
view.addClass('open')
|
93
|
+
|
94
|
+
if (options.search) {
|
95
|
+
$(searchField.input).focus()
|
96
|
+
} else {
|
97
|
+
pane.view.find("ul.results li:first").focus()
|
98
|
+
}
|
64
99
|
|
65
100
|
triggerEvent(eventsTriggered.shown)
|
66
101
|
})
|
67
102
|
|
103
|
+
|
104
|
+
// When the pane is hidden
|
105
|
+
$(pane).on('hidden', function(){
|
106
|
+
view.removeClass('open')
|
107
|
+
view.focus()
|
108
|
+
})
|
109
|
+
|
68
110
|
// When the query is changed
|
69
111
|
$(search).on('queryChanged', function(){
|
70
112
|
updateMessages()
|
@@ -96,6 +138,8 @@ var UberSearch = function(data, options){
|
|
96
138
|
return
|
97
139
|
}
|
98
140
|
|
141
|
+
event.stopPropagation();
|
142
|
+
|
99
143
|
setValue(valueFromResult(this))
|
100
144
|
pane.hide()
|
101
145
|
triggerEvent(eventsTriggered.select, [datum, this, event])
|
@@ -106,20 +150,13 @@ var UberSearch = function(data, options){
|
|
106
150
|
options.onNoHighlightSubmit($(this).val())
|
107
151
|
})
|
108
152
|
|
109
|
-
// When the pane is hidden
|
110
|
-
$(pane).on('hidden', function(){
|
111
|
-
view.removeClass('open')
|
112
|
-
})
|
113
|
-
|
114
153
|
|
115
154
|
// INITIALIZATION
|
116
155
|
|
117
156
|
setDisabled(options.disabled)
|
118
157
|
setData(data)
|
119
158
|
|
120
|
-
if (options.search){
|
121
|
-
pane.addContent('search', searchField.view)
|
122
|
-
}
|
159
|
+
if (options.search) { pane.addContent('search', searchField.view) }
|
123
160
|
pane.addContent('messages', messages)
|
124
161
|
pane.addContent('results', resultsContainer)
|
125
162
|
|
@@ -239,7 +276,7 @@ var UberSearch = function(data, options){
|
|
239
276
|
}
|
240
277
|
|
241
278
|
function buildResult(datum){
|
242
|
-
var result = $('<li class="result"></li>')
|
279
|
+
var result = $('<li class="result" tabindex="0"></li>')
|
243
280
|
.html((options.treatBlankOptionAsPlaceholder ? datum.text || options.placeholder : datum.text) || " ")
|
244
281
|
.data(datum) // Store the datum so we can get know what the value of the selected item is
|
245
282
|
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
<span class="example">
|
20
20
|
<label for="select">
|
21
|
-
|
21
|
+
Search and placeholder
|
22
22
|
</label>
|
23
23
|
<select placeholder="Choose a gender">
|
24
24
|
<option></option>
|
@@ -31,6 +31,17 @@
|
|
31
31
|
</p>
|
32
32
|
</span>
|
33
33
|
|
34
|
+
<span class="example">
|
35
|
+
<label for="select">
|
36
|
+
Search input attributes
|
37
|
+
</label>
|
38
|
+
<select data-uber-options='{"searchInputAttributes": {"aria-label": "This is a test"}}'>
|
39
|
+
<option></option>
|
40
|
+
<option>male</option>
|
41
|
+
<option>female</option>
|
42
|
+
</select>
|
43
|
+
<p>This example includes an aria label attribute for the search input element.</p>
|
44
|
+
</span>
|
34
45
|
|
35
46
|
<span class="example">
|
36
47
|
<label for="select">
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: uber_select_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Jakobsen
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
|
-
description:
|
55
|
+
description:
|
56
56
|
email:
|
57
57
|
- nicholas.jakobsen@gmail.com
|
58
58
|
executables: []
|
@@ -84,7 +84,7 @@ files:
|
|
84
84
|
homepage: https://github.com/culturecode/uber_select_rails
|
85
85
|
licenses: []
|
86
86
|
metadata: {}
|
87
|
-
post_install_message:
|
87
|
+
post_install_message:
|
88
88
|
rdoc_options: []
|
89
89
|
require_paths:
|
90
90
|
- lib
|
@@ -99,8 +99,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
99
|
- !ruby/object:Gem::Version
|
100
100
|
version: '0'
|
101
101
|
requirements: []
|
102
|
-
rubygems_version: 3.
|
103
|
-
signing_key:
|
102
|
+
rubygems_version: 3.2.3
|
103
|
+
signing_key:
|
104
104
|
specification_version: 4
|
105
105
|
summary: A Rails gem containing a javascript plugin that adds a layer of UI goodness
|
106
106
|
overtop of basic HTML select elements
|