uber_select_rails 0.4.6 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/uber_select_rails/version.rb +1 -1
- data/vendor/assets/javascript/uber_select/README.md +91 -1
- data/vendor/assets/javascript/uber_select/javascript/jquery.uber-select.js +7 -1
- 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 +58 -16
- data/vendor/assets/javascript/uber_select/test.html +12 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dad48d52dd5e14c133c8d6c01861f5ae3e9069110df7b8b5faa7840703342f7
|
4
|
+
data.tar.gz: 72be4762c753d35290e7f9d63d6b9575f0967d44d9a9b382d417accb6324fd6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a39831aaeb705925e5bf27053e4445232096eb8ba8f4e572ce2809a21b1cd4a9f42af62189614089fa7dba4fa9b5f046988fcfea92ce47ee872e76f24692b797
|
7
|
+
data.tar.gz: 98cdf58391fea57de5ac5ea903a72e2d6fb15b67956ec64d0ffcdf73aa3231349f38b1555a31f2422653b2ed6acb37b63882918cbf16856368cb54af42c1924f
|
@@ -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,61 @@ $('.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
|
-
- ##### dataUrl
|
55
|
+
- ##### dataUrl <a name="dataUrl"></a>
|
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
|
|
62
|
+
- ##### dataFormatter
|
63
|
+
|
64
|
+
A function that can modify the data from the dataUrl before it is used.
|
65
|
+
|
66
|
+
The function signature is as follows:
|
67
|
+
|
68
|
+
```js
|
69
|
+
function(data) {
|
70
|
+
// Modify the data
|
71
|
+
|
72
|
+
return modifiedData
|
73
|
+
}
|
74
|
+
```
|
75
|
+
See <a href="#dataUrl">dataUrl</a> for details about the expected format of `data`.
|
76
|
+
|
53
77
|
- ##### optionFromDatum
|
78
|
+
|
54
79
|
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
80
|
|
56
81
|
The function signature is as follows:
|
82
|
+
|
57
83
|
```js
|
58
84
|
function(datum) {
|
59
85
|
return // a <option> element to represent the select
|
@@ -63,25 +89,36 @@ as a JSON string. All options on the are passed to the underlying UberSearch, se
|
|
63
89
|
Default: `datum.value` populates the `<option>` value, `datum.text` populates the `<option>` text.
|
64
90
|
|
65
91
|
- ##### value
|
92
|
+
|
66
93
|
Initialize the UberSearch with this selected value
|
67
94
|
|
68
95
|
Default: `<select>` element `value` property
|
69
96
|
|
97
|
+
- ##### ariaLabel
|
98
|
+
|
99
|
+
Add an aria-label attribute with this value to the uber_select element.
|
100
|
+
|
70
101
|
#### Events Triggered
|
102
|
+
|
71
103
|
- ##### uber-select:ready
|
104
|
+
|
72
105
|
This fires when the UberSelect has initialized and is ready for user interaction
|
73
106
|
|
74
107
|
#### Events Observed
|
108
|
+
|
75
109
|
The `<select>` element observes the following events:
|
76
110
|
|
77
111
|
- ##### uber-select:refreshOptions
|
112
|
+
|
78
113
|
The UberSearch options list will be updated to match the `<select>` element's `<option>` list.
|
79
114
|
|
80
115
|
- ##### uber-select:refresh
|
116
|
+
|
81
117
|
The UberSearch will update its selected value to match the `<select>` element's. This handler also runs when the
|
82
118
|
`<select>` element triggers a `change` event.
|
83
119
|
|
84
120
|
### UberSearch
|
121
|
+
|
85
122
|
The UberSearch performs all of the heavy lifting. It creates the UI views, maintains state, and performs the searching.
|
86
123
|
It can be instantiated without the use of an UberSelect, which can be useful for situations where the selected value is
|
87
124
|
being used in purely in JS, and not being linked to a `<select>` element in a form.
|
@@ -93,114 +130,152 @@ new UberSearch(data, options);
|
|
93
130
|
```
|
94
131
|
|
95
132
|
#### Data
|
133
|
+
|
96
134
|
Data is an array of objects. Each object may have the following properties:
|
97
135
|
|
98
136
|
- ##### text
|
137
|
+
|
99
138
|
String shown to the user in the list of results. This value is required if *value* is not provided.
|
100
139
|
|
101
140
|
- ##### selectedText
|
141
|
+
|
102
142
|
String shown to the user in the output container when this option is selected. *optional*
|
103
143
|
|
104
144
|
- ##### title
|
145
|
+
|
105
146
|
Title text shown to the user when hovering over the result. *optional*
|
106
147
|
|
107
148
|
- ##### value
|
149
|
+
|
108
150
|
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
151
|
|
110
152
|
- ##### matchValue
|
153
|
+
|
111
154
|
This overrides the value used to match against search input text when the user searches. *optional*
|
112
155
|
|
113
156
|
- ##### visibility
|
157
|
+
|
114
158
|
This is used to determine whether the option appears only when searching or only when not searching. Values accepted: `query`, `no-query`. *optional*
|
115
159
|
|
116
160
|
- ##### disabled
|
161
|
+
|
117
162
|
This is used to determine whether the option appears disabled. *optional*
|
118
163
|
|
119
164
|
- ##### group
|
165
|
+
|
120
166
|
This is used to visually group options. All options with the same group will appear together. *optional*
|
121
167
|
|
122
168
|
#### Methods
|
123
169
|
|
124
170
|
- ##### setData(data)
|
171
|
+
|
125
172
|
Sets the data. `data` should be an Array conforming to the specifications described in <a href="#data">Data</a>
|
126
173
|
|
174
|
+
- ##### getValue()
|
175
|
+
|
176
|
+
Returns the currently selected value.
|
177
|
+
|
178
|
+
- ##### getSelection()
|
179
|
+
|
180
|
+
Returns the currently selected element from the search results.
|
181
|
+
|
127
182
|
|
128
183
|
#### Options <a name="UberSearch options"></a>
|
184
|
+
|
129
185
|
Options can be specified by setting the `data-uber-options` attribute on the `<select>` element. Values should be passed
|
130
186
|
as a JSON string.
|
131
187
|
|
132
188
|
- ##### value
|
189
|
+
|
133
190
|
Sets the initially selected value of the UberSearch. This value should match the `value` property of the desired
|
134
191
|
option data.
|
135
192
|
|
136
193
|
Default: `null`
|
137
194
|
|
138
195
|
- ##### search
|
196
|
+
|
139
197
|
Determines whether the search input be shown.
|
140
198
|
|
141
199
|
Default: `true`
|
142
200
|
|
143
201
|
- ##### clearSearchButton
|
202
|
+
|
144
203
|
Sets the text content of clear search button.
|
145
204
|
|
146
205
|
Default: `✕`
|
147
206
|
|
148
207
|
- ##### selectCaret
|
208
|
+
|
149
209
|
Sets the text content of clear select caret.
|
150
210
|
|
151
211
|
Default: `⌄`
|
152
212
|
|
153
213
|
- ##### hideBlankOption
|
214
|
+
|
154
215
|
Sets whether blank options should be hidden automatically.
|
155
216
|
|
156
217
|
Default: `false`
|
157
218
|
|
158
219
|
- ##### treatBlankOptionAsPlaceholder
|
220
|
+
|
159
221
|
Determines whether the `text` property of an option with a blank `value` property should be used as the placeholder
|
160
222
|
text if no placeholder is specified.
|
161
223
|
|
162
224
|
Default: `false`
|
163
225
|
|
164
226
|
- ##### highlightByDefault
|
227
|
+
|
165
228
|
Determines whether the first search result be auto-highlighted.
|
166
229
|
|
167
230
|
Default: `true`
|
168
231
|
|
169
232
|
- ##### minQueryLength
|
233
|
+
|
170
234
|
Sets minimum number of characters the user must type before a search will be performed.
|
171
235
|
|
172
236
|
Default: `0`
|
173
237
|
|
174
238
|
- ##### minQueryMessage
|
239
|
+
|
175
240
|
Sets the message shown to the user when the query doesn't exceed the minimum length. `true` for a default message,
|
176
241
|
`false` for none, or provide a string to set a custom message.
|
177
242
|
|
178
243
|
Default: `true`
|
179
244
|
|
180
245
|
- ##### placeholder
|
246
|
+
|
181
247
|
Sets the placeholder shown in the selected text area.
|
182
248
|
|
183
249
|
Default: `null`
|
184
250
|
|
185
251
|
- ##### searchPlaceholder
|
252
|
+
|
186
253
|
Sets the placeholder shown in the search input.
|
187
254
|
|
188
255
|
Default: `'Type to search'`
|
189
256
|
|
190
257
|
- ##### noResultsText
|
258
|
+
|
191
259
|
Sets the message shown when there are no results.
|
192
260
|
|
193
261
|
Default: `'No Matches Found'`
|
194
262
|
|
195
263
|
- ##### noDataText
|
264
|
+
|
196
265
|
Sets the text to show when the results list is empty and no search is in progress
|
197
266
|
|
198
267
|
Default: `'No options'`
|
199
268
|
|
269
|
+
- ##### searchInputAttributes
|
270
|
+
|
271
|
+
An Object containing attributes to add to the search input element.
|
272
|
+
|
200
273
|
- ##### buildResult
|
274
|
+
|
201
275
|
A function that is used to build result elements.
|
202
276
|
|
203
277
|
The function signature is as follows:
|
278
|
+
|
204
279
|
```js
|
205
280
|
function(listOptionData) {
|
206
281
|
return // HTML/element to insert into the the results list
|
@@ -208,10 +283,12 @@ as a JSON string.
|
|
208
283
|
```
|
209
284
|
|
210
285
|
- ##### resultPostprocessor
|
286
|
+
|
211
287
|
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
288
|
functionality of an existing UberSearch implementation.
|
213
289
|
|
214
290
|
The function signature is as follows:
|
291
|
+
|
215
292
|
```js
|
216
293
|
function(resultsListElement, listOptionData) { }
|
217
294
|
```
|
@@ -219,50 +296,63 @@ as a JSON string.
|
|
219
296
|
Default: No-op
|
220
297
|
|
221
298
|
- ##### onRender
|
299
|
+
|
222
300
|
A function to run when the results container is rendered. If the result returns false, the default `select` event
|
223
301
|
handler is not run and the event is cancelled.
|
224
302
|
|
225
303
|
The function signature is as follows:
|
304
|
+
|
226
305
|
```js
|
227
306
|
function(resultsContainer, searchResultsHTML) { }
|
228
307
|
```
|
229
308
|
|
230
309
|
- ##### onSelect
|
310
|
+
|
231
311
|
A function to run when a result is selected. If the result returns false, the default `select` event handler is not
|
232
312
|
run and the event is cancelled.
|
233
313
|
|
234
314
|
The function signature is as follows:
|
315
|
+
|
235
316
|
```js
|
236
317
|
function(listOptionData, resultsListElement, clickEvent) { }
|
237
318
|
```
|
238
319
|
|
239
320
|
- ##### onNoHighlightSubmit
|
321
|
+
|
240
322
|
A function to run when a user presses enter without selecting a result.
|
241
323
|
Should be used in combination with `highlightByDefault: false`.
|
242
324
|
|
243
325
|
The function signature is as follows:
|
326
|
+
|
244
327
|
```js
|
245
328
|
function(value) { }
|
246
329
|
```
|
247
330
|
|
248
331
|
- ##### outputContainer (Deprecated)
|
332
|
+
|
249
333
|
An object that receives the output once a result is selected. Must respond to `setValue(value)` and `view()`. This object serves to
|
250
334
|
attach the result list to the DOM at the desired location.
|
251
335
|
|
252
336
|
#### Events Triggered
|
337
|
+
|
253
338
|
- ##### shown
|
339
|
+
|
254
340
|
This fires when the UberSearch pane is opened.
|
255
341
|
|
256
342
|
- ##### renderedResults
|
343
|
+
|
257
344
|
This fires each time the list of results is updated.
|
258
345
|
|
259
346
|
- ##### clear
|
347
|
+
|
260
348
|
This fires when the user clicks the clear search button.
|
261
349
|
|
262
350
|
- ##### select
|
351
|
+
|
263
352
|
This fires when the user selects a result.
|
264
353
|
|
265
354
|
The handler function signature is as follows:
|
355
|
+
|
266
356
|
```js
|
267
357
|
function(event, [listOptionData, resultsContainer, originalEvent]) { }
|
268
358
|
```
|
@@ -17,6 +17,7 @@
|
|
17
17
|
disabled: $(select).is(':disabled'), // Whether the select is currently disabled
|
18
18
|
placeholder: $(select).attr('placeholder') || $(select).attr('data-placeholder'), // Placeholder to show in the selected text area
|
19
19
|
dataUrl: null, // A url to pre-fetch select options from, see optionsFromData for data format
|
20
|
+
dataFormatter: function(data) { return data }, // A function to manipulate data received from the dataUrl before it is used. The function should return an array of data with desired modifications.
|
20
21
|
optionFromDatum: optionFromDatum, // A function to create select options
|
21
22
|
value: $(select).val() // Initialize the UberSearch with this selected value
|
22
23
|
}, opts, $(select).data('uber-options'))
|
@@ -61,6 +62,7 @@
|
|
61
62
|
hideSelect()
|
62
63
|
if (options.dataUrl) {
|
63
64
|
$.getJSON(options.dataUrl).done(function(data){
|
65
|
+
data = options.dataFormatter(data)
|
64
66
|
$(select).append(optionsFromData(data))
|
65
67
|
updateSelectValue(options.value)
|
66
68
|
uberSearch.setData(dataFromSelect(select))
|
@@ -134,7 +136,11 @@
|
|
134
136
|
|
135
137
|
// Copies the value of the select into the search input
|
136
138
|
function updateSearchValueFromSelect(){
|
137
|
-
|
139
|
+
var index = select.selectedIndex
|
140
|
+
|
141
|
+
if (index == undefined) { return }
|
142
|
+
|
143
|
+
uberSearch.searchField.input.val($(select).find('option').eq(index).text())
|
138
144
|
uberSearch.searchField.refresh()
|
139
145
|
}
|
140
146
|
|
@@ -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
91
|
markSelected()
|
62
|
-
$(searchField.input).focus()
|
63
92
|
view.addClass('open')
|
64
93
|
|
94
|
+
if (options.search) {
|
95
|
+
$(searchField.input).focus()
|
96
|
+
} else {
|
97
|
+
pane.view.find("ul.results li:first").focus()
|
98
|
+
}
|
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
|
|
@@ -152,6 +189,11 @@ var UberSearch = function(data, options){
|
|
152
189
|
markSelected()
|
153
190
|
}
|
154
191
|
|
192
|
+
// Returns the selected value
|
193
|
+
function getValue(){
|
194
|
+
return selectedValue
|
195
|
+
}
|
196
|
+
|
155
197
|
// Enables or disables UberSearch
|
156
198
|
function setDisabled(boolean){
|
157
199
|
outputContainer.setDisabled(boolean)
|
@@ -239,7 +281,7 @@ var UberSearch = function(data, options){
|
|
239
281
|
}
|
240
282
|
|
241
283
|
function buildResult(datum){
|
242
|
-
var result = $('<li class="result"></li>')
|
284
|
+
var result = $('<li class="result" tabindex="0"></li>')
|
243
285
|
.html((options.treatBlankOptionAsPlaceholder ? datum.text || options.placeholder : datum.text) || " ")
|
244
286
|
.data(datum) // Store the datum so we can get know what the value of the selected item is
|
245
287
|
|
@@ -325,5 +367,5 @@ var UberSearch = function(data, options){
|
|
325
367
|
|
326
368
|
// PUBLIC INTERFACE
|
327
369
|
|
328
|
-
$.extend(this, {view:view, searchField:searchField, setValue:setValue, setData:setData, setDisabled:setDisabled, options:options})
|
370
|
+
$.extend(this, {view:view, searchField:searchField, setValue:setValue, getValue: getValue, setData:setData, setDisabled:setDisabled, getSelection:getSelection, options:options})
|
329
371
|
}
|
@@ -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.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Jakobsen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -99,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
99
|
- !ruby/object:Gem::Version
|
100
100
|
version: '0'
|
101
101
|
requirements: []
|
102
|
-
rubygems_version: 3.
|
102
|
+
rubygems_version: 3.2.3
|
103
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
|