chosen-rails 1.5.2 → 1.8.2
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/README.md +1 -10
- data/lib/chosen-rails/rspec.rb +1 -1
- data/lib/chosen-rails/version.rb +2 -2
- data/vendor/assets/javascripts/chosen.jquery.coffee +114 -117
- data/vendor/assets/javascripts/chosen.proto.coffee +109 -96
- data/vendor/assets/javascripts/lib/abstract-chosen.coffee +112 -31
- data/vendor/assets/javascripts/lib/select-parser.coffee +1 -16
- data/vendor/assets/stylesheets/chosen-base.scss +17 -12
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84d37ed2825106c6c400858bff7497d7d9319335
|
4
|
+
data.tar.gz: 6f5a6bbbdf12cf07e6830d3c4ed9f834b6409f5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e61368b655875ed16a8b99080fb0a2344e249e3ae96121bee97f40f7bda9c060f4d0e6078b8a2bc41fbfe3847e55c456020b4a6fd0150ccdcaf14e76b75aa28
|
7
|
+
data.tar.gz: c092ae8213173a6e1d357dea55fbb6cdad215a72e09efbcbd628864a48e7aa2d30217b0871f4c2515eb58593c52916940cad55d7641987576a9984c691c51913
|
data/README.md
CHANGED
@@ -8,17 +8,14 @@ The `chosen-rails` gem integrates the `Chosen` with the Rails asset pipeline.
|
|
8
8
|
|
9
9
|
### Install chosen-rails gem
|
10
10
|
|
11
|
-
Include `chosen-rails` in
|
11
|
+
Include `chosen-rails` in Gemfile
|
12
12
|
|
13
13
|
```rb
|
14
|
-
gem 'compass-rails'
|
15
14
|
gem 'chosen-rails'
|
16
15
|
```
|
17
16
|
|
18
17
|
Then run `bundle install`
|
19
18
|
|
20
|
-
You need to add `compass-rails` manually since it is not a dependency from version 1.5.1.
|
21
|
-
|
22
19
|
Please consider [jquery-turbolinks](https://github.com/kossnocorp/jquery.turbolinks) if you have turbolinks issues for Rails 4 +.
|
23
20
|
|
24
21
|
### Include chosen javascript assets
|
@@ -39,12 +36,6 @@ Or with Prototype
|
|
39
36
|
|
40
37
|
Add to your `app/assets/stylesheets/application.css`
|
41
38
|
|
42
|
-
```scss
|
43
|
-
*= require chosen-compass
|
44
|
-
```
|
45
|
-
|
46
|
-
or without `compass-rails`
|
47
|
-
|
48
39
|
```scss
|
49
40
|
*= require chosen
|
50
41
|
```
|
data/lib/chosen-rails/rspec.rb
CHANGED
data/lib/chosen-rails/version.rb
CHANGED
@@ -24,7 +24,6 @@ class Chosen extends AbstractChosen
|
|
24
24
|
setup: ->
|
25
25
|
@form_field_jq = $ @form_field
|
26
26
|
@current_selectedIndex = @form_field.selectedIndex
|
27
|
-
@is_rtl = @form_field_jq.hasClass "chosen-rtl"
|
28
27
|
|
29
28
|
set_up_html: ->
|
30
29
|
container_classes = ["chosen-container"]
|
@@ -34,17 +33,19 @@ class Chosen extends AbstractChosen
|
|
34
33
|
|
35
34
|
container_props =
|
36
35
|
'class': container_classes.join ' '
|
37
|
-
'style': "width: #{this.container_width()};"
|
38
36
|
'title': @form_field.title
|
39
37
|
|
40
38
|
container_props.id = @form_field.id.replace(/[^\w]/g, '_') + "_chosen" if @form_field.id.length
|
41
39
|
|
42
40
|
@container = ($ "<div />", container_props)
|
43
41
|
|
42
|
+
# CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
|
43
|
+
@container.width this.container_width()
|
44
|
+
|
44
45
|
if @is_multiple
|
45
|
-
@container.html
|
46
|
+
@container.html this.get_multi_html()
|
46
47
|
else
|
47
|
-
@container.html
|
48
|
+
@container.html this.get_single_html()
|
48
49
|
|
49
50
|
@form_field_jq.hide().after @container
|
50
51
|
@dropdown = @container.find('div.chosen-drop').first()
|
@@ -70,42 +71,44 @@ class Chosen extends AbstractChosen
|
|
70
71
|
@form_field_jq.trigger("chosen:ready", {chosen: this})
|
71
72
|
|
72
73
|
register_observers: ->
|
73
|
-
@container.
|
74
|
-
@container.
|
75
|
-
|
76
|
-
@container.
|
77
|
-
@container.
|
78
|
-
@container.
|
79
|
-
@container.
|
80
|
-
|
81
|
-
@search_results.
|
82
|
-
@search_results.
|
83
|
-
@search_results.
|
84
|
-
@search_results.
|
85
|
-
|
86
|
-
@search_results.
|
87
|
-
@search_results.
|
88
|
-
@search_results.
|
89
|
-
|
90
|
-
@form_field_jq.
|
91
|
-
@form_field_jq.
|
92
|
-
@form_field_jq.
|
93
|
-
@form_field_jq.
|
94
|
-
|
95
|
-
@search_field.
|
96
|
-
@search_field.
|
97
|
-
@search_field.
|
98
|
-
@search_field.
|
99
|
-
@search_field.
|
100
|
-
@search_field.
|
74
|
+
@container.on 'touchstart.chosen', (evt) => this.container_mousedown(evt); return
|
75
|
+
@container.on 'touchend.chosen', (evt) => this.container_mouseup(evt); return
|
76
|
+
|
77
|
+
@container.on 'mousedown.chosen', (evt) => this.container_mousedown(evt); return
|
78
|
+
@container.on 'mouseup.chosen', (evt) => this.container_mouseup(evt); return
|
79
|
+
@container.on 'mouseenter.chosen', (evt) => this.mouse_enter(evt); return
|
80
|
+
@container.on 'mouseleave.chosen', (evt) => this.mouse_leave(evt); return
|
81
|
+
|
82
|
+
@search_results.on 'mouseup.chosen', (evt) => this.search_results_mouseup(evt); return
|
83
|
+
@search_results.on 'mouseover.chosen', (evt) => this.search_results_mouseover(evt); return
|
84
|
+
@search_results.on 'mouseout.chosen', (evt) => this.search_results_mouseout(evt); return
|
85
|
+
@search_results.on 'mousewheel.chosen DOMMouseScroll.chosen', (evt) => this.search_results_mousewheel(evt); return
|
86
|
+
|
87
|
+
@search_results.on 'touchstart.chosen', (evt) => this.search_results_touchstart(evt); return
|
88
|
+
@search_results.on 'touchmove.chosen', (evt) => this.search_results_touchmove(evt); return
|
89
|
+
@search_results.on 'touchend.chosen', (evt) => this.search_results_touchend(evt); return
|
90
|
+
|
91
|
+
@form_field_jq.on "chosen:updated.chosen", (evt) => this.results_update_field(evt); return
|
92
|
+
@form_field_jq.on "chosen:activate.chosen", (evt) => this.activate_field(evt); return
|
93
|
+
@form_field_jq.on "chosen:open.chosen", (evt) => this.container_mousedown(evt); return
|
94
|
+
@form_field_jq.on "chosen:close.chosen", (evt) => this.close_field(evt); return
|
95
|
+
|
96
|
+
@search_field.on 'blur.chosen', (evt) => this.input_blur(evt); return
|
97
|
+
@search_field.on 'keyup.chosen', (evt) => this.keyup_checker(evt); return
|
98
|
+
@search_field.on 'keydown.chosen', (evt) => this.keydown_checker(evt); return
|
99
|
+
@search_field.on 'focus.chosen', (evt) => this.input_focus(evt); return
|
100
|
+
@search_field.on 'cut.chosen', (evt) => this.clipboard_event_checker(evt); return
|
101
|
+
@search_field.on 'paste.chosen', (evt) => this.clipboard_event_checker(evt); return
|
101
102
|
|
102
103
|
if @is_multiple
|
103
|
-
@search_choices.
|
104
|
+
@search_choices.on 'click.chosen', (evt) => this.choices_click(evt); return
|
104
105
|
else
|
105
|
-
@container.
|
106
|
+
@container.on 'click.chosen', (evt) -> evt.preventDefault(); return # gobble click of anchor
|
106
107
|
|
107
108
|
destroy: ->
|
108
|
-
$(@container[0].ownerDocument).
|
109
|
+
$(@container[0].ownerDocument).off 'click.chosen', @click_test_action
|
110
|
+
@form_field_label.off 'click.chosen' if @form_field_label.length > 0
|
111
|
+
|
109
112
|
if @search_field[0].tabIndex
|
110
113
|
@form_field_jq[0].tabIndex = @search_field[0].tabIndex
|
111
114
|
|
@@ -114,32 +117,35 @@ class Chosen extends AbstractChosen
|
|
114
117
|
@form_field_jq.show()
|
115
118
|
|
116
119
|
search_field_disabled: ->
|
117
|
-
@is_disabled = @form_field_jq
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
120
|
+
@is_disabled = @form_field.disabled || @form_field_jq.parents('fieldset').is(':disabled')
|
121
|
+
|
122
|
+
@container.toggleClass 'chosen-disabled', @is_disabled
|
123
|
+
@search_field[0].disabled = @is_disabled
|
124
|
+
|
125
|
+
unless @is_multiple
|
126
|
+
@selected_item.off 'focus.chosen', this.activate_field
|
127
|
+
|
128
|
+
if @is_disabled
|
122
129
|
this.close_field()
|
123
|
-
else
|
124
|
-
@
|
125
|
-
@search_field[0].disabled = false
|
126
|
-
@selected_item.bind "focus.chosen", @activate_action if !@is_multiple
|
130
|
+
else unless @is_multiple
|
131
|
+
@selected_item.on 'focus.chosen', this.activate_field
|
127
132
|
|
128
133
|
container_mousedown: (evt) ->
|
129
|
-
if
|
130
|
-
|
131
|
-
|
134
|
+
return if @is_disabled
|
135
|
+
|
136
|
+
if evt and evt.type in ['mousedown', 'touchstart'] and not @results_showing
|
137
|
+
evt.preventDefault()
|
132
138
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
139
|
+
if not (evt? and ($ evt.target).hasClass "search-choice-close")
|
140
|
+
if not @active_field
|
141
|
+
@search_field.val "" if @is_multiple
|
142
|
+
$(@container[0].ownerDocument).on 'click.chosen', @click_test_action
|
143
|
+
this.results_show()
|
144
|
+
else if not @is_multiple and evt and (($(evt.target)[0] == @selected_item[0]) || $(evt.target).parents("a.chosen-single").length)
|
145
|
+
evt.preventDefault()
|
146
|
+
this.results_toggle()
|
141
147
|
|
142
|
-
|
148
|
+
this.activate_field()
|
143
149
|
|
144
150
|
container_mouseup: (evt) ->
|
145
151
|
this.results_reset(evt) if evt.target.nodeName is "ABBR" and not @is_disabled
|
@@ -155,7 +161,7 @@ class Chosen extends AbstractChosen
|
|
155
161
|
this.close_field() if not @active_field and @container.hasClass "chosen-container-active"
|
156
162
|
|
157
163
|
close_field: ->
|
158
|
-
$(@container[0].ownerDocument).
|
164
|
+
$(@container[0].ownerDocument).off "click.chosen", @click_test_action
|
159
165
|
|
160
166
|
@active_field = false
|
161
167
|
this.results_hide()
|
@@ -165,8 +171,11 @@ class Chosen extends AbstractChosen
|
|
165
171
|
|
166
172
|
this.show_search_field_default()
|
167
173
|
this.search_field_scale()
|
174
|
+
@search_field.blur()
|
168
175
|
|
169
176
|
activate_field: ->
|
177
|
+
return if @is_disabled
|
178
|
+
|
170
179
|
@container.addClass "chosen-container-active"
|
171
180
|
@active_field = true
|
172
181
|
|
@@ -238,7 +247,7 @@ class Chosen extends AbstractChosen
|
|
238
247
|
@results_showing = true
|
239
248
|
|
240
249
|
@search_field.focus()
|
241
|
-
@search_field.val
|
250
|
+
@search_field.val this.get_search_field_value()
|
242
251
|
|
243
252
|
this.winnow_results()
|
244
253
|
@form_field_jq.trigger("chosen:showing_dropdown", {chosen: this})
|
@@ -268,7 +277,7 @@ class Chosen extends AbstractChosen
|
|
268
277
|
@form_field_label = $("label[for='#{@form_field.id}']") #next check for a for=#{id}
|
269
278
|
|
270
279
|
if @form_field_label.length > 0
|
271
|
-
@form_field_label.
|
280
|
+
@form_field_label.on 'click.chosen', this.label_click_handler
|
272
281
|
|
273
282
|
show_search_field_default: ->
|
274
283
|
if @is_multiple and this.choices_count() < 1 and not @active_field
|
@@ -290,7 +299,7 @@ class Chosen extends AbstractChosen
|
|
290
299
|
this.result_do_highlight( target ) if target
|
291
300
|
|
292
301
|
search_results_mouseout: (evt) ->
|
293
|
-
this.result_clear_highlight() if $(evt.target).hasClass
|
302
|
+
this.result_clear_highlight() if $(evt.target).hasClass("active-result") or $(evt.target).parents('.active-result').first()
|
294
303
|
|
295
304
|
choice_build: (item) ->
|
296
305
|
choice = $('<li />', { class: "search-choice" }).html("<span>#{this.choice_label(item)}</span>")
|
@@ -299,7 +308,7 @@ class Chosen extends AbstractChosen
|
|
299
308
|
choice.addClass 'search-choice-disabled'
|
300
309
|
else
|
301
310
|
close_link = $('<a />', { class: 'search-choice-close', 'data-option-array-index': item.array_index })
|
302
|
-
close_link.
|
311
|
+
close_link.on 'click.chosen', (evt) => this.choice_destroy_link_click(evt)
|
303
312
|
choice.append close_link
|
304
313
|
|
305
314
|
@search_container.before choice
|
@@ -311,9 +320,12 @@ class Chosen extends AbstractChosen
|
|
311
320
|
|
312
321
|
choice_destroy: (link) ->
|
313
322
|
if this.result_deselect( link[0].getAttribute("data-option-array-index") )
|
314
|
-
|
323
|
+
if @active_field
|
324
|
+
@search_field.focus()
|
325
|
+
else
|
326
|
+
this.show_search_field_default()
|
315
327
|
|
316
|
-
this.results_hide() if @is_multiple and this.choices_count() > 0 and
|
328
|
+
this.results_hide() if @is_multiple and this.choices_count() > 0 and this.get_search_field_value().length < 1
|
317
329
|
|
318
330
|
link.parents('li').first().remove()
|
319
331
|
|
@@ -325,7 +337,7 @@ class Chosen extends AbstractChosen
|
|
325
337
|
this.single_set_selected_text()
|
326
338
|
this.show_search_field_default()
|
327
339
|
this.results_reset_cleanup()
|
328
|
-
|
340
|
+
this.trigger_form_field_change()
|
329
341
|
this.results_hide() if @active_field
|
330
342
|
|
331
343
|
results_reset_cleanup: ->
|
@@ -354,16 +366,20 @@ class Chosen extends AbstractChosen
|
|
354
366
|
|
355
367
|
@form_field.options[item.options_index].selected = true
|
356
368
|
@selected_option_count = null
|
369
|
+
@search_field.val("")
|
357
370
|
|
358
371
|
if @is_multiple
|
359
372
|
this.choice_build item
|
360
373
|
else
|
361
374
|
this.single_set_selected_text(this.choice_label(item))
|
362
375
|
|
363
|
-
|
364
|
-
|
376
|
+
if @is_multiple && (!@hide_results_on_select || (evt.metaKey or evt.ctrlKey))
|
377
|
+
this.winnow_results()
|
378
|
+
else
|
379
|
+
this.results_hide()
|
380
|
+
this.show_search_field_default()
|
365
381
|
|
366
|
-
|
382
|
+
this.trigger_form_field_change selected: @form_field.options[item.options_index].value if @is_multiple || @form_field.selectedIndex != @current_selectedIndex
|
367
383
|
@current_selectedIndex = @form_field.selectedIndex
|
368
384
|
|
369
385
|
evt.preventDefault()
|
@@ -391,7 +407,7 @@ class Chosen extends AbstractChosen
|
|
391
407
|
this.result_clear_highlight()
|
392
408
|
this.winnow_results() if @results_showing
|
393
409
|
|
394
|
-
|
410
|
+
this.trigger_form_field_change deselected: @form_field.options[result_data.options_index].value
|
395
411
|
this.search_field_scale()
|
396
412
|
|
397
413
|
return true
|
@@ -403,8 +419,14 @@ class Chosen extends AbstractChosen
|
|
403
419
|
@selected_item.find("span").first().after "<abbr class=\"search-choice-close\"></abbr>" unless @selected_item.find("abbr").length
|
404
420
|
@selected_item.addClass("chosen-single-with-deselect")
|
405
421
|
|
422
|
+
get_search_field_value: ->
|
423
|
+
@search_field.val()
|
424
|
+
|
406
425
|
get_search_text: ->
|
407
|
-
|
426
|
+
$.trim this.get_search_field_value()
|
427
|
+
|
428
|
+
escape_html: (text) ->
|
429
|
+
$('<div/>').text(text).html()
|
408
430
|
|
409
431
|
winnow_results_set_highlight: ->
|
410
432
|
selected_results = if not @is_multiple then @search_results.find(".result-selected.active-result") else []
|
@@ -413,9 +435,7 @@ class Chosen extends AbstractChosen
|
|
413
435
|
this.result_do_highlight do_high if do_high?
|
414
436
|
|
415
437
|
no_results: (terms) ->
|
416
|
-
no_results_html =
|
417
|
-
no_results_html.find("span").first().html(terms)
|
418
|
-
|
438
|
+
no_results_html = this.get_no_results_html(terms)
|
419
439
|
@search_results.append no_results_html
|
420
440
|
@form_field_jq.trigger("chosen:no_results", {chosen:this})
|
421
441
|
|
@@ -458,56 +478,33 @@ class Chosen extends AbstractChosen
|
|
458
478
|
@pending_backstroke.removeClass "search-choice-focus" if @pending_backstroke
|
459
479
|
@pending_backstroke = null
|
460
480
|
|
461
|
-
keydown_checker: (evt) ->
|
462
|
-
stroke = evt.which ? evt.keyCode
|
463
|
-
this.search_field_scale()
|
464
|
-
|
465
|
-
this.clear_backstroke() if stroke != 8 and this.pending_backstroke
|
466
|
-
|
467
|
-
switch stroke
|
468
|
-
when 8
|
469
|
-
@backstroke_length = this.search_field.val().length
|
470
|
-
break
|
471
|
-
when 9
|
472
|
-
this.result_select(evt) if this.results_showing and not @is_multiple
|
473
|
-
@mouse_on_container = false
|
474
|
-
break
|
475
|
-
when 13
|
476
|
-
evt.preventDefault() if this.results_showing
|
477
|
-
break
|
478
|
-
when 32
|
479
|
-
evt.preventDefault() if @disable_search
|
480
|
-
break
|
481
|
-
when 38
|
482
|
-
evt.preventDefault()
|
483
|
-
this.keyup_arrow()
|
484
|
-
break
|
485
|
-
when 40
|
486
|
-
evt.preventDefault()
|
487
|
-
this.keydown_arrow()
|
488
|
-
break
|
489
|
-
|
490
481
|
search_field_scale: ->
|
491
|
-
|
492
|
-
|
493
|
-
|
482
|
+
return unless @is_multiple
|
483
|
+
|
484
|
+
style_block =
|
485
|
+
position: 'absolute'
|
486
|
+
left: '-1000px'
|
487
|
+
top: '-1000px'
|
488
|
+
display: 'none'
|
489
|
+
whiteSpace: 'pre'
|
494
490
|
|
495
|
-
|
496
|
-
styles = ['font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing']
|
491
|
+
styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing']
|
497
492
|
|
498
|
-
|
499
|
-
|
493
|
+
for style in styles
|
494
|
+
style_block[style] = @search_field.css(style)
|
500
495
|
|
501
|
-
|
502
|
-
|
503
|
-
|
496
|
+
div = $('<div />').css(style_block)
|
497
|
+
div.text this.get_search_field_value()
|
498
|
+
$('body').append div
|
504
499
|
|
505
|
-
|
506
|
-
|
500
|
+
width = div.width() + 25
|
501
|
+
div.remove()
|
507
502
|
|
508
|
-
|
503
|
+
if @container.is(':visible')
|
504
|
+
width = Math.min(@container.outerWidth() - 10, width)
|
509
505
|
|
510
|
-
|
511
|
-
w = f_width - 10
|
506
|
+
@search_field.width(width)
|
512
507
|
|
513
|
-
|
508
|
+
trigger_form_field_change: (extra) ->
|
509
|
+
@form_field_jq.trigger "input", extra
|
510
|
+
@form_field_jq.trigger "change", extra
|
@@ -2,15 +2,6 @@ class @Chosen extends AbstractChosen
|
|
2
2
|
|
3
3
|
setup: ->
|
4
4
|
@current_selectedIndex = @form_field.selectedIndex
|
5
|
-
@is_rtl = @form_field.hasClassName "chosen-rtl"
|
6
|
-
|
7
|
-
set_default_values: ->
|
8
|
-
super()
|
9
|
-
|
10
|
-
# HTML Templates
|
11
|
-
@single_temp = new Template('<a class="chosen-single chosen-default"><span>#{default}</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>')
|
12
|
-
@multi_temp = new Template('<ul class="chosen-choices"><li class="search-field"><input type="text" value="#{default}" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>')
|
13
|
-
@no_results_temp = new Template('<li class="no-results">' + @results_none_found + ' "<span>#{terms}</span>"</li>')
|
14
5
|
|
15
6
|
set_up_html: ->
|
16
7
|
container_classes = ["chosen-container"]
|
@@ -20,12 +11,19 @@ class @Chosen extends AbstractChosen
|
|
20
11
|
|
21
12
|
container_props =
|
22
13
|
'class': container_classes.join ' '
|
23
|
-
'style': "width: #{this.container_width()};"
|
24
14
|
'title': @form_field.title
|
25
15
|
|
26
16
|
container_props.id = @form_field.id.replace(/[^\w]/g, '_') + "_chosen" if @form_field.id.length
|
27
17
|
|
28
|
-
@container =
|
18
|
+
@container = new Element('div', container_props)
|
19
|
+
|
20
|
+
# CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
|
21
|
+
@container.setStyle(width: this.container_width())
|
22
|
+
|
23
|
+
if @is_multiple
|
24
|
+
@container.update this.get_multi_html()
|
25
|
+
else
|
26
|
+
@container.update this.get_single_html()
|
29
27
|
|
30
28
|
@form_field.hide().insert({ after: @container })
|
31
29
|
@dropdown = @container.down('div.chosen-drop')
|
@@ -51,8 +49,8 @@ class @Chosen extends AbstractChosen
|
|
51
49
|
@form_field.fire("chosen:ready", {chosen: this})
|
52
50
|
|
53
51
|
register_observers: ->
|
54
|
-
@container.observe "touchstart", (evt) => this.container_mousedown(evt)
|
55
|
-
@container.observe "touchend", (evt) => this.container_mouseup(evt)
|
52
|
+
@container.observe "touchstart", (evt) => this.container_mousedown(evt)
|
53
|
+
@container.observe "touchend", (evt) => this.container_mouseup(evt)
|
56
54
|
|
57
55
|
@container.observe "mousedown", (evt) => this.container_mousedown(evt)
|
58
56
|
@container.observe "mouseup", (evt) => this.container_mouseup(evt)
|
@@ -72,7 +70,7 @@ class @Chosen extends AbstractChosen
|
|
72
70
|
@form_field.observe "chosen:updated", (evt) => this.results_update_field(evt)
|
73
71
|
@form_field.observe "chosen:activate", (evt) => this.activate_field(evt)
|
74
72
|
@form_field.observe "chosen:open", (evt) => this.container_mousedown(evt)
|
75
|
-
@form_field.observe "chosen:close", (evt) => this.
|
73
|
+
@form_field.observe "chosen:close", (evt) => this.close_field(evt)
|
76
74
|
|
77
75
|
@search_field.observe "blur", (evt) => this.input_blur(evt)
|
78
76
|
@search_field.observe "keyup", (evt) => this.keyup_checker(evt)
|
@@ -89,7 +87,9 @@ class @Chosen extends AbstractChosen
|
|
89
87
|
destroy: ->
|
90
88
|
@container.ownerDocument.stopObserving "click", @click_test_action
|
91
89
|
|
92
|
-
|
90
|
+
for event in ['chosen:updated', 'chosen:activate', 'chosen:open', 'chosen:close']
|
91
|
+
@form_field.stopObserving(event)
|
92
|
+
|
93
93
|
@container.stopObserving()
|
94
94
|
@search_results.stopObserving()
|
95
95
|
@search_field.stopObserving()
|
@@ -109,31 +109,38 @@ class @Chosen extends AbstractChosen
|
|
109
109
|
@form_field.show()
|
110
110
|
|
111
111
|
search_field_disabled: ->
|
112
|
-
@is_disabled = @form_field.disabled
|
113
|
-
|
112
|
+
@is_disabled = @form_field.disabled || @form_field.up('fieldset')?.disabled || false
|
113
|
+
|
114
|
+
if @is_disabled
|
114
115
|
@container.addClassName 'chosen-disabled'
|
115
|
-
@search_field.disabled = true
|
116
|
-
@selected_item.stopObserving "focus", @activate_action if !@is_multiple
|
117
|
-
this.close_field()
|
118
116
|
else
|
119
117
|
@container.removeClassName 'chosen-disabled'
|
120
|
-
|
121
|
-
|
118
|
+
|
119
|
+
@search_field.disabled = @is_disabled
|
120
|
+
|
121
|
+
unless @is_multiple
|
122
|
+
@selected_item.stopObserving 'focus', this.activate_field
|
123
|
+
|
124
|
+
if @is_disabled
|
125
|
+
this.close_field()
|
126
|
+
else unless @is_multiple
|
127
|
+
@selected_item.observe 'focus', this.activate_field
|
122
128
|
|
123
129
|
container_mousedown: (evt) ->
|
124
|
-
if
|
125
|
-
|
126
|
-
|
130
|
+
return if @is_disabled
|
131
|
+
|
132
|
+
if evt and evt.type in ['mousedown', 'touchstart'] and not @results_showing
|
133
|
+
evt.preventDefault()
|
127
134
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
+
if not (evt? and evt.target.hasClassName "search-choice-close")
|
136
|
+
if not @active_field
|
137
|
+
@search_field.clear() if @is_multiple
|
138
|
+
@container.ownerDocument.observe "click", @click_test_action
|
139
|
+
this.results_show()
|
140
|
+
else if not @is_multiple and evt and (evt.target is @selected_item || evt.target.up("a.chosen-single"))
|
141
|
+
this.results_toggle()
|
135
142
|
|
136
|
-
|
143
|
+
this.activate_field()
|
137
144
|
|
138
145
|
container_mouseup: (evt) ->
|
139
146
|
this.results_reset(evt) if evt.target.nodeName is "ABBR" and not @is_disabled
|
@@ -159,12 +166,15 @@ class @Chosen extends AbstractChosen
|
|
159
166
|
|
160
167
|
this.show_search_field_default()
|
161
168
|
this.search_field_scale()
|
169
|
+
@search_field.blur()
|
162
170
|
|
163
171
|
activate_field: ->
|
172
|
+
return if @is_disabled
|
173
|
+
|
164
174
|
@container.addClassName "chosen-container-active"
|
165
175
|
@active_field = true
|
166
176
|
|
167
|
-
@search_field.value =
|
177
|
+
@search_field.value = this.get_search_field_value()
|
168
178
|
@search_field.focus()
|
169
179
|
|
170
180
|
test_active_click: (evt) ->
|
@@ -229,7 +239,7 @@ class @Chosen extends AbstractChosen
|
|
229
239
|
@results_showing = true
|
230
240
|
|
231
241
|
@search_field.focus()
|
232
|
-
@search_field.value =
|
242
|
+
@search_field.value = this.get_search_field_value()
|
233
243
|
|
234
244
|
this.winnow_results()
|
235
245
|
@form_field.fire("chosen:showing_dropdown", {chosen: this})
|
@@ -259,7 +269,7 @@ class @Chosen extends AbstractChosen
|
|
259
269
|
@form_field_label = $$("label[for='#{@form_field.id}']").first() #next check for a for=#{id}
|
260
270
|
|
261
271
|
if @form_field_label?
|
262
|
-
@form_field_label.observe "click",
|
272
|
+
@form_field_label.observe "click", this.label_click_handler
|
263
273
|
|
264
274
|
show_search_field_default: ->
|
265
275
|
if @is_multiple and this.choices_count() < 1 and not @active_field
|
@@ -302,9 +312,12 @@ class @Chosen extends AbstractChosen
|
|
302
312
|
|
303
313
|
choice_destroy: (link) ->
|
304
314
|
if this.result_deselect link.readAttribute("rel")
|
305
|
-
|
315
|
+
if @active_field
|
316
|
+
@search_field.focus()
|
317
|
+
else
|
318
|
+
this.show_search_field_default()
|
306
319
|
|
307
|
-
this.results_hide() if @is_multiple and this.choices_count() > 0 and
|
320
|
+
this.results_hide() if @is_multiple and this.choices_count() > 0 and this.get_search_field_value().length < 1
|
308
321
|
|
309
322
|
link.up('li').remove()
|
310
323
|
|
@@ -316,7 +329,7 @@ class @Chosen extends AbstractChosen
|
|
316
329
|
this.single_set_selected_text()
|
317
330
|
this.show_search_field_default()
|
318
331
|
this.results_reset_cleanup()
|
319
|
-
|
332
|
+
this.trigger_form_field_change()
|
320
333
|
this.results_hide() if @active_field
|
321
334
|
|
322
335
|
results_reset_cleanup: ->
|
@@ -345,16 +358,20 @@ class @Chosen extends AbstractChosen
|
|
345
358
|
|
346
359
|
@form_field.options[item.options_index].selected = true
|
347
360
|
@selected_option_count = null
|
361
|
+
@search_field.value = ""
|
348
362
|
|
349
363
|
if @is_multiple
|
350
364
|
this.choice_build item
|
351
365
|
else
|
352
366
|
this.single_set_selected_text(this.choice_label(item))
|
353
367
|
|
354
|
-
|
355
|
-
|
368
|
+
if @is_multiple && (!@hide_results_on_select || (evt.metaKey or evt.ctrlKey))
|
369
|
+
this.winnow_results()
|
370
|
+
else
|
371
|
+
this.results_hide()
|
372
|
+
this.show_search_field_default()
|
356
373
|
|
357
|
-
|
374
|
+
this.trigger_form_field_change() if @is_multiple || @form_field.selectedIndex != @current_selectedIndex
|
358
375
|
@current_selectedIndex = @form_field.selectedIndex
|
359
376
|
|
360
377
|
evt.preventDefault()
|
@@ -382,7 +399,7 @@ class @Chosen extends AbstractChosen
|
|
382
399
|
this.result_clear_highlight()
|
383
400
|
this.winnow_results() if @results_showing
|
384
401
|
|
385
|
-
|
402
|
+
this.trigger_form_field_change()
|
386
403
|
this.search_field_scale()
|
387
404
|
return true
|
388
405
|
else
|
@@ -393,8 +410,14 @@ class @Chosen extends AbstractChosen
|
|
393
410
|
@selected_item.down("span").insert { after: "<abbr class=\"search-choice-close\"></abbr>" } unless @selected_item.down("abbr")
|
394
411
|
@selected_item.addClassName("chosen-single-with-deselect")
|
395
412
|
|
413
|
+
get_search_field_value: ->
|
414
|
+
@search_field.value
|
415
|
+
|
396
416
|
get_search_text: ->
|
397
|
-
|
417
|
+
this.get_search_field_value().strip()
|
418
|
+
|
419
|
+
escape_html: (text) ->
|
420
|
+
text.escapeHTML()
|
398
421
|
|
399
422
|
winnow_results_set_highlight: ->
|
400
423
|
if not @is_multiple
|
@@ -406,7 +429,7 @@ class @Chosen extends AbstractChosen
|
|
406
429
|
this.result_do_highlight do_high if do_high?
|
407
430
|
|
408
431
|
no_results: (terms) ->
|
409
|
-
@search_results.insert
|
432
|
+
@search_results.insert this.get_no_results_html(terms)
|
410
433
|
@form_field.fire("chosen:no_results", {chosen: this})
|
411
434
|
|
412
435
|
no_results_clear: ->
|
@@ -453,55 +476,45 @@ class @Chosen extends AbstractChosen
|
|
453
476
|
@pending_backstroke.removeClassName("search-choice-focus") if @pending_backstroke
|
454
477
|
@pending_backstroke = null
|
455
478
|
|
456
|
-
keydown_checker: (evt) ->
|
457
|
-
stroke = evt.which ? evt.keyCode
|
458
|
-
this.search_field_scale()
|
459
|
-
|
460
|
-
this.clear_backstroke() if stroke != 8 and this.pending_backstroke
|
461
|
-
|
462
|
-
switch stroke
|
463
|
-
when 8
|
464
|
-
@backstroke_length = this.search_field.value.length
|
465
|
-
break
|
466
|
-
when 9
|
467
|
-
this.result_select(evt) if this.results_showing and not @is_multiple
|
468
|
-
@mouse_on_container = false
|
469
|
-
break
|
470
|
-
when 13
|
471
|
-
evt.preventDefault() if this.results_showing
|
472
|
-
break
|
473
|
-
when 32
|
474
|
-
evt.preventDefault() if @disable_search
|
475
|
-
break
|
476
|
-
when 38
|
477
|
-
evt.preventDefault()
|
478
|
-
this.keyup_arrow()
|
479
|
-
break
|
480
|
-
when 40
|
481
|
-
evt.preventDefault()
|
482
|
-
this.keydown_arrow()
|
483
|
-
break
|
484
|
-
|
485
479
|
search_field_scale: ->
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
480
|
+
return unless @is_multiple
|
481
|
+
|
482
|
+
style_block =
|
483
|
+
position: 'absolute'
|
484
|
+
left: '-1000px'
|
485
|
+
top: '-1000px'
|
486
|
+
display: 'none'
|
487
|
+
whiteSpace: 'pre'
|
488
|
+
|
489
|
+
styles = ['fontSize', 'fontStyle', 'fontWeight', 'fontFamily', 'lineHeight', 'textTransform', 'letterSpacing']
|
490
|
+
|
491
|
+
for style in styles
|
492
|
+
style_block[style] = @search_field.getStyle(style)
|
493
|
+
|
494
|
+
div = new Element('div').update(this.escape_html(this.get_search_field_value()))
|
495
|
+
# CSP without 'unsafe-inline' doesn't allow setting the style attribute directly
|
496
|
+
div.setStyle(style_block)
|
497
|
+
document.body.appendChild(div)
|
498
|
+
|
499
|
+
width = div.measure('width') + 25
|
500
|
+
div.remove()
|
501
|
+
|
502
|
+
if container_width = @container.getWidth()
|
503
|
+
width = Math.min(container_width - 10, width)
|
504
|
+
|
505
|
+
@search_field.setStyle(width: width + 'px')
|
506
|
+
|
507
|
+
trigger_form_field_change: ->
|
508
|
+
triggerHtmlEvent @form_field, 'input'
|
509
|
+
triggerHtmlEvent @form_field, 'change'
|
510
|
+
|
511
|
+
triggerHtmlEvent = (element, eventType) ->
|
512
|
+
if element.dispatchEvent # Modern way:
|
513
|
+
try
|
514
|
+
evt = new Event(eventType, bubbles: true, cancelable: true)
|
515
|
+
catch
|
516
|
+
evt = document.createEvent('HTMLEvents')
|
517
|
+
evt.initEvent(eventType, true, true);
|
518
|
+
element.dispatchEvent(evt)
|
519
|
+
else # Old IE:
|
520
|
+
element.fireEvent("on#{eventType}", document.createEventObject());
|
@@ -20,6 +20,7 @@ class AbstractChosen
|
|
20
20
|
@mouse_on_container = false
|
21
21
|
@results_showing = false
|
22
22
|
@result_highlighted = null
|
23
|
+
@is_rtl = @options.rtl || /\bchosen-rtl\b/.test(@form_field.className)
|
23
24
|
@allow_single_deselect = if @options.allow_single_deselect? and @form_field.options[0]? and @form_field.options[0].text is "" then @options.allow_single_deselect else false
|
24
25
|
@disable_search_threshold = @options.disable_search_threshold || 0
|
25
26
|
@disable_search = @options.disable_search || false
|
@@ -34,6 +35,7 @@ class AbstractChosen
|
|
34
35
|
@include_group_label_in_selected = @options.include_group_label_in_selected || false
|
35
36
|
@max_shown_results = @options.max_shown_results || Number.POSITIVE_INFINITY
|
36
37
|
@case_sensitive_search = @options.case_sensitive_search || false
|
38
|
+
@hide_results_on_select = if @options.hide_results_on_select? then @options.hide_results_on_select else true
|
37
39
|
|
38
40
|
set_default_text: ->
|
39
41
|
if @form_field.getAttribute("data-placeholder")
|
@@ -43,6 +45,8 @@ class AbstractChosen
|
|
43
45
|
else
|
44
46
|
@default_text = @options.placeholder_text_single || @options.placeholder_text || AbstractChosen.default_single_text
|
45
47
|
|
48
|
+
@default_text = this.escape_html(@default_text)
|
49
|
+
|
46
50
|
@results_none_found = @form_field.getAttribute("data-no_results_text") || @options.no_results_text || AbstractChosen.default_no_result_text
|
47
51
|
|
48
52
|
choice_label: (item) ->
|
@@ -65,6 +69,12 @@ class AbstractChosen
|
|
65
69
|
@active_field = false
|
66
70
|
setTimeout (=> this.blur_test()), 100
|
67
71
|
|
72
|
+
label_click_handler: (evt) =>
|
73
|
+
if @is_multiple
|
74
|
+
this.container_mousedown(evt)
|
75
|
+
else
|
76
|
+
this.activate_field()
|
77
|
+
|
68
78
|
results_option_build: (options) ->
|
69
79
|
content = ''
|
70
80
|
shown_results = 0
|
@@ -106,7 +116,7 @@ class AbstractChosen
|
|
106
116
|
option_el.className = classes.join(" ")
|
107
117
|
option_el.style.cssText = option.style
|
108
118
|
option_el.setAttribute("data-option-array-index", option.array_index)
|
109
|
-
option_el.innerHTML = option.
|
119
|
+
option_el.innerHTML = option.highlighted_html or option.html
|
110
120
|
option_el.title = option.title if option.title
|
111
121
|
|
112
122
|
this.outerHTML(option_el)
|
@@ -121,7 +131,7 @@ class AbstractChosen
|
|
121
131
|
|
122
132
|
group_el = document.createElement("li")
|
123
133
|
group_el.className = classes.join(" ")
|
124
|
-
group_el.innerHTML = group.
|
134
|
+
group_el.innerHTML = group.highlighted_html or this.escape_html(group.label)
|
125
135
|
group_el.title = group.title if group.title
|
126
136
|
|
127
137
|
this.outerHTML(group_el)
|
@@ -154,15 +164,16 @@ class AbstractChosen
|
|
154
164
|
|
155
165
|
results = 0
|
156
166
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
regex = this.get_search_regex(escapedSearchText)
|
167
|
+
query = this.get_search_text()
|
168
|
+
escapedQuery = query.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
|
169
|
+
regex = this.get_search_regex(escapedQuery)
|
161
170
|
|
162
171
|
for option in @results_data
|
163
172
|
|
164
173
|
option.search_match = false
|
165
174
|
results_group = null
|
175
|
+
search_match = null
|
176
|
+
option.highlighted_html = ''
|
166
177
|
|
167
178
|
if this.include_option_in_results(option)
|
168
179
|
|
@@ -175,17 +186,21 @@ class AbstractChosen
|
|
175
186
|
results += 1 if results_group.active_options is 0 and results_group.search_match
|
176
187
|
results_group.active_options += 1
|
177
188
|
|
178
|
-
|
189
|
+
text = if option.group then option.label else option.text
|
179
190
|
|
180
191
|
unless option.group and not @group_search
|
181
|
-
|
192
|
+
search_match = this.search_string_match(text, regex)
|
193
|
+
option.search_match = search_match?
|
194
|
+
|
182
195
|
results += 1 if option.search_match and not option.group
|
183
196
|
|
184
197
|
if option.search_match
|
185
|
-
if
|
186
|
-
startpos =
|
187
|
-
|
188
|
-
|
198
|
+
if query.length
|
199
|
+
startpos = search_match.index
|
200
|
+
prefix = text.slice(0, startpos)
|
201
|
+
fix = text.slice(startpos, startpos + query.length)
|
202
|
+
suffix = text.slice(startpos + query.length)
|
203
|
+
option.highlighted_html = "#{this.escape_html(prefix)}<em>#{this.escape_html(fix)}</em>#{this.escape_html(suffix)}"
|
189
204
|
|
190
205
|
results_group.group_match = true if results_group?
|
191
206
|
|
@@ -194,28 +209,23 @@ class AbstractChosen
|
|
194
209
|
|
195
210
|
this.result_clear_highlight()
|
196
211
|
|
197
|
-
if results < 1 and
|
212
|
+
if results < 1 and query.length
|
198
213
|
this.update_results_content ""
|
199
|
-
this.no_results
|
214
|
+
this.no_results query
|
200
215
|
else
|
201
216
|
this.update_results_content this.results_option_build()
|
202
217
|
this.winnow_results_set_highlight()
|
203
218
|
|
204
219
|
get_search_regex: (escaped_search_string) ->
|
205
|
-
|
220
|
+
regex_string = if @search_contains then escaped_search_string else "(^|\\s|\\b)#{escaped_search_string}[^\\s]*"
|
221
|
+
regex_string = "^#{regex_string}" unless @enable_split_word_search or @search_contains
|
206
222
|
regex_flag = if @case_sensitive_search then "" else "i"
|
207
|
-
new RegExp(
|
223
|
+
new RegExp(regex_string, regex_flag)
|
208
224
|
|
209
225
|
search_string_match: (search_string, regex) ->
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
#TODO: replace this substitution of /\[\]/ with a list of characters to skip.
|
214
|
-
parts = search_string.replace(/\[|\]/g, "").split(" ")
|
215
|
-
if parts.length
|
216
|
-
for part in parts
|
217
|
-
if regex.test part
|
218
|
-
return true
|
226
|
+
match = regex.exec(search_string)
|
227
|
+
match.index += 1 if !@search_contains && match?[1] # make up for lack of lookbehind operator in regex
|
228
|
+
match
|
219
229
|
|
220
230
|
choices_count: ->
|
221
231
|
return @selected_option_count if @selected_option_count?
|
@@ -228,30 +238,68 @@ class AbstractChosen
|
|
228
238
|
|
229
239
|
choices_click: (evt) ->
|
230
240
|
evt.preventDefault()
|
241
|
+
this.activate_field()
|
231
242
|
this.results_show() unless @results_showing or @is_disabled
|
232
243
|
|
244
|
+
keydown_checker: (evt) ->
|
245
|
+
stroke = evt.which ? evt.keyCode
|
246
|
+
this.search_field_scale()
|
247
|
+
|
248
|
+
this.clear_backstroke() if stroke != 8 and @pending_backstroke
|
249
|
+
|
250
|
+
switch stroke
|
251
|
+
when 8 # backspace
|
252
|
+
@backstroke_length = this.get_search_field_value().length
|
253
|
+
break
|
254
|
+
when 9 # tab
|
255
|
+
this.result_select(evt) if @results_showing and not @is_multiple
|
256
|
+
@mouse_on_container = false
|
257
|
+
break
|
258
|
+
when 13 # enter
|
259
|
+
evt.preventDefault() if @results_showing
|
260
|
+
break
|
261
|
+
when 27 # escape
|
262
|
+
evt.preventDefault() if @results_showing
|
263
|
+
break
|
264
|
+
when 32 # space
|
265
|
+
evt.preventDefault() if @disable_search
|
266
|
+
break
|
267
|
+
when 38 # up arrow
|
268
|
+
evt.preventDefault()
|
269
|
+
this.keyup_arrow()
|
270
|
+
break
|
271
|
+
when 40 # down arrow
|
272
|
+
evt.preventDefault()
|
273
|
+
this.keydown_arrow()
|
274
|
+
break
|
275
|
+
|
233
276
|
keyup_checker: (evt) ->
|
234
277
|
stroke = evt.which ? evt.keyCode
|
235
278
|
this.search_field_scale()
|
236
279
|
|
237
280
|
switch stroke
|
238
|
-
when 8
|
281
|
+
when 8 # backspace
|
239
282
|
if @is_multiple and @backstroke_length < 1 and this.choices_count() > 0
|
240
283
|
this.keydown_backstroke()
|
241
284
|
else if not @pending_backstroke
|
242
285
|
this.result_clear_highlight()
|
243
286
|
this.results_search()
|
244
|
-
|
287
|
+
break
|
288
|
+
when 13 # enter
|
245
289
|
evt.preventDefault()
|
246
290
|
this.result_select(evt) if this.results_showing
|
247
|
-
|
291
|
+
break
|
292
|
+
when 27 # escape
|
248
293
|
this.results_hide() if @results_showing
|
249
|
-
|
250
|
-
when 9,
|
294
|
+
break
|
295
|
+
when 9, 16, 17, 18, 38, 40, 91
|
251
296
|
# don't do anything on these keys
|
252
|
-
else
|
297
|
+
else
|
298
|
+
this.results_search()
|
299
|
+
break
|
253
300
|
|
254
301
|
clipboard_event_checker: (evt) ->
|
302
|
+
return if @is_disabled
|
255
303
|
setTimeout (=> this.results_search()), 50
|
256
304
|
|
257
305
|
container_width: ->
|
@@ -281,6 +329,39 @@ class AbstractChosen
|
|
281
329
|
tmp.appendChild(element)
|
282
330
|
tmp.innerHTML
|
283
331
|
|
332
|
+
get_single_html: ->
|
333
|
+
"""
|
334
|
+
<a class="chosen-single chosen-default">
|
335
|
+
<span>#{@default_text}</span>
|
336
|
+
<div><b></b></div>
|
337
|
+
</a>
|
338
|
+
<div class="chosen-drop">
|
339
|
+
<div class="chosen-search">
|
340
|
+
<input class="chosen-search-input" type="text" autocomplete="off" />
|
341
|
+
</div>
|
342
|
+
<ul class="chosen-results"></ul>
|
343
|
+
</div>
|
344
|
+
"""
|
345
|
+
|
346
|
+
get_multi_html: ->
|
347
|
+
"""
|
348
|
+
<ul class="chosen-choices">
|
349
|
+
<li class="search-field">
|
350
|
+
<input class="chosen-search-input" type="text" autocomplete="off" value="#{@default_text}" />
|
351
|
+
</li>
|
352
|
+
</ul>
|
353
|
+
<div class="chosen-drop">
|
354
|
+
<ul class="chosen-results"></ul>
|
355
|
+
</div>
|
356
|
+
"""
|
357
|
+
|
358
|
+
get_no_results_html: (terms) ->
|
359
|
+
"""
|
360
|
+
<li class="no-results">
|
361
|
+
#{@results_none_found} <span>#{this.escape_html(terms)}</span>
|
362
|
+
</li>
|
363
|
+
"""
|
364
|
+
|
284
365
|
# class methods and variables ============================================================
|
285
366
|
|
286
367
|
@browser_is_supported: ->
|
@@ -15,7 +15,7 @@ class SelectParser
|
|
15
15
|
@parsed.push
|
16
16
|
array_index: group_position
|
17
17
|
group: true
|
18
|
-
label:
|
18
|
+
label: group.label
|
19
19
|
title: group.title if group.title
|
20
20
|
children: 0
|
21
21
|
disabled: group.disabled,
|
@@ -47,21 +47,6 @@ class SelectParser
|
|
47
47
|
empty: true
|
48
48
|
@options_index += 1
|
49
49
|
|
50
|
-
escapeExpression: (text) ->
|
51
|
-
if not text? or text is false
|
52
|
-
return ""
|
53
|
-
unless /[\&\<\>\"\'\`]/.test(text)
|
54
|
-
return text
|
55
|
-
map =
|
56
|
-
"<": "<"
|
57
|
-
">": ">"
|
58
|
-
'"': """
|
59
|
-
"'": "'"
|
60
|
-
"`": "`"
|
61
|
-
unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g
|
62
|
-
text.replace unsafe_chars, (chr) ->
|
63
|
-
map[chr] || "&"
|
64
|
-
|
65
50
|
SelectParser.select_to_array = (select) ->
|
66
51
|
parser = new SelectParser()
|
67
52
|
parser.add_node( child ) for child in select.childNodes
|
@@ -1,8 +1,7 @@
|
|
1
1
|
//= depend_on_asset "chosen-sprite.png"
|
2
2
|
//= depend_on_asset "chosen-sprite@2x.png"
|
3
|
-
|
4
|
-
$chosen-sprite:
|
5
|
-
$chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
3
|
+
$chosen-sprite: url('chosen-sprite.png') !default;
|
4
|
+
$chosen-sprite-retina: url('chosen-sprite@2x.png') !default;
|
6
5
|
|
7
6
|
/* @group Base */
|
8
7
|
.chosen-container {
|
@@ -10,21 +9,23 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
10
9
|
display: inline-block;
|
11
10
|
vertical-align: middle;
|
12
11
|
font-size: 13px;
|
12
|
+
user-select: none;
|
13
13
|
* {
|
14
|
+
box-sizing: border-box;
|
14
15
|
}
|
15
16
|
.chosen-drop {
|
16
17
|
position: absolute;
|
17
18
|
top: 100%;
|
18
|
-
left: -9999px;
|
19
19
|
z-index: 1010;
|
20
20
|
width: 100%;
|
21
21
|
border: 1px solid #aaa;
|
22
22
|
border-top: 0;
|
23
23
|
background: #fff;
|
24
24
|
box-shadow: 0 4px 5px rgba(#000,.15);
|
25
|
+
clip: rect(0,0,0,0);
|
25
26
|
}
|
26
27
|
&.chosen-with-drop .chosen-drop {
|
27
|
-
|
28
|
+
clip: auto;
|
28
29
|
}
|
29
30
|
a{
|
30
31
|
cursor: pointer;
|
@@ -59,6 +60,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
59
60
|
border: 1px solid #aaa;
|
60
61
|
border-radius: 5px;
|
61
62
|
background-color: #fff;
|
63
|
+
background: linear-gradient(#fff 20%, #f6f6f6 50%, #eee 52%, #f4f4f4 100%);
|
62
64
|
background-clip: padding-box;
|
63
65
|
box-shadow: 0 0 3px #fff inset, 0 1px 1px rgba(#000,.1);
|
64
66
|
color: #444;
|
@@ -115,6 +117,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
115
117
|
margin: 0;
|
116
118
|
padding: 3px 4px;
|
117
119
|
white-space: nowrap;
|
120
|
+
|
118
121
|
input[type="text"] {
|
119
122
|
margin: 1px 0;
|
120
123
|
padding: 4px 20px 4px 5px;
|
@@ -122,7 +125,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
122
125
|
height: auto;
|
123
126
|
outline: 0;
|
124
127
|
border: 1px solid #aaa;
|
125
|
-
background:
|
128
|
+
background: $chosen-sprite no-repeat 100% -20px;
|
126
129
|
font-size: 1em;
|
127
130
|
font-family: sans-serif;
|
128
131
|
line-height: normal;
|
@@ -136,7 +139,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
136
139
|
}
|
137
140
|
&.chosen-container-single-nosearch .chosen-search {
|
138
141
|
position: absolute;
|
139
|
-
|
142
|
+
clip: rect(0,0,0,0);
|
140
143
|
}
|
141
144
|
}
|
142
145
|
/* @end */
|
@@ -170,6 +173,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
170
173
|
}
|
171
174
|
&.highlighted {
|
172
175
|
background-color: #3875d7;
|
176
|
+
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
|
173
177
|
color: #fff;
|
174
178
|
}
|
175
179
|
&.no-results {
|
@@ -204,6 +208,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
204
208
|
height: auto;
|
205
209
|
border: 1px solid #aaa;
|
206
210
|
background-color: #fff;
|
211
|
+
background-image: linear-gradient(#eee 1%, #fff 15%);
|
207
212
|
cursor: text;
|
208
213
|
}
|
209
214
|
.chosen-choices li {
|
@@ -226,6 +231,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
226
231
|
font-family: sans-serif;
|
227
232
|
line-height: normal;
|
228
233
|
border-radius: 0;
|
234
|
+
width: 25px;
|
229
235
|
}
|
230
236
|
}
|
231
237
|
&.search-choice {
|
@@ -236,6 +242,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
236
242
|
max-width: 100%;
|
237
243
|
border-radius: 3px;
|
238
244
|
background-color: #eeeeee;
|
245
|
+
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
|
239
246
|
background-size: 100% 19px;
|
240
247
|
background-repeat: repeat-x;
|
241
248
|
background-clip: padding-box;
|
@@ -264,6 +271,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
264
271
|
padding-right: 5px;
|
265
272
|
border: 1px solid #ccc;
|
266
273
|
background-color: #e4e4e4;
|
274
|
+
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
|
267
275
|
color: #666;
|
268
276
|
}
|
269
277
|
&.search-choice-focus {
|
@@ -298,6 +306,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
298
306
|
border-bottom-right-radius: 0;
|
299
307
|
-moz-border-radius-bottomleft: 0;
|
300
308
|
border-bottom-left-radius: 0;
|
309
|
+
background-image: linear-gradient(#eee 20%, #fff 80%);
|
301
310
|
box-shadow: 0 1px 0 #fff inset;
|
302
311
|
}
|
303
312
|
.chosen-single div {
|
@@ -368,10 +377,6 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
368
377
|
}
|
369
378
|
}
|
370
379
|
}
|
371
|
-
&.chosen-container-single-nosearch .chosen-search,
|
372
|
-
.chosen-drop {
|
373
|
-
left: 9999px;
|
374
|
-
}
|
375
380
|
&.chosen-container-single .chosen-results {
|
376
381
|
margin: 0 0 4px 4px;
|
377
382
|
padding: 0 4px 0 0;
|
@@ -385,7 +390,7 @@ $chosen-sprite-retina: image-url('chosen-sprite@2x.png') !default;
|
|
385
390
|
}
|
386
391
|
.chosen-search input[type="text"] {
|
387
392
|
padding: 4px 5px 4px 20px;
|
388
|
-
background:
|
393
|
+
background: $chosen-sprite no-repeat -30px -20px;
|
389
394
|
direction: rtl;
|
390
395
|
}
|
391
396
|
&.chosen-container-single{
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chosen-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tse-Ching Ho
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -147,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
147
|
version: '0'
|
148
148
|
requirements: []
|
149
149
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.
|
150
|
+
rubygems_version: 2.6.13
|
151
151
|
signing_key:
|
152
152
|
specification_version: 4
|
153
153
|
summary: Integrate Chosen javascript library with Rails asset pipeline
|