chosen-awesome-rails 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +104 -0
- data/LICENSE.txt +20 -0
- data/README.md +89 -0
- data/Rakefile +2 -0
- data/chosen-awesome-rails.gemspec +42 -0
- data/lib/chosen-awesome-rails.rb +13 -0
- data/lib/chosen-awesome-rails/engine.rb +7 -0
- data/lib/chosen-awesome-rails/engine3.rb +9 -0
- data/lib/chosen-awesome-rails/version.rb +5 -0
- data/vendor/assets/images/chosen-arrow.gif +0 -0
- data/vendor/assets/javascripts/chosen.js.coffee +39 -0
- data/vendor/assets/javascripts/chosen/chosen.js.coffee +470 -0
- data/vendor/assets/javascripts/chosen/multiple.js.coffee +136 -0
- data/vendor/assets/javascripts/chosen/parser.js.coffee +293 -0
- data/vendor/assets/javascripts/chosen/single.js.coffee +93 -0
- data/vendor/assets/stylesheets/chosen.css.scss +1 -0
- data/vendor/assets/stylesheets/chosen/bootstrap.css.scss +76 -0
- data/vendor/assets/stylesheets/chosen/default.css.scss +323 -0
- metadata +149 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
chosen-awesome-rails (1.0.0)
|
5
|
+
coffee-rails (>= 3.2)
|
6
|
+
railties (>= 3.0)
|
7
|
+
sass-rails (>= 3.2)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
actionmailer (4.0.0)
|
13
|
+
actionpack (= 4.0.0)
|
14
|
+
mail (~> 2.5.3)
|
15
|
+
actionpack (4.0.0)
|
16
|
+
activesupport (= 4.0.0)
|
17
|
+
builder (~> 3.1.0)
|
18
|
+
erubis (~> 2.7.0)
|
19
|
+
rack (~> 1.5.2)
|
20
|
+
rack-test (~> 0.6.2)
|
21
|
+
activemodel (4.0.0)
|
22
|
+
activesupport (= 4.0.0)
|
23
|
+
builder (~> 3.1.0)
|
24
|
+
activerecord (4.0.0)
|
25
|
+
activemodel (= 4.0.0)
|
26
|
+
activerecord-deprecated_finders (~> 1.0.2)
|
27
|
+
activesupport (= 4.0.0)
|
28
|
+
arel (~> 4.0.0)
|
29
|
+
activerecord-deprecated_finders (1.0.3)
|
30
|
+
activesupport (4.0.0)
|
31
|
+
i18n (~> 0.6, >= 0.6.4)
|
32
|
+
minitest (~> 4.2)
|
33
|
+
multi_json (~> 1.3)
|
34
|
+
thread_safe (~> 0.1)
|
35
|
+
tzinfo (~> 0.3.37)
|
36
|
+
arel (4.0.0)
|
37
|
+
atomic (1.1.10)
|
38
|
+
builder (3.1.4)
|
39
|
+
coffee-rails (4.0.0)
|
40
|
+
coffee-script (>= 2.2.0)
|
41
|
+
railties (>= 4.0.0.beta, < 5.0)
|
42
|
+
coffee-script (2.2.0)
|
43
|
+
coffee-script-source
|
44
|
+
execjs
|
45
|
+
coffee-script-source (1.6.3)
|
46
|
+
erubis (2.7.0)
|
47
|
+
execjs (1.4.0)
|
48
|
+
multi_json (~> 1.0)
|
49
|
+
hike (1.2.3)
|
50
|
+
i18n (0.6.4)
|
51
|
+
mail (2.5.4)
|
52
|
+
mime-types (~> 1.16)
|
53
|
+
treetop (~> 1.4.8)
|
54
|
+
mime-types (1.23)
|
55
|
+
minitest (4.7.5)
|
56
|
+
multi_json (1.7.7)
|
57
|
+
polyglot (0.3.3)
|
58
|
+
rack (1.5.2)
|
59
|
+
rack-test (0.6.2)
|
60
|
+
rack (>= 1.0)
|
61
|
+
rails (4.0.0)
|
62
|
+
actionmailer (= 4.0.0)
|
63
|
+
actionpack (= 4.0.0)
|
64
|
+
activerecord (= 4.0.0)
|
65
|
+
activesupport (= 4.0.0)
|
66
|
+
bundler (>= 1.3.0, < 2.0)
|
67
|
+
railties (= 4.0.0)
|
68
|
+
sprockets-rails (~> 2.0.0)
|
69
|
+
railties (4.0.0)
|
70
|
+
actionpack (= 4.0.0)
|
71
|
+
activesupport (= 4.0.0)
|
72
|
+
rake (>= 0.8.7)
|
73
|
+
thor (>= 0.18.1, < 2.0)
|
74
|
+
rake (10.1.0)
|
75
|
+
sass (3.2.10)
|
76
|
+
sass-rails (4.0.0)
|
77
|
+
railties (>= 4.0.0.beta, < 5.0)
|
78
|
+
sass (>= 3.1.10)
|
79
|
+
sprockets-rails (~> 2.0.0)
|
80
|
+
sprockets (2.10.0)
|
81
|
+
hike (~> 1.2)
|
82
|
+
multi_json (~> 1.0)
|
83
|
+
rack (~> 1.0)
|
84
|
+
tilt (~> 1.1, != 1.3.0)
|
85
|
+
sprockets-rails (2.0.0)
|
86
|
+
actionpack (>= 3.0)
|
87
|
+
activesupport (>= 3.0)
|
88
|
+
sprockets (~> 2.8)
|
89
|
+
thor (0.18.1)
|
90
|
+
thread_safe (0.1.2)
|
91
|
+
atomic
|
92
|
+
tilt (1.4.1)
|
93
|
+
treetop (1.4.14)
|
94
|
+
polyglot
|
95
|
+
polyglot (>= 0.3.1)
|
96
|
+
tzinfo (0.3.37)
|
97
|
+
|
98
|
+
PLATFORMS
|
99
|
+
ruby
|
100
|
+
|
101
|
+
DEPENDENCIES
|
102
|
+
bundler (>= 1.0)
|
103
|
+
chosen-awesome-rails!
|
104
|
+
rails (>= 3.0)
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 heaven
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# Chosen awesome (with ajax support and dynamic options injection)
|
2
|
+
|
3
|
+
A written from the scratch library that wraps around default html select controls
|
4
|
+
and makes them more user friendly (Ruby on Rails package).
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
### Install chosen-awesome-rails gem
|
9
|
+
|
10
|
+
Include `chosen-awesome-rails` in Gemefile
|
11
|
+
|
12
|
+
gem 'chosen-awesome-rails'
|
13
|
+
|
14
|
+
Then run `bundle install`
|
15
|
+
|
16
|
+
### Include javascript assets
|
17
|
+
|
18
|
+
Add to your `app/assets/javascripts/application.js`
|
19
|
+
|
20
|
+
//= require chosen
|
21
|
+
|
22
|
+
### Include chosen stylesheet assets
|
23
|
+
|
24
|
+
Add to your `app/assets/stylesheets/application.css`
|
25
|
+
|
26
|
+
*= require chosen
|
27
|
+
|
28
|
+
You might also use twitter bootstrap integration by adding
|
29
|
+
|
30
|
+
*= require chosen/bootstrap
|
31
|
+
|
32
|
+
### Enable chosen
|
33
|
+
```javascript
|
34
|
+
$("select").chosen()
|
35
|
+
```
|
36
|
+
|
37
|
+
Default options are:
|
38
|
+
|
39
|
+
```javascript
|
40
|
+
{
|
41
|
+
allow_insertion: false, // allows to add missing options dynamically, e.g. when you
|
42
|
+
// need to show a list of tags allowing users to add missing ones
|
43
|
+
inherit_classes: true, // whether chosen should inherit html class names from the
|
44
|
+
// original select element
|
45
|
+
option_parser: null, // a function that should return an object that
|
46
|
+
// will be passed right to jQuery's append method to build
|
47
|
+
// html option elemets: $("<option />", parsed_object)
|
48
|
+
option_formatter: null // a function that accepts an option object (jquery selector)
|
49
|
+
// and returns an array of 2 values where one is used
|
50
|
+
// for the dropdown item and another for the choice element
|
51
|
+
}
|
52
|
+
```
|
53
|
+
|
54
|
+
Dynamic insertion example:
|
55
|
+
|
56
|
+
![Dynamic insertion example]
|
57
|
+
(http://oi62.tinypic.com/14kb808.jpg)
|
58
|
+
|
59
|
+
The option formatter allows to build selects like this one:
|
60
|
+
|
61
|
+
![Custom dropdown options]
|
62
|
+
(http://oi60.tinypic.com/28818i8.jpg)
|
63
|
+
|
64
|
+
You can also override text messages with:
|
65
|
+
|
66
|
+
```javascript
|
67
|
+
{
|
68
|
+
locale: {
|
69
|
+
no_results: "No results found",
|
70
|
+
start_typing: "Please start typing",
|
71
|
+
add_new: "add new"
|
72
|
+
}
|
73
|
+
}
|
74
|
+
```
|
75
|
+
|
76
|
+
And pass the next ajax options:
|
77
|
+
|
78
|
+
```javascript
|
79
|
+
{
|
80
|
+
ajax: {
|
81
|
+
url: "where to fetch options",
|
82
|
+
type: "get", // optional
|
83
|
+
dataType: "json", // optional
|
84
|
+
data: {}, // optional
|
85
|
+
async: true, // optional
|
86
|
+
xhrFields: null // optional
|
87
|
+
}
|
88
|
+
}
|
89
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: chosen-awesome-rails 0.0.1 ruby lib
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "chosen-awesome-rails"
|
6
|
+
s.version = "1.0.0"
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
|
+
s.require_paths = ["lib"]
|
10
|
+
s.authors = ["heaven"]
|
11
|
+
s.date = "2013-08-04"
|
12
|
+
s.description = "Chosen is a javascript library of select box enhancer for jQuery, integrates with Rails asset pipeline for ease of use."
|
13
|
+
s.email = ["alex@codeart.pw"]
|
14
|
+
s.files = [".gitignore", "Gemfile", "Gemfile.lock", "LICENSE.txt", "README.md", "Rakefile", "chosen-awesome-rails.gemspec", "lib/chosen-awesome-rails.rb", "lib/chosen-awesome-rails/engine.rb", "lib/chosen-awesome-rails/engine3.rb", "lib/chosen-awesome-rails/version.rb", "vendor/assets/images/chosen-arrow.gif", "vendor/assets/javascripts/chosen.js.coffee", "vendor/assets/javascripts/chosen/chosen.js.coffee", "vendor/assets/javascripts/chosen/multiple.js.coffee", "vendor/assets/javascripts/chosen/parser.js.coffee", "vendor/assets/javascripts/chosen/single.js.coffee", "vendor/assets/stylesheets/chosen.css.scss", "vendor/assets/stylesheets/chosen/bootstrap.css.scss", "vendor/assets/stylesheets/chosen/default.css.scss"]
|
15
|
+
s.homepage = "https://github.com/heaven/chosen-awesome-rails"
|
16
|
+
s.rubygems_version = "2.2.1"
|
17
|
+
s.summary = "Integrate Chosen javascript library with Rails asset pipeline"
|
18
|
+
|
19
|
+
if s.respond_to? :specification_version then
|
20
|
+
s.specification_version = 3
|
21
|
+
|
22
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
23
|
+
s.add_runtime_dependency(%q<railties>, [">= 3.0"])
|
24
|
+
s.add_runtime_dependency(%q<coffee-rails>, [">= 3.2"])
|
25
|
+
s.add_runtime_dependency(%q<sass-rails>, [">= 3.2"])
|
26
|
+
s.add_development_dependency(%q<bundler>, [">= 1.0"])
|
27
|
+
s.add_development_dependency(%q<rails>, [">= 3.0"])
|
28
|
+
else
|
29
|
+
s.add_dependency(%q<railties>, [">= 3.0"])
|
30
|
+
s.add_dependency(%q<coffee-rails>, [">= 3.2"])
|
31
|
+
s.add_dependency(%q<sass-rails>, [">= 3.2"])
|
32
|
+
s.add_dependency(%q<bundler>, [">= 1.0"])
|
33
|
+
s.add_dependency(%q<rails>, [">= 3.0"])
|
34
|
+
end
|
35
|
+
else
|
36
|
+
s.add_dependency(%q<railties>, [">= 3.0"])
|
37
|
+
s.add_dependency(%q<coffee-rails>, [">= 3.2"])
|
38
|
+
s.add_dependency(%q<sass-rails>, [">= 3.2"])
|
39
|
+
s.add_dependency(%q<bundler>, [">= 1.0"])
|
40
|
+
s.add_dependency(%q<rails>, [">= 3.0"])
|
41
|
+
end
|
42
|
+
end
|
Binary file
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#= require chosen/chosen
|
2
|
+
#= require chosen/multiple
|
3
|
+
#= require chosen/single
|
4
|
+
#= require chosen/parser
|
5
|
+
|
6
|
+
$ = jQuery
|
7
|
+
|
8
|
+
$.fn.extend
|
9
|
+
chosen: (options) ->
|
10
|
+
return @ unless Chosen.is_supported()
|
11
|
+
|
12
|
+
@each ->
|
13
|
+
$this = $(@)
|
14
|
+
|
15
|
+
unless $this.data("chosen")
|
16
|
+
$this.data('chosen',
|
17
|
+
if @multiple
|
18
|
+
new Chosen.Multiple($this, options)
|
19
|
+
else
|
20
|
+
new Chosen.Single($this, options)
|
21
|
+
).trigger("chosen:ready")
|
22
|
+
|
23
|
+
$(window).bind("resize", (evt) ->
|
24
|
+
for chosen in Chosen.pool
|
25
|
+
chosen.update_dropdown_position()
|
26
|
+
|
27
|
+
return
|
28
|
+
).bind "scroll", (evt) ->
|
29
|
+
for chosen in Chosen.pool
|
30
|
+
chosen.close() if chosen.opened
|
31
|
+
|
32
|
+
return
|
33
|
+
|
34
|
+
$(document).ready ->
|
35
|
+
$("body").on "click", "input[type=reset]", (evt) ->
|
36
|
+
$(evt.target.form).find("select.chosen").each ->
|
37
|
+
chosen = $(@).data("chosen")
|
38
|
+
chosen and chosen.reset()
|
39
|
+
|
@@ -0,0 +1,470 @@
|
|
1
|
+
$ = jQuery
|
2
|
+
|
3
|
+
class Chosen
|
4
|
+
constructor: (@$target, options = {}) ->
|
5
|
+
$.extend(@, $.extend($.extend($.extend({}, Chosen.defaults), @constructor.defaults), options))
|
6
|
+
|
7
|
+
@$body = $("body")
|
8
|
+
@target = @$target[0]
|
9
|
+
@parser = new Chosen.Parser(@)
|
10
|
+
@default_values = $.map @parser.selected_options, (option) -> option
|
11
|
+
|
12
|
+
@allow_deselect = @is_multiple or (@parser.includes_blank() and @allow_deselect != false)
|
13
|
+
@activated = false
|
14
|
+
@opened = false
|
15
|
+
|
16
|
+
@search_value = ""
|
17
|
+
@cursor_option = null
|
18
|
+
|
19
|
+
@build()
|
20
|
+
@load()
|
21
|
+
@complete()
|
22
|
+
|
23
|
+
complete: ->
|
24
|
+
Chosen.pool.push(@)
|
25
|
+
|
26
|
+
if @target.disabled
|
27
|
+
@disabled = false
|
28
|
+
@disable()
|
29
|
+
else
|
30
|
+
@disabled = true
|
31
|
+
@enable()
|
32
|
+
|
33
|
+
@$target.addClass("chosen").after(@$container)
|
34
|
+
|
35
|
+
destroy: ->
|
36
|
+
@unbind_events()
|
37
|
+
|
38
|
+
delete @$body
|
39
|
+
|
40
|
+
@$container.remove()
|
41
|
+
@$dropdown.remove()
|
42
|
+
@$target.removeData("chosen").removeClass("chosen").show()
|
43
|
+
|
44
|
+
delete @$container
|
45
|
+
delete @$dropdown
|
46
|
+
delete @$target
|
47
|
+
delete @target
|
48
|
+
|
49
|
+
@parser.destroy()
|
50
|
+
|
51
|
+
delete @parser
|
52
|
+
|
53
|
+
index = Chosen.pool.indexOf(@)
|
54
|
+
Chosen.pool.splice(index, 1) if index >= 0
|
55
|
+
|
56
|
+
reset: ->
|
57
|
+
@deselect_all()
|
58
|
+
|
59
|
+
$.each @default_values, (index, option) =>
|
60
|
+
@parser.restore(option)
|
61
|
+
|
62
|
+
@load()
|
63
|
+
|
64
|
+
build: ->
|
65
|
+
select_classes = ["chosen-container"]
|
66
|
+
|
67
|
+
select_classes.push if @is_multiple then "multiple" else "single"
|
68
|
+
select_classes.push "rtl" if @is_rtl
|
69
|
+
select_classes.push @target.className if @inherit_classes and @target.className
|
70
|
+
|
71
|
+
width = if @width? then @width else "#{@target.offsetWidth}px"
|
72
|
+
|
73
|
+
container_props =
|
74
|
+
class: select_classes.join ' '
|
75
|
+
style: "width: #{width}; min-width: #{width}; max-width: #{width}"
|
76
|
+
|
77
|
+
container_props.title = @target.title if @target.title.length
|
78
|
+
container_props.id = @target.id.replace(/[^\w]/g, '-') + "-chosen" if @target.id
|
79
|
+
placeholder = @$target.attr("placeholder") || @placeholder
|
80
|
+
|
81
|
+
@$container = $("<div />", container_props)
|
82
|
+
@$container.html "<ul class=\"chosen-choices\"><li class=\"chosen-search-field\"><input type=\"text\" placeholder=\"#{placeholder}\" autocomplete=\"off\" /></li></ul>"
|
83
|
+
@$container.$choices = @$container.find("ul.chosen-choices")
|
84
|
+
@$container.$search_container = @$container.$choices.find("li.chosen-search-field")
|
85
|
+
@$container.$search = @$container.$choices.find("input[type=text]").attr(tabindex: @target.tabindex || "0")
|
86
|
+
|
87
|
+
dropdown_classes = ["chosen-dropdown"]
|
88
|
+
|
89
|
+
dropdown_classes.push if @is_multiple then "multiple" else "single"
|
90
|
+
dropdown_classes.push "rtl" if @is_rtl
|
91
|
+
|
92
|
+
dropdown_props =
|
93
|
+
class: dropdown_classes.join ' '
|
94
|
+
unselectable: "on"
|
95
|
+
html: "<ul></ul>"
|
96
|
+
|
97
|
+
@$dropdown = $("<div />", dropdown_props)
|
98
|
+
@$dropdown.$list = @$dropdown.find("ul").first()
|
99
|
+
@$dropdown.$list.$no_results = $("<li />", class: "chosen-noresults")
|
100
|
+
@$dropdown.$list.suggestion = null
|
101
|
+
|
102
|
+
bind_events: ->
|
103
|
+
if @target.id.length
|
104
|
+
$("label[for=#{@target.id}]").bind "click", (evt) =>
|
105
|
+
@$container.$search.trigger("focus")
|
106
|
+
@open()
|
107
|
+
evt.preventDefault()
|
108
|
+
|
109
|
+
@$container.bind "mousedown", (evt) =>
|
110
|
+
@$container.$search.trigger("focus")
|
111
|
+
@open()
|
112
|
+
evt.preventDefault()
|
113
|
+
|
114
|
+
@$container.$search.bind "mousedown", (evt) =>
|
115
|
+
@$container.$search.trigger("focus")
|
116
|
+
@open()
|
117
|
+
evt.stopImmediatePropagation()
|
118
|
+
|
119
|
+
@$container.$search.bind "keydown", (evt) => @keydown(evt)
|
120
|
+
@$container.$search.bind "keyup", (evt) => @keyup(evt)
|
121
|
+
@$container.$search.bind "focus", (evt) => @focus(evt)
|
122
|
+
@$container.$search.bind "blur", (evt) => @blur(evt)
|
123
|
+
|
124
|
+
return true
|
125
|
+
|
126
|
+
unbind_events: ->
|
127
|
+
if @target.id.length
|
128
|
+
$("label[for=#{@target.id}]").unbind "click"
|
129
|
+
|
130
|
+
@$dropdown.unbind()
|
131
|
+
@$container.$search.unbind()
|
132
|
+
@$container.unbind()
|
133
|
+
|
134
|
+
return true
|
135
|
+
|
136
|
+
activate: ->
|
137
|
+
@$container.$search.trigger("focus")
|
138
|
+
return @
|
139
|
+
|
140
|
+
deactivate: ->
|
141
|
+
@$container.$search.trigger("blur")
|
142
|
+
return @
|
143
|
+
|
144
|
+
enable: ->
|
145
|
+
if @disabled
|
146
|
+
@$target.removeAttr("disabled")
|
147
|
+
@$container.$search.removeAttr("disabled")
|
148
|
+
@$container.removeClass("disabled")
|
149
|
+
@$container.find("a").each ->
|
150
|
+
$(@).attr(tabindex: @tabindex) if @tabindex
|
151
|
+
|
152
|
+
@bind_events()
|
153
|
+
@disabled = false
|
154
|
+
|
155
|
+
return @
|
156
|
+
|
157
|
+
disable: ->
|
158
|
+
unless @disabled
|
159
|
+
@close()
|
160
|
+
@blur()
|
161
|
+
@unbind_events()
|
162
|
+
|
163
|
+
@$container.find("a").each(->
|
164
|
+
$link = $(@)
|
165
|
+
|
166
|
+
@tabindex = $link.attr("tabindex")
|
167
|
+
$link.attr(tabindex: "-1")
|
168
|
+
)
|
169
|
+
|
170
|
+
@$container.addClass("disabled")
|
171
|
+
@$container.$search.attr(disabled: "disabled")
|
172
|
+
@$target.attr(disabled: "disabled")
|
173
|
+
@disabled = true
|
174
|
+
|
175
|
+
return @
|
176
|
+
|
177
|
+
focus: (evt) ->
|
178
|
+
return @ if @activated
|
179
|
+
|
180
|
+
@activated = true
|
181
|
+
@$container.addClass("focus")
|
182
|
+
|
183
|
+
return @
|
184
|
+
|
185
|
+
blur: (evt) ->
|
186
|
+
return @ unless @activated
|
187
|
+
|
188
|
+
@set_default_value()
|
189
|
+
@close()
|
190
|
+
@activated = false
|
191
|
+
@$container.removeClass("focus")
|
192
|
+
|
193
|
+
return @
|
194
|
+
|
195
|
+
open: ->
|
196
|
+
return @ if @opened
|
197
|
+
|
198
|
+
@opened = true
|
199
|
+
|
200
|
+
@redraw_dropdown()
|
201
|
+
|
202
|
+
@$container.$search.trigger("focus") unless @activated
|
203
|
+
@$body.append(@$dropdown)
|
204
|
+
|
205
|
+
@move_selection_to(@parser.index_of(@cursor_option))
|
206
|
+
|
207
|
+
@$dropdown.bind "mouseover", "li.chosen-option", (evt) => @dropdown_mouseover(evt)
|
208
|
+
@$dropdown.bind "mousedown", "li.chosen-option", (evt) => @dropdown_mousedown(evt)
|
209
|
+
|
210
|
+
@$container.addClass("opened")
|
211
|
+
@$dropdown.addClass("opened")
|
212
|
+
|
213
|
+
return @
|
214
|
+
|
215
|
+
close: ->
|
216
|
+
return @ unless @opened
|
217
|
+
|
218
|
+
@$container.removeClass("opened")
|
219
|
+
@$dropdown.removeClass("opened")
|
220
|
+
@$dropdown.unbind "mouseover mousedown"
|
221
|
+
@$dropdown.remove()
|
222
|
+
@opened = false
|
223
|
+
|
224
|
+
return @
|
225
|
+
|
226
|
+
loading: ->
|
227
|
+
@loaded()
|
228
|
+
@$container.addClass("loading")
|
229
|
+
@$dropdown.addClass("loading")
|
230
|
+
return @
|
231
|
+
|
232
|
+
loaded: ->
|
233
|
+
@$container.removeClass("loading error")
|
234
|
+
@$dropdown.removeClass("loading error")
|
235
|
+
return @
|
236
|
+
|
237
|
+
error: ->
|
238
|
+
@loaded()
|
239
|
+
@$container.addClass("error")
|
240
|
+
@$dropdown.addClass("error")
|
241
|
+
return @
|
242
|
+
|
243
|
+
dropdown_mouseover: (evt) ->
|
244
|
+
option = @parser.find_by_element(evt.target)
|
245
|
+
|
246
|
+
@move_selection_to(@parser.index_of(option)) if option
|
247
|
+
|
248
|
+
evt.preventDefault()
|
249
|
+
evt.stopImmediatePropagation()
|
250
|
+
return
|
251
|
+
|
252
|
+
dropdown_mousedown: (evt) ->
|
253
|
+
option = @parser.find_by_element(evt.target)
|
254
|
+
|
255
|
+
@select(option) if option
|
256
|
+
|
257
|
+
evt.preventDefault()
|
258
|
+
evt.stopImmediatePropagation()
|
259
|
+
return
|
260
|
+
|
261
|
+
keydown: (evt) ->
|
262
|
+
code = evt.which ? evt.keyCode
|
263
|
+
|
264
|
+
switch code
|
265
|
+
when 13
|
266
|
+
if @opened
|
267
|
+
@select(@cursor_option)
|
268
|
+
@move_selection(1) if @is_multiple
|
269
|
+
else
|
270
|
+
@open()
|
271
|
+
evt.preventDefault()
|
272
|
+
when 27
|
273
|
+
evt.preventDefault()
|
274
|
+
evt.stopPropagation()
|
275
|
+
when 38, 40
|
276
|
+
@open()
|
277
|
+
@move_selection(code - 39)
|
278
|
+
evt.preventDefault()
|
279
|
+
else
|
280
|
+
true
|
281
|
+
|
282
|
+
return
|
283
|
+
|
284
|
+
keyup: (evt) ->
|
285
|
+
code = evt.which ? evt.keyCode
|
286
|
+
|
287
|
+
return if [9, 13, 16, 35, 36, 37, 38, 39, 40].indexOf(code) >= 0
|
288
|
+
|
289
|
+
if code is 27 and @opened
|
290
|
+
@close()
|
291
|
+
evt.stopPropagation()
|
292
|
+
else if @has_filter_changed()
|
293
|
+
@open()
|
294
|
+
|
295
|
+
if @ajax then @pull_updates() else @redraw_dropdown()
|
296
|
+
|
297
|
+
return
|
298
|
+
|
299
|
+
redraw_dropdown: (data) ->
|
300
|
+
@parser.update(data) unless data is undefined
|
301
|
+
|
302
|
+
changed = @apply_filter()
|
303
|
+
|
304
|
+
@update_dropdown_position()
|
305
|
+
@update_dropdown_content()
|
306
|
+
@move_selection_to(0) if changed
|
307
|
+
|
308
|
+
return
|
309
|
+
|
310
|
+
update_dropdown_position: ->
|
311
|
+
return unless @opened
|
312
|
+
|
313
|
+
list = @$container.find("ul")
|
314
|
+
offsets = list.offset()
|
315
|
+
height = list.innerHeight()
|
316
|
+
width = list.innerWidth()
|
317
|
+
|
318
|
+
@$dropdown.css
|
319
|
+
left: "#{offsets.left}px",
|
320
|
+
top: "#{offsets.top + height}px"
|
321
|
+
width: "#{width}px"
|
322
|
+
|
323
|
+
return
|
324
|
+
|
325
|
+
update_dropdown_content: ->
|
326
|
+
@insert_suggestion()
|
327
|
+
|
328
|
+
if @parser.selectable_options.length
|
329
|
+
@$dropdown.$list.html(@parser.to_html())
|
330
|
+
else
|
331
|
+
@show_no_results()
|
332
|
+
|
333
|
+
return
|
334
|
+
|
335
|
+
insert_suggestion: ->
|
336
|
+
return unless @allow_insertion
|
337
|
+
|
338
|
+
if @$dropdown.$list.suggestion
|
339
|
+
@parser.remove(@$dropdown.$list.suggestion)
|
340
|
+
|
341
|
+
if @$container.$search[0].value and not @parser.exact_matches().length
|
342
|
+
@$dropdown.$list.suggestion = suggestion = @parser.insert(
|
343
|
+
value: @$container.$search[0].value
|
344
|
+
label: @$container.$search[0].value
|
345
|
+
)
|
346
|
+
|
347
|
+
value = "#{suggestion.value} (#{@locale.add_new})"
|
348
|
+
|
349
|
+
suggestion.$listed.contents().last()[0].nodeValue = value
|
350
|
+
suggestion.$choice.contents().last()[0].nodeValue = value
|
351
|
+
else if @$dropdown.$list.suggestion
|
352
|
+
@$dropdown.$list.suggestion = null
|
353
|
+
|
354
|
+
show_no_results: ->
|
355
|
+
text = if @ajax then @locale.start_typing else @locale.no_results
|
356
|
+
|
357
|
+
@$dropdown.$list.$no_results.text(text)
|
358
|
+
@$dropdown.$list.html(@$dropdown.$list.$no_results)
|
359
|
+
|
360
|
+
apply_filter: ->
|
361
|
+
return false unless @has_filter_changed()
|
362
|
+
|
363
|
+
@search_value = @$container.$search[0].value
|
364
|
+
@parser.apply_filter(@$container.$search[0].value)
|
365
|
+
|
366
|
+
true
|
367
|
+
|
368
|
+
has_filter_changed: ->
|
369
|
+
@search_value isnt @$container.$search[0].value
|
370
|
+
|
371
|
+
move_selection: (dir) ->
|
372
|
+
cursor = @parser.index_of(@cursor_option) + dir
|
373
|
+
cursor = @parser.available_options.length - 1 if cursor < 0
|
374
|
+
cursor = 0 if cursor > @parser.available_options.length - 1
|
375
|
+
|
376
|
+
@move_selection_to(cursor)
|
377
|
+
|
378
|
+
if @cursor_option and @cursor_option.selected and @parser.selectable_options.length
|
379
|
+
# TODO: optimize this
|
380
|
+
return @move_selection(dir)
|
381
|
+
|
382
|
+
return @
|
383
|
+
|
384
|
+
move_selection_to: (cursor) ->
|
385
|
+
if @cursor_option
|
386
|
+
@cursor_option.$listed.removeClass("active")
|
387
|
+
|
388
|
+
@cursor_option = @parser.available_options[cursor]
|
389
|
+
|
390
|
+
return unless @cursor_option
|
391
|
+
|
392
|
+
$element = @cursor_option.$listed.addClass("active")
|
393
|
+
top = $element.position().top + $element.height()
|
394
|
+
list_height = @$dropdown.height()
|
395
|
+
list_scroll = @$dropdown.scrollTop()
|
396
|
+
|
397
|
+
if top >= list_height + list_scroll or list_scroll >= top
|
398
|
+
@$dropdown.scrollTop($element.position().top)
|
399
|
+
|
400
|
+
return @
|
401
|
+
|
402
|
+
get_caret_position: ->
|
403
|
+
field = @$container.$search[0]
|
404
|
+
|
405
|
+
if document.selection
|
406
|
+
sel = document.selection.createRange()
|
407
|
+
length = sel.text.length
|
408
|
+
|
409
|
+
sel.moveStart('character', -field.value.length)
|
410
|
+
|
411
|
+
sel.text.length - length
|
412
|
+
else if field.selectionStart or field.selectionStart is '0'
|
413
|
+
field.selectionStart
|
414
|
+
else
|
415
|
+
0
|
416
|
+
|
417
|
+
pull_updates: ->
|
418
|
+
return @ if not @ajax or not @$container.$search[0].value
|
419
|
+
|
420
|
+
if @ajax.pending_update
|
421
|
+
clearTimeout(@ajax.pending_update)
|
422
|
+
|
423
|
+
@ajax.pending_update = setTimeout =>
|
424
|
+
if @ajax.pending_request and @ajax.pending_request.readyState isnt 4
|
425
|
+
@ajax.pending_request.abort()
|
426
|
+
|
427
|
+
data =
|
428
|
+
query: @$container.$search[0].value
|
429
|
+
|
430
|
+
@ajax.pending_request = $.ajax
|
431
|
+
url: @ajax.url
|
432
|
+
type: @ajax.type or "get"
|
433
|
+
dataType: @ajax.dataType or "json"
|
434
|
+
data: $.extend(@ajax.data || {}, data)
|
435
|
+
async: @ajax.async or true
|
436
|
+
xhrFields: @ajax.xhrFields
|
437
|
+
|
438
|
+
beforeSend: (xhr) =>
|
439
|
+
@loading()
|
440
|
+
@ajax.beforeSend(xhr) if typeof @ajax.beforeSend is "function"
|
441
|
+
success: (data) =>
|
442
|
+
@loaded()
|
443
|
+
@redraw_dropdown(data)
|
444
|
+
error: =>
|
445
|
+
@error()
|
446
|
+
|
447
|
+
, 300
|
448
|
+
|
449
|
+
return @
|
450
|
+
|
451
|
+
@is_crappy_browser: (version) ->
|
452
|
+
window.navigator.appName == "Microsoft Internet Explorer" and document.documentMode <= version
|
453
|
+
|
454
|
+
@is_supported: ->
|
455
|
+
not Chosen.is_crappy_browser(6)
|
456
|
+
|
457
|
+
@defaults:
|
458
|
+
allow_insertion: false
|
459
|
+
inherit_classes: true
|
460
|
+
is_rtl: false
|
461
|
+
option_parser: null
|
462
|
+
option_formatter: null
|
463
|
+
locale:
|
464
|
+
no_results: "No results found"
|
465
|
+
start_typing: "Please start typing"
|
466
|
+
add_new: "add new"
|
467
|
+
|
468
|
+
@pool: []
|
469
|
+
|
470
|
+
@Chosen = Chosen
|