better_select 0.0.4 → 0.1.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.
@@ -1,185 +0,0 @@
1
- $$ = (html) ->
2
- elm = document.createElement 'div'
3
- elm.innerHTML = html
4
- if elm.children.length > 1 then elm.children else elm.children[0]
5
-
6
- getPos = (tgt, method) ->
7
- pos = 0
8
- while tgt
9
- pos += tgt[method]
10
- tgt = tgt.offsetParent
11
- pos
12
-
13
- getTop = (tgt) -> getPos tgt, 'offsetTop'
14
- getLeft = (tgt) -> getPos tgt, 'offsetLeft'
15
-
16
- getClasses = (tgt) -> tgt.getAttribute('class').split ' '
17
-
18
- setClasses = (tgt, classes) ->
19
- tgt.setAttribute 'class', classes.join ' '
20
- tgt
21
-
22
- addClass = (tgt, className) ->
23
- classes = getClasses tgt
24
- classes.push(className) if classes.indexOf(className) is -1
25
- setClasses tgt, classes
26
-
27
- removeClass = (tgt, className) ->
28
- classes.splice(index, 1) unless index = (classes = getClasses tgt).indexOf className is -1
29
- setClasses tgt, classes
30
-
31
- letters = 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.split ' '
32
- numbers = '0 1 2 3 4 5 6 7 8 9 0'.split ' '
33
-
34
- build_element = (what, orig, obj) ->
35
- elm = $$ _.template(obj["#{what}_template"]) obj["process_#{what}"] orig
36
- elm.orig = orig
37
- orig.better_version = elm
38
- elm.better_select = obj
39
- elm
40
-
41
- renderOption = (orig_option, bs) ->
42
- option = build_element 'option', orig_option, bs
43
- option.reset = ->
44
- @orig.selected = undefined
45
- @setAttribute 'class', 'option'
46
- bs.reset @
47
- option.select = ->
48
- @orig.selected = 'selected'
49
- @setAttribute 'class', 'option selected'
50
- bs.toggle() if bs.select.getAttribute('class').indexOf('open') isnt -1
51
- bs.set_selected option
52
- option.addEventListener 'click', -> option.select()
53
- option.addEventListener 'mouseover', -> option.better_select.set_focused option
54
- bs.options.push option
55
- first_char = option.innerHTML.substr(0, 1).toLowerCase()
56
- bs.options_by_first_char[first_char] = [] unless bs.options_by_first_char[first_char]
57
- bs.options_by_first_char[first_char].push option
58
- bs.options_by_first_char[first_char].sort()
59
- option
60
-
61
- renderOptionGroup = (orig_group, bs) ->
62
- group = build_element 'option_group', orig_group, bs
63
- group.appendChild(renderOption child, bs) for child in orig_group.children
64
- bs.option_groups.push group
65
- group
66
-
67
- class BetterSelect
68
- defaults:
69
- positionDropdown: true
70
- constructor: (elm, options) ->
71
- return unless elm && elm.tagName && elm.tagName is 'SELECT'
72
- @settings = _.extend {}, @defaults, options
73
- @options = []
74
- @options_by_first_char = {}
75
- @option_groups = []
76
- selected = elm.selectedOptions
77
- @select = build_element 'select', elm, @
78
- [@selected_option, @dropdown] = @select.children
79
- if elm.id
80
- @select.id = "#{elm.id}-better-select"
81
- @dropdown.id = "#{elm.id}-better-select-dropdown"
82
- @default_selected = [elm.children[elm.selectedIndex]]
83
- elm.parentNode.insertBefore @select, elm
84
- elm.parentNode.insertBefore elm, @select
85
- elm.style.display = 'none'
86
- children = elm.children
87
- if @settings.positionDropdown
88
- document.body.appendChild @dropdown
89
- @dropdown.style.left = '-9999px'
90
- for child in children
91
- switch child.tagName
92
- when 'OPTION'
93
- method = renderOption
94
- when 'OPTGROUP'
95
- method = renderOptionGroup
96
- @dropdown.appendChild(method child, @)
97
- @default_selected[0].better_version.select() if @default_selected
98
- @selected_option.addEventListener 'click', =>
99
- @toggle()
100
- @set_selected @dropdown_selected_option
101
- window.addEventListener 'click', (e) =>
102
- unless e.target == @selected_option || e.target == @select || @options.indexOf(e.target) isnt -1
103
- @toggle() if @open
104
- last_char = false
105
- @selected_option.addEventListener 'focus', =>
106
- document.body.style.overflow = 'hidden'
107
- addClass @select, 'focus'
108
- @selected_option.addEventListener 'blur', =>
109
- removeClass @select, 'focus'
110
- document.body.style.overflow = 'auto'
111
- @toggle() if @open is true
112
- true
113
- @selected_option.addEventListener 'keydown', (e) => e.preventDefault() unless [38, 40].indexOf(e.keyCode) is -1
114
- @selected_option.addEventListener 'keyup', (e) =>
115
- @toggle() if @open is false
116
- keyCode = e.keyCode
117
- switch keyCode
118
- when 38 then @set_focused @options[if (@focus_index -= 1) < 0 then @focus_index = @options.length - 1 else @focus_index]
119
- when 40 then @set_focused @options[if (@focus_index += 1) >= @options.length then @focus_index = 0 else @focus_index]
120
- when 13
121
- @focused_option.select()
122
- else
123
- if keyCode > 47 && keyCode < 58
124
- char = numbers[keyCode - 47]
125
- else if keyCode > 64 && keyCode < 91
126
- char = letters[keyCode - 65]
127
- else
128
- if @focused_option
129
- removeClass @focused_option, 'focus'
130
- @focused_option = false
131
- @focus_index = -1
132
- @toggle()
133
- if char && @options_by_first_char[char]
134
- @options_by_first_char[char].sort() unless last_char is char
135
- option = @options_by_first_char[char].shift()
136
- @options_by_first_char[char].push option
137
- @set_focused option
138
- @focus_index = @options.indexOf option
139
- last_character = char
140
- @dropdown.addEventListener('click', -> console.log arguments)
141
- e.preventDefault()
142
- e.stopPropagation()
143
- e.returnValue = false
144
- false
145
- focused_option: false
146
- focus_index: -1
147
- set_focused: (option) ->
148
- class_for_selected = (option) => if @selected_option && option.innerHTML is @selected_option.innerHTML then " selected" else ""
149
- @focused_option.setAttribute('class', "option#{class_for_selected(@focused_option)}") if @focused_option
150
- @focused_option = option
151
- @focused_option.setAttribute("class", "option focus#{class_for_selected(option)}")
152
- @focus_index = @options.indexOf @focused_option
153
- open: false
154
- toggle: ->
155
- (if @open = !@open then addClass else removeClass)(@select, 'open')
156
- if @settings.positionDropdown
157
- if @dropdown.offsetHeight > window.innerHeight
158
- height = window.innerHeight * .50
159
- @dropdown.style.height = height + 'px'
160
- @dropdown.style['overflow-y'] = 'auto'
161
- if @dropdown_selected_option.offsetTop > height || @adjust_height
162
- @dropdown_selected_option.scrollIntoView()
163
- @adjust_height = true
164
- top = top || (getTop(@select) - @dropdown_selected_option.offsetTop)
165
- top = getTop(@select) - (@dropdown_selected_option.offsetTop - @dropdown.scrollTop)
166
- @dropdown.style.top = (if top < 0 then 0 else top) + 'px'
167
- @dropdown.style.left = if @open then getLeft(@select) + 'px' else '-9999px'
168
- reset: (option) -> @default_selected[0].better_version.select() if @default_selected
169
- set_selected: (option) ->
170
- unless @selected_option.innerHTML == option.innerHTML
171
- removeClass(@dropdown_selected_option, 'selected') if @dropdown_selected_option
172
- addClass @dropdown_selected_option = option, 'selected'
173
- @selected_option.innerHTML = option.innerHTML
174
- e = document.createEvent('Event')
175
- e.initEvent 'change', true, true
176
- @select.orig.dispatchEvent e
177
- option_template: '<div class="option"><%= innerHTML %></div>'
178
- option_group_template: '<div class="optgroup"><div class="option-group-label"><%= label %></div></div>'
179
- select_template: '<div class="select"><a href="javascript:void(0)" class="selected-option"></a><div class="better-select-dropdown dropdown"></div></div>'
180
- process_option: (option) -> option
181
- process_option_group: (option_group) -> option_group
182
- process_select: (select) -> select
183
-
184
-
185
- window.BetterSelect = BetterSelect
@@ -1,183 +0,0 @@
1
- $$ = (html) ->
2
- elm = document.createElement 'div'
3
- elm.innerHTML = html
4
- if elm.children.length > 1 then elm.children else elm.children[0]
5
-
6
- getPos = (tgt, method) ->
7
- pos = 0
8
- while tgt
9
- pos += tgt[method]
10
- tgt = tgt.offsetParent
11
- pos
12
-
13
- getTop = (tgt) -> getPos tgt, 'offsetTop'
14
- getLeft = (tgt) -> getPos tgt, 'offsetLeft'
15
-
16
- getClasses = (tgt) -> tgt.getAttribute('class').split ' '
17
-
18
- setClasses = (tgt, classes) ->
19
- tgt.setAttribute 'class', classes.join ' '
20
- tgt
21
-
22
- addClass = (tgt, className) ->
23
- classes = getClasses tgt
24
- classes.push(className) if classes.indexOf(className) is -1
25
- setClasses tgt, classes
26
-
27
- removeClass = (tgt, className) ->
28
- classes.splice(index, 1) unless index = (classes = getClasses tgt).indexOf className is -1
29
- setClasses tgt, classes
30
-
31
- letters = 'a b c d e f g h i j k l m n o p q r s t u v w x y z'.split ' '
32
- numbers = '0 1 2 3 4 5 6 7 8 9 0'.split ' '
33
-
34
- build_element = (what, orig, obj) ->
35
- ((elm = $$ _.template(obj["#{what}_template"]) obj["process_#{what}"] orig).orig = orig).better_version = elm
36
- elm.better_select = obj
37
- elm
38
-
39
- renderOption = (orig_option, bs) ->
40
- option = build_element 'option', orig_option, bs
41
- option.reset = ->
42
- @orig.selected = undefined
43
- @setAttribute 'class', 'option'
44
- bs.reset @
45
- option.select = ->
46
- @orig.selected = 'selected'
47
- @setAttribute 'class', 'option selected'
48
- bs.toggle() if bs.select.getAttribute('class').indexOf('open') isnt -1
49
- bs.set_selected option
50
- option.addEventListener 'click', -> option.select()
51
- option.addEventListener 'mouseover', -> option.better_select.set_focused option
52
- bs.options.push option
53
- first_char = option.innerHTML.substr(0, 1).toLowerCase()
54
- bs.options_by_first_char[first_char] = [] unless bs.options_by_first_char[first_char]
55
- bs.options_by_first_char[first_char].push option
56
- bs.options_by_first_char[first_char].sort()
57
- option
58
-
59
- renderOptionGroup = (orig_group, bs) ->
60
- group = build_element 'option_group', orig_group, bs
61
- group.appendChild(renderOption child, bs) for child in orig_group.children
62
- bs.option_groups.push group
63
- group
64
-
65
- class BetterSelect
66
- defaults:
67
- positionDropdown: true
68
- constructor: (elm, options) ->
69
- return unless elm && elm.tagName && elm.tagName is 'SELECT'
70
- @settings = _.extend {}, @defaults, options
71
- @options = []
72
- @options_by_first_char = {}
73
- @option_groups = []
74
- selected = elm.selectedOptions
75
- @select = build_element 'select', elm, @
76
- [@selected_option, @dropdown] = @select.children
77
- if elm.id
78
- @select.id = "#{elm.id}-better-select"
79
- @dropdown.id = "#{elm.id}-better-select-dropdown"
80
- @default_selected = [elm.children[elm.selectedIndex]]
81
- elm.parentNode.insertBefore @select, elm
82
- elm.parentNode.insertBefore elm, @select
83
- elm.style.display = 'none'
84
- children = elm.children
85
- if @settings.positionDropdown
86
- document.body.appendChild @dropdown
87
- @dropdown.style.left = '-9999px'
88
- for child in children
89
- switch child.tagName
90
- when 'OPTION'
91
- method = renderOption
92
- when 'OPTGROUP'
93
- method = renderOptionGroup
94
- @dropdown.appendChild(method child, @)
95
- @default_selected[0].better_version.select() if @default_selected
96
- @selected_option.addEventListener 'click', =>
97
- @toggle()
98
- @set_selected @dropdown_selected_option
99
- window.addEventListener 'click', (e) =>
100
- unless e.target == @selected_option || e.target == @select || @options.indexOf(e.target) isnt -1
101
- @toggle() if @open
102
- last_char = false
103
- @selected_option.addEventListener 'focus', =>
104
- document.body.style.overflow = 'hidden'
105
- addClass @select, 'focus'
106
- @selected_option.addEventListener 'blur', =>
107
- removeClass @select, 'focus'
108
- document.body.style.overflow = 'auto'
109
- @toggle() if @open is true
110
- true
111
- @selected_option.addEventListener 'keydown', (e) => e.preventDefault() unless [38, 40].indexOf(e.keyCode) is -1
112
- @selected_option.addEventListener 'keyup', (e) =>
113
- @toggle() if @open is false
114
- keyCode = e.keyCode
115
- switch keyCode
116
- when 38 then @set_focused @options[if (@focus_index -= 1) < 0 then @focus_index = @options.length - 1 else @focus_index]
117
- when 40 then @set_focused @options[if (@focus_index += 1) >= @options.length then @focus_index = 0 else @focus_index]
118
- when 13
119
- @focused_option.select()
120
- else
121
- if keyCode > 47 && keyCode < 58
122
- char = numbers[keyCode - 47]
123
- else if keyCode > 64 && keyCode < 91
124
- char = letters[keyCode - 65]
125
- else
126
- if @focused_option
127
- removeClass @focused_option, 'focus'
128
- @focused_option = false
129
- @focus_index = -1
130
- @toggle()
131
- if char && @options_by_first_char[char]
132
- @options_by_first_char[char].sort() unless last_char is char
133
- option = @options_by_first_char[char].shift()
134
- @options_by_first_char[char].push option
135
- @set_focused option
136
- @focus_index = @options.indexOf option
137
- last_character = char
138
- @dropdown.addEventListener('click', -> console.log arguments)
139
- e.preventDefault()
140
- e.stopPropagation()
141
- e.returnValue = false
142
- false
143
- focused_option: false
144
- focus_index: -1
145
- set_focused: (option) ->
146
- class_for_selected = (option) => if @selected_option && option.innerHTML is @selected_option.innerHTML then " selected" else ""
147
- @focused_option.setAttribute('class', "option#{class_for_selected(@focused_option)}") if @focused_option
148
- @focused_option = option
149
- @focused_option.setAttribute("class", "option focus#{class_for_selected(option)}")
150
- @focus_index = @options.indexOf @focused_option
151
- open: false
152
- toggle: ->
153
- (if @open = !@open then addClass else removeClass)(@select, 'open')
154
- if @settings.positionDropdown
155
- if @dropdown.offsetHeight > window.innerHeight
156
- height = window.innerHeight * .50
157
- @dropdown.style.height = height + 'px'
158
- @dropdown.style['overflow-y'] = 'auto'
159
- if @dropdown_selected_option.offsetTop > height || @adjust_height
160
- @dropdown_selected_option.scrollIntoView()
161
- @adjust_height = true
162
- top = top || (getTop(@select) - @dropdown_selected_option.offsetTop)
163
- top = getTop(@select) - (@dropdown_selected_option.offsetTop - @dropdown.scrollTop)
164
- @dropdown.style.top = (if top < 0 then 0 else top) + 'px'
165
- @dropdown.style.left = if @open then getLeft(@select) + 'px' else '-9999px'
166
- reset: (option) -> @default_selected[0].better_version.select() if @default_selected
167
- set_selected: (option) ->
168
- unless @selected_option.innerHTML == option.innerHTML
169
- removeClass(@dropdown_selected_option, 'selected') if @dropdown_selected_option
170
- addClass @dropdown_selected_option = option, 'selected'
171
- @selected_option.innerHTML = option.innerHTML
172
- e = document.createEvent('Event')
173
- e.initEvent 'change', true, true
174
- @select.orig.dispatchEvent e
175
- option_template: '<div class="option"><%= innerHTML %></div>'
176
- option_group_template: '<div class="optgroup"><div class="option-group-label"><%= label %></div></div>'
177
- select_template: '<div class="select"><a href="javascript:void(0)" class="selected-option"></a><div class="better-select-dropdown dropdown"></div></div>'
178
- process_option: (option) -> option
179
- process_option_group: (option_group) -> option_group
180
- process_select: (select) -> select
181
-
182
-
183
- window.BetterSelect = BetterSelect
@@ -1,32 +0,0 @@
1
- .better-select-dropdown {
2
- position: fixed;
3
-
4
- .option {
5
- cursor: pointer;
6
- }
7
- }
8
-
9
- .select {
10
- position: static;
11
-
12
- &.dont-position-dropdown {
13
- position: relative;
14
-
15
- .dropdown {
16
- top: 100%;
17
- left: -99999px;
18
- }
19
- }
20
-
21
- &.open {
22
- &.dont-position-dropdown {
23
- .dropdown {
24
- left: 0px;
25
- }
26
- }
27
- }
28
-
29
- .selected-option {
30
- cursor: pointer;
31
- }
32
- }
@@ -1,32 +0,0 @@
1
- .better-select-dropdown {
2
- position: fixed;
3
-
4
- .option {
5
- cursor: pointer;
6
- }
7
- }
8
-
9
- .select {
10
- position: static;
11
-
12
- &.dont-position-dropdown {
13
- position: relative;
14
-
15
- .dropdown {
16
- top: 100%;
17
- left: -99999px;
18
- }
19
- }
20
-
21
- &.open {
22
- &.dont-position-dropdown {
23
- .dropdown {
24
- left: 0px;
25
- }
26
- }
27
- }
28
-
29
- .selected-option {
30
- cursor: pointer;
31
- }
32
- }