simple_form_extension 1.1.0 → 1.1.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: 946b7d8265779451e32f1032aa3b9ace6d8f02c4
4
- data.tar.gz: 0bd6a400862b4f5fdea0b5fab2fd476c64ab0d27
3
+ metadata.gz: dce3e78a64dd2c77636f1d9a891d6863d6da048f
4
+ data.tar.gz: d4342009b4702683ce62bbc0382fd3ea27717441
5
5
  SHA512:
6
- metadata.gz: aee6e469e6e1fec674d2aae34dd90cf4b8f5a7337b7f1e479b504573082de14bd1ca43fe2990b99da422524accf9066ed96cb3d1274af8dd2d9dd051bb69f84c
7
- data.tar.gz: 1e5f4de04288e9789a897d2cd4e338a9fcaf4fa7b8854b68bd2f8b3cb6314d6a602d60d550539b9b0c36e603d5c3e4f20ef402db74b8ab13d14aced69de85514
6
+ metadata.gz: 6e9c2f6d5cb278850a4e5c97152c505ac83251442926e6b98adf16d97a193a1ab6585fbfcc07165132a8ee9db728e669fa5e5e48fe5be9ff18e2e016f9117b4e
7
+ data.tar.gz: 5ba0bceafadeeea0fbe1f114c425f5327aa7b043c7ae2d8b1ade47764763749fc2714f15f9eb1a16eab59fc3d6c685cc4049eb0d87e50cd900cc8dd49634e81f
@@ -13,7 +13,7 @@ module SimpleFormExtension
13
13
  <span class=\"fileinput-exists\">#{ _translate('image.change') }</span>
14
14
  #{@builder.file_field(attribute_name, input_html_options)}
15
15
  </div>
16
- <button class=\"btn btn-danger fileinput-exists pull-right\" data-dismiss=\"fileinput\" type=\"button\"><i class=\"fa fa-times\"></i></button>
16
+ <button class=\"btn btn-danger fileinput-exists\" data-dismiss=\"fileinput\" type=\"button\"><i class=\"fa fa-times\"></i></button>
17
17
  </div>
18
18
  <div class=\"fileinput-preview thumbnail\">
19
19
  #{ image_tag }
@@ -33,12 +33,12 @@ module SimpleFormExtension
33
33
 
34
34
  def multi?
35
35
  (options.key?(:multi) && !!options[:multi]) ||
36
- value.class.include?(Enumerable)
36
+ enumerable?(value)
37
37
  end
38
38
 
39
39
  def collection
40
40
  if (collection = options[:collection])
41
- if collection.class.include?(Enumerable)
41
+ if enumerable?(collection)
42
42
  collection.map(&method(:serialize_option))
43
43
  else
44
44
  (object.send(collection) || []).map(&method(:serialize_option))
@@ -65,8 +65,10 @@ module SimpleFormExtension
65
65
  private
66
66
 
67
67
  def serialize_option(option)
68
- if option.kind_of?(Hash) && options.key?(:text) && option.key?(:value)
68
+ if option.kind_of?(Hash) && option.key?(:text) && option.key?(:value)
69
69
  option
70
+ elsif option.kind_of?(ActiveRecord::Base)
71
+ { text: name_for(option), value: option.id }
70
72
  elsif !option.kind_of?(Hash)
71
73
  { text: option.to_s, value: option }
72
74
  else
@@ -83,6 +85,14 @@ module SimpleFormExtension
83
85
  # Return default block value or nil if no block was given
84
86
  block ? block.call : nil
85
87
  end
88
+
89
+ def enumerable?(object)
90
+ object.class.include?(Enumerable) || ActiveRecord::Relation === object
91
+ end
92
+
93
+ def name_for(option)
94
+ option.try(:name) || options.try(:title) || option.to_s
95
+ end
86
96
  end
87
97
  end
88
98
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleFormExtension
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -2,10 +2,13 @@
2
2
  #= require redactor-rails/langs/fr
3
3
  #= require redactor-rails/plugins
4
4
  #= require selectize
5
+ #= require spinbox
5
6
  #= require jquery.datetimepicker
6
7
  #= require_self
7
8
  #= require_tree ./simple_form_extension
8
9
 
10
+ $.fn.simpleForm = {}
11
+
9
12
  window.onPageReady = (callback) ->
10
13
  $(document).ready ->
11
14
  callback() if Turbolinks is undefined
@@ -43,4 +43,5 @@ onPageReady ->
43
43
 
44
44
  $('body').on 'click', '.date .datetimepicker-trigger', (e) ->
45
45
  $input = $(e.currentTarget).closest('.date').find('input.date')
46
- DatePicker.forInput($input, DatePicker).show()
46
+ DatePicker.forInput($input, DatePicker).show()
47
+
@@ -49,4 +49,3 @@ onPageReady ->
49
49
  lang: "fr"
50
50
 
51
51
  $textArea.data('initialized.redactor', true)
52
-
@@ -43,13 +43,12 @@ class Selectize
43
43
  </div>
44
44
  """
45
45
 
46
- onPageReady ->
47
- $selectizes = $('[data-selectize]')
48
-
49
- return unless $selectizes.length
50
-
51
- $('[data-selectize]').each (i, el) ->
46
+ $.fn.simpleFormSelectize = ->
47
+ @each (i, el) ->
52
48
  $select = $(el)
53
49
  return if $select.data('simple-form:selectize')
54
50
  instance = new Selectize($select)
55
51
  $select.data('simple-form:selectize', instance)
52
+
53
+ onPageReady ->
54
+ $('[data-selectize]').simpleFormSelectize()
@@ -0,0 +1,16 @@
1
+ class Spinbox
2
+ constructor: (@$el) ->
3
+ @el = @$el[0]
4
+
5
+ @$el.spinbox()
6
+
7
+ onPageReady ->
8
+ $spinbox = $('.spinner')
9
+
10
+ return unless $spinbox.length
11
+
12
+ $spinbox.each (i, el) ->
13
+ $spinner = $(el)
14
+ return if $spinner.data('simple-form:spinner')
15
+ instance = new Spinbox($spinner)
16
+ $spinner.data('simple-form:spinner', instance)
@@ -0,0 +1,445 @@
1
+ /*
2
+ * Fuel UX Spinbox
3
+ * https://github.com/ExactTarget/fuelux
4
+ *
5
+ * Copyright (c) 2014 ExactTarget
6
+ * Licensed under the BSD New license.
7
+ */
8
+
9
+ // -- BEGIN UMD WRAPPER PREFACE --
10
+
11
+ // For more information on UMD visit:
12
+ // https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
13
+
14
+ (function(factory) {
15
+ if (typeof define === 'function' && define.amd) {
16
+ // if AMD loader is available, register as an anonymous module.
17
+ define(['jquery'], factory);
18
+ } else {
19
+ // OR use browser globals if AMD is not present
20
+ factory(jQuery);
21
+ }
22
+ }(function($) {
23
+ // -- END UMD WRAPPER PREFACE --
24
+
25
+ // -- BEGIN MODULE CODE HERE --
26
+
27
+ var old = $.fn.spinbox;
28
+
29
+ // SPINBOX CONSTRUCTOR AND PROTOTYPE
30
+
31
+ var Spinbox = function(element, options) {
32
+ this.$element = $(element);
33
+ this.$element.find('.btn').on('click', function(e) {
34
+ //keep spinbox from submitting if they forgot to say type="button" on their spinner buttons
35
+ e.preventDefault();
36
+ });
37
+ this.options = $.extend({}, $.fn.spinbox.defaults, options);
38
+ this.$input = this.$element.find('.spinner-input');
39
+ this.$element.on('focusin.fu.spinbox', this.$input, $.proxy(this.changeFlag, this));
40
+ this.$element.on('focusout.fu.spinbox', this.$input, $.proxy(this.change, this));
41
+ this.$element.on('keydown.fu.spinbox', this.$input, $.proxy(this.keydown, this));
42
+ this.$element.on('keyup.fu.spinbox', this.$input, $.proxy(this.keyup, this));
43
+
44
+ this.bindMousewheelListeners();
45
+ this.mousewheelTimeout = {};
46
+
47
+ if (this.options.hold) {
48
+ this.$element.on('mousedown.fu.spinbox', '.spinner-up', $.proxy(function() {
49
+ this.startSpin(true);
50
+ }, this));
51
+ this.$element.on('mouseup.fu.spinbox', '.spinner-up, .spinner-down', $.proxy(this.stopSpin, this));
52
+ this.$element.on('mouseout.fu.spinbox', '.spinner-up, .spinner-down', $.proxy(this.stopSpin, this));
53
+ this.$element.on('mousedown.fu.spinbox', '.spinner-down', $.proxy(function() {
54
+ this.startSpin(false);
55
+ }, this));
56
+ } else {
57
+ this.$element.on('click.fu.spinbox', '.spinner-up', $.proxy(function() {
58
+ this.step(true);
59
+ }, this));
60
+ this.$element.on('click.fu.spinbox', '.spinner-down', $.proxy(function() {
61
+ this.step(false);
62
+ }, this));
63
+ }
64
+
65
+ this.switches = {
66
+ count: 1,
67
+ enabled: true
68
+ };
69
+
70
+ if (this.options.speed === 'medium') {
71
+ this.switches.speed = 300;
72
+ } else if (this.options.speed === 'fast') {
73
+ this.switches.speed = 100;
74
+ } else {
75
+ this.switches.speed = 500;
76
+ }
77
+
78
+ this.lastValue = this.options.value;
79
+
80
+ this.render();
81
+
82
+ if (this.options.disabled) {
83
+ this.disable();
84
+ }
85
+ };
86
+
87
+ Spinbox.prototype = {
88
+ constructor: Spinbox,
89
+
90
+ destroy: function() {
91
+ this.$element.remove();
92
+ // any external bindings
93
+ // [none]
94
+ // set input value attrbute
95
+ this.$element.find('input').each(function() {
96
+ $(this).attr('value', $(this).val());
97
+ });
98
+ // empty elements to return to original markup
99
+ // [none]
100
+ // returns string of markup
101
+ return this.$element[0].outerHTML;
102
+ },
103
+
104
+ render: function() {
105
+ var inputValue = this.parseInput(this.$input.val());
106
+ var maxUnitLength = '';
107
+
108
+ // if input is empty and option value is default, 0
109
+ if (inputValue !== '' && this.options.value === 0) {
110
+ this.value(inputValue);
111
+ } else {
112
+ this.output (this.options.value);
113
+ }
114
+
115
+ if (this.options.units.length) {
116
+ $.each(this.options.units, function(index, value) {
117
+ if (value.length > maxUnitLength.length) {
118
+ maxUnitLength = value;
119
+ }
120
+ });
121
+ }
122
+
123
+ },
124
+
125
+ output: function(value, updateField) {
126
+ value = (value + '').split('.').join(this.options.decimalMark);
127
+ updateField = (updateField || true);
128
+ if (updateField) {
129
+ this.$input.val(value);
130
+ }
131
+
132
+ return value;
133
+ },
134
+
135
+ parseInput: function(value) {
136
+ value = (value + '').split(this.options.decimalMark).join('.');
137
+
138
+ return value;
139
+ },
140
+
141
+ change: function() {
142
+ var newVal = this.parseInput(this.$input.val()) || '';
143
+
144
+ if (this.options.units.length || this.options.decimalMark !== '.') {
145
+ newVal = this.parseValueWithUnit(newVal);
146
+ } else if (newVal / 1) {
147
+ newVal = this.options.value = this.checkMaxMin(newVal / 1);
148
+ } else {
149
+ newVal = this.checkMaxMin(newVal.replace(/[^0-9.-]/g, '') || '');
150
+ this.options.value = newVal / 1;
151
+ }
152
+ this.output (newVal);
153
+
154
+ this.changeFlag = false;
155
+ this.triggerChangedEvent();
156
+ },
157
+
158
+ changeFlag: function() {
159
+ this.changeFlag = true;
160
+ },
161
+
162
+ stopSpin: function() {
163
+ if (this.switches.timeout !== undefined) {
164
+ clearTimeout(this.switches.timeout);
165
+ this.switches.count = 1;
166
+ this.triggerChangedEvent();
167
+ }
168
+ },
169
+
170
+ triggerChangedEvent: function() {
171
+ var currentValue = this.value();
172
+ if (currentValue === this.lastValue) return;
173
+
174
+ this.lastValue = currentValue;
175
+
176
+ // Primary changed event
177
+ this.$element.trigger('changed.fu.spinbox', this.output(currentValue, false)); // no DOM update
178
+ },
179
+
180
+ startSpin: function(type) {
181
+
182
+ if (!this.options.disabled) {
183
+ var divisor = this.switches.count;
184
+
185
+ if (divisor === 1) {
186
+ this.step(type);
187
+ divisor = 1;
188
+ } else if (divisor < 3) {
189
+ divisor = 1.5;
190
+ } else if (divisor < 8) {
191
+ divisor = 2.5;
192
+ } else {
193
+ divisor = 4;
194
+ }
195
+
196
+ this.switches.timeout = setTimeout($.proxy(function() {
197
+ this.iterate(type);
198
+ }, this), this.switches.speed / divisor);
199
+ this.switches.count++;
200
+ }
201
+ },
202
+
203
+ iterate: function(type) {
204
+ this.step(type);
205
+ this.startSpin(type);
206
+ },
207
+
208
+ step: function(isIncrease) {
209
+ // isIncrease: true is up, false is down
210
+
211
+ var digits, multiple, currentValue, limitValue;
212
+
213
+ // trigger change event
214
+ if (this.changeFlag) {
215
+ this.change();
216
+ }
217
+
218
+ // get current value and min/max options
219
+ currentValue = this.options.value;
220
+ limitValue = isIncrease ? this.options.max : this.options.min;
221
+
222
+ if ( (isIncrease ? currentValue < limitValue : currentValue > limitValue) ) {
223
+ var newVal = currentValue + (isIncrease ? 1 : -1) * this.options.step;
224
+
225
+ // raise to power of 10 x number of decimal places, then round
226
+ if (this.options.step % 1 !== 0) {
227
+ digits = (this.options.step + '').split('.')[1].length;
228
+ multiple = Math.pow(10, digits);
229
+ newVal = Math.round(newVal * multiple) / multiple;
230
+ }
231
+
232
+ // if outside limits, set to limit value
233
+ if (isIncrease ? newVal > limitValue : newVal < limitValue) {
234
+ this.value(limitValue);
235
+ } else {
236
+ this.value(newVal);
237
+ }
238
+
239
+ } else if (this.options.cycle) {
240
+ var cycleVal = isIncrease ? this.options.min : this.options.max;
241
+ this.value(cycleVal);
242
+ }
243
+ },
244
+
245
+ value: function(value) {
246
+
247
+ if (value || value === 0) {
248
+ if (this.options.units.length || this.options.decimalMark !== '.') {
249
+ this.output(this.parseValueWithUnit(value + (this.unit || '')));
250
+ return this;
251
+
252
+ } else if (!isNaN(parseFloat(value)) && isFinite(value)) {
253
+ this.options.value = value / 1;
254
+ this.output (value + (this.unit ? this.unit : ''));
255
+ return this;
256
+
257
+ }
258
+ } else {
259
+ if (this.changeFlag) {
260
+ this.change();
261
+ }
262
+
263
+ if (this.unit) {
264
+ return this.options.value + this.unit;
265
+ } else {
266
+ return this.output(this.options.value, false); // no DOM update
267
+ }
268
+ }
269
+ },
270
+
271
+ isUnitLegal: function(unit) {
272
+ var legalUnit;
273
+
274
+ $.each(this.options.units, function(index, value) {
275
+ if (value.toLowerCase() === unit.toLowerCase()) {
276
+ legalUnit = unit.toLowerCase();
277
+ return false;
278
+ }
279
+ });
280
+
281
+ return legalUnit;
282
+ },
283
+
284
+ // strips units and add them back
285
+ parseValueWithUnit: function(value) {
286
+ var unit = value.replace(/[^a-zA-Z]/g, '');
287
+ var number = value.replace(/[^0-9.-]/g, '');
288
+
289
+ if (unit) {
290
+ unit = this.isUnitLegal(unit);
291
+ }
292
+
293
+ this.options.value = this.checkMaxMin(number / 1);
294
+ this.unit = unit || undefined;
295
+ return this.options.value + (unit || '');
296
+ },
297
+
298
+ checkMaxMin: function(value) {
299
+ // if unreadable
300
+ if (isNaN(parseFloat(value))) {
301
+ return value;
302
+ }
303
+ // if not within range return the limit
304
+ if (!(value <= this.options.max && value >= this.options.min)) {
305
+ value = value >= this.options.max ? this.options.max : this.options.min;
306
+ }
307
+ return value;
308
+ },
309
+
310
+ disable: function() {
311
+ this.options.disabled = true;
312
+ this.$element.addClass('disabled');
313
+ this.$input.attr('disabled', '');
314
+ this.$element.find('button').addClass('disabled');
315
+ },
316
+
317
+ enable: function() {
318
+ this.options.disabled = false;
319
+ this.$element.removeClass('disabled');
320
+ this.$input.removeAttr('disabled');
321
+ this.$element.find('button').removeClass('disabled');
322
+ },
323
+
324
+ keydown: function(event) {
325
+ var keyCode = event.keyCode;
326
+ if (keyCode === 38) {
327
+ this.step(true);
328
+ } else if (keyCode === 40) {
329
+ this.step(false);
330
+ }
331
+ },
332
+
333
+ keyup: function(event) {
334
+ var keyCode = event.keyCode;
335
+
336
+ if (keyCode === 38 || keyCode === 40) {
337
+ this.triggerChangedEvent();
338
+ }
339
+ },
340
+
341
+ bindMousewheelListeners: function() {
342
+ var inputEl = this.$input.get(0);
343
+ if (inputEl.addEventListener) {
344
+ //IE 9, Chrome, Safari, Opera
345
+ inputEl.addEventListener('mousewheel', $.proxy(this.mousewheelHandler, this), false);
346
+ // Firefox
347
+ inputEl.addEventListener('DOMMouseScroll', $.proxy(this.mousewheelHandler, this), false);
348
+ } else {
349
+ // IE <9
350
+ inputEl.attachEvent('onmousewheel', $.proxy(this.mousewheelHandler, this));
351
+ }
352
+ },
353
+
354
+ mousewheelHandler: function(event) {
355
+ var e = window.event || event; // old IE support
356
+ var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
357
+ var self = this;
358
+
359
+ clearTimeout(this.mousewheelTimeout);
360
+ this.mousewheelTimeout = setTimeout(function() {
361
+ self.triggerChangedEvent();
362
+ }, 300);
363
+
364
+ if (delta < 0) {
365
+ this.step(true);
366
+ } else {
367
+ this.step(false);
368
+ }
369
+
370
+ if (e.preventDefault) {
371
+ e.preventDefault();
372
+ } else {
373
+ e.returnValue = false;
374
+ }
375
+ return false;
376
+ }
377
+ };
378
+
379
+
380
+ // SPINBOX PLUGIN DEFINITION
381
+
382
+ $.fn.spinbox = function(option) {
383
+ var args = Array.prototype.slice.call(arguments, 1);
384
+ var methodReturn;
385
+
386
+ var $set = this.each(function() {
387
+ var $this = $(this);
388
+ var data = $this.data('fu.spinbox');
389
+ var options = typeof option === 'object' && option;
390
+
391
+ if (!data) {
392
+ $this.data('fu.spinbox', (data = new Spinbox(this, options)));
393
+ }
394
+ if (typeof option === 'string') {
395
+ methodReturn = data[option].apply(data, args);
396
+ }
397
+ });
398
+
399
+ return (methodReturn === undefined) ? $set : methodReturn;
400
+ };
401
+
402
+ // value needs to be 0 for this.render();
403
+ $.fn.spinbox.defaults = {
404
+ value: 0,
405
+ min: 0,
406
+ max: 999,
407
+ step: 1,
408
+ hold: true,
409
+ speed: 'medium',
410
+ disabled: false,
411
+ cycle: false,
412
+ units: [],
413
+ decimalMark: '.'
414
+ };
415
+
416
+ $.fn.spinbox.Constructor = Spinbox;
417
+
418
+ $.fn.spinbox.noConflict = function() {
419
+ $.fn.spinbox = old;
420
+ return this;
421
+ };
422
+
423
+
424
+ // DATA-API
425
+
426
+ $(document).on('mousedown.fu.spinbox.data-api', '[data-initialize=spinbox]', function(e) {
427
+ var $control = $(e.target).closest('.spinner');
428
+ if (!$control.data('fu.spinbox')) {
429
+ $control.spinbox($control.data());
430
+ }
431
+ });
432
+
433
+ // Must be domReady for AMD compatibility
434
+ $(function() {
435
+ $('[data-initialize=spinbox]').each(function() {
436
+ var $this = $(this);
437
+ if (!$this.data('fu.spinbox')) {
438
+ $this.spinbox($this.data());
439
+ }
440
+ });
441
+ });
442
+
443
+ // -- BEGIN UMD WRAPPER AFTERWORD --
444
+ }));
445
+ // -- END UMD WRAPPER AFTERWORD --
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_form_extension
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Vasseur
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-03 00:00:00.000000000 Z
11
+ date: 2015-01-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -140,6 +140,8 @@ files:
140
140
  - vendor/assets/javascripts/simple_form_extension/datetimepicker.coffee
141
141
  - vendor/assets/javascripts/simple_form_extension/redactor.coffee
142
142
  - vendor/assets/javascripts/simple_form_extension/selectize.coffee
143
+ - vendor/assets/javascripts/simple_form_extension/spinbox.coffee
144
+ - vendor/assets/javascripts/spinbox.js
143
145
  - vendor/assets/stylesheets/jquery.datetimepicker.css
144
146
  - vendor/assets/stylesheets/simple_form_extension.sass
145
147
  homepage: http://www.glyph.fr
@@ -162,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
164
  version: '0'
163
165
  requirements: []
164
166
  rubyforge_project:
165
- rubygems_version: 2.4.1
167
+ rubygems_version: 2.2.2
166
168
  signing_key:
167
169
  specification_version: 4
168
170
  summary: A simple extention for simple_form with, colorpiker, icon, fileupload, image