selectivity-rails 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f193b5755b553f98fc709e5290054ec9f02d6b19
4
- data.tar.gz: e0df86c48b839a856bce58f13d4a3239416e3032
3
+ metadata.gz: f21a7721f33a3ddc9a7058bfaeceabca54710d98
4
+ data.tar.gz: 5fc4d027995d1eb62b7e1459c3af1ab8ee63e867
5
5
  SHA512:
6
- metadata.gz: 5b70b0fe542ad62b62bc52c13004bce87aecb11c7fa15f572667c49b81f2ce2479b3f7559953730b2ce3bf8a4ef365c77bda5cb0f258eeb7fefc644b4f772ec1
7
- data.tar.gz: 568502d3cb475107c5c3d2d04fb7e0656c6a27a326eb21a07f5a4b312e8e2e537bd7c83917a0d3c515ff1ffc3923ff2589b17b5ffb54f77f3d318f6526162f9a
6
+ metadata.gz: dab56b3d161184d8de361c509f12f7ab4d3073c52219a84e8b2eec9875abac2b14e4e809e06e0822afb368539b9cb0e8cbf2bf4b70e6bfb3bfc08677525c49a1
7
+ data.tar.gz: 118e473372f92de9992e9c2ac277efb57736bc33a3a89bc578a6916c6e47b355122f01834000c7f63eade59dff7f73bdf81959d645706e95c10c0bed814cee2f
data/Rakefile CHANGED
@@ -1 +1,28 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ namespace :vendor do
4
+ desc 'Update vendored selectivity'
5
+ task :update do
6
+ require 'open-uri'
7
+
8
+ root = 'https://raw.githubusercontent.com/arendjr/selectivity/master'
9
+
10
+ src_uri = File.join(root, 'dist/selectivity-full.js')
11
+
12
+ open(src_uri) do |f|
13
+ dest_file = File.expand_path('../vendor/assets/javascripts/selectivity.js', __FILE__)
14
+ puts "Writing `#{dest_file}' from `#{src_uri}'"
15
+ File.write dest_file, f.read
16
+ end
17
+
18
+ Dir['vendor/assets/stylesheets/selectivity/*.sass'].each do |file|
19
+ src_uri = File.join(root, "styles/selectivity/#{File.basename(file)}")
20
+
21
+ open(src_uri) do |f|
22
+ dest_file = File.expand_path("../#{file}", __FILE__)
23
+ puts "Writing `#{dest_file}' from `#{src_uri}'"
24
+ File.write dest_file, f.read
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  module Selectivity
2
2
  module Rails
3
- VERSION = '0.0.9'
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  end
@@ -8,7 +8,7 @@ module Selectivity
8
8
  fail('Selectivity input not set!') unless options.has_key?(:from)
9
9
 
10
10
  from = options.delete(:from)
11
- input = find(:div, from, options)
11
+ input = find_selectivity_input(from, options)
12
12
  items = multiselect?(input) ? args.unshift(value).uniq : [value]
13
13
 
14
14
  items.each do |item|
@@ -22,7 +22,7 @@ module Selectivity
22
22
  fail('Selectivity input not set!') unless options.has_key?(:from)
23
23
 
24
24
  from = options.delete(:from)
25
- input = find(:div, from, options)
25
+ input = find_selectivity_input(from, options)
26
26
  items = multiselect?(input) ? args.unshift(value).uniq : [value]
27
27
 
28
28
  items.each do |item|
@@ -36,6 +36,14 @@ module Selectivity
36
36
 
37
37
  private
38
38
 
39
+ def find_selectivity_input(from, options)
40
+ find(:div, from, options)
41
+ rescue Capybara::ElementNotFound
42
+ label = find('label', { text: from }.merge(options))
43
+
44
+ find(:div, "##{label[:for]}", options)
45
+ end
46
+
39
47
  def multiselect?(input)
40
48
  input.first('.selectivity-multiple-input-container').present?
41
49
  end
@@ -1,6 +1,79 @@
1
1
  !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.selectivity=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
2
- _dereq_(4);_dereq_(5);_dereq_(6);_dereq_(8);_dereq_(9);_dereq_(10);_dereq_(11);_dereq_(12);_dereq_(13);_dereq_(14);_dereq_(15);_dereq_(16);_dereq_(17);_dereq_(18);module.exports=_dereq_(7);
3
- },{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9}],2:[function(_dereq_,module,exports){
2
+ _dereq_(5);_dereq_(6);_dereq_(7);_dereq_(9);_dereq_(10);_dereq_(11);_dereq_(12);_dereq_(13);_dereq_(14);_dereq_(15);_dereq_(16);_dereq_(17);_dereq_(18);_dereq_(19);module.exports=_dereq_(8);
3
+ },{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"5":5,"6":6,"7":7,"8":8,"9":9}],2:[function(_dereq_,module,exports){
4
+ 'use strict';
5
+
6
+ var $ = window.jQuery || window.Zepto;
7
+
8
+ /**
9
+ * Event Delegator Constructor.
10
+ */
11
+ function EventDelegator() {
12
+
13
+ this._events = [];
14
+
15
+ this.delegateEvents();
16
+ }
17
+
18
+ /**
19
+ * Methods.
20
+ */
21
+ $.extend(EventDelegator.prototype, {
22
+
23
+ /**
24
+ * Attaches all listeners from the events map to the instance's element.
25
+ *
26
+ * Normally, you should not have to call this method yourself as it's called automatically in
27
+ * the constructor.
28
+ */
29
+ delegateEvents: function() {
30
+
31
+ this.undelegateEvents();
32
+
33
+ $.each(this.events, function(event, listener) {
34
+ var selector, index = event.indexOf(' ');
35
+ if (index > -1) {
36
+ selector = event.slice(index + 1);
37
+ event = event.slice(0, index);
38
+ }
39
+
40
+ if ($.type(listener) === 'string') {
41
+ listener = this[listener];
42
+ }
43
+
44
+ listener = listener.bind(this);
45
+
46
+ if (selector) {
47
+ this.$el.on(event, selector, listener);
48
+ } else {
49
+ this.$el.on(event, listener);
50
+ }
51
+
52
+ this._events.push({ event: event, selector: selector, listener: listener });
53
+ }.bind(this));
54
+ },
55
+
56
+ /**
57
+ * Detaches all listeners from the events map from the instance's element.
58
+ */
59
+ undelegateEvents: function() {
60
+
61
+ this._events.forEach(function(event) {
62
+ if (event.selector) {
63
+ this.$el.off(event.event, event.selector, event.listener);
64
+ } else {
65
+ this.$el.off(event.event, event.listener);
66
+ }
67
+ }, this);
68
+
69
+ this._events = [];
70
+ }
71
+
72
+ });
73
+
74
+ module.exports = EventDelegator;
75
+
76
+ },{"jquery":"jquery"}],3:[function(_dereq_,module,exports){
4
77
  'use strict';
5
78
 
6
79
  /**
@@ -88,7 +161,7 @@ function debounce(func, wait) {
88
161
 
89
162
  module.exports = debounce;
90
163
 
91
- },{}],3:[function(_dereq_,module,exports){
164
+ },{}],4:[function(_dereq_,module,exports){
92
165
  'use strict';
93
166
 
94
167
  /**
@@ -141,16 +214,16 @@ function escape(string) {
141
214
 
142
215
  module.exports = escape;
143
216
 
144
- },{}],4:[function(_dereq_,module,exports){
217
+ },{}],5:[function(_dereq_,module,exports){
145
218
  'use strict';
146
219
 
147
220
  var $ = window.jQuery || window.Zepto;
148
221
 
149
- var debounce = _dereq_(2);
222
+ var debounce = _dereq_(3);
150
223
 
151
- var Selectivity = _dereq_(7);
224
+ var Selectivity = _dereq_(8);
152
225
 
153
- _dereq_(12);
226
+ _dereq_(13);
154
227
 
155
228
  /**
156
229
  * Option listener that implements a convenience query function for performing AJAX requests.
@@ -216,10 +289,10 @@ Selectivity.OptionListeners.unshift(function(selectivity, options) {
216
289
  }
217
290
  });
218
291
 
219
- },{"12":12,"2":2,"7":7,"jquery":"jquery"}],5:[function(_dereq_,module,exports){
292
+ },{"13":13,"3":3,"8":8,"jquery":"jquery"}],6:[function(_dereq_,module,exports){
220
293
  'use strict';
221
294
 
222
- var Selectivity = _dereq_(7);
295
+ var Selectivity = _dereq_(8);
223
296
 
224
297
  var latestQueryNum = 0;
225
298
 
@@ -252,12 +325,12 @@ Selectivity.OptionListeners.push(function(selectivity, options) {
252
325
  }
253
326
  });
254
327
 
255
- },{"7":7}],6:[function(_dereq_,module,exports){
328
+ },{"8":8}],7:[function(_dereq_,module,exports){
256
329
  'use strict';
257
330
 
258
331
  var $ = window.jQuery || window.Zepto;
259
332
 
260
- var SelectivityDropdown = _dereq_(9);
333
+ var SelectivityDropdown = _dereq_(10);
261
334
 
262
335
  /**
263
336
  * Methods.
@@ -296,11 +369,13 @@ $.extend(SelectivityDropdown.prototype, {
296
369
 
297
370
  });
298
371
 
299
- },{"9":9,"jquery":"jquery"}],7:[function(_dereq_,module,exports){
372
+ },{"10":10,"jquery":"jquery"}],8:[function(_dereq_,module,exports){
300
373
  'use strict';
301
374
 
302
375
  var $ = window.jQuery || window.Zepto;
303
376
 
377
+ var EventDelegator = _dereq_(2);
378
+
304
379
  /**
305
380
  * Create a new Selectivity instance or invoke a method on an instance.
306
381
  *
@@ -487,19 +562,17 @@ function Selectivity(options) {
487
562
  this.data(options.data || null, { triggerChange: false });
488
563
  }
489
564
 
490
- this._events = [];
491
-
492
565
  this._$searchInputs = [];
493
566
 
494
567
  this.$el.on('selectivity-close', this._closed.bind(this));
495
568
 
496
- this.delegateEvents();
569
+ EventDelegator.call(this);
497
570
  }
498
571
 
499
572
  /**
500
573
  * Methods.
501
574
  */
502
- $.extend(Selectivity.prototype, {
575
+ $.extend(Selectivity.prototype, EventDelegator.prototype, {
503
576
 
504
577
  /**
505
578
  * Convenience shortcut for this.$el.find(selector).
@@ -552,39 +625,6 @@ $.extend(Selectivity.prototype, {
552
625
  }
553
626
  },
554
627
 
555
- /**
556
- * Attaches all listeners from the events map to the instance's element.
557
- *
558
- * Normally, you should not have to call this method yourself as it's called automatically in
559
- * the constructor.
560
- */
561
- delegateEvents: function() {
562
-
563
- this.undelegateEvents();
564
-
565
- $.each(this.events, function(event, listener) {
566
- var selector, index = event.indexOf(' ');
567
- if (index > -1) {
568
- selector = event.slice(index + 1);
569
- event = event.slice(0, index);
570
- }
571
-
572
- if ($.type(listener) === 'string') {
573
- listener = this[listener];
574
- }
575
-
576
- listener = listener.bind(this);
577
-
578
- if (selector) {
579
- this.$el.on(event, selector, listener);
580
- } else {
581
- this.$el.on(event, listener);
582
- }
583
-
584
- this._events.push({ event: event, selector: selector, listener: listener });
585
- }.bind(this));
586
- },
587
-
588
628
  /**
589
629
  * Destroys the Selectivity instance.
590
630
  */
@@ -971,25 +1011,6 @@ $.extend(Selectivity.prototype, {
971
1011
  return !event.isDefaultPrevented();
972
1012
  },
973
1013
 
974
- /**
975
- * Detaches all listeners from the events map from the instance's element.
976
- *
977
- * Normally, you should not have to call this method yourself as it's called automatically in
978
- * the destroy() method.
979
- */
980
- undelegateEvents: function() {
981
-
982
- this._events.forEach(function(event) {
983
- if (event.selector) {
984
- this.$el.off(event.event, event.selector, event.listener);
985
- } else {
986
- this.$el.off(event.event, event.listener);
987
- }
988
- }, this);
989
-
990
- this._events = [];
991
- },
992
-
993
1014
  /**
994
1015
  * Shorthand for value().
995
1016
  */
@@ -1393,7 +1414,7 @@ Selectivity.transformText = function(string) {
1393
1414
 
1394
1415
  module.exports = $.fn.selectivity = Selectivity;
1395
1416
 
1396
- },{"jquery":"jquery"}],8:[function(_dereq_,module,exports){
1417
+ },{"2":2,"jquery":"jquery"}],9:[function(_dereq_,module,exports){
1397
1418
  'use strict';
1398
1419
 
1399
1420
  var DIACRITICS = {
@@ -2238,7 +2259,7 @@ var DIACRITICS = {
2238
2259
  '\u03C2': '\u03C3'
2239
2260
  };
2240
2261
 
2241
- var Selectivity = _dereq_(7);
2262
+ var Selectivity = _dereq_(8);
2242
2263
  var previousTransform = Selectivity.transformText;
2243
2264
 
2244
2265
  /**
@@ -2257,14 +2278,16 @@ Selectivity.transformText = function(string) {
2257
2278
  return previousTransform(result);
2258
2279
  };
2259
2280
 
2260
- },{"7":7}],9:[function(_dereq_,module,exports){
2281
+ },{"8":8}],10:[function(_dereq_,module,exports){
2261
2282
  'use strict';
2262
2283
 
2263
2284
  var $ = window.jQuery || window.Zepto;
2264
2285
 
2265
- var debounce = _dereq_(2);
2286
+ var debounce = _dereq_(3);
2266
2287
 
2267
- var Selectivity = _dereq_(7);
2288
+ var EventDelegator = _dereq_(2);
2289
+
2290
+ var Selectivity = _dereq_(8);
2268
2291
 
2269
2292
  /**
2270
2293
  * selectivity Dropdown Constructor.
@@ -2324,6 +2347,8 @@ function SelectivityDropdown(options) {
2324
2347
  selectivity.$el.on('selectivity-selecting', this._closeProxy);
2325
2348
  }
2326
2349
 
2350
+ this._lastMousePosition = {};
2351
+
2327
2352
  this.addToDom();
2328
2353
  this.position();
2329
2354
  this.setupCloseHandler();
@@ -2337,7 +2362,7 @@ function SelectivityDropdown(options) {
2337
2362
  selectivity.focus();
2338
2363
  }
2339
2364
 
2340
- this._delegateEvents();
2365
+ EventDelegator.call(this);
2341
2366
 
2342
2367
  this.showLoading();
2343
2368
 
@@ -2347,7 +2372,7 @@ function SelectivityDropdown(options) {
2347
2372
  /**
2348
2373
  * Methods.
2349
2374
  */
2350
- $.extend(SelectivityDropdown.prototype, {
2375
+ $.extend(SelectivityDropdown.prototype, EventDelegator.prototype, {
2351
2376
 
2352
2377
  /**
2353
2378
  * Convenience shortcut for this.$el.find(selector).
@@ -2362,7 +2387,12 @@ $.extend(SelectivityDropdown.prototype, {
2362
2387
  */
2363
2388
  addToDom: function() {
2364
2389
 
2365
- this.$el.appendTo(this.selectivity.$el[0].ownerDocument.body);
2390
+ var $next;
2391
+ var $anchor = this.selectivity.$el;
2392
+ while (($next = $anchor.next('.selectivity-dropdown')).length) {
2393
+ $anchor = $next;
2394
+ }
2395
+ this.$el.insertAfter($anchor);
2366
2396
  },
2367
2397
 
2368
2398
  /**
@@ -2391,8 +2421,9 @@ $.extend(SelectivityDropdown.prototype, {
2391
2421
  events: {
2392
2422
  'click .selectivity-load-more': '_loadMoreClicked',
2393
2423
  'click .selectivity-result-item': '_resultClicked',
2394
- 'mouseenter .selectivity-load-more': 'highlightLoadMore',
2395
- 'mouseenter .selectivity-result-item': '_resultHovered'
2424
+ 'mouseenter .selectivity-load-more': '_loadMoreHovered',
2425
+ 'mouseenter .selectivity-result-item': '_resultHovered',
2426
+ 'mousemove': '_recordMousePosition'
2396
2427
  },
2397
2428
 
2398
2429
  /**
@@ -2610,28 +2641,6 @@ $.extend(SelectivityDropdown.prototype, {
2610
2641
  this.selectivity.$el.trigger('selectivity-open');
2611
2642
  },
2612
2643
 
2613
- /**
2614
- * @private
2615
- */
2616
- _delegateEvents: function() {
2617
-
2618
- $.each(this.events, function(event, listener) {
2619
- var index = event.indexOf(' ');
2620
- var selector = event.slice(index + 1);
2621
- event = event.slice(0, index);
2622
-
2623
- if ($.type(listener) === 'string') {
2624
- listener = this[listener];
2625
- }
2626
-
2627
- listener = listener.bind(this);
2628
-
2629
- this.$el.on(event, selector, listener);
2630
- }.bind(this));
2631
-
2632
- this.$results.on('scroll touchmove touchend', this._scrolledProxy);
2633
- },
2634
-
2635
2644
  /**
2636
2645
  * @private
2637
2646
  */
@@ -2674,6 +2683,27 @@ $.extend(SelectivityDropdown.prototype, {
2674
2683
  return false;
2675
2684
  },
2676
2685
 
2686
+ /**
2687
+ * @private
2688
+ */
2689
+ _loadMoreHovered: function(event) {
2690
+
2691
+ if (event.screenX === undefined || event.screenX !== this._lastMousePosition.x ||
2692
+ event.screenY === undefined || event.screenY !== this._lastMousePosition.y) {
2693
+ this.highlightLoadMore();
2694
+
2695
+ this._recordMousePosition(event);
2696
+ }
2697
+ },
2698
+
2699
+ /**
2700
+ * @private
2701
+ */
2702
+ _recordMousePosition: function(event) {
2703
+
2704
+ this._lastMousePosition = { x: event.screenX, y: event.screenY };
2705
+ },
2706
+
2677
2707
  /**
2678
2708
  * @private
2679
2709
  */
@@ -2689,10 +2719,15 @@ $.extend(SelectivityDropdown.prototype, {
2689
2719
  */
2690
2720
  _resultHovered: function(event) {
2691
2721
 
2692
- var id = this.selectivity._getItemId(event);
2693
- var item = Selectivity.findNestedById(this.results, id);
2694
- if (item) {
2695
- this.highlight(item);
2722
+ if (event.screenX === undefined || event.screenX !== this._lastMousePosition.x ||
2723
+ event.screenY === undefined || event.screenY !== this._lastMousePosition.y) {
2724
+ var id = this.selectivity._getItemId(event);
2725
+ var item = Selectivity.findNestedById(this.results, id);
2726
+ if (item) {
2727
+ this.highlight(item);
2728
+ }
2729
+
2730
+ this._recordMousePosition(event);
2696
2731
  }
2697
2732
  },
2698
2733
 
@@ -2782,13 +2817,13 @@ $.extend(SelectivityDropdown.prototype, {
2782
2817
 
2783
2818
  module.exports = Selectivity.Dropdown = SelectivityDropdown;
2784
2819
 
2785
- },{"2":2,"7":7,"jquery":"jquery"}],10:[function(_dereq_,module,exports){
2820
+ },{"2":2,"3":3,"8":8,"jquery":"jquery"}],11:[function(_dereq_,module,exports){
2786
2821
  'use strict';
2787
2822
 
2788
2823
  var $ = window.jQuery || window.Zepto;
2789
2824
 
2790
- var Selectivity = _dereq_(7);
2791
- var MultipleSelectivity = _dereq_(13);
2825
+ var Selectivity = _dereq_(8);
2826
+ var MultipleSelectivity = _dereq_(14);
2792
2827
 
2793
2828
  function isValidEmail(email) {
2794
2829
 
@@ -2947,10 +2982,10 @@ var callSuper = Selectivity.inherits(Emailselectivity, MultipleSelectivity, {
2947
2982
 
2948
2983
  module.exports = Selectivity.InputTypes.Email = Emailselectivity;
2949
2984
 
2950
- },{"13":13,"7":7,"jquery":"jquery"}],11:[function(_dereq_,module,exports){
2985
+ },{"14":14,"8":8,"jquery":"jquery"}],12:[function(_dereq_,module,exports){
2951
2986
  'use strict';
2952
2987
 
2953
- var Selectivity = _dereq_(7);
2988
+ var Selectivity = _dereq_(8);
2954
2989
 
2955
2990
  var KEY_BACKSPACE = 8;
2956
2991
  var KEY_DOWN_ARROW = 40;
@@ -3030,7 +3065,7 @@ function listener(selectivity, $input) {
3030
3065
  var result = Selectivity.findNestedById(results,
3031
3066
  selectivity._getItemId($results[index]));
3032
3067
  if (result) {
3033
- dropdown.highlight(result);
3068
+ dropdown.highlight(result, { delay: !!result.submenu });
3034
3069
  scrollToHighlight();
3035
3070
  }
3036
3071
  }
@@ -3080,8 +3115,13 @@ function listener(selectivity, $input) {
3080
3115
 
3081
3116
  if (closeSubmenu) {
3082
3117
  closeSubmenu.close();
3118
+ selectivity.focus();
3083
3119
  closeSubmenu = null;
3084
3120
  }
3121
+ } else if (event.keyCode === KEY_BACKSPACE) {
3122
+ if (!dropdown && selectivity.options.allowClear) {
3123
+ selectivity.clear();
3124
+ }
3085
3125
  } else if (event.keyCode === KEY_ENTER && !event.ctrlKey) {
3086
3126
  if (dropdown) {
3087
3127
  dropdown.selectHighlight();
@@ -3111,11 +3151,11 @@ function listener(selectivity, $input) {
3111
3151
 
3112
3152
  Selectivity.SearchInputListeners.push(listener);
3113
3153
 
3114
- },{"7":7}],12:[function(_dereq_,module,exports){
3154
+ },{"8":8}],13:[function(_dereq_,module,exports){
3115
3155
  'use strict';
3116
3156
 
3117
- var escape = _dereq_(3);
3118
- var Selectivity = _dereq_(7);
3157
+ var escape = _dereq_(4);
3158
+ var Selectivity = _dereq_(8);
3119
3159
 
3120
3160
  /**
3121
3161
  * Localizable elements of the Selectivity Templates.
@@ -3136,12 +3176,12 @@ Selectivity.Locale = {
3136
3176
 
3137
3177
  };
3138
3178
 
3139
- },{"3":3,"7":7}],13:[function(_dereq_,module,exports){
3179
+ },{"4":4,"8":8}],14:[function(_dereq_,module,exports){
3140
3180
  'use strict';
3141
3181
 
3142
3182
  var $ = window.jQuery || window.Zepto;
3143
3183
 
3144
- var Selectivity = _dereq_(7);
3184
+ var Selectivity = _dereq_(8);
3145
3185
 
3146
3186
  var KEY_BACKSPACE = 8;
3147
3187
  var KEY_DELETE = 46;
@@ -3167,16 +3207,21 @@ function MultipleSelectivity(options) {
3167
3207
  this._rerenderSelection();
3168
3208
 
3169
3209
  if (!options.positionDropdown) {
3210
+ // dropdowns for multiple-value inputs should open below the select box,
3211
+ // unless there is not enough space below, but there is space enough above, then it should
3212
+ // open upwards
3170
3213
  this.options.positionDropdown = function($el, $selectEl) {
3171
- var offset = $selectEl.offset(),
3172
- elHeight = $el.height(),
3214
+ var position = $selectEl.position(),
3215
+ dropdownHeight = $el.height(),
3173
3216
  selectHeight = $selectEl.height(),
3174
- bottom = $selectEl[0].getBoundingClientRect().top + selectHeight + elHeight;
3217
+ top = $selectEl[0].getBoundingClientRect().top,
3218
+ bottom = top + selectHeight + dropdownHeight,
3219
+ openUpwards = (typeof window !== 'undefined' && bottom > $(window).height() &&
3220
+ top - dropdownHeight > 0);
3175
3221
 
3176
3222
  $el.css({
3177
- left: offset.left + 'px',
3178
- top: offset.top + (typeof window !== 'undefined' &&
3179
- bottom > $(window).height() ? -elHeight : selectHeight) + 'px'
3223
+ left: position.left + 'px',
3224
+ top: position.top + (openUpwards ? -dropdownHeight : selectHeight) + 'px'
3180
3225
  }).width($selectEl.width());
3181
3226
  };
3182
3227
  }
@@ -3683,12 +3728,12 @@ var callSuper = Selectivity.inherits(MultipleSelectivity, {
3683
3728
 
3684
3729
  module.exports = Selectivity.InputTypes.Multiple = MultipleSelectivity;
3685
3730
 
3686
- },{"7":7,"jquery":"jquery"}],14:[function(_dereq_,module,exports){
3731
+ },{"8":8,"jquery":"jquery"}],15:[function(_dereq_,module,exports){
3687
3732
  'use strict';
3688
3733
 
3689
3734
  var $ = window.jQuery || window.Zepto;
3690
3735
 
3691
- var Selectivity = _dereq_(7);
3736
+ var Selectivity = _dereq_(8);
3692
3737
 
3693
3738
  /**
3694
3739
  * SingleSelectivity Constructor.
@@ -3706,21 +3751,25 @@ function SingleSelectivity(options) {
3706
3751
  this._rerenderSelection();
3707
3752
 
3708
3753
  if (!options.positionDropdown) {
3754
+ // dropdowns for single-value inputs should open below the select box,
3755
+ // unless there is not enough space below, in which case the dropdown should be moved up
3756
+ // just enough so it fits in the window, but never so much that it reaches above the top
3709
3757
  this.options.positionDropdown = function($el, $selectEl) {
3710
- var offset = $selectEl.offset(),
3711
- top = offset.top + $selectEl.height();
3758
+ var position = $selectEl.position(),
3759
+ dropdownHeight = $el.height(),
3760
+ selectHeight = $selectEl.height(),
3761
+ top = $selectEl[0].getBoundingClientRect().top,
3762
+ bottom = top + selectHeight + dropdownHeight,
3763
+ deltaUp = 0;
3712
3764
 
3713
3765
  if (typeof window !== 'undefined') {
3714
- var fixedOffset = $selectEl[0].getBoundingClientRect(),
3715
- elHeight = $el.height(),
3716
- windowHeight = $(window).height();
3717
-
3718
- if (fixedOffset.top + elHeight > windowHeight) {
3719
- top = Math.max(windowHeight - elHeight + offset.top - fixedOffset.top, 0);
3720
- }
3766
+ deltaUp = Math.min(Math.max(bottom - $(window).height(), 0), top + selectHeight);
3721
3767
  }
3722
3768
 
3723
- $el.css({ left: offset.left + 'px', top: top + 'px' }).width($selectEl.width());
3769
+ $el.css({
3770
+ left: position.left + 'px',
3771
+ top: (position.top + selectHeight - deltaUp) + 'px'
3772
+ }).width($selectEl.width());
3724
3773
  };
3725
3774
  }
3726
3775
 
@@ -3766,8 +3815,13 @@ var callSuper = Selectivity.inherits(SingleSelectivity, {
3766
3815
 
3767
3816
  callSuper(this, 'close');
3768
3817
 
3818
+ var $input = this.$('.selectivity-single-select-input');
3819
+ if (!this.$searchInput) {
3820
+ this.initSearchInput($input, { noSearch: true });
3821
+ }
3822
+
3769
3823
  if (!options || options.keepFocus !== false) {
3770
- this.$('.selectivity-single-select-input').focus();
3824
+ $input.focus();
3771
3825
  }
3772
3826
 
3773
3827
  this._closing = false;
@@ -3935,11 +3989,11 @@ var callSuper = Selectivity.inherits(SingleSelectivity, {
3935
3989
 
3936
3990
  module.exports = Selectivity.InputTypes.Single = SingleSelectivity;
3937
3991
 
3938
- },{"7":7,"jquery":"jquery"}],15:[function(_dereq_,module,exports){
3992
+ },{"8":8,"jquery":"jquery"}],16:[function(_dereq_,module,exports){
3939
3993
  'use strict';
3940
3994
 
3941
- var Selectivity = _dereq_(7);
3942
- var SelectivityDropdown = _dereq_(9);
3995
+ var Selectivity = _dereq_(8);
3996
+ var SelectivityDropdown = _dereq_(10);
3943
3997
 
3944
3998
  /**
3945
3999
  * Extended dropdown that supports submenus.
@@ -3954,6 +4008,8 @@ function SelectivitySubmenu(options) {
3954
4008
  SelectivityDropdown.call(this, options);
3955
4009
 
3956
4010
  this._closeSubmenuTimeout = 0;
4011
+
4012
+ this._openSubmenuTimeout = 0;
3957
4013
  }
3958
4014
 
3959
4015
  var callSuper = Selectivity.inherits(SelectivitySubmenu, SelectivityDropdown, {
@@ -3980,31 +4036,42 @@ var callSuper = Selectivity.inherits(SelectivitySubmenu, SelectivityDropdown, {
3980
4036
  this.parentMenu.submenu = null;
3981
4037
  this.parentMenu = null;
3982
4038
  }
4039
+
4040
+ clearTimeout(this._closeSubmenuTimeout);
4041
+ clearTimeout(this._openSubmenuTimeout);
3983
4042
  },
3984
4043
 
3985
4044
  /**
3986
4045
  * @inherit
4046
+ *
4047
+ * @param options Optional options object. May contain the following property:
4048
+ * delay - If true, indicates any submenu should not be opened until after some
4049
+ * delay.
3987
4050
  */
3988
- highlight: function(item) {
4051
+ highlight: function(item, options) {
3989
4052
 
3990
- if (this.submenu) {
3991
- if (!this.highlightedResult || this.highlightedResult.id !== item.id) {
3992
- if (this._closeSubmenuTimeout) {
3993
- clearTimeout(this._closeSubmenuTimeout);
3994
- }
4053
+ if (options && options.delay) {
4054
+ callSuper(this, 'highlight', item);
4055
+
4056
+ clearTimeout(this._openSubmenuTimeout);
4057
+ this._openSubmenuTimeout = setTimeout(this._doHighlight.bind(this, item), 300);
4058
+ } else if (this.submenu) {
4059
+ if (this.highlightedResult && this.highlightedResult.id === item.id) {
4060
+ this._doHighlight(item);
4061
+ } else {
4062
+ clearTimeout(this._closeSubmenuTimeout);
3995
4063
  this._closeSubmenuTimeout = setTimeout(
3996
4064
  this._closeSubmenuAndHighlight.bind(this, item), 100
3997
4065
  );
3998
- return;
3999
4066
  }
4000
4067
  } else {
4001
4068
  if (this.parentMenu && this.parentMenu._closeSubmenuTimeout) {
4002
4069
  clearTimeout(this.parentMenu._closeSubmenuTimeout);
4003
4070
  this.parentMenu._closeSubmenuTimeout = 0;
4004
4071
  }
4005
- }
4006
4072
 
4007
- this._doHighlight(item);
4073
+ this._doHighlight(item);
4074
+ }
4008
4075
  },
4009
4076
 
4010
4077
  /**
@@ -4100,11 +4167,11 @@ var callSuper = Selectivity.inherits(SelectivitySubmenu, SelectivityDropdown, {
4100
4167
  this.submenu = new Dropdown({
4101
4168
  parentMenu: this,
4102
4169
  position: item.submenu.positionDropdown || function($el) {
4103
- var offset = $item.offset();
4170
+ var dropdownPosition = $dropdownEl.position();
4104
4171
  var width = $dropdownEl.width();
4105
4172
  $el.css({
4106
- left: offset.left + width + 'px',
4107
- top: offset.top + 'px'
4173
+ left: dropdownPosition.left + width + 'px',
4174
+ top: $item.position().top + dropdownPosition.top + 'px'
4108
4175
  }).width(width);
4109
4176
  },
4110
4177
  restoreOptions: {
@@ -4150,14 +4217,14 @@ Selectivity.findNestedById = function(array, id) {
4150
4217
 
4151
4218
  module.exports = SelectivitySubmenu;
4152
4219
 
4153
- },{"7":7,"9":9}],16:[function(_dereq_,module,exports){
4220
+ },{"10":10,"8":8}],17:[function(_dereq_,module,exports){
4154
4221
  'use strict';
4155
4222
 
4156
- var escape = _dereq_(3);
4223
+ var escape = _dereq_(4);
4157
4224
 
4158
- var Selectivity = _dereq_(7);
4225
+ var Selectivity = _dereq_(8);
4159
4226
 
4160
- _dereq_(12);
4227
+ _dereq_(13);
4161
4228
 
4162
4229
  /**
4163
4230
  * Default set of templates to use with Selectivity.js.
@@ -4454,12 +4521,12 @@ Selectivity.Templates = {
4454
4521
 
4455
4522
  };
4456
4523
 
4457
- },{"12":12,"3":3,"7":7}],17:[function(_dereq_,module,exports){
4524
+ },{"13":13,"4":4,"8":8}],18:[function(_dereq_,module,exports){
4458
4525
  'use strict';
4459
4526
 
4460
4527
  var $ = window.jQuery || window.Zepto;
4461
4528
 
4462
- var Selectivity = _dereq_(7);
4529
+ var Selectivity = _dereq_(8);
4463
4530
 
4464
4531
  function defaultTokenizer(input, selection, createToken, options) {
4465
4532
 
@@ -4521,12 +4588,12 @@ Selectivity.OptionListeners.push(function(selectivity, options) {
4521
4588
  }
4522
4589
  });
4523
4590
 
4524
- },{"7":7,"jquery":"jquery"}],18:[function(_dereq_,module,exports){
4591
+ },{"8":8,"jquery":"jquery"}],19:[function(_dereq_,module,exports){
4525
4592
  'use strict';
4526
4593
 
4527
4594
  var $ = window.jQuery || window.Zepto;
4528
4595
 
4529
- var Selectivity = _dereq_(7);
4596
+ var Selectivity = _dereq_(8);
4530
4597
 
4531
4598
  function replaceSelectElement($el, options) {
4532
4599
 
@@ -4632,5 +4699,5 @@ Selectivity.OptionListeners.push(function(selectivity, options) {
4632
4699
  }
4633
4700
  });
4634
4701
 
4635
- },{"7":7,"jquery":"jquery"}]},{},[1])(1)
4702
+ },{"8":8,"jquery":"jquery"}]},{},[1])(1)
4636
4703
  });
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: selectivity-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konrad Jurkowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-01 00:00:00.000000000 Z
11
+ date: 2015-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler