glider-rails 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,16 +1,23 @@
1
1
  ###
2
- glider 0.0.6 - AngularJS slider
3
- https://github.com/evrone/glider
4
- Copyright (c) 2013 Valentin Vasilyev, Dmitry Karpunin
5
- Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
2
+ glider 0.1.0 - AngularJS slider
3
+ https://github.com/evrone/glider
4
+ Copyright (c) 2013 Valentin Vasilyev, Dmitry Karpunin
5
+ Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
6
+
7
+ examples:
8
+
9
+ basic:
10
+ <slider min="0" max="100" step="1" value="age"></slider>
11
+
12
+ update only on mouse up
13
+ <slider defer_update min="0" max="100" step="1" value="age"></slider>
14
+
15
+ slider with increments (incompatible with step option)
16
+ <slider min="0" max="100" increments="10,50,60,90"></slider>
6
17
  ###
7
18
  'use strict';
8
19
  app = angular.module("glider", [])
9
- # example:
10
- # <slider min="0" max="100" step="1" value="age"></slider>
11
- # example with update only on mouse up and stop drag
12
- # <slider defer_update min="0" max="100" step="1" value="age"></slider>
13
- #
20
+
14
21
  app.directive "slider", ["$document", ($document) ->
15
22
 
16
23
  getSubElement = (sliderElement, className) ->
@@ -28,14 +35,20 @@ app.directive "slider", ["$document", ($document) ->
28
35
  </span>
29
36
  <span class="side dec">
30
37
  <span class="button" ng-click="step(-1)">-</span>
31
- <span class="bound-value">{{min() | slice}}</span>
38
+ <span class="bound-value">{{min() | intersperse}}</span>
32
39
  </span>
33
40
  <span class="side inc">
34
41
  <span class="button" ng-click="step(+1)">+</span>
35
- <span class="bound-value">{{max() | slice}}</span>
42
+ <span class="bound-value">{{max() | intersperse}}</span>
43
+ </span>
44
+ <span class="increments">
45
+ <span ng-repeat="i in increments" class="i" style="left: {{i.offset}}%">
46
+ {{ i.value | intersperse }}
47
+ </span>
36
48
  </span>
37
49
  </span>
38
50
  """
51
+
39
52
  replace: true
40
53
  restrict: "E"
41
54
  scope:
@@ -44,6 +57,17 @@ app.directive "slider", ["$document", ($document) ->
44
57
  max: "&"
45
58
 
46
59
  link: (scope, element, attrs) ->
60
+ parseIncrements = ->
61
+ trim = (input) -> if input then input.replace(/^\s+|\s+$/g, '') else input
62
+ offset = (min, max, value) -> value / Math.abs(max - min) * 100
63
+ if attrs.increments
64
+ min = scope.min()
65
+ max = scope.max()
66
+ increments = attrs.increments.split(',')
67
+ increments = for i in increments when min < parseInt(i) < max
68
+ value: parseInt(trim(i), 10)
69
+ offset: offset(min, max, i)
70
+
47
71
  sliderElement = getSubElement(element, "slider")
48
72
  dragging = false
49
73
  xPosition = 0
@@ -52,6 +76,12 @@ app.directive "slider", ["$document", ($document) ->
52
76
 
53
77
  scope.value = scope.min() unless scope.value?
54
78
 
79
+ scope.increments = parseIncrements(attrs.increments)
80
+ if attrs.increments?
81
+ scope.snapValues = ([scope.min(), scope.max()].concat(i.value for i in scope.increments))
82
+ .sort((a,b) -> a - b)
83
+
84
+
55
85
  refreshHandle = ->
56
86
  range = scope.max() - scope.min()
57
87
  if range is 0
@@ -73,14 +103,31 @@ app.directive "slider", ["$document", ($document) ->
73
103
  else
74
104
  refreshHandle()
75
105
 
76
- scope.$watch "value", ->
106
+ scope.$watch "value", (newVal, oldVal)->
77
107
  return if dragging
78
- refreshHandle()
108
+ if scope.min() <= newVal <= scope.max()
109
+ refreshHandle()
110
+ else
111
+ newVal = oldVal
79
112
 
80
113
  scope.step = (steps) ->
81
- newValue = scope.value + steps * step
82
- if scope.min() <= newValue <= scope.max()
83
- scope.value = newValue
114
+ doStep = (steps)->
115
+ newValue = scope.value + steps * step
116
+ if scope.min() <= newValue <= scope.max()
117
+ scope.value = newValue
118
+
119
+ doIncrement = (steps) ->
120
+ newVal = if steps > 0
121
+ (sv for sv in scope.snapValues when sv > scope.value)[0]
122
+ else
123
+ (sv for sv in scope.snapValues when sv < scope.value).sort((a,b) -> b - a)[0]
124
+ scope.value = newVal if newVal?
125
+
126
+ if attrs.increments?
127
+ doIncrement(steps)
128
+ else
129
+ doStep(steps)
130
+
84
131
 
85
132
  scope.mouseDown = ($event) ->
86
133
  dragging = true
@@ -90,6 +137,20 @@ app.directive "slider", ["$document", ($document) ->
90
137
  scope.value = Math.round((((scope.max() - scope.min()) * (xPosition / 100)) + scope.min()) / step) * step
91
138
  scope.$apply()
92
139
 
140
+ snap = ->
141
+ i = 0
142
+ l = scope.snapValues.length
143
+
144
+ while i < l
145
+ diff = Math.abs(scope.snapValues[i] - scope.value)
146
+ min = diff unless min?
147
+ if diff <= min
148
+ closest = scope.snapValues[i]
149
+ min = diff
150
+ i++
151
+ scope.value = closest
152
+ scope.$apply()
153
+
93
154
  $document.on "mousemove", ($event) ->
94
155
  return unless dragging
95
156
  # Calculate value handle position
@@ -107,9 +168,10 @@ app.directive "slider", ["$document", ($document) ->
107
168
  $document.on "mouseup", ->
108
169
  dragging = false
109
170
  updateValue() if deferUpdate
171
+ snap() if scope.increments
110
172
  $document.off "mousemove"
111
173
  ]
112
- app.filter 'slice', ->
174
+ app.filter 'intersperse', ->
113
175
  (input) ->
114
176
  return unless input?
115
177
  input = input.toString()
@@ -1,9 +1,20 @@
1
1
  // Generated by CoffeeScript 1.6.3
2
2
  /*
3
- glider 0.0.6 - AngularJS slider
4
- https://github.com/evrone/glider
5
- Copyright (c) 2013 Valentin Vasilyev, Dmitry Karpunin
6
- Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
3
+ glider 0.1.0 - AngularJS slider
4
+ https://github.com/evrone/glider
5
+ Copyright (c) 2013 Valentin Vasilyev, Dmitry Karpunin
6
+ Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
7
+
8
+ examples:
9
+
10
+ basic:
11
+ <slider min="0" max="100" step="1" value="age"></slider>
12
+
13
+ update only on mouse up
14
+ <slider defer_update min="0" max="100" step="1" value="age"></slider>
15
+
16
+ slider with increments (incompatible with step option)
17
+ <slider min="0" max="100" increments="10,50,60,90"></slider>
7
18
  */
8
19
 
9
20
 
@@ -24,7 +35,7 @@
24
35
  return angular.element(getSubElement(elem, "range")).css("width", "" + posX + "%");
25
36
  };
26
37
  return {
27
- template: "<span class=\"g-slider horizontal\">\n <span class=\"slider\">\n <span class=\"range\"></span>\n <span class=\"handle\" ng-mousedown=\"mouseDown($event)\"></span>\n </span>\n <span class=\"side dec\">\n <span class=\"button\" ng-click=\"step(-1)\">-</span>\n <span class=\"bound-value\">{{min() | slice}}</span>\n </span>\n <span class=\"side inc\">\n <span class=\"button\" ng-click=\"step(+1)\">+</span>\n <span class=\"bound-value\">{{max() | slice}}</span>\n </span>\n</span>",
38
+ template: "<span class=\"g-slider horizontal\">\n <span class=\"slider\">\n <span class=\"range\"></span>\n <span class=\"handle\" ng-mousedown=\"mouseDown($event)\"></span>\n </span>\n <span class=\"side dec\">\n <span class=\"button\" ng-click=\"step(-1)\">-</span>\n <span class=\"bound-value\">{{min() | intersperse}}</span>\n </span>\n <span class=\"side inc\">\n <span class=\"button\" ng-click=\"step(+1)\">+</span>\n <span class=\"bound-value\">{{max() | intersperse}}</span>\n </span>\n <span class=\"increments\">\n <span ng-repeat=\"i in increments\" class=\"i\" style=\"left: {{i.offset}}%\">\n {{ i.value | intersperse }}\n </span>\n </span>\n</span>",
28
39
  replace: true,
29
40
  restrict: "E",
30
41
  scope: {
@@ -33,7 +44,39 @@
33
44
  max: "&"
34
45
  },
35
46
  link: function(scope, element, attrs) {
36
- var deferUpdate, dragging, refreshHandle, sliderElement, step, xPosition;
47
+ var deferUpdate, dragging, i, parseIncrements, refreshHandle, sliderElement, step, xPosition;
48
+ parseIncrements = function() {
49
+ var i, increments, max, min, offset, trim;
50
+ trim = function(input) {
51
+ if (input) {
52
+ return input.replace(/^\s+|\s+$/g, '');
53
+ } else {
54
+ return input;
55
+ }
56
+ };
57
+ offset = function(min, max, value) {
58
+ return value / Math.abs(max - min) * 100;
59
+ };
60
+ if (attrs.increments) {
61
+ min = scope.min();
62
+ max = scope.max();
63
+ increments = attrs.increments.split(',');
64
+ return increments = (function() {
65
+ var _i, _len, _ref, _results;
66
+ _results = [];
67
+ for (_i = 0, _len = increments.length; _i < _len; _i++) {
68
+ i = increments[_i];
69
+ if ((min < (_ref = parseInt(i)) && _ref < max)) {
70
+ _results.push({
71
+ value: parseInt(trim(i), 10),
72
+ offset: offset(min, max, i)
73
+ });
74
+ }
75
+ }
76
+ return _results;
77
+ })();
78
+ }
79
+ };
37
80
  sliderElement = getSubElement(element, "slider");
38
81
  dragging = false;
39
82
  xPosition = 0;
@@ -42,6 +85,21 @@
42
85
  if (scope.value == null) {
43
86
  scope.value = scope.min();
44
87
  }
88
+ scope.increments = parseIncrements(attrs.increments);
89
+ if (attrs.increments != null) {
90
+ scope.snapValues = ([scope.min(), scope.max()].concat((function() {
91
+ var _i, _len, _ref, _results;
92
+ _ref = scope.increments;
93
+ _results = [];
94
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
95
+ i = _ref[_i];
96
+ _results.push(i.value);
97
+ }
98
+ return _results;
99
+ })())).sort(function(a, b) {
100
+ return a - b;
101
+ });
102
+ }
45
103
  refreshHandle = function() {
46
104
  var range;
47
105
  range = scope.max() - scope.min();
@@ -67,27 +125,88 @@
67
125
  return refreshHandle();
68
126
  }
69
127
  });
70
- scope.$watch("value", function() {
128
+ scope.$watch("value", function(newVal, oldVal) {
71
129
  if (dragging) {
72
130
  return;
73
131
  }
74
- return refreshHandle();
132
+ if ((scope.min() <= newVal && newVal <= scope.max())) {
133
+ return refreshHandle();
134
+ } else {
135
+ return newVal = oldVal;
136
+ }
75
137
  });
76
138
  scope.step = function(steps) {
77
- var newValue;
78
- newValue = scope.value + steps * step;
79
- if ((scope.min() <= newValue && newValue <= scope.max())) {
80
- return scope.value = newValue;
139
+ var doIncrement, doStep;
140
+ doStep = function(steps) {
141
+ var newValue;
142
+ newValue = scope.value + steps * step;
143
+ if ((scope.min() <= newValue && newValue <= scope.max())) {
144
+ return scope.value = newValue;
145
+ }
146
+ };
147
+ doIncrement = function(steps) {
148
+ var newVal, sv;
149
+ newVal = steps > 0 ? ((function() {
150
+ var _i, _len, _ref, _results;
151
+ _ref = scope.snapValues;
152
+ _results = [];
153
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
154
+ sv = _ref[_i];
155
+ if (sv > scope.value) {
156
+ _results.push(sv);
157
+ }
158
+ }
159
+ return _results;
160
+ })())[0] : ((function() {
161
+ var _i, _len, _ref, _results;
162
+ _ref = scope.snapValues;
163
+ _results = [];
164
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
165
+ sv = _ref[_i];
166
+ if (sv < scope.value) {
167
+ _results.push(sv);
168
+ }
169
+ }
170
+ return _results;
171
+ })()).sort(function(a, b) {
172
+ return b - a;
173
+ })[0];
174
+ if (newVal != null) {
175
+ return scope.value = newVal;
176
+ }
177
+ };
178
+ if (attrs.increments != null) {
179
+ return doIncrement(steps);
180
+ } else {
181
+ return doStep(steps);
81
182
  }
82
183
  };
83
184
  return scope.mouseDown = function($event) {
84
- var startPointX, updateValue;
185
+ var snap, startPointX, updateValue;
85
186
  dragging = true;
86
187
  startPointX = $event.pageX;
87
188
  updateValue = function() {
88
189
  scope.value = Math.round((((scope.max() - scope.min()) * (xPosition / 100)) + scope.min()) / step) * step;
89
190
  return scope.$apply();
90
191
  };
192
+ snap = function() {
193
+ var closest, diff, l, min;
194
+ i = 0;
195
+ l = scope.snapValues.length;
196
+ while (i < l) {
197
+ diff = Math.abs(scope.snapValues[i] - scope.value);
198
+ if (typeof min === "undefined" || min === null) {
199
+ min = diff;
200
+ }
201
+ if (diff <= min) {
202
+ closest = scope.snapValues[i];
203
+ min = diff;
204
+ }
205
+ i++;
206
+ }
207
+ scope.value = closest;
208
+ return scope.$apply();
209
+ };
91
210
  $document.on("mousemove", function($event) {
92
211
  var moveDelta;
93
212
  if (!dragging) {
@@ -112,6 +231,9 @@
112
231
  if (deferUpdate) {
113
232
  updateValue();
114
233
  }
234
+ if (scope.increments) {
235
+ snap();
236
+ }
115
237
  return $document.off("mousemove");
116
238
  });
117
239
  };
@@ -120,7 +242,7 @@
120
242
  }
121
243
  ]);
122
244
 
123
- app.filter('slice', function() {
245
+ app.filter('intersperse', function() {
124
246
  return function(input) {
125
247
  var reverse, reversed, reversed_and_sliced, sliced;
126
248
  if (input == null) {
data/glider-rails.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
6
  gem.name = "glider-rails"
7
- gem.version = "0.0.6"
7
+ gem.version = "0.1.0"
8
8
  gem.authors = ["Valentin Vasilyev", "Dmitry Karpunin"]
9
9
  gem.email = ["iamvalentin@gmail.com", "koderfunk@gmail.com"]
10
10
  gem.description = "Glider, AngularJS UI slider for rails asset pipeline"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glider-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-09-18 00:00:00.000000000 Z
13
+ date: 2013-10-03 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: Glider, AngularJS UI slider for rails asset pipeline
16
16
  email: