selectBoxIt 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.
Files changed (30) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +52 -0
  6. data/Rakefile +2 -0
  7. data/app/assets/javascripts/selectBoxIt/jquery.selectBoxIt.js +3259 -0
  8. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.add.js +183 -0
  9. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.ariaAccessibility.js +117 -0
  10. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.copyAttributes.js +63 -0
  11. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.core.js +1802 -0
  12. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.destroy.js +58 -0
  13. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.disable.js +137 -0
  14. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.dynamicPositioning.js +102 -0
  15. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.enable.js +76 -0
  16. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.endClosure.js +1 -0
  17. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.keyboardNavigation.js +143 -0
  18. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.keyboardSearch.js +209 -0
  19. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.mobile.js +158 -0
  20. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.remove.js +90 -0
  21. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.selectOption.js +36 -0
  22. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.setOption.js +33 -0
  23. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.setOptions.js +32 -0
  24. data/app/assets/javascripts/selectBoxIt/modules/jquery.selectBoxIt.wait.js +19 -0
  25. data/app/assets/stylesheets/selectBoxIt/jquery.selectBoxIt.css +278 -0
  26. data/lib/selectBoxIt.rb +6 -0
  27. data/lib/selectBoxIt/engine.rb +4 -0
  28. data/lib/selectBoxIt/version.rb +3 -0
  29. data/selectBoxIt.gemspec +23 -0
  30. metadata +100 -0
@@ -0,0 +1,58 @@
1
+ // Destroy Module
2
+ // ==============
3
+
4
+ // Destroy
5
+ // -------
6
+ // Removes the plugin from the page
7
+
8
+ selectBoxIt.destroy = function(callback) {
9
+
10
+ // Stores the plugin context inside of the self variable
11
+ var self = this;
12
+
13
+ self._destroySelectBoxIt();
14
+
15
+ // Calls the jQueryUI Widget Factory destroy method
16
+ self.widgetProto.destroy.call(self);
17
+
18
+ // Provides callback function support
19
+ self._callbackSupport(callback);
20
+
21
+ // Maintains chainability
22
+ return self;
23
+
24
+ };
25
+
26
+ // Internal Destroy Method
27
+ // -----------------------
28
+ // Removes the plugin from the page
29
+
30
+ selectBoxIt._destroySelectBoxIt = function() {
31
+
32
+ // Stores the plugin context inside of the self variable
33
+ var self = this;
34
+
35
+ // Unbinds all of the dropdown list event handlers with the `selectBoxIt` namespace
36
+ self.dropdown.off(".selectBoxIt");
37
+
38
+ // If the original select box has been placed inside of the new drop down container
39
+ if ($.contains(self.dropdownContainer[0], self.originalElem)) {
40
+
41
+ // Moves the original select box before the drop down container
42
+ self.dropdownContainer.before(self.selectBox);
43
+
44
+ }
45
+
46
+ // Remove all of the `selectBoxIt` DOM elements from the page
47
+ self.dropdownContainer.remove();
48
+
49
+ // Resets the style attributes for the original select box
50
+ self.selectBox.removeAttr("style").attr("style", self.selectBoxStyles);
51
+
52
+ // Triggers the custom `destroy` event on the original select box
53
+ self.triggerEvent("destroy");
54
+
55
+ // Maintains chainability
56
+ return self;
57
+
58
+ };
@@ -0,0 +1,137 @@
1
+
2
+ // Disable Module
3
+ // ==============
4
+
5
+ // Disable
6
+ // -------
7
+ // Disables the new dropdown list
8
+
9
+ selectBoxIt.disable = function(callback) {
10
+
11
+ var self = this;
12
+
13
+ if(!self.options["disabled"]) {
14
+
15
+ // Makes sure the dropdown list is closed
16
+ self.close();
17
+
18
+ // Sets the `disabled` attribute on the original select box
19
+ self.selectBox.attr("disabled", "disabled");
20
+
21
+ // Makes the dropdown list not focusable by removing the `tabindex` attribute
22
+ self.dropdown.removeAttr("tabindex").
23
+
24
+ // Disables styling for enabled state
25
+ removeClass(self.theme["enabled"]).
26
+
27
+ // Enabled styling for disabled state
28
+ addClass(self.theme["disabled"]);
29
+
30
+ self.setOption("disabled", true);
31
+
32
+ // Triggers a `disable` custom event on the original select box
33
+ self.triggerEvent("disable");
34
+
35
+ }
36
+
37
+ // Provides callback function support
38
+ self._callbackSupport(callback);
39
+
40
+ // Maintains chainability
41
+ return self;
42
+
43
+ };
44
+
45
+ // Disable Option
46
+ // --------------
47
+ // Disables a single drop down option
48
+
49
+ selectBoxIt.disableOption = function(index, callback) {
50
+
51
+ var self = this, currentSelectBoxOption, hasNextEnabled, hasPreviousEnabled, type = $.type(index);
52
+
53
+ // If an index is passed to target an indropdownidual drop down option
54
+ if(type === "number") {
55
+
56
+ // Makes sure the dropdown list is closed
57
+ self.close();
58
+
59
+ // The select box option being targeted
60
+ currentSelectBoxOption = self.selectBox.find("option").eq(index);
61
+
62
+ // Triggers a `disable-option` custom event on the original select box and passes the disabled option
63
+ self.triggerEvent("disable-option");
64
+
65
+ // Disables the targeted select box option
66
+ currentSelectBoxOption.attr("disabled", "disabled");
67
+
68
+ // Disables the drop down option
69
+ self.listItems.eq(index).attr("data-disabled", "true").
70
+
71
+ // Applies disabled styling for the drop down option
72
+ addClass(self.theme["disabled"]);
73
+
74
+ // If the currently selected drop down option is the item being disabled
75
+ if(self.currentFocus === index) {
76
+
77
+ hasNextEnabled = self.listItems.eq(self.currentFocus).nextAll("li").not("[data-disabled='true']").first().length;
78
+
79
+ hasPreviousEnabled = self.listItems.eq(self.currentFocus).prevAll("li").not("[data-disabled='true']").first().length;
80
+
81
+ // If there is a currently enabled option beneath the currently selected option
82
+ if(hasNextEnabled) {
83
+
84
+ // Selects the option beneath the currently selected option
85
+ self.moveDown();
86
+
87
+ }
88
+
89
+ // If there is a currently enabled option above the currently selected option
90
+ else if(hasPreviousEnabled) {
91
+
92
+ // Selects the option above the currently selected option
93
+ self.moveUp();
94
+
95
+ }
96
+
97
+ // If there is not a currently enabled option
98
+ else {
99
+
100
+ // Disables the entire drop down list
101
+ self.disable();
102
+
103
+ }
104
+
105
+ }
106
+
107
+ }
108
+
109
+ // Provides callback function support
110
+ self._callbackSupport(callback);
111
+
112
+ // Maintains chainability
113
+ return self;
114
+
115
+ };
116
+
117
+ // _Is Disabled
118
+ // -----------
119
+ // Checks the original select box for the
120
+ // disabled attribute
121
+
122
+ selectBoxIt._isDisabled = function(callback) {
123
+
124
+ var self = this;
125
+
126
+ // If the original select box is disabled
127
+ if (self.originalElem.disabled) {
128
+
129
+ // Disables the dropdown list
130
+ self.disable();
131
+
132
+ }
133
+
134
+ // Maintains chainability
135
+ return self;
136
+
137
+ };
@@ -0,0 +1,102 @@
1
+
2
+ // Dynamic Positioning Module
3
+ // ==========================
4
+
5
+ // _Dynamic positioning
6
+ // --------------------
7
+ // Dynamically positions the dropdown list options list
8
+
9
+ selectBoxIt._dynamicPositioning = function() {
10
+
11
+ var self = this;
12
+
13
+ // If the `size` option is a number
14
+ if($.type(self.listSize) === "number") {
15
+
16
+ // Set's the max-height of the drop down list
17
+ self.list.css("max-height", self.maxHeight || "none");
18
+
19
+ }
20
+
21
+ // If the `size` option is not a number
22
+ else {
23
+
24
+ // Returns the x and y coordinates of the dropdown list options list relative to the document
25
+ var listOffsetTop = self.dropdown.offset().top,
26
+
27
+ // The height of the dropdown list options list
28
+ listHeight = self.list.data("max-height") || self.list.outerHeight(),
29
+
30
+ // The height of the dropdown list DOM element
31
+ selectBoxHeight = self.dropdown.outerHeight(),
32
+
33
+ viewport = self.options["viewport"],
34
+
35
+ viewportHeight = viewport.height(),
36
+
37
+ viewportScrollTop = $.isWindow(viewport.get(0)) ? viewport.scrollTop() : viewport.offset().top,
38
+
39
+ topToBottom = (listOffsetTop + selectBoxHeight + listHeight <= viewportHeight + viewportScrollTop),
40
+
41
+ bottomReached = !topToBottom;
42
+
43
+ if(!self.list.data("max-height")) {
44
+
45
+ self.list.data("max-height", self.list.outerHeight());
46
+
47
+ }
48
+
49
+ // If there is room on the bottom of the viewport to display the drop down options
50
+ if (!bottomReached) {
51
+
52
+ self.list.css("max-height", listHeight);
53
+
54
+ // Sets custom CSS properties to place the dropdown list options directly below the dropdown list
55
+ self.list.css("top", "auto");
56
+
57
+ }
58
+
59
+ // If there is room on the top of the viewport
60
+ else if((self.dropdown.offset().top - viewportScrollTop) >= listHeight) {
61
+
62
+ self.list.css("max-height", listHeight);
63
+
64
+ // Sets custom CSS properties to place the dropdown list options directly above the dropdown list
65
+ self.list.css("top", (self.dropdown.position().top - self.list.outerHeight()));
66
+
67
+ }
68
+
69
+ // If there is not enough room on the top or the bottom
70
+ else {
71
+
72
+ var outsideBottomViewport = Math.abs((listOffsetTop + selectBoxHeight + listHeight) - (viewportHeight + viewportScrollTop)),
73
+
74
+ outsideTopViewport = Math.abs((self.dropdown.offset().top - viewportScrollTop) - listHeight);
75
+
76
+ // If there is more room on the bottom
77
+ if(outsideBottomViewport < outsideTopViewport) {
78
+
79
+ self.list.css("max-height", listHeight - outsideBottomViewport - (selectBoxHeight/2));
80
+
81
+ self.list.css("top", "auto");
82
+
83
+ }
84
+
85
+ // If there is more room on the top
86
+ else {
87
+
88
+ self.list.css("max-height", listHeight - outsideTopViewport - (selectBoxHeight/2));
89
+
90
+ // Sets custom CSS properties to place the dropdown list options directly above the dropdown list
91
+ self.list.css("top", (self.dropdown.position().top - self.list.outerHeight()));
92
+
93
+ }
94
+
95
+ }
96
+
97
+ }
98
+
99
+ // Maintains chainability
100
+ return self;
101
+
102
+ };
@@ -0,0 +1,76 @@
1
+
2
+ // Enable Module
3
+ // =============
4
+
5
+ // Enable
6
+ // ------
7
+ // Enables the new dropdown list
8
+
9
+ selectBoxIt.enable = function(callback) {
10
+
11
+ var self = this;
12
+
13
+ if(self.options["disabled"]) {
14
+
15
+ // Triggers a `enable` custom event on the original select box
16
+ self.triggerEvent("enable");
17
+
18
+ // Removes the `disabled` attribute from the original dropdown list
19
+ self.selectBox.removeAttr("disabled");
20
+
21
+ // Make the dropdown list focusable
22
+ self.dropdown.attr("tabindex", 0).
23
+
24
+ // Disable styling for disabled state
25
+ removeClass(self.theme["disabled"]).
26
+
27
+ // Enables styling for enabled state
28
+ addClass(self.theme["enabled"]);
29
+
30
+ self.setOption("disabled", false);
31
+
32
+ // Provide callback function support
33
+ self._callbackSupport(callback);
34
+
35
+ }
36
+
37
+ // Maintains chainability
38
+ return self;
39
+
40
+ };
41
+
42
+ // Enable Option
43
+ // -------------
44
+ // Disables a single drop down option
45
+
46
+ selectBoxIt.enableOption = function(index, callback) {
47
+
48
+ var self = this, currentSelectBoxOption, currentIndex = 0, hasNextEnabled, hasPreviousEnabled, type = $.type(index);
49
+
50
+ // If an index is passed to target an indropdownidual drop down option
51
+ if(type === "number") {
52
+
53
+ // The select box option being targeted
54
+ currentSelectBoxOption = self.selectBox.find("option").eq(index);
55
+
56
+ // Triggers a `enable-option` custom event on the original select box and passes the enabled option
57
+ self.triggerEvent("enable-option");
58
+
59
+ // Disables the targeted select box option
60
+ currentSelectBoxOption.removeAttr("disabled");
61
+
62
+ // Disables the drop down option
63
+ self.listItems.eq(index).attr("data-disabled", "false").
64
+
65
+ // Applies disabled styling for the drop down option
66
+ removeClass(self.theme["disabled"]);
67
+
68
+ }
69
+
70
+ // Provides callback function support
71
+ self._callbackSupport(callback);
72
+
73
+ // Maintains chainability
74
+ return self;
75
+
76
+ };
@@ -0,0 +1,143 @@
1
+
2
+ // Keyboard Navigation Module
3
+ // ==========================
4
+
5
+ // Move Down
6
+ // ---------
7
+ // Handles the down keyboard navigation logic
8
+
9
+ selectBoxIt.moveDown = function(callback) {
10
+
11
+ var self = this;
12
+
13
+ // Increments `currentFocus`, which represents the currently focused list item `id` attribute.
14
+ self.currentFocus += 1;
15
+
16
+ // Determines whether the dropdown option the user is trying to go to is currently disabled
17
+ var disabled = self.listItems.eq(self.currentFocus).attr("data-disabled") === "true" ? true: false,
18
+
19
+ hasNextEnabled = self.listItems.eq(self.currentFocus).nextAll("li").not("[data-disabled='true']").first().length;
20
+
21
+ // If the user has reached the top of the list
22
+ if (self.currentFocus === self.listItems.length) {
23
+
24
+ // Does not allow the user to continue to go up the list
25
+ self.currentFocus -= 1;
26
+
27
+ }
28
+
29
+ // If the option the user is trying to go to is disabled, but there is another enabled option
30
+ else if (disabled && hasNextEnabled) {
31
+
32
+ // Blur the previously selected option
33
+ self.listItems.eq(self.currentFocus - 1).blur();
34
+
35
+ // Call the `moveDown` method again
36
+ self.moveDown();
37
+
38
+ // Exit the method
39
+ return;
40
+
41
+ }
42
+
43
+ // If the option the user is trying to go to is disabled, but there is not another enabled option
44
+ else if (disabled && !hasNextEnabled) {
45
+
46
+ self.currentFocus -= 1;
47
+
48
+ }
49
+
50
+ // If the user has not reached the bottom of the unordered list
51
+ else {
52
+
53
+ // Blurs the previously focused list item
54
+ // The jQuery `end()` method allows you to continue chaining while also using a different selector
55
+ self.listItems.eq(self.currentFocus - 1).blur().end().
56
+
57
+ // Focuses the currently focused list item
58
+ eq(self.currentFocus).focusin();
59
+
60
+ // Calls `scrollToView` to make sure the `scrollTop` is correctly updated. The `down` user action
61
+ self._scrollToView("down");
62
+
63
+ // Triggers the custom `moveDown` event on the original select box
64
+ self.triggerEvent("moveDown");
65
+
66
+ }
67
+
68
+ // Provide callback function support
69
+ self._callbackSupport(callback);
70
+
71
+ // Maintains chainability
72
+ return self;
73
+
74
+ };
75
+
76
+ // Move Up
77
+ // ------
78
+ // Handles the up keyboard navigation logic
79
+ selectBoxIt.moveUp = function(callback) {
80
+
81
+ var self = this;
82
+
83
+ // Increments `currentFocus`, which represents the currently focused list item `id` attribute.
84
+ self.currentFocus -= 1;
85
+
86
+ // Determines whether the dropdown option the user is trying to go to is currently disabled
87
+ var disabled = self.listItems.eq(self.currentFocus).attr("data-disabled") === "true" ? true: false,
88
+
89
+ hasPreviousEnabled = self.listItems.eq(self.currentFocus).prevAll("li").not("[data-disabled='true']").first().length;
90
+
91
+ // If the user has reached the top of the list
92
+ if (self.currentFocus === -1) {
93
+
94
+ // Does not allow the user to continue to go up the list
95
+ self.currentFocus += 1;
96
+
97
+ }
98
+
99
+ // If the option the user is trying to go to is disabled and the user is not trying to go up after the user has reached the top of the list
100
+ else if (disabled && hasPreviousEnabled) {
101
+
102
+ // Blur the previously selected option
103
+ self.listItems.eq(self.currentFocus + 1).blur();
104
+
105
+ // Call the `moveUp` method again
106
+ self.moveUp();
107
+
108
+ // Exits the method
109
+ return;
110
+
111
+ }
112
+
113
+ else if (disabled && !hasPreviousEnabled) {
114
+
115
+ self.currentFocus += 1;
116
+
117
+ }
118
+
119
+ // If the user has not reached the top of the unordered list
120
+ else {
121
+
122
+ // Blurs the previously focused list item
123
+ // The jQuery `end()` method allows you to continue chaining while also using a different selector
124
+ self.listItems.eq(this.currentFocus + 1).blur().end().
125
+
126
+ // Focuses the currently focused list item
127
+ eq(self.currentFocus).focusin();
128
+
129
+ // Calls `scrollToView` to make sure the `scrollTop` is correctly updated. The `down` user action
130
+ self._scrollToView("up");
131
+
132
+ // Triggers the custom `moveDown` event on the original select box
133
+ self.triggerEvent("moveUp");
134
+
135
+ }
136
+
137
+ // Provide callback function support
138
+ self._callbackSupport(callback);
139
+
140
+ // Maintains chainability
141
+ return self;
142
+
143
+ };