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,209 @@
1
+
2
+ // Keyboard Search Module
3
+ // ======================
4
+
5
+ // _Set Current Search Option
6
+ // -------------------------
7
+ // Sets the currently selected dropdown list search option
8
+
9
+ selectBoxIt._setCurrentSearchOption = function(currentOption) {
10
+
11
+ var self = this;
12
+
13
+ // Does not change the current option if `showFirstOption` is false and the matched search item is the hidden first option.
14
+ // Otherwise, the current option value is updated
15
+ if ((self.options["aggressiveChange"] || self.options["selectWhenHidden"] || self.listItems.eq(currentOption).is(":visible")) && self.listItems.eq(currentOption).data("disabled") !== true) {
16
+
17
+ // Calls the `blur` event of the currently selected dropdown list option
18
+ self.listItems.eq(self.currentFocus).blur();
19
+
20
+ // Sets `currentIndex` to the currently selected dropdown list option
21
+ self.currentIndex = currentOption;
22
+
23
+ // Sets `currentFocus` to the currently selected dropdown list option
24
+ self.currentFocus = currentOption;
25
+
26
+ // Focuses the currently selected dropdown list option
27
+ self.listItems.eq(self.currentFocus).focusin();
28
+
29
+ // Updates the scrollTop so that the currently selected dropdown list option is visible to the user
30
+ self._scrollToView("search");
31
+
32
+ // Triggers the custom `search` event on the original select box
33
+ self.triggerEvent("search");
34
+
35
+ }
36
+
37
+ // Maintains chainability
38
+ return self;
39
+
40
+ };
41
+
42
+ // _Search Algorithm
43
+ // -----------------
44
+ // Uses regular expressions to find text matches
45
+ selectBoxIt._searchAlgorithm = function(currentIndex, alphaNumeric) {
46
+
47
+ var self = this,
48
+
49
+ // Boolean to determine if a pattern match exists
50
+ matchExists = false,
51
+
52
+ // Iteration variable used in the outermost for loop
53
+ x,
54
+
55
+ // Iteration variable used in the nested for loop
56
+ y,
57
+
58
+ // Variable used to cache the length of the text array (Small enhancement to speed up traversing)
59
+ arrayLength,
60
+
61
+ // Variable storing the current search
62
+ currentSearch,
63
+
64
+ // Variable storing the textArray property
65
+ textArray = self.textArray,
66
+
67
+ // Variable storing the current text property
68
+ currentText = self.currentText;
69
+
70
+ // Loops through the text array to find a pattern match
71
+ for (x = currentIndex, arrayLength = textArray.length; x < arrayLength; x += 1) {
72
+
73
+ currentSearch = textArray[x];
74
+
75
+ // Nested for loop to help search for a pattern match with the currently traversed array item
76
+ for (y = 0; y < arrayLength; y += 1) {
77
+
78
+ // Searches for a match
79
+ if (textArray[y].search(alphaNumeric) !== -1) {
80
+
81
+ // `matchExists` is set to true if there is a match
82
+ matchExists = true;
83
+
84
+ // Exits the nested for loop
85
+ y = arrayLength;
86
+
87
+ }
88
+
89
+ } // End nested for loop
90
+
91
+ // If a match does not exist
92
+ if (!matchExists) {
93
+
94
+ // Sets the current text to the last entered character
95
+ self.currentText = self.currentText.charAt(self.currentText.length - 1).
96
+
97
+ // Escapes the regular expression to make sure special characters are seen as literal characters instead of special commands
98
+ replace(/[|()\[{.+*?$\\]/g, "\\$0");
99
+
100
+ currentText = self.currentText;
101
+
102
+ }
103
+
104
+ // Resets the regular expression with the new value of `self.currentText`
105
+ alphaNumeric = new RegExp(currentText, "gi");
106
+
107
+ // Searches based on the first letter of the dropdown list options text if the currentText < 3 characters
108
+ if (currentText.length < 3) {
109
+
110
+ alphaNumeric = new RegExp(currentText.charAt(0), "gi");
111
+
112
+ // If there is a match based on the first character
113
+ if ((currentSearch.charAt(0).search(alphaNumeric) !== -1)) {
114
+
115
+ // Sets properties of that dropdown list option to make it the currently selected option
116
+ self._setCurrentSearchOption(x);
117
+
118
+ if((currentSearch.substring(0, currentText.length).toLowerCase() !== currentText.toLowerCase()) || self.options["similarSearch"]) {
119
+
120
+ // Increments the current index by one
121
+ self.currentIndex += 1;
122
+
123
+ }
124
+
125
+ // Exits the search
126
+ return false;
127
+
128
+ }
129
+
130
+ }
131
+
132
+ // If `self.currentText` > 1 character
133
+ else {
134
+
135
+ // If there is a match based on the entire string
136
+ if ((currentSearch.search(alphaNumeric) !== -1)) {
137
+
138
+ // Sets properties of that dropdown list option to make it the currently selected option
139
+ self._setCurrentSearchOption(x);
140
+
141
+ // Exits the search
142
+ return false;
143
+
144
+ }
145
+
146
+ }
147
+
148
+ // If the current text search is an exact match
149
+ if (currentSearch.toLowerCase() === self.currentText.toLowerCase()) {
150
+
151
+ // Sets properties of that dropdown list option to make it the currently selected option
152
+ self._setCurrentSearchOption(x);
153
+
154
+ // Resets the current text search to a blank string to start fresh again
155
+ self.currentText = "";
156
+
157
+ // Exits the search
158
+ return false;
159
+
160
+ }
161
+
162
+ }
163
+
164
+ // Returns true if there is not a match at all
165
+ return true;
166
+
167
+ };
168
+
169
+ // Search
170
+ // ------
171
+ // Calls searchAlgorithm()
172
+ selectBoxIt.search = function(alphaNumericKey, callback, rememberPreviousSearch) {
173
+
174
+ var self = this;
175
+
176
+ // If the search method is being called internally by the plugin, and not externally as a method by a user
177
+ if (rememberPreviousSearch) {
178
+
179
+ // Continued search with history from past searches. Properly escapes the regular expression
180
+ self.currentText += alphaNumericKey.replace(/[|()\[{.+*?$\\]/g, "\\$0");
181
+
182
+ }
183
+
184
+ else {
185
+
186
+ // Brand new search. Properly escapes the regular expression
187
+ self.currentText = alphaNumericKey.replace(/[|()\[{.+*?$\\]/g, "\\$0");
188
+
189
+ }
190
+
191
+ // Searches globally
192
+ var searchResults = self._searchAlgorithm(self.currentIndex, new RegExp(self.currentText, "gi"));
193
+
194
+ // Searches the list again if a match is not found. This is needed, because the first search started at the array indece of the currently selected dropdown list option, and does not search the options before the current array indece.
195
+ // If there are many similar dropdown list options, starting the search at the indece of the currently selected dropdown list option is needed to properly traverse the text array.
196
+ if (searchResults) {
197
+
198
+ // Searches the dropdown list values starting from the beginning of the text array
199
+ self._searchAlgorithm(0, self.currentText);
200
+
201
+ }
202
+
203
+ // Provide callback function support
204
+ self._callbackSupport(callback);
205
+
206
+ // Maintains chainability
207
+ return self;
208
+
209
+ };
@@ -0,0 +1,158 @@
1
+
2
+ // Mobile Module
3
+ // =============
4
+
5
+ // Set Mobile Text
6
+ // ---------------
7
+ // Updates the text of the drop down
8
+ selectBoxIt._updateMobileText = function() {
9
+
10
+ var self = this,
11
+ currentOption,
12
+ currentDataText,
13
+ currentText;
14
+
15
+ currentOption = self.selectBox.find("option").filter(":selected");
16
+
17
+ currentDataText = currentOption.attr("data-text");
18
+
19
+ currentText = currentDataText ? currentDataText: currentOption.text();
20
+
21
+ // Sets the new dropdown list text to the value of the original dropdown list
22
+ self._setText(self.dropdownText, currentText);
23
+
24
+ if(self.list.find('li[data-val="' + currentOption.val() + '"]').find("i").attr("class")) {
25
+
26
+ self.dropdownImage.attr("class", self.list.find('li[data-val="' + currentOption.val() + '"]').find("i").attr("class")).addClass("selectboxit-default-icon");
27
+
28
+ }
29
+
30
+ };
31
+
32
+ // Apply Native Select
33
+ // -------------------
34
+ // Applies the original select box directly over the new drop down
35
+
36
+ selectBoxIt._applyNativeSelect = function() {
37
+
38
+ // Stores the plugin context inside of the self variable
39
+ var self = this;
40
+
41
+ // Appends the native select box to the drop down (allows for relative positioning using the position() method)
42
+ self.dropdownContainer.append(self.selectBox);
43
+
44
+ self.dropdown.attr("tabindex", "-1");
45
+
46
+ // Positions the original select box directly over top the new dropdown list using position absolute and "hides" the original select box using an opacity of 0. This allows the mobile browser "wheel" interface for better usability.
47
+ self.selectBox.css({
48
+
49
+ "display": "block",
50
+
51
+ "visibility": "visible",
52
+
53
+ "width": self._realOuterWidth(self.dropdown),
54
+
55
+ "height": self.dropdown.outerHeight(),
56
+
57
+ "opacity": "0",
58
+
59
+ "position": "absolute",
60
+
61
+ "top": "0",
62
+
63
+ "left": "0",
64
+
65
+ "cursor": "pointer",
66
+
67
+ "z-index": "999999",
68
+
69
+ "margin": self.dropdown.css("margin"),
70
+
71
+ "padding": "0",
72
+
73
+ "-webkit-appearance": "menulist-button"
74
+
75
+ });
76
+
77
+ if(self.originalElem.disabled) {
78
+
79
+ self.triggerEvent("disable");
80
+
81
+ }
82
+
83
+ return this;
84
+
85
+ };
86
+
87
+ // Mobile Events
88
+ // -------------
89
+ // Listens to mobile-specific events
90
+ selectBoxIt._mobileEvents = function() {
91
+
92
+ var self = this;
93
+
94
+ self.selectBox.on({
95
+
96
+ "changed.selectBoxIt": function() {
97
+
98
+ self.hasChanged = true;
99
+
100
+ self._updateMobileText();
101
+
102
+ // Triggers the `option-click` event on mobile
103
+ self.triggerEvent("option-click");
104
+
105
+ },
106
+
107
+ "mousedown.selectBoxIt": function() {
108
+
109
+ // If the select box has not been changed, the defaultText option is being used
110
+ if(!self.hasChanged && self.options.defaultText && !self.originalElem.disabled) {
111
+
112
+ self._updateMobileText();
113
+
114
+ self.triggerEvent("option-click");
115
+
116
+ }
117
+
118
+ },
119
+
120
+ "enable.selectBoxIt": function() {
121
+
122
+ // Moves SelectBoxIt onto the page
123
+ self.selectBox.removeClass('selectboxit-rendering');
124
+
125
+ },
126
+
127
+ "disable.selectBoxIt": function() {
128
+
129
+ // Moves SelectBoxIt off the page
130
+ self.selectBox.addClass('selectboxit-rendering');
131
+
132
+ }
133
+
134
+ });
135
+
136
+ };
137
+
138
+ // Mobile
139
+ // ------
140
+ // Applies the native "wheel" interface when a mobile user is interacting with the dropdown
141
+
142
+ selectBoxIt._mobile = function(callback) {
143
+
144
+ // Stores the plugin context inside of the self variable
145
+ var self = this;
146
+
147
+ if(self.isMobile) {
148
+
149
+ self._applyNativeSelect();
150
+
151
+ self._mobileEvents();
152
+
153
+ }
154
+
155
+ // Maintains chainability
156
+ return this;
157
+
158
+ };
@@ -0,0 +1,90 @@
1
+
2
+ // Remove Options Module
3
+ // =====================
4
+
5
+ // remove
6
+ // ------
7
+ // Removes drop down list options
8
+ // using an index
9
+
10
+ selectBoxIt.remove = function(indexes, callback) {
11
+
12
+ var self = this,
13
+ dataType = $.type(indexes),
14
+ value,
15
+ x = 0,
16
+ dataLength,
17
+ elems = "";
18
+
19
+ // If an array is passed in
20
+ if(dataType === "array") {
21
+
22
+ // Loops through the array
23
+ for(dataLength = indexes.length; x <= dataLength - 1; x += 1) {
24
+
25
+ // Stores the currently traversed array item in the local `value` variable
26
+ value = indexes[x];
27
+
28
+ // If the currently traversed array item is an object literal
29
+ if($.type(value) === "number") {
30
+
31
+ if(elems.length) {
32
+
33
+ // Adds an element to the removal string
34
+ elems += ", option:eq(" + value + ")";
35
+
36
+ }
37
+
38
+ else {
39
+
40
+ // Adds an element to the removal string
41
+ elems += "option:eq(" + value + ")";
42
+
43
+ }
44
+
45
+ }
46
+
47
+ }
48
+
49
+ // Removes all of the appropriate options from the select box
50
+ self.selectBox.find(elems).remove();
51
+
52
+ }
53
+
54
+ // If a number is passed in
55
+ else if(dataType === "number") {
56
+
57
+ self.selectBox.find("option").eq(indexes).remove();
58
+
59
+ }
60
+
61
+ // If anything besides a number or array is passed in
62
+ else {
63
+
64
+ // Removes all of the options from the original select box
65
+ self.selectBox.find("option").remove();
66
+
67
+ }
68
+
69
+ // If the dropdown property exists
70
+ if(self.dropdown) {
71
+
72
+ // Rebuilds the dropdown
73
+ self.refresh(function() {
74
+
75
+ // Provide callback function support
76
+ self._callbackSupport(callback);
77
+
78
+ }, true);
79
+
80
+ } else {
81
+
82
+ // Provide callback function support
83
+ self._callbackSupport(callback);
84
+
85
+ }
86
+
87
+ // Maintains chainability
88
+ return self;
89
+
90
+ };