uber_select_rails 0.4.4 → 0.5.1
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 +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
|