glider-rails 0.0.6 → 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,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: