material_raingular 0.0.1.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +32 -0
- data/Rakefile +2 -0
- data/lib/assets/javascripts/ajax_errors.js.coffee +13 -0
- data/lib/assets/javascripts/dateconverter.coffee +23 -0
- data/lib/assets/javascripts/directives/ngauthorize.js.coffee +8 -0
- data/lib/assets/javascripts/directives/ngautocomplete.js.coffee +135 -0
- data/lib/assets/javascripts/directives/ngboolean.js.coffee +34 -0
- data/lib/assets/javascripts/directives/ngchangeonblur.js.coffee +19 -0
- data/lib/assets/javascripts/directives/ngcreate.js.coffee +27 -0
- data/lib/assets/javascripts/directives/ngdestroy.js.coffee +24 -0
- data/lib/assets/javascripts/directives/ngdownload.js.coffee +8 -0
- data/lib/assets/javascripts/directives/ngdrag.js.coffee +122 -0
- data/lib/assets/javascripts/directives/ngfade.js.coffee +21 -0
- data/lib/assets/javascripts/directives/ngload.js.coffee +16 -0
- data/lib/assets/javascripts/directives/ngmatches.js.coffee +14 -0
- data/lib/assets/javascripts/directives/ngpopup.js.coffee +37 -0
- data/lib/assets/javascripts/directives/ngrepeatlist.js.coffee +52 -0
- data/lib/assets/javascripts/directives/ngslide.js.coffee +82 -0
- data/lib/assets/javascripts/directives/ngswipe.js.coffee +60 -0
- data/lib/assets/javascripts/directives/ngupdate.js.coffee +62 -0
- data/lib/assets/javascripts/directives/ngupload.js.coffee +127 -0
- data/lib/assets/javascripts/directives/ngwatchcontent.js.coffee +13 -0
- data/lib/assets/javascripts/directives/ngwatchshow.js.coffee +15 -0
- data/lib/assets/javascripts/directives/table.js.coffee +43 -0
- data/lib/assets/javascripts/directives/textarea.coffee +11 -0
- data/lib/assets/javascripts/directives/video.js.coffee +10 -0
- data/lib/assets/javascripts/factory_name.js.coffee +9 -0
- data/lib/assets/javascripts/material_raingular.js.coffee +17 -0
- data/lib/material_raingular/version.rb +3 -0
- data/lib/material_raingular.rb +8 -0
- data/lib/tasks/material_raingular.rake +42 -0
- data/material_raingular.gemspec +25 -0
- data/vendor/assets/angular/.jshintrc +181 -0
- data/vendor/assets/angular/angular-animate.js +3708 -0
- data/vendor/assets/angular/angular-aria.js +378 -0
- data/vendor/assets/angular/angular-cookies.js +320 -0
- data/vendor/assets/angular/angular-loader.js +429 -0
- data/vendor/assets/angular/angular-material.min.css +6 -0
- data/vendor/assets/angular/angular-material.min.js +14 -0
- data/vendor/assets/angular/angular-message-format.js +980 -0
- data/vendor/assets/angular/angular-messages.js +678 -0
- data/vendor/assets/angular/angular-resource.js +668 -0
- data/vendor/assets/angular/angular-route.js +991 -0
- data/vendor/assets/angular/angular-sanitize.js +683 -0
- data/vendor/assets/angular/angular-touch.js +627 -0
- data/vendor/assets/angular/angular.js +28133 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fc8b3fde9153d728b103515e331213214f7d8869
|
4
|
+
data.tar.gz: be9370ebe8c6d33b766c9ecb3d8fe46186948a58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bbbc21e4a0d5d4b1888844258afeb510eecad05f7e6e37c3495b496ca8414dc6fcef56cfae64f5649c9126d0be6bc5a9bea345b50efe50873d4841a9d049c970
|
7
|
+
data.tar.gz: 9762463d29da0434cfa4790e1a9bf9e8e41893890e66e2059849ca94d1096d89ab2a1ec033cce48a0d6677b03cfc7d7a821e4064763b2b01a53b705361e89255
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Chris Moody
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# MaterialRaingular
|
2
|
+
|
3
|
+
Simple convention over configuration rails angular tie in.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'material_raingular', github: 'transcon/material_raingular'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install material_raingular
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
The factories will be auto-generated when you run migrations to manually create the factories:
|
23
|
+
|
24
|
+
$ rake material_raingular:factories
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it ( https://github.com/transcon/material_raingular/fork )
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
angular.factories
|
2
|
+
.factory 'AjaxErrorsInterceptor', ($q, $rootScope) ->
|
3
|
+
request: (config) ->
|
4
|
+
$rootScope.xhr_errors = []
|
5
|
+
config
|
6
|
+
requestError: (rejection) -> rejection
|
7
|
+
response: (response) -> response
|
8
|
+
responseError: (rejection) ->
|
9
|
+
$rootScope.xhr_errors = []
|
10
|
+
for k,v of rejection.data
|
11
|
+
for description in v
|
12
|
+
$rootScope.xhr_errors.push(k + ' ' + ' ' + description)
|
13
|
+
rejection
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class DateParser
|
2
|
+
constructor: (object)->
|
3
|
+
@object = object
|
4
|
+
evaluate: ->
|
5
|
+
for i of @object
|
6
|
+
if @object[i] != null and typeof @object[i] == 'object'
|
7
|
+
new DateParser(@object[i]).evaluate()
|
8
|
+
else if @object[i] != null and typeof @object[i] == 'string'
|
9
|
+
if !!@object[i].match(/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/)
|
10
|
+
time = new Date(@object[i])
|
11
|
+
time.setTime( time.getTime() + time.getTimezoneOffset()*60*1000 ) #offset timezone
|
12
|
+
@object[i] = time
|
13
|
+
else if !!@object[i].match(/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T[0-9]{2}\:[0-9]{2}\:[0-9]{2}\.[0-9]{3}[A-Z]$/)
|
14
|
+
@object[i] = new Date(@object[i])
|
15
|
+
return
|
16
|
+
angular.factories
|
17
|
+
.factory 'DateConverterInterceptor', ($q, $rootScope) ->
|
18
|
+
request: (config) -> config
|
19
|
+
requestError: (rejection) -> rejection
|
20
|
+
response: (response) ->
|
21
|
+
new DateParser(response.data).evaluate()
|
22
|
+
response
|
23
|
+
responseError: (rejection) -> rejection
|
@@ -0,0 +1,8 @@
|
|
1
|
+
angular.module('NgAuthorize', [])
|
2
|
+
.directive 'ngAuthorize', ($http) ->
|
3
|
+
controller: ($scope, $element) ->
|
4
|
+
params = $element[0].attributes['ng-authorize'].value.split(',')
|
5
|
+
object = {action: params[0], object: params[1]}
|
6
|
+
$http url: '/authorize.json', method: "GET", params: object
|
7
|
+
.success (data) ->
|
8
|
+
$scope.authorized = data.authorized
|
@@ -0,0 +1,135 @@
|
|
1
|
+
class Autocomplete
|
2
|
+
constructor: (scope,factory_name, element,$filter)->
|
3
|
+
@element = element
|
4
|
+
@attributes = element[0].attributes
|
5
|
+
@scope = scope
|
6
|
+
@model_name = @attributes['ng-model'].value
|
7
|
+
@list_model = @attributes['ng-list-model'].value.split('.')
|
8
|
+
@options = if @attributes['ng-list-options'] then eval("(" + @attributes['ng-list-options'].value + ")") else {}
|
9
|
+
@context = if @attributes['ng-context'] then @attributes['ng-context'].value
|
10
|
+
@sort_by = if @attributes['ng-sort-by'] then @attributes['ng-sort-by'].value else @list_attr
|
11
|
+
@list_attr = @list_model[1]
|
12
|
+
@factory = factory_name(@list_model[0])
|
13
|
+
@scopes = @context.split('.') if @context
|
14
|
+
@parent_name = @scopes.pop() if @scopes
|
15
|
+
@list = angular.element("<div class='autocomplete menu'></div>")
|
16
|
+
@filter = $filter
|
17
|
+
@existing_factory = @scope[@factory] || @scope.$parent[@factory]
|
18
|
+
@listFactory = @element.injector().get(@factory) unless @existing_factory
|
19
|
+
@list.insertAfter(@element[0])
|
20
|
+
|
21
|
+
if @parent_name
|
22
|
+
@parent_id = @parent_name + if @parent_name.indexOf('_id') < 0 then '_id' else ''
|
23
|
+
|
24
|
+
@load()
|
25
|
+
|
26
|
+
parent_context: =>
|
27
|
+
hash = {}
|
28
|
+
hash[@parent_id] = @parent() if @context
|
29
|
+
return hash
|
30
|
+
serialize: =>
|
31
|
+
hash = {}
|
32
|
+
for key,val of @options
|
33
|
+
hash[key] = val
|
34
|
+
for key,val of @parent_context()
|
35
|
+
hash[key] = val
|
36
|
+
hash
|
37
|
+
model: (val)=>
|
38
|
+
return @scope.$eval(@model_name + '="' + val + '"') if val
|
39
|
+
return @scope.$eval(@model_name)
|
40
|
+
parent: =>
|
41
|
+
return null unless @context
|
42
|
+
return @scope.$eval(@context)
|
43
|
+
load: ->
|
44
|
+
scope = @scope
|
45
|
+
factory = @factory
|
46
|
+
model = @model
|
47
|
+
updateView = @updateView
|
48
|
+
if @context
|
49
|
+
return unless @parent()
|
50
|
+
if @existing_factory
|
51
|
+
scope[factory] = @existing_factory
|
52
|
+
scope.$watchCollection factory, (newVal) ->
|
53
|
+
updateView(model())
|
54
|
+
updateView(model())
|
55
|
+
else
|
56
|
+
@listFactory.index @serialize(), (data) ->
|
57
|
+
scope[factory] = data
|
58
|
+
updateView(model())
|
59
|
+
updateView: (value) =>
|
60
|
+
object = {}
|
61
|
+
object[@list_attr] = value || ''
|
62
|
+
scope = @scope
|
63
|
+
model = @model
|
64
|
+
model_name = @model_name
|
65
|
+
filtered = @filter('filter')((scope[@factory] || []), object )
|
66
|
+
filtered = @filter('orderBy')(filtered, @sort_by)
|
67
|
+
items = []
|
68
|
+
for item in filtered
|
69
|
+
item = angular.element "<a class='item'>" + item[@list_attr] + "</a>"
|
70
|
+
item.bind 'click', (event) ->
|
71
|
+
model(event.target.textContent)
|
72
|
+
scope.$eval event.target.parentNode.previousSibling.attributes['ng-change-on-blur'].value
|
73
|
+
items.push item
|
74
|
+
@list.empty()
|
75
|
+
@list.append(items)
|
76
|
+
|
77
|
+
angular.module('AutoComplete', [ 'FactoryName'])
|
78
|
+
|
79
|
+
.directive 'ngAutocomplete', ->
|
80
|
+
restrict: 'E'
|
81
|
+
replace: true
|
82
|
+
require: 'ngModel'
|
83
|
+
require: 'ngListModel'
|
84
|
+
template: (element, attributes) ->
|
85
|
+
newElement = angular.element('<input>')
|
86
|
+
newElement.addClass('autocomplete')
|
87
|
+
newElement[0].setAttribute('ng-update',attributes.ngModel)
|
88
|
+
newElement[0].setAttribute('auto-complete',true)
|
89
|
+
return newElement[0].outerHTML
|
90
|
+
controller: ($scope, $element, $filter, $timeout, factoryName) ->
|
91
|
+
ac = new Autocomplete($scope,factoryName,$element,$filter)
|
92
|
+
if ac.context
|
93
|
+
$scope.$watch ac.context, (newVal, oldVal) ->
|
94
|
+
if newVal
|
95
|
+
ac.load()
|
96
|
+
$scope.$watch ac.model_name, (newVal) ->
|
97
|
+
ac.updateView(newVal)
|
98
|
+
|
99
|
+
.directive 'autoComplete', ->
|
100
|
+
restrict: 'A'
|
101
|
+
require: '?ngModel'
|
102
|
+
link: (scope, element, attributes, ngModel) ->
|
103
|
+
if element[0].tagName == 'INPUT'
|
104
|
+
element.bind 'focus', ->
|
105
|
+
pos = element.position()
|
106
|
+
element.next()[0].style.left = '0px'
|
107
|
+
element.bind 'blur', ->
|
108
|
+
element.parent().find('.active').removeClass('active')
|
109
|
+
ngModel.$setViewValue(element.val())
|
110
|
+
ngModel.$render()
|
111
|
+
element.bind 'keydown', (input)->
|
112
|
+
if input.keyCode == 40
|
113
|
+
selected = element.next().find('a.active')
|
114
|
+
if selected.hasClass('active')
|
115
|
+
selected.removeClass('active')
|
116
|
+
selected = selected.next('a')
|
117
|
+
else
|
118
|
+
selected = element.next().find('a').first()
|
119
|
+
if !selected.html() then selected = element.next().find('a').first()
|
120
|
+
scroll = selected[0].scrollHeight * element.next().find('a').index(selected)
|
121
|
+
selected[0].parentElement.scrollTop = scroll
|
122
|
+
selected.addClass('active')
|
123
|
+
element.val(selected.text())
|
124
|
+
if input.keyCode == 38
|
125
|
+
selected = element.next().find('a.active')
|
126
|
+
if selected.hasClass('active')
|
127
|
+
selected.removeClass('active')
|
128
|
+
selected = selected.prev('a')
|
129
|
+
else
|
130
|
+
selected = element.next().find('a').last()
|
131
|
+
if !selected.html() then selected = element.next().find('a').last()
|
132
|
+
scroll = selected[0].scrollHeight * element.next().find('a').index(selected)
|
133
|
+
selected[0].parentElement.scrollTop = scroll
|
134
|
+
selected.addClass('active')
|
135
|
+
element.val(selected.text())
|
@@ -0,0 +1,34 @@
|
|
1
|
+
angular.module 'NgBoolean', ['Factories', 'FactoryName']
|
2
|
+
|
3
|
+
.directive 'ngBoolean', ($timeout, $compile) ->
|
4
|
+
restrict: 'A'
|
5
|
+
|
6
|
+
link: (scope, element, attributes, ngModelCtrl) ->
|
7
|
+
model = attributes.ngModel
|
8
|
+
callFunction = model + ' = !' + model + ' ; update("' + model + '")'
|
9
|
+
callFunction += ';' + attributes.ngCallback if attributes.ngCallback
|
10
|
+
element.attr("call-function", callFunction)
|
11
|
+
element.bind 'click', ->
|
12
|
+
scope.$eval(element.attr("call-function"))
|
13
|
+
|
14
|
+
controller: ($scope, $injector,factoryName) ->
|
15
|
+
$scope.update = (modelName)->
|
16
|
+
input = modelName.split(',')
|
17
|
+
trackby = input.pop() if input.length > 1
|
18
|
+
trackby = trackby.split(';') if trackby
|
19
|
+
trackby = [] unless trackby
|
20
|
+
data = input.splice(0,1)[0].split('.')
|
21
|
+
functions = input.join(',').split(')')
|
22
|
+
factory = factoryName(data[0])
|
23
|
+
object = {id: $scope[data[0]]['id']}
|
24
|
+
object[data[0]] = {id: $scope[data[0]]['id']}
|
25
|
+
object[data[0]][data[1]] = $scope[data[0]][data[1]]
|
26
|
+
list = $injector.get(factory)
|
27
|
+
list.update object, (returnData) ->
|
28
|
+
for tracked in trackby
|
29
|
+
$scope[data[0]][tracked] = returnData[tracked]
|
30
|
+
$scope[data[0]][data[1]] = returnData[data[1]] if $scope[data[0]][data[1]] == object[data[0]][data[1]]
|
31
|
+
callFunctions = []
|
32
|
+
for callFunction in functions
|
33
|
+
callFunctions.push(callFunction + ',' + JSON.stringify(returnData) + ')') if callFunction.length > 0
|
34
|
+
$scope.$eval( callFunctions.join('') ) if callFunctions.join('').length > 0
|
@@ -0,0 +1,19 @@
|
|
1
|
+
angular.module('NgChangeOnBlur', [])
|
2
|
+
.directive 'ngChangeOnBlur', ($timeout)->
|
3
|
+
restrict: 'A',
|
4
|
+
require: 'ngModel',
|
5
|
+
link: (scope, element, attributes, ngModelCtrl) ->
|
6
|
+
return if (attributes.type == 'radio' || attributes.type == 'checkbox')
|
7
|
+
callFunction = attributes.ngChangeOnBlur
|
8
|
+
oldValue = null
|
9
|
+
element.bind 'focus', ->
|
10
|
+
scope.$apply ->
|
11
|
+
oldValue = element.val()
|
12
|
+
element.bind 'blur', (event) ->
|
13
|
+
delay = if element.hasClass('autocomplete') then 300 else 0
|
14
|
+
$timeout ->
|
15
|
+
scope.$apply ->
|
16
|
+
newValue = element.val()
|
17
|
+
scope.$eval(callFunction) if (newValue != oldValue)
|
18
|
+
, delay
|
19
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
angular.module 'NgCreate', ['Factories', 'FactoryName']
|
2
|
+
|
3
|
+
.directive 'ngCreate', ($timeout, $compile) ->
|
4
|
+
restrict: 'A'
|
5
|
+
link: (scope, element, attributes) ->
|
6
|
+
element.bind 'click', (event) ->
|
7
|
+
[parentName, listName] = attributes.ngContext.split('.') if attributes.ngContext
|
8
|
+
attr = eval('(' + attributes.ngAttributes + ')') || {}
|
9
|
+
scope.create(attributes.ngCreate,parentName,listName,attr)
|
10
|
+
controller: ($scope, $injector, factoryName) ->
|
11
|
+
$scope.create = (modelName,parentName,listName,attributes) ->
|
12
|
+
factory = factoryName(modelName)
|
13
|
+
list = $injector.get(factory)
|
14
|
+
object = {}
|
15
|
+
object[modelName] = attributes
|
16
|
+
if parentName
|
17
|
+
object[parentName] = $scope[parentName] unless parentName.indexOf('_id') < 0
|
18
|
+
object[parentName + '_id'] = $scope[parentName].id if parentName.indexOf('_id') < 0
|
19
|
+
list.create object, (returnData) ->
|
20
|
+
if listName
|
21
|
+
scope = if $scope[parentName] then $scope else $scope.$parent
|
22
|
+
scope[parentName] = {} unless scope[parentName]
|
23
|
+
scope[parentName][listName] = [] unless scope[parentName][listName]
|
24
|
+
scope[parentName][listName].push(returnData)
|
25
|
+
else
|
26
|
+
$scope[factory] = [] unless $scope[factory]
|
27
|
+
$scope[factory].push(returnData)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
angular.module 'NgDestroy', ['Factories']
|
2
|
+
|
3
|
+
.directive 'ngDestroy', ($timeout, $compile) ->
|
4
|
+
restrict: 'A'
|
5
|
+
link: (scope, element, attributes) ->
|
6
|
+
element.bind 'click', (event) ->
|
7
|
+
scope.destroy(attributes.ngDestroy,attributes.ngContext)
|
8
|
+
controller: ($scope, $injector) ->
|
9
|
+
$scope.destroy = (modelName,listName) ->
|
10
|
+
raw_factory = modelName.split('_')
|
11
|
+
factory=[]
|
12
|
+
for word in raw_factory
|
13
|
+
factory.push(word.charAt(0).toUpperCase() + word.slice(1))
|
14
|
+
factory = factory.join('')
|
15
|
+
if listName
|
16
|
+
list = $scope
|
17
|
+
for scope in listName.split('.')
|
18
|
+
list = list[scope]
|
19
|
+
else
|
20
|
+
list = $scope[factory]
|
21
|
+
list.splice(list.indexOf($scope[modelName]),1)
|
22
|
+
list = $injector.get(factory)
|
23
|
+
object = {id: $scope[modelName].id}
|
24
|
+
list.delete object
|
@@ -0,0 +1,8 @@
|
|
1
|
+
angular.module('NgDownload', [])
|
2
|
+
.directive 'ngDownload', ->
|
3
|
+
replace: true,
|
4
|
+
link: (scope, element, attrs) ->
|
5
|
+
value = attrs.ngDownload
|
6
|
+
value = if value == true || value == 'true' then '' else value
|
7
|
+
value = null if (value == null || value == 'false' || value == '')
|
8
|
+
element.attr 'download',value
|
@@ -0,0 +1,122 @@
|
|
1
|
+
angular.module('NgDrag', [])
|
2
|
+
.factory 'DragHolder', ->
|
3
|
+
object = { scope: '', dragging: '', context: '' }
|
4
|
+
|
5
|
+
object.set = (scope,dragging,context) ->
|
6
|
+
this.scope = scope
|
7
|
+
this.dragging = dragging
|
8
|
+
this.context = context
|
9
|
+
|
10
|
+
object.get = ->
|
11
|
+
return this
|
12
|
+
|
13
|
+
return object
|
14
|
+
.directive 'ngPositionable', (DragHolder) ->
|
15
|
+
link: (scope, element, attributes, ngModelCtrl) ->
|
16
|
+
el = element[0]
|
17
|
+
element.css('transition', '0.3s all')
|
18
|
+
el.draggable = true
|
19
|
+
el.addEventListener 'dragstart', (e) ->
|
20
|
+
this.classList.add('drag')
|
21
|
+
DragHolder.set scope,attributes.ngPositionable,attributes.ngContext
|
22
|
+
e.stopPropagation()
|
23
|
+
el.addEventListener 'dragend',(e) ->
|
24
|
+
this.classList.remove('drag')
|
25
|
+
el.droppable = true
|
26
|
+
el.addEventListener 'dragover', (e) ->
|
27
|
+
e.dataTransfer.dropEffect = 'move'
|
28
|
+
e.preventDefault()
|
29
|
+
e.stopPropagation()
|
30
|
+
this.classList.add('over')
|
31
|
+
el.addEventListener 'dragenter', (e) ->
|
32
|
+
e.preventDefault()
|
33
|
+
e.stopPropagation()
|
34
|
+
this.classList.add('over')
|
35
|
+
el.addEventListener 'dragleave', (e) ->
|
36
|
+
this.classList.remove('over')
|
37
|
+
e.preventDefault()
|
38
|
+
el.addEventListener 'drop', (e) ->
|
39
|
+
e.stopPropagation() if (e.stopPropagation)
|
40
|
+
this.classList.remove('over')
|
41
|
+
raw_factory = attributes.ngPositionable.split('_')
|
42
|
+
factory=[]
|
43
|
+
for word in raw_factory
|
44
|
+
factory.push(word.charAt(0).toUpperCase() + word.slice(1))
|
45
|
+
factory = factory.join('')
|
46
|
+
dragged = DragHolder.get()
|
47
|
+
dragging = dragged.scope[dragged.dragging]
|
48
|
+
if dragged.context
|
49
|
+
draggingContext = dragged.scope[dragged.context]
|
50
|
+
droppingContext = scope[attributes.ngContext]
|
51
|
+
if draggingContext != droppingContext
|
52
|
+
dragged.scope[factory].splice(dragged.scope[factory].indexOf(dragging),1)
|
53
|
+
scope[factory].push(dragging)
|
54
|
+
dropping = scope[attributes.ngPositionable]
|
55
|
+
if attributes.ngDisabled
|
56
|
+
disabled = attributes.ngDisabled.split('!')
|
57
|
+
disabled[0] = '!' if disabled.length > 1
|
58
|
+
bool = scope.$parent[disabled.pop()]
|
59
|
+
bool = !bool if disabled.length > 0
|
60
|
+
else
|
61
|
+
bool = false
|
62
|
+
unless bool
|
63
|
+
scope.setPosition(dragging,dropping,draggingContext,droppingContext,attributes.ngContext,factory)
|
64
|
+
controller: ($scope, $element, $filter, $injector) ->
|
65
|
+
$scope.setPosition = (dragging,dropping,draggingContext,droppingContext,context,factory) ->
|
66
|
+
unless dragging == dropping
|
67
|
+
orderedArray = $filter('orderBy')($scope[factory], 'position')
|
68
|
+
index = orderedArray.indexOf(dropping)
|
69
|
+
unless dragging == orderedArray[index - 1]
|
70
|
+
unless index == 0
|
71
|
+
dragging.position = parseFloat(dropping.position) - (parseFloat(dropping.position) - parseFloat(orderedArray[index - 1].position)) / 2
|
72
|
+
else
|
73
|
+
dragging.position = parseFloat(dropping.position) / 2
|
74
|
+
object = {id: dragging.id, position: dragging.position}
|
75
|
+
object[context + '_id'] = droppingContext.id if context
|
76
|
+
list = $injector.get(factory)
|
77
|
+
list.update object, (returnData) ->
|
78
|
+
dragging = returnData
|
79
|
+
|
80
|
+
.directive 'ngDrag', ->
|
81
|
+
link: (scope, element, attributes, ngModelCtrl) ->
|
82
|
+
callFunction = attributes.ngDrag
|
83
|
+
el = element[0]
|
84
|
+
el.draggable = true
|
85
|
+
el.addEventListener 'dragstart', (e) ->
|
86
|
+
e.dataTransfer.setData('html',el)
|
87
|
+
this.classList.add('drag')
|
88
|
+
scope.$eval(callFunction)
|
89
|
+
el.addEventListener 'dragend',(e) ->
|
90
|
+
this.classList.remove('drag')
|
91
|
+
|
92
|
+
.directive 'ngDrop', ->
|
93
|
+
link: (scope, element, attributes, ngModelCtrl) ->
|
94
|
+
callFunction = attributes.ngDrop
|
95
|
+
el = element[0]
|
96
|
+
el.droppable = true
|
97
|
+
el.addEventListener 'dragover', (e) ->
|
98
|
+
e.dataTransfer.dropEffect = 'move'
|
99
|
+
e.preventDefault()
|
100
|
+
this.classList.add('over')
|
101
|
+
el.addEventListener 'dragenter', (e) ->
|
102
|
+
e.preventDefault()
|
103
|
+
this.classList.add('over')
|
104
|
+
el.addEventListener 'dragleave', (e) ->
|
105
|
+
this.classList.remove('over')
|
106
|
+
e.preventDefault()
|
107
|
+
el.addEventListener 'drop', (e) ->
|
108
|
+
e.stopPropagation() if (e.stopPropagation)
|
109
|
+
this.classList.remove('over')
|
110
|
+
scope.$eval(callFunction)
|
111
|
+
|
112
|
+
.directive 'ngChangeDebounce', ($timeout) ->
|
113
|
+
restrict: 'A',
|
114
|
+
require: 'ngModel',
|
115
|
+
link: (scope, element, attr, ngModelCtrl) ->
|
116
|
+
return if (attr.type == 'radio' || attr.type == 'checkbox')
|
117
|
+
callFunction = attr.ngChangeDebounce
|
118
|
+
element.bind 'keyup', ->
|
119
|
+
$timeout.cancel(scope.debounce)
|
120
|
+
scope.debounce = $timeout ->
|
121
|
+
scope.$eval(callFunction)
|
122
|
+
,750
|
@@ -0,0 +1,21 @@
|
|
1
|
+
angular.module('NgFade', [])
|
2
|
+
.directive 'ngFadeOut', ->
|
3
|
+
link: (scope, element, attributes) ->
|
4
|
+
element.css('transition', '0.3s all')
|
5
|
+
scope.$watch attributes.ngFadeOut, (value) ->
|
6
|
+
if value
|
7
|
+
element.css('opacity', '0')
|
8
|
+
element.css('z-index', '0')
|
9
|
+
else
|
10
|
+
element.css('opacity', '1')
|
11
|
+
element.css('z-index', '1')
|
12
|
+
.directive 'ngFadeIn', ->
|
13
|
+
link: (scope, element, attributes) ->
|
14
|
+
element.css('transition', '0.3s all')
|
15
|
+
scope.$watch attributes.ngFadeIn, (value) ->
|
16
|
+
if value
|
17
|
+
element.css('opacity', '1')
|
18
|
+
element.css('z-index', '1')
|
19
|
+
else
|
20
|
+
element.css('opacity', '0')
|
21
|
+
element.css('z-index', '0')
|
@@ -0,0 +1,16 @@
|
|
1
|
+
angular.module 'NgLoad', ['Factories', 'FactoryName']
|
2
|
+
|
3
|
+
.directive 'ngLoad', ->
|
4
|
+
restrict: 'E'
|
5
|
+
require: 'ngModel'
|
6
|
+
|
7
|
+
controller: ($scope, $element, $injector, $routeParams, factoryName) ->
|
8
|
+
factory = factoryName($element[0].attributes['ng-model'].value)
|
9
|
+
object = {id: $routeParams.id}
|
10
|
+
list = $injector.get(factory)
|
11
|
+
if $routeParams.id
|
12
|
+
list.show object, (returnData) ->
|
13
|
+
$scope[$element[0].attributes['ng-model'].value] = returnData
|
14
|
+
else
|
15
|
+
list.create (returnData) ->
|
16
|
+
$scope[$element[0].attributes['ng-model'].value] = returnData
|
@@ -0,0 +1,14 @@
|
|
1
|
+
angular.module('NgMatches', [])
|
2
|
+
.directive 'ngMatches', ->
|
3
|
+
replace: true
|
4
|
+
scope: {
|
5
|
+
ngMatches: '='
|
6
|
+
}
|
7
|
+
template: (element, attributes) ->
|
8
|
+
element[0].setAttribute('ng-show','checkMatch(ngMatches)')
|
9
|
+
element[0].removeAttribute('ng-matches')
|
10
|
+
return element[0].outerHTML
|
11
|
+
controller: ($scope,$element) ->
|
12
|
+
$scope.checkMatch = (model) ->
|
13
|
+
return true unless model
|
14
|
+
return $element[0].textContent.toLowerCase().indexOf(model.toLowerCase()) > -1
|
@@ -0,0 +1,37 @@
|
|
1
|
+
angular.module('NgPopup', [])
|
2
|
+
.directive 'ngPopup',($timeout) ->
|
3
|
+
restrict: 'A',
|
4
|
+
scope: {
|
5
|
+
ngPopup: '@'
|
6
|
+
}
|
7
|
+
controller: ($scope, $element) ->
|
8
|
+
popup = document.createElement('div')
|
9
|
+
popup.setAttribute('class','ng-popup ng-hide')
|
10
|
+
exitStatus = true
|
11
|
+
while exitStatus
|
12
|
+
$scope.uniqueId = Math.floor(Math.random()*(1000000))
|
13
|
+
exitStatus = !!document.getElementById($scope.uniqueId)
|
14
|
+
popup.setAttribute('id', $scope.uniqueId)
|
15
|
+
document.body.appendChild(popup)
|
16
|
+
|
17
|
+
link: (scope, element, attributes) ->
|
18
|
+
setView = (start) ->
|
19
|
+
if start
|
20
|
+
pos = element[0].getBoundingClientRect()
|
21
|
+
popup = document.getElementById(scope.uniqueId)
|
22
|
+
popup.style.left = (pos.right + 3) + 'px'
|
23
|
+
popup.style.top = (pos.top + 3) + 'px'
|
24
|
+
scope.runner = $timeout ->
|
25
|
+
document.getElementById(scope.uniqueId).innerHTML = scope.ngPopup
|
26
|
+
setView(true)
|
27
|
+
30
|
28
|
+
popup.classList.remove('ng-hide')
|
29
|
+
else
|
30
|
+
$timeout.cancel scope.runner
|
31
|
+
document.getElementById(scope.uniqueId).classList.add('ng-hide')
|
32
|
+
startListener = if (element[0].tagName == 'INPUT' || element[0].tagName == 'INPUT') then 'focus' else 'mouseenter'
|
33
|
+
stopListener = if (element[0].tagName == 'INPUT' || element[0].tagName == 'INPUT') then 'blur' else 'mouseout'
|
34
|
+
element[0].addEventListener startListener, ->
|
35
|
+
setView(true)
|
36
|
+
element[0].addEventListener stopListener, ->
|
37
|
+
setView()
|