material_raingular 0.0.3 → 0.0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ea94f133f48652bdd35aad89979c597ce1c7893
|
4
|
+
data.tar.gz: 203d64c5846c918081873b6441732814db7aa025
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5e66387e6d9135d424b33ba1c9db028124063222aad8771e1ae6da31c53929e45f569fdcc1f2c88e653e208fae99d49344ad47b68f4f83adc41630f87e56b9f
|
7
|
+
data.tar.gz: fb439a409e1bfcbe33f3445cf4ef730075f5bd41b2c6d42e8d4e87876909bbbdf123dc917ef3cb0c4c20722f4267e59489c977016ce2e9a30ecd5f9284c22445
|
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
class SelectOptions
|
2
|
+
REGEXP: /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/;
|
2
3
|
# 1: Model Value
|
3
4
|
# 2: Display Value
|
4
5
|
# 3: group by expression (groupByFn)
|
@@ -8,126 +9,261 @@ REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?
|
|
8
9
|
# 7: object item value variable name
|
9
10
|
# 8: collection
|
10
11
|
# 9: track by expressionj
|
12
|
+
constructor: (@unparsed,@html) ->
|
13
|
+
@filters = @unparsed.split('|')
|
14
|
+
@options = @filters.shift()
|
15
|
+
@match = @options.match(@REGEXP)
|
16
|
+
@raiseError() if !@match
|
17
|
+
raiseError: ->
|
18
|
+
throw new Error(
|
19
|
+
"Expected expression in form of " +
|
20
|
+
"'_select_ (as _label_)? for (_key_,)?_value_ in _collection_'" +
|
21
|
+
" but got '" + @unparsed + "'. Element: " + @html)
|
22
|
+
class SelectFunctions
|
23
|
+
constructor: (match,parse) ->
|
24
|
+
@collection = parse(match[8])
|
25
|
+
@modelValue = match[1].replace(match[5] + '.','')
|
26
|
+
@viewValue = if match[2] then match[2].replace(match[5] + '.','') else @modelValue
|
27
|
+
@viewValueFn = parse(@viewValue || @modelValue)
|
28
|
+
@modelValueFn = parse(@modelValue || @viewValue)
|
29
|
+
|
30
|
+
class MobileTemplate
|
31
|
+
constructor: (@element,functions) ->
|
32
|
+
@template = angular.element("<ul> </ul>")
|
33
|
+
@search = angular.element "<input type='search' placeholder='Search'>"
|
34
|
+
@tempHolder = angular.element("<div class='filtered-select' ></div>")
|
35
|
+
@body = angular.element(document.body)
|
36
|
+
@mousedownFunction = functions[0]
|
37
|
+
@keydownFunction = functions[1]
|
38
|
+
@inputFunction = functions[2]
|
39
|
+
|
40
|
+
@bind()
|
41
|
+
@stylize()
|
42
|
+
@attachElements()
|
43
|
+
attachElements: ->
|
44
|
+
@tempHolder.append @search
|
45
|
+
@tempHolder.append @template
|
46
|
+
@body.append @tempHolder
|
47
|
+
stylize: ->
|
48
|
+
ulHeight = =>
|
49
|
+
full = window.innerHeight
|
50
|
+
full = full/2 if @element.hasClass('bottom')
|
51
|
+
full - @search[0].offsetHeight + 'px'
|
52
|
+
@tempHolder.addClass('bottom') if @element.hasClass('bottom')
|
53
|
+
@template.css('height',ulHeight())
|
54
|
+
|
55
|
+
bind: ->
|
56
|
+
@element.bind 'mousedown', (event) =>
|
57
|
+
@mousedownFunction(@tempHolder,@search,event)
|
58
|
+
@body.bind 'keydown', (event) =>
|
59
|
+
@keydownFunction(@tempHolder,event)
|
60
|
+
@search.bind 'input', (event) =>
|
61
|
+
@inputFunction(event)
|
62
|
+
|
63
|
+
class StandardTemplate
|
64
|
+
constructor: (@element,attrs,functions,@disabled) ->
|
65
|
+
@span = angular.element "<span></span>"
|
66
|
+
@search = angular.element "<input style='opacity:0.5'class='autocomplete' type='search' placeholder='" + attrs.placeholder + "'>"
|
67
|
+
@tempHolder = angular.element "<div class='autocomplete menu md-whiteframe-z1'>"
|
68
|
+
@template = @tempHolder
|
69
|
+
@typeAhead = angular.element "<span style='position:absolute;'></span>"
|
70
|
+
@inputFunction = functions[0]
|
71
|
+
@focusFunction = functions[1]
|
72
|
+
@blurFunction = functions[2]
|
73
|
+
@keydownFunction = functions[3]
|
74
|
+
@attachElements()
|
75
|
+
@stylize()
|
76
|
+
@bind()
|
77
|
+
stylize: ->
|
78
|
+
@search.addClass('md-input') if @element.hasClass('md-input')
|
79
|
+
@search.css({'width': '100%','color': 'black'})
|
80
|
+
searchCss = window.getComputedStyle(@search[0])
|
81
|
+
@typeAhead.css('padding-left', parseFloat(searchCss["padding-left"]) + parseFloat(searchCss["margin-left"]) + parseFloat(searchCss["border-left-width"]) + 'px')
|
82
|
+
@typeAhead.css('padding-top', parseFloat(searchCss["padding-top"]) + parseFloat(searchCss["margin-top"]) + parseFloat(searchCss["border-top-width"]) + 'px')
|
83
|
+
|
84
|
+
bind: ->
|
85
|
+
@search.bind 'input', (event)=>
|
86
|
+
@inputFunction(@search,@typeAhead,event)
|
87
|
+
@search.bind 'focus', (event)=>
|
88
|
+
@focusFunction(event)
|
89
|
+
@search.bind 'blur', (event)=>
|
90
|
+
@blurFunction(@search,event)
|
91
|
+
@search.bind 'keydown', (event)=>
|
92
|
+
@keydownFunction(@search,@typeAhead,@template,event)
|
93
|
+
attachElements: ->
|
94
|
+
@span.append @typeAhead
|
95
|
+
@span.append @search
|
96
|
+
@span.append @tempHolder
|
97
|
+
@element.append @span
|
98
|
+
|
99
|
+
class EventFunctions
|
100
|
+
constructor: (@functions,@buildTemplate,@updateValue,@filteredList,@filter,@timeout,@parse,@scope,@disabled) ->
|
101
|
+
|
102
|
+
inputFunction: (search,typeAhead,event) =>
|
103
|
+
location = search[0].selectionStart
|
104
|
+
if location > 3
|
105
|
+
if @functions.viewValueFn(@filteredList()[0])
|
106
|
+
search.val(@functions.viewValueFn(@filteredList()[0]))
|
107
|
+
else
|
108
|
+
search.val(search.val()[0..location - 1])
|
109
|
+
search[0].setSelectionRange(location,location)
|
110
|
+
else
|
111
|
+
search.val(search.val()[0..2])
|
112
|
+
typeAhead.html(search.val()[0..location - 1])
|
113
|
+
@buildTemplate()
|
114
|
+
focusFunction: (event) =>
|
115
|
+
@buildTemplate()
|
116
|
+
blurFunction: (search,event) =>
|
117
|
+
obj={}
|
118
|
+
obj[@functions.viewValue] = search.val()
|
119
|
+
val = @filter('filter')(@functions.collection(@scope), obj)[0]
|
120
|
+
@updateValue @functions.modelValueFn(val)
|
121
|
+
search.css
|
122
|
+
search.val(@functions.viewValueFn(val))
|
123
|
+
keydownFunction: (search,typeAhead,template,input) =>
|
124
|
+
keypress = (direction) ->
|
125
|
+
index = if direction == 'next' then 0 else template.find('a').length - 1
|
126
|
+
selected = angular.element(template[0].getElementsByClassName('active')[0])
|
127
|
+
if selected.hasClass('active')
|
128
|
+
selected.removeClass('active')
|
129
|
+
until complete
|
130
|
+
selected = angular.element(selected[0][direction + 'Sibling']) if selected[0]
|
131
|
+
complete = !!selected[0]
|
132
|
+
complete = selected[0].tagName == 'A' if complete
|
133
|
+
complete = true if !selected[0]
|
134
|
+
selected = angular.element(template.find('a')[index]) unless selected[0]
|
135
|
+
ind = 0
|
136
|
+
for el,i in template[0].getElementsByTagName('a')
|
137
|
+
ind = i if el == selected[0]
|
138
|
+
scroll = selected[0].scrollHeight * ind
|
139
|
+
selected[0].parentElement.scrollTop = scroll
|
140
|
+
selected.addClass('active')
|
141
|
+
location = search[0].selectionStart
|
142
|
+
search.val(selected.text())
|
143
|
+
search[0].setSelectionRange(location,location)
|
144
|
+
typeAhead.html(selected.text()[0..location - 1])
|
145
|
+
if input.keyCode == 40
|
146
|
+
input.preventDefault()
|
147
|
+
keypress('next')
|
148
|
+
if input.keyCode == 38
|
149
|
+
input.preventDefault()
|
150
|
+
keypress('previous')
|
151
|
+
mkeydownFunction: (tempHolder,event) =>
|
152
|
+
tempHolder.removeClass('active') if event.keyCode == 27
|
153
|
+
mousedownFunction: (tempHolder,search,event) =>
|
154
|
+
return if tempHolder.hasClass('active')
|
155
|
+
return if @disabled
|
156
|
+
search.val('')
|
157
|
+
@buildTemplate()
|
158
|
+
tempHolder.css('top',event.clientY)
|
159
|
+
tempHolder.css('transition','none')
|
160
|
+
@timeout ->
|
161
|
+
tempHolder.css('transition','')
|
162
|
+
tempHolder.css('top','')
|
163
|
+
tempHolder.addClass('active')
|
164
|
+
minputFunction: (event) =>
|
165
|
+
@buildTemplate()
|
166
|
+
|
167
|
+
standard: ->
|
168
|
+
[@inputFunction,@focusFunction,@blurFunction,@keydownFunction]
|
169
|
+
mobile: ->
|
170
|
+
[@mousedownFunction,@mkeydownFunction,@minputFunction]
|
171
|
+
|
11
172
|
|
12
173
|
angular.module('FilteredSelect', [])
|
13
174
|
.directive 'ngFilteredSelect', ($parse,$filter,$timeout)->
|
14
175
|
require: 'ngModel'
|
15
176
|
link: (scope,element,attrs,ngModel) ->
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
template = angular.element("<ul> </ul>")
|
28
|
-
search = angular.element "<input type='search' placeholder='Search'>"
|
29
|
-
tempHolder = angular.element("<div class='filtered-select' ></div>")
|
30
|
-
viewValueFn = $parse(viewValue || modelValue)
|
31
|
-
modelValueFn = $parse(modelValue || viewValue)
|
32
|
-
tempHolder.addClass('bottom') if element.hasClass('bottom')
|
33
|
-
template.bind 'mousewheel DOMMouseScroll', (event)->
|
34
|
-
delta = event.wheelDelta or event.originalEvent and event.originalEvent.wheelDelta or -event.detail
|
35
|
-
bottomOverflow = template[0].scrollTop + template.outerHeight() - template[0].scrollHeight >= 0
|
36
|
-
topOverflow = template[0].scrollTop <= 0
|
37
|
-
if delta < 0 and bottomOverflow or delta > 0 and topOverflow
|
38
|
-
event.preventDefault()
|
39
|
-
scrollStart = null
|
40
|
-
scrollTop = null
|
41
|
-
template.bind 'touchstart', (event)->
|
42
|
-
event.stopPropagation()
|
43
|
-
scrollStart = event.originalEvent.touches[0].clientY
|
44
|
-
template.bind 'touchmove', (event) ->
|
45
|
-
event.stopPropagation()
|
46
|
-
scroll = event.originalEvent.touches[0].clientY
|
47
|
-
scrollStart = scroll unless scrollStart
|
48
|
-
if scroll > scrollStart
|
49
|
-
event.preventDefault() if template.scrollTop() == 0
|
50
|
-
else if scroll < scrollStart
|
51
|
-
newScrollTop = template.scrollTop()
|
52
|
-
event.preventDefault() if scrollTop == newScrollTop
|
53
|
-
scrollTop = newScrollTop
|
54
|
-
scrollStart = scroll
|
55
|
-
return true
|
56
|
-
template.bind 'touchend', ->
|
57
|
-
event.stopPropagation()
|
58
|
-
scrollStart = null
|
59
|
-
body = angular.element('body')
|
60
|
-
body.bind 'keydown', (event) ->
|
61
|
-
tempHolder.removeClass('active') if event.keyCode == 27
|
62
|
-
tempHolder.append search
|
63
|
-
tempHolder.append template
|
64
|
-
body.append tempHolder
|
65
|
-
ulHeight = ->
|
66
|
-
full = window.innerHeight
|
67
|
-
full = full/3 if element.hasClass('bottom')
|
68
|
-
full - search[0].offsetHeight + 'px'
|
69
|
-
template.css('height',ulHeight())
|
70
|
-
scope.$watch collection, (newVal,oldVal) ->
|
71
|
-
return if newVal == oldVal
|
72
|
-
setInitialValue()
|
73
|
-
buildTemplate()
|
74
|
-
scope.$watch attrs.ngModel, (newVal,oldVal) ->
|
75
|
-
return if newVal == oldVal
|
76
|
-
setInitialValue()
|
77
|
-
search.bind 'input', ->
|
78
|
-
buildTemplate()
|
79
|
-
buildTemplate = ->
|
80
|
-
list= []
|
177
|
+
equiv = (left,right) ->
|
178
|
+
return true if left == right
|
179
|
+
return true if (!!left && !!right) == false
|
180
|
+
if !isNaN(left) && !isNaN(right)
|
181
|
+
return true if parseFloat(left) == parseFloat(right)
|
182
|
+
false
|
183
|
+
filteredList = (bool)->
|
184
|
+
if bool
|
185
|
+
bool = (left,right) ->
|
186
|
+
!!left.match(new RegExp("^" + right))
|
187
|
+
location = elements.search[0].selectionStart || elements.search.val().length
|
81
188
|
obj={}
|
82
|
-
obj[viewValue] = search.val() || ''
|
83
|
-
return unless collection(scope)
|
84
|
-
|
85
|
-
for filter in filters
|
189
|
+
obj[functions.viewValue] = elements.search.val()[0..location - 1] || ''
|
190
|
+
return unless functions.collection(scope)
|
191
|
+
fList = $filter('orderBy')($filter('filter')(functions.collection(scope), obj,bool), functions.viewValue)
|
192
|
+
for filter in options.filters
|
86
193
|
[filterType,value] = filter.replace(/\s+/,'').split(':')
|
87
|
-
|
88
|
-
|
89
|
-
|
194
|
+
fList = $filter(filterType)(fList, value)
|
195
|
+
fList
|
196
|
+
buildTemplate = ->
|
197
|
+
elements.template.empty()
|
198
|
+
return unless filteredList()
|
199
|
+
for item in filteredList()
|
200
|
+
if isMobile
|
201
|
+
li = angular.element '<li>' + functions.viewValueFn(item) + '</li>'
|
202
|
+
else
|
203
|
+
li = angular.element '<a class="item">' + functions.viewValueFn(item) + '</a>'
|
204
|
+
ip = angular.element '<input type="hidden">'
|
205
|
+
ip.val(functions.modelValueFn(item))
|
206
|
+
li.append(ip)
|
90
207
|
li.bind 'mousedown', ($event)->
|
91
|
-
updateValue($event.target.
|
92
|
-
|
93
|
-
template.empty()
|
94
|
-
template.append(list)
|
208
|
+
updateValue($event.target.children[0].value)
|
209
|
+
elements.template.append(li)
|
95
210
|
setInitialValue = ->
|
96
|
-
unless
|
97
|
-
view = attrs.placeholder
|
98
|
-
element.css('color','rgba(0,0,0,0.4)')
|
99
|
-
else
|
100
|
-
element.css('color','')
|
211
|
+
unless isMobile
|
101
212
|
obj = {}
|
102
|
-
obj[modelValue] =
|
103
|
-
list = $filter('filter')(collection(scope), obj)
|
213
|
+
obj[functions.modelValue] = ngModel.$modelValue
|
214
|
+
list = $filter('filter')(functions.collection(scope), obj,equiv)
|
104
215
|
viewScope = list[0] if list
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
216
|
+
elements.search.val(if viewScope then functions.viewValueFn(viewScope) else '')
|
217
|
+
elements.typeAhead.html(elements.search.val())
|
218
|
+
else
|
219
|
+
unless model = ngModel.$modelValue
|
220
|
+
view = attrs.placeholder
|
221
|
+
element.css('color','rgba(0,0,0,0.4)')
|
222
|
+
else
|
223
|
+
element.css('color','')
|
224
|
+
obj = {}
|
225
|
+
obj[functions.modelValue] = model
|
226
|
+
list = $filter('filter')(functions.collection(scope), obj,true)
|
227
|
+
viewScope = list[0] if list
|
228
|
+
view = if viewScope then functions.viewValueFn(viewScope) else attrs.placeholder
|
229
|
+
element.html('')
|
230
|
+
element.html(view)
|
231
|
+
|
110
232
|
updateValue = (model) ->
|
111
233
|
ngModel.$setViewValue(model)
|
112
|
-
tempHolder.removeClass('active')
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
done
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
return if
|
123
|
-
if fieldset
|
234
|
+
elements.tempHolder.removeClass('active')
|
235
|
+
setInitialValue()
|
236
|
+
disabled = ->
|
237
|
+
unless typeof fieldset != 'undefined'
|
238
|
+
done = false
|
239
|
+
fieldset = element
|
240
|
+
until done
|
241
|
+
fieldset = fieldset.parent()
|
242
|
+
unless done = typeof fieldset[0] == 'undefined'
|
243
|
+
done = fieldset[0].tagName == 'FIELDSET'
|
244
|
+
return true if typeof element[0].attributes.disabled != 'undefined' || $parse(attrs.ngDisabled)(scope)
|
245
|
+
if fieldset.length > 0
|
124
246
|
ngdis = if fieldset[0].attributes.ngDisabled then fieldset[0].attributes.ngDisabled.value else ''
|
125
|
-
return if fieldset[0].attributes.disabled || $parse(ngdis)(scope)
|
126
|
-
|
247
|
+
return true if fieldset[0].attributes.disabled || $parse(ngdis)(scope)
|
248
|
+
return false
|
249
|
+
|
250
|
+
options = new SelectOptions(attrs.ngSelectOptions,element[0].outerHTML)
|
251
|
+
functions = new SelectFunctions(options.match,$parse)
|
252
|
+
eFunctions = new EventFunctions(functions,buildTemplate,updateValue,filteredList,$filter,$timeout,$parse,scope,disabled())
|
253
|
+
if isMobile = typeof attrs.ngMobile != 'undefined'
|
254
|
+
elements = new MobileTemplate(element,eFunctions.mobile())
|
255
|
+
else
|
256
|
+
elements = new StandardTemplate(element,attrs,eFunctions.standard(),disabled())
|
257
|
+
scope.$watchCollection functions.collection, (newVal,oldVal) ->
|
258
|
+
return if newVal == oldVal
|
259
|
+
setInitialValue()
|
127
260
|
buildTemplate()
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
261
|
+
scope.$watch attrs.ngModel, (newVal,oldVal) ->
|
262
|
+
return if newVal == oldVal
|
263
|
+
setInitialValue()
|
264
|
+
scope.$watch disabled, (newVal,oldVal) ->
|
265
|
+
return if newVal == oldVal
|
266
|
+
elements.search[0].disabled = newVal
|
267
|
+
|
268
|
+
setInitialValue()
|
269
|
+
buildTemplate()
|
@@ -1,3 +1,4 @@
|
|
1
|
+
@import "angular-material.min"
|
1
2
|
div.filtered-select
|
2
3
|
position: fixed
|
3
4
|
z-index: 1001
|
@@ -33,12 +34,54 @@ div.filtered-select
|
|
33
34
|
cursor: pointer
|
34
35
|
box-shadow: 0 4px 2px -2px rgba(0,0,0,0.14)
|
35
36
|
&.bottom
|
36
|
-
top:
|
37
|
+
top: 50%
|
37
38
|
z-index: 1000
|
38
39
|
&.active
|
39
|
-
height:
|
40
|
+
height: 50%
|
40
41
|
ng-filtered-select
|
41
42
|
display: block
|
42
43
|
width: 100%
|
43
44
|
overflow: hidden
|
44
45
|
text-overflow: ellipsis
|
46
|
+
md-autocomplete
|
47
|
+
background: none
|
48
|
+
md-autocomplete-wrap.md-whiteframe-z1
|
49
|
+
box-shadow: none
|
50
|
+
button
|
51
|
+
display: none
|
52
|
+
.autocomplete.menu
|
53
|
+
text-align: left
|
54
|
+
&:empty
|
55
|
+
display: none
|
56
|
+
a
|
57
|
+
overflow: hidden
|
58
|
+
width: 100%
|
59
|
+
text-overflow: ellipsis
|
60
|
+
display: block
|
61
|
+
line-height: 48px
|
62
|
+
height: 48px
|
63
|
+
font-size: 14px
|
64
|
+
white-space: nowrap
|
65
|
+
cursor: pointer
|
66
|
+
&.active
|
67
|
+
font-weight: bolder
|
68
|
+
&:hover
|
69
|
+
max-height: 30rem
|
70
|
+
padding: 0.5rem
|
71
|
+
opacity: 1
|
72
|
+
z-index: 10
|
73
|
+
max-height: 0
|
74
|
+
overflow-y: hidden
|
75
|
+
overflow-x: hidden
|
76
|
+
position: absolute
|
77
|
+
background-color: white
|
78
|
+
opacity: 0
|
79
|
+
border-radius: 0.25rem
|
80
|
+
text-overflow: ellipsis
|
81
|
+
transition: all 0.55s cubic-bezier(0.25, 0.8, 0.25, 1)
|
82
|
+
padding: 0
|
83
|
+
|
84
|
+
input.autocomplete:focus + div
|
85
|
+
max-height: 30rem
|
86
|
+
padding: 0.5rem
|
87
|
+
opacity: 1
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: material_raingular
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3
|
4
|
+
version: 0.0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Moody
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|