uber_select_rails 0.4.6 → 0.6.0
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 +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
|