better_select 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }