romo 0.19.10 → 0.20.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,25 +1,19 @@
1
- $.fn.romoOptionListDropdown = function() {
2
- return $.map(this, function(element) {
3
- return new RomoOptionListDropdown(element);
4
- });
5
- }
6
-
7
- var RomoOptionListDropdown = function(element) {
8
- this.elem = $(element);
1
+ var RomoOptionListDropdown = RomoComponent(function(elem) {
2
+ this.elem = elem;
9
3
 
10
4
  this.prevValue = '';
11
5
  this.optionListItems = [];
12
6
 
13
- var selCustomization = this.elem.data('romo-option-list-dropdown-item-selector-customization') || '';
7
+ var selCustomization = Romo.data(this.elem, 'romo-option-list-dropdown-item-selector-customization') || '';
14
8
  this.itemSelector = 'LI[data-romo-option-list-dropdown-item="opt"]:not(.disabled)'+selCustomization;
15
- this.focusStyleClass = this.elem.data('romo-option-list-focus-style-class');
16
- this.openOnFocus = this.elem.data('romo-option-list-dropdown-open-on-focus');
9
+ this.focusStyleClass = Romo.data(this.elem, 'romo-option-list-focus-style-class');
10
+ this.openOnFocus = Romo.data(this.elem, 'romo-option-list-dropdown-open-on-focus');
17
11
 
18
12
  this.doInit();
19
13
  this._bindElem();
20
14
 
21
- this.elem.trigger('romoOptionListDropdown:ready', [this]);
22
- }
15
+ Romo.trigger(this.elem, 'romoOptionListDropdown:ready', [this]);
16
+ });
23
17
 
24
18
  RomoOptionListDropdown.prototype.bodyElem = function() {
25
19
  return this.romoDropdown.bodyElem;
@@ -38,51 +32,46 @@ RomoOptionListDropdown.prototype.popupClosed = function() {
38
32
  }
39
33
 
40
34
  RomoOptionListDropdown.prototype.selectedItemElem = function() {
41
- return this.romoDropdown.bodyElem.find('LI.selected');
35
+ return Romo.find(this.romoDropdown.bodyElem, 'LI.selected')[0];
42
36
  }
43
37
 
44
38
  RomoOptionListDropdown.prototype.selectedItemValue = function() {
45
- // need to use `attr` so it will always read from the DOM
46
- // using `data` works the first time but does some elem caching or something
47
- // so it won't work subsequent times.
48
- return this.elem.attr('data-romo-option-list-dropdown-selected-value');
39
+ return Romo.data(this.elem, 'romo-option-list-dropdown-selected-value');
49
40
  }
50
41
 
51
42
  RomoOptionListDropdown.prototype.selectedItemText = function() {
52
- // need to use `attr` so it will always read from the DOM
53
- // using `data` works the first time but does some elem caching or something
54
- // so it won't work subsequent times.
55
- return this.elem.attr('data-romo-option-list-dropdown-selected-text');
43
+ return Romo.data(this.elem, 'romo-option-list-dropdown-selected-text');
56
44
  }
57
45
 
58
46
  RomoOptionListDropdown.prototype.optionFilterValue = function() {
59
- return this.optionFilterElem.val();
47
+ return this.optionFilterElem.value;
60
48
  }
61
49
 
62
50
  RomoOptionListDropdown.prototype.optItemElems = function() {
63
- return this.romoDropdown.bodyElem.find('LI[data-romo-option-list-dropdown-item="opt"]');
51
+ return Romo.find(this.romoDropdown.bodyElem, 'LI[data-romo-option-list-dropdown-item="opt"]');
64
52
  }
65
53
 
66
54
  RomoOptionListDropdown.prototype.optgroupItemElems = function() {
67
- return this.romoDropdown.bodyElem.find('LI[data-romo-option-list-dropdown-item="optgroup"]');
68
- }
69
-
70
- RomoOptionListDropdown.prototype.doInit = function() {
71
- // override as needed
55
+ return Romo.find(this.romoDropdown.bodyElem, 'LI[data-romo-option-list-dropdown-item="optgroup"]');
72
56
  }
73
57
 
74
58
  RomoOptionListDropdown.prototype.doSetSelectedItem = function(itemValue) {
75
- this.selectedItemElem().removeClass('selected');
59
+ var oldSelectedElem = this.selectedItemElem();
60
+ if (oldSelectedElem !== undefined) {
61
+ Romo.removeClass(oldSelectedElem, 'selected');
62
+ }
76
63
  if (itemValue !== undefined) {
77
- this.romoDropdown.bodyElem.find(
64
+ var itemElem = Romo.find(
65
+ this.romoDropdown.bodyElem,
78
66
  'LI[data-romo-option-list-dropdown-option-value="'+itemValue+'"]'
79
- ).addClass('selected');
67
+ )[0];
68
+ Romo.addClass(itemElem, 'selected');
80
69
  }
81
70
  var selectedElem = this.selectedItemElem();
82
- if (selectedElem[0] !== undefined) {
71
+ if (selectedElem !== undefined) {
83
72
  this.doSetSelectedValueAndText(
84
- this.selectedItemElem().data('romo-option-list-dropdown-option-value'),
85
- this.selectedItemElem().data('romo-option-list-dropdown-option-display-text')
73
+ Romo.data(selectedElem, 'romo-option-list-dropdown-option-value'),
74
+ Romo.data(selectedElem, 'romo-option-list-dropdown-option-display-text')
86
75
  );
87
76
  } else {
88
77
  this.doSetSelectedValueAndText('', '');
@@ -90,10 +79,8 @@ RomoOptionListDropdown.prototype.doSetSelectedItem = function(itemValue) {
90
79
  }
91
80
 
92
81
  RomoOptionListDropdown.prototype.doSetSelectedValueAndText = function(value, text) {
93
- // need to use `attr` to persist selected values to the DOM for back button logic
94
- // to work. using `data` won't persist changes to DOM and breaks back button logic.
95
- this.elem.attr('data-romo-option-list-dropdown-selected-value', value);
96
- this.elem.attr('data-romo-option-list-dropdown-selected-text', text);
82
+ Romo.setData(this.elem, 'romo-option-list-dropdown-selected-value', value);
83
+ Romo.setData(this.elem, 'romo-option-list-dropdown-selected-text', text);
97
84
 
98
85
  this.prevValue = value;
99
86
  }
@@ -133,89 +120,93 @@ Example:
133
120
 
134
121
  RomoOptionListDropdown.prototype.doSetListItems = function(itemsList) {
135
122
  this.optionListItems = itemsList;
136
- this.optionListContainer.html(this._buildListElem(itemsList));
123
+ Romo.update(this.optionListContainerElem, this._buildListElem(itemsList));
137
124
 
138
125
  this._updateOptionsListUI();
139
126
 
140
- this.optionListContainer.find(this.itemSelector).on('mouseenter', $.proxy(this._onItemEnter, this));
141
- this.optionListContainer.find(this.itemSelector).on('click', $.proxy(this._onItemClick, this));
127
+ var itemElems = Romo.find(this.optionListContainerElem, this.itemSelector);
128
+ Romo.on(itemElems, 'mouseenter', Romo.proxy(this._onItemEnter, this));
129
+ Romo.on(itemElems, 'click', Romo.proxy(this._onItemClick, this));
142
130
  }
143
131
 
144
132
  /* private */
145
133
 
146
134
  RomoOptionListDropdown.prototype._bindElem = function() {
147
- this.elem.on('keydown', $.proxy(this._onElemKeyDown, this));
148
- this.elem.on('dropdown:popupOpen', $.proxy(this._onPopupOpen, this));
149
- this.elem.on('dropdown:popupClose', $.proxy(this._onPopupClose, this));
135
+ Romo.on(this.elem, 'keydown', Romo.proxy(this._onElemKeyDown, this));
136
+ Romo.on(this.elem, 'romoDropdown:popupOpen', Romo.proxy(this._onPopupOpen, this));
137
+ Romo.on(this.elem, 'romoDropdown:popupClose', Romo.proxy(this._onPopupClose, this));
150
138
 
151
- this.elem.on('dropdown:toggle', $.proxy(function(e, dropdown) {
152
- this.elem.trigger('romoOptionListDropdown:dropdown:toggle', [dropdown, this]);
139
+ Romo.on(this.elem, 'romoDropdown:toggle', Romo.proxy(function(e, romoDropdown) {
140
+ Romo.trigger(this.elem, 'romoOptionListDropdown:romoDropdown:toggle', [romoDropdown, this]);
153
141
  }, this));
154
- this.elem.on('dropdown:popupOpen', $.proxy(function(e, dropdown) {
155
- this.elem.trigger('romoOptionListDropdown:dropdown:popupOpen', [dropdown, this]);
142
+ Romo.on(this.elem, 'romoDropdown:popupOpen', Romo.proxy(function(e, romoDropdown) {
143
+ Romo.trigger(this.elem, 'romoOptionListDropdown:romoDropdown:popupOpen', [romoDropdown, this]);
156
144
  }, this));
157
- this.elem.on('dropdown:popupClose', $.proxy(function(e, dropdown) {
158
- this.elem.trigger('romoOptionListDropdown:dropdown:popupClose', [dropdown, this]);
145
+ Romo.on(this.elem, 'romoDropdown:popupClose', Romo.proxy(function(e, romoDropdown) {
146
+ Romo.trigger(this.elem, 'romoOptionListDropdown:romoDropdown:popupClose', [romoDropdown, this]);
159
147
  }, this));
160
148
 
161
- this.elem.on('romoOptionListDropdown:triggerListOptionsUpdate', $.proxy(function(e, highlightOptionElem) {
149
+ Romo.on(this.elem, 'romoOptionListDropdown:triggerListOptionsUpdate', Romo.proxy(function(e, highlightOptionElem) {
162
150
  this._updateOptionsListUI(highlightOptionElem);
163
151
  }, this));
164
152
 
165
- this.elem.on('romoOptionListDropdown:triggerToggle', $.proxy(function(e) {
166
- this.elem.trigger('dropdown:triggerToggle', []);
153
+ Romo.on(this.elem, 'romoOptionListDropdown:triggerToggle', Romo.proxy(function(e) {
154
+ Romo.trigger(this.elem, 'romoDropdown:triggerToggle', []);
167
155
  }, this));
168
- this.elem.on('romoOptionListDropdown:triggerPopupOpen', $.proxy(function(e) {
169
- this.elem.trigger('dropdown:triggerPopupOpen', []);
156
+ Romo.on(this.elem, 'romoOptionListDropdown:triggerPopupOpen', Romo.proxy(function(e) {
157
+ Romo.trigger(this.elem, 'romoDropdown:triggerPopupOpen', []);
170
158
  }, this));
171
- this.elem.on('romoOptionListDropdown:triggerPopupClose', $.proxy(function(e) {
172
- this.elem.trigger('dropdown:triggerPopupClose', []);
159
+ Romo.on(this.elem, 'romoOptionListDropdown:triggerPopupClose', Romo.proxy(function(e) {
160
+ Romo.trigger(this.elem, 'romoDropdown:triggerPopupClose', []);
173
161
  }, this));
174
162
 
175
- this.elem.on('romoOptionListDropdown:triggerFilterIndicatorStart', $.proxy(function(e) {
176
- this.optionFilterElem.trigger(
177
- 'indicatorTextInput:triggerIndicatorStart',
178
- [Romo.getComputedStyle(this.optionFilterElem[0], "height")]
163
+ Romo.on(this.elem, 'romoOptionListDropdown:triggerFilterSpinnerStart', Romo.proxy(function(e) {
164
+ Romo.trigger(
165
+ this.optionFilterElem,
166
+ 'romoIndicatorTextInput:triggerSpinnerStart',
167
+ [Romo.css(this.optionFilterElem, "height")]
179
168
  );
180
169
  }, this));
181
- this.elem.on('romoOptionListDropdown:triggerFilterIndicatorStop', $.proxy(function(e) {
182
- this.optionFilterElem.trigger('indicatorTextInput:triggerIndicatorStop', []);
170
+ Romo.on(this.elem, 'romoOptionListDropdown:triggerFilterSpinnerStop', Romo.proxy(function(e) {
171
+ Romo.trigger(this.optionFilterElem, 'romoIndicatorTextInput:triggerSpinnerStop', []);
183
172
  }, this));
184
173
 
185
- this.romoDropdown = this.elem.romoDropdown()[0];
174
+ this.romoDropdown = new RomoDropdown(this.elem);
186
175
  this.romoDropdown.doSetPopupZIndex(this.elem);
187
176
 
188
- this.romoDropdown.popupElem.on('keydown', $.proxy(this._onElemKeyDown, this));
189
- this.romoDropdown.popupElem.on('mousedown', $.proxy(this._onPopupMouseDown, this));
190
- this.romoDropdown.popupElem.on('mouseup', $.proxy(this._onPopupMouseUp, this));
177
+ Romo.on(this.romoDropdown.popupElem, 'keydown', Romo.proxy(this._onElemKeyDown, this));
178
+ Romo.on(this.romoDropdown.popupElem, 'mousedown', Romo.proxy(this._onPopupMouseDown, this));
179
+ Romo.on(this.romoDropdown.popupElem, 'mouseup', Romo.proxy(this._onPopupMouseUp, this));
191
180
 
192
- this.romoDropdown.bodyElem.addClass('romo-input-option-list');
193
- this.romoDropdown.bodyElem.html('');
181
+ Romo.addClass(this.romoDropdown.bodyElem, 'romo-input-option-list');
182
+ Romo.updateHtml(this.romoDropdown.bodyElem, '');
194
183
 
195
- if (this.elem.data('romo-option-list-dropdown-no-filter') !== true) {
184
+ if (Romo.data(this.elem, 'romo-option-list-dropdown-no-filter') !== true) {
196
185
  this.optionFilterElem = this._buildOptionFilter();
197
- var optionFilterWrapperElem = $('<div class="romo-option-list-dropdown-filter-wrapper"></div>');
186
+ var optionFilterWrapperElem = Romo.elems('<div class="romo-option-list-dropdown-filter-wrapper"></div>')[0];
198
187
  optionFilterWrapperElem.append(this.optionFilterElem);
199
- this.romoDropdown.popupElem.prepend(optionFilterWrapperElem);
188
+ Romo.prepend(this.romoDropdown.popupElem, optionFilterWrapperElem);
200
189
  this._bindDropdownOptionFilter();
201
190
  }
202
191
 
203
- this.romoDropdown.bodyElem.append($('<div class="romo-option-list-dropdown-container"></div>'));
204
- this.optionListContainer = this.romoDropdown.bodyElem.find('.romo-option-list-dropdown-container');
192
+ this.romoDropdown.bodyElem.append(Romo.elems('<div class="romo-option-list-dropdown-container"></div>')[0]);
193
+ this.optionListContainerElem = Romo.find(this.romoDropdown.bodyElem, '.romo-option-list-dropdown-container')[0];
205
194
 
206
195
  this.doSetListItems([]);
207
196
  }
208
197
 
209
198
  RomoOptionListDropdown.prototype._buildListElem = function(itemsList, listClass) {
210
- var listElem = $('<ul></ul>');
199
+ var listElem = Romo.elems('<ul></ul>')[0];
211
200
 
212
- listElem.addClass(listClass);
213
- $.each(itemsList, $.proxy(function(idx, item) {
201
+ if (listClass !== undefined) {
202
+ Romo.addClass(listElem, listClass);
203
+ }
204
+ itemsList.forEach(Romo.proxy(function(item) {
214
205
  if (item.type === 'option') {
215
- listElem.append(this._buildListOptionElem(item));
206
+ Romo.append(listElem, this._buildListOptionElem(item));
216
207
  } else if (item.type === 'optgroup') {
217
- listElem.append(this._buildListOptGroupElem(item));
218
- listElem.append(this._buildListElem(item.items, 'romo-option-list-optgroup'));
208
+ Romo.append(listElem, this._buildListOptGroupElem(item));
209
+ Romo.append(listElem, this._buildListElem(item.items, 'romo-option-list-optgroup'));
219
210
  }
220
211
  }, this));
221
212
 
@@ -223,143 +214,146 @@ RomoOptionListDropdown.prototype._buildListElem = function(itemsList, listClass)
223
214
  }
224
215
 
225
216
  RomoOptionListDropdown.prototype._buildListOptionElem = function(item) {
226
- var itemElem = $('<li data-romo-option-list-dropdown-item="opt"></li>');
217
+ var itemElem = Romo.elems('<li data-romo-option-list-dropdown-item="opt"></li>')[0];
227
218
  var value = item.value || '';
228
219
  var displayText = item.displayText || '';
229
- var displayHtml = item.displayHtml || item.displayText || '&nbsp;'
220
+ var displayHtml = item.displayHtml || item.displayText || '<span>&nbsp;</span>'
221
+
222
+ Romo.setData(itemElem, 'romo-option-list-dropdown-option-value', value);
223
+ Romo.setData(itemElem, 'romo-option-list-dropdown-option-display-text', displayText);
230
224
 
231
- itemElem.attr('data-romo-option-list-dropdown-option-value', value);
232
- itemElem.attr('data-romo-option-list-dropdown-option-display-text', displayText);
233
- itemElem.html(displayHtml);
225
+ var displayElems = Romo.elems(displayHtml);
226
+ if (displayElems.length !== 0) {
227
+ Romo.update(itemElem, displayElems);
228
+ } else {
229
+ Romo.updateText(itemElem, displayHtml);
230
+ }
234
231
 
235
232
  if (item.selected === true) {
236
- itemElem.addClass('selected');
233
+ Romo.addClass(itemElem, 'selected');
237
234
  this.prevValue = value; // the last option marked selected is used
238
235
  }
239
236
  if (item.disabled === true) {
240
- itemElem.addClass('disabled');
237
+ Romo.addClass(itemElem, 'disabled');
241
238
  }
242
239
 
243
240
  return itemElem;
244
241
  }
245
242
 
246
243
  RomoOptionListDropdown.prototype._buildListOptGroupElem = function(item) {
247
- var itemElem = $('<li data-romo-option-list-dropdown-item="optgroup"></li>');
248
-
249
- itemElem.text(item.label);
244
+ var itemElem = Romo.elems('<li data-romo-option-list-dropdown-item="optgroup"></li>')[0];
245
+ Romo.updateText(itemElem, item.label);
250
246
 
251
247
  return itemElem;
252
248
  }
253
249
 
254
250
  RomoOptionListDropdown.prototype._buildOptionFilter = function() {
255
- var filter = $('<input type="text" size="1" class="romo-option-list-dropdown-filter"></input>');
251
+ var filterElem = Romo.elems('<input type="text" size="1" class="romo-option-list-dropdown-filter"></input>')[0];
256
252
 
257
- if (this.elem.data('romo-option-list-dropdown-filter-placeholder') !== undefined) {
258
- filter.attr('placeholder', this.elem.data('romo-option-list-dropdown-filter-placeholder'));
253
+ if (Romo.data(this.elem, 'romo-option-list-dropdown-filter-placeholder') !== undefined) {
254
+ Romo.setAttr(filterElem, 'placeholder', Romo.data(this.elem, 'romo-option-list-dropdown-filter-placeholder'));
259
255
  }
260
- filter.attr('data-romo-indicator-text-input-elem-display', "block");
261
- filter.attr('data-romo-indicator-text-input-indicator-position', "right");
262
- if (this.elem.data('romo-option-list-dropdown-filter-indicator') !== undefined) {
263
- filter.attr('data-romo-indicator-text-input-indicator', this.elem.data('romo-option-list-dropdown-filter-indicator'));
256
+ Romo.setData(filterElem, 'romo-indicator-text-input-elem-display', "block");
257
+ Romo.setData(filterElem, 'romo-indicator-text-input-indicator-position', "right");
258
+ if (Romo.data(this.elem, 'romo-option-list-dropdown-filter-indicator') !== undefined) {
259
+ Romo.setData(filterElem, 'romo-indicator-text-input-indicator', Romo.data(this.elem, 'romo-option-list-dropdown-filter-indicator'));
264
260
  }
265
- if (this.elem.data('romo-option-list-dropdown-filter-indicator-width-px') !== undefined) {
266
- filter.attr('data-romo-indicator-text-input-indicator-width-px', this.elem.data('romo-option-list-dropdown-filter-indicator-width-px'));
261
+ if (Romo.data(this.elem, 'romo-option-list-dropdown-filter-indicator-width-px') !== undefined) {
262
+ Romo.setData(filterElem, 'romo-indicator-text-input-indicator-width-px', Romo.data(this.elem, 'romo-option-list-dropdown-filter-indicator-width-px'));
267
263
  }
268
- filter.attr('data-romo-form-disable-enter-submit', "true");
269
- filter.attr('data-romo-onkey-on', "keydown");
264
+ Romo.setData(filterElem, 'romo-form-disable-enter-submit', "true");
265
+ Romo.setData(filterElem, 'romo-onkey-on', "keydown");
266
+ Romo.setData(filterElem, 'romo-onkey-delay-ms', 100); // 0.1 secs, want it to be really responsive
270
267
 
271
- filter.attr('autocomplete', 'off');
268
+ Romo.setAttr(filterElem, 'autocomplete', 'off');
272
269
 
273
- return filter;
270
+ return filterElem;
274
271
  }
275
272
 
276
273
  RomoOptionListDropdown.prototype._bindDropdownOptionFilter = function() {
277
- this.optionFilterElem.romoIndicatorTextInput();
278
- this.optionFilterElem.romoOnkey();
274
+ this.romoIndicatorTextInput = new RomoIndicatorTextInput(this.optionFilterElem);
275
+ new RomoOnkey(this.optionFilterElem);
279
276
 
280
- this.romoDropdown.elem.on('focus', $.proxy(function(e) {
277
+ Romo.on(this.romoDropdown.elem, 'mousedown', Romo.proxy(function(e) {
278
+ // don't open on focus because this focus is from a click
279
+ // so the click will handle opening the popup
280
+ this.openOnFocus = false;
281
+ }, this));
282
+
283
+ Romo.on(this.romoDropdown.elem, 'focus', Romo.proxy(function(e) {
281
284
  if (this.blurTimeoutId !== undefined) {
282
285
  clearTimeout(this.blurTimeoutId);
283
286
  }
284
287
  // remove any manual elem focus when elem is actually focused
285
288
  this.optionFilterFocused = false;
286
- this.romoDropdown.elem.removeClass(this.focusStyleClass);
289
+ Romo.removeClass(this.romoDropdown.elem, this.focusStyleClass);
287
290
 
288
291
  if (this.openOnFocus === true) {
289
- this.romoDropdown.elem.trigger('dropdown:triggerPopupOpen', []);
292
+ Romo.trigger(this.romoDropdown.elem, 'romoDropdown:triggerPopupOpen', []);
290
293
  } else {
291
- this.openOnFocus = this.elem.data('romo-option-list-dropdown-open-on-focus');
294
+ this.openOnFocus = Romo.data(this.elem, 'romo-option-list-dropdown-open-on-focus');
292
295
  }
293
296
  }, this));
294
- this.romoDropdown.elem.on('blur', $.proxy(function(e) {
297
+ Romo.on(this.romoDropdown.elem, 'blur', Romo.proxy(function(e) {
295
298
  if (this.blurTimeoutId !== undefined) {
296
299
  clearTimeout(this.blurTimeoutId);
297
300
  }
298
301
  // close the dropdown when elem is blurred
299
302
  // remove any manual focus as well
300
- this.romoDropdown.elem.removeClass(this.focusStyleClass);
301
- this.blurTimeoutId = setTimeout($.proxy(function() {
303
+ Romo.removeClass(this.romoDropdown.elem, this.focusStyleClass);
304
+ this.blurTimeoutId = setTimeout(Romo.proxy(function() {
302
305
  if (this.popupMouseDown !== true && this.optionFilterFocused !== true) {
303
- this.romoDropdown.elem.trigger('dropdown:triggerPopupClose', []);
306
+ Romo.trigger(this.romoDropdown.elem, 'romoDropdown:triggerPopupClose', []);
304
307
  }
305
308
  }, this), 10);
306
309
  }, this));
307
- this.optionFilterElem.on('focus', $.proxy(function(e) {
310
+ Romo.on(this.optionFilterElem, 'focus', Romo.proxy(function(e) {
308
311
  if (this.blurTimeoutId !== undefined) {
309
312
  clearTimeout(this.blurTimeoutId);
310
313
  }
311
314
  // manually make the elem focused when its filter is focused
312
315
  this.optionFilterFocused = true;
313
- this.romoDropdown.elem.addClass(this.focusStyleClass);
316
+ Romo.addClass(this.romoDropdown.elem, this.focusStyleClass);
314
317
  }, this));
315
- this.optionFilterElem.on('blur', $.proxy(function(e) {
318
+ Romo.on(this.optionFilterElem, 'blur', Romo.proxy(function(e) {
316
319
  // remove any manual elem focus when its filter is blurred
317
320
  this.optionFilterFocused = false;
318
- this.romoDropdown.elem.removeClass(this.focusStyleClass);
321
+ Romo.removeClass(this.romoDropdown.elem, this.focusStyleClass);
319
322
  }, this));
320
323
 
321
- this.romoDropdown.elem.on('dropdown:popupOpen', $.proxy(function(e, dropdown) {
322
- this.optionFilterElem.trigger('indicatorTextInput:triggerPlaceIndicator');
324
+ Romo.on(this.romoDropdown.elem, 'romoDropdown:popupOpen', Romo.proxy(function(e, romoDropdown) {
325
+ Romo.trigger(this.optionFilterElem, 'romoIndicatorTextInput:triggerPlaceIndicator');
323
326
  this.optionFilterElem.focus();
324
327
  this._filterOptionElems();
325
328
  this.openOnFocus = false;
326
329
  }, this));
327
- this.romoDropdown.elem.on('dropdown:popupClose', $.proxy(function(e, dropdown) {
328
- this.optionFilterElem.val('');
330
+ Romo.on(this.romoDropdown.elem, 'romoDropdown:popupClose', Romo.proxy(function(e, romoDropdown) {
331
+ this.optionFilterElem.value = '';
329
332
  /*
330
333
  don't call `_filterOptionElems()` here. we need to keep the option markup as is
331
334
  until the popup is opened again so selecting an option works. selecting an option
332
335
  depends on the selected item elem method which requires the markup to be in place
333
336
  */
334
337
  }, this));
335
- this.romoDropdown.elem.on('dropdown:popupClosedByEsc', $.proxy(function(e, dropdown) {
338
+ Romo.on(this.romoDropdown.elem, 'romoDropdown:popupClosedByEsc', Romo.proxy(function(e, romoDropdown) {
336
339
  this.romoDropdown.elem.focus();
337
340
  }, this));
338
- this.optionFilterElem.on('click', $.proxy(function(e) {
339
- if (e !== undefined) {
340
- e.stopPropagation();
341
- }
341
+ Romo.on(this.optionFilterElem, 'click', Romo.proxy(function(e) {
342
+ e.stopPropagation();
342
343
  }, this));
343
- this.romoDropdown.popupElem.on('click', $.proxy(function(e) {
344
+ Romo.on(this.romoDropdown.popupElem, 'click', Romo.proxy(function(e) {
344
345
  this.optionFilterElem.focus();
345
346
  }, this));
346
347
 
347
- this.onkeySearchTimeout = undefined;
348
- this.onkeySearchDelay = 100; // 0.1 secs, want it to be really responsive
349
-
350
- this.optionFilterElem.on('onkey:trigger', $.proxy(function(e, triggerEvent, onkey) {
351
- // TODO: incorp this timeout logic into the onkey component so don't have to repeat it
352
- clearTimeout(this.onkeySearchTimeout);
353
- this.onkeySearchTimeout = setTimeout($.proxy(function() {
354
- if (Romo.nonInputTextKeyCodes().indexOf(triggerEvent.keyCode) === -1 /* Input Text */) {
355
- this._filterOptionElems();
356
- }
357
- }, this), this.onkeySearchDelay);
348
+ Romo.on(this.optionFilterElem, 'romoOnkey:trigger', Romo.proxy(function(e, triggerEvent, romoOnkey) {
349
+ if (Romo.nonInputTextKeyCodes().indexOf(triggerEvent.keyCode) === -1 /* Input Text */) {
350
+ this._filterOptionElems();
351
+ }
358
352
  }, this));
359
353
  }
360
354
 
361
355
  RomoOptionListDropdown.prototype._filterOptionElems = function() {
362
- this.elem.trigger('romoOptionListDropdown:filterChange', [this.optionFilterElem.val(), this]);
356
+ Romo.trigger(this.elem, 'romoOptionListDropdown:filterChange', [this.optionFilterElem.value, this]);
363
357
  }
364
358
 
365
359
  RomoOptionListDropdown.prototype._updateOptionsListUI = function(highlightOptionElem) {
@@ -374,91 +368,223 @@ RomoOptionListDropdown.prototype._updateOptionsListUI = function(highlightOption
374
368
  }
375
369
 
376
370
  RomoOptionListDropdown.prototype._selectHighlightedItem = function() {
377
- var curr = this._getHighlightedItemElem();
378
- if (curr.length !== 0) {
371
+ var currElem = this._getHighlightedItemElem();
372
+ if (currElem !== undefined) {
379
373
  var prevValue = this.prevValue;
380
- var newValue = curr.data('romo-option-list-dropdown-option-value');
381
- var newText = curr.data('romo-option-list-dropdown-option-display-text');
374
+ var newValue = Romo.data(currElem, 'romo-option-list-dropdown-option-value');
375
+ var newText = Romo.data(currElem, 'romo-option-list-dropdown-option-display-text');
382
376
 
383
377
  this.romoDropdown.doPopupClose();
384
378
 
385
- this.elem.trigger('romoOptionListDropdown:itemSelected', [newValue, newText, this]);
379
+ Romo.trigger(this.elem, 'romoOptionListDropdown:itemSelected', [newValue, newText, this]);
386
380
  if (newValue !== prevValue) {
387
381
  this.doSetSelectedItem(newValue);
382
+ Romo.trigger(this.elem, 'romoOptionListDropdown:newItemSelected', [newValue, newText, this]);
388
383
  // always publish the item selected events before publishing any change events
389
- this.elem.trigger('romoOptionListDropdown:newItemSelected', [newValue, newText, this]);
390
- this.elem.trigger('romoOptionListDropdown:change', [newValue, prevValue, this]);
384
+ Romo.trigger(this.elem, 'romoOptionListDropdown:change', [newValue, prevValue, this]);
391
385
  }
392
386
  }
393
387
  }
394
388
 
395
- RomoOptionListDropdown.prototype._onPopupOpen = function(e) {
396
- if (this.elem.hasClass('disabled') === false) {
389
+ RomoOptionListDropdown.prototype._scrollTopToItem = function(itemElem) {
390
+ if (itemElem !== undefined) {
391
+ var scrollElem = this.romoDropdown.bodyElem;
392
+ scrollElem.scrollTop = 0;
393
+
394
+ var scrollOffsetTop = Romo.offset(scrollElem).top;
395
+ var selOffsetTop = Romo.offset(itemElem).top;
396
+ var selOffset = parseInt(Romo.css(itemElem, 'height'), 10) / 2;
397
+
398
+ scrollElem.scrollTop = selOffsetTop - scrollOffsetTop - selOffset;
399
+ }
400
+ }
401
+
402
+ RomoOptionListDropdown.prototype._scrollBottomToItem = function(itemElem) {
403
+ if (itemElem !== undefined) {
404
+ var scrollElem = this.romoDropdown.bodyElem;
405
+ scrollElem.scrollTop = 0;
406
+
407
+ var scrollOffsetTop = Romo.offset(scrollElem).top;
408
+ var selOffsetTop = Romo.offset(itemElem).top;
409
+ var selOffset = scrollElem.offsetHeight - parseInt(Romo.css(itemElem, 'height'), 10);
410
+
411
+ scrollElem.scrollTop = selOffsetTop - scrollOffsetTop - selOffset;
412
+ }
413
+ }
414
+
415
+ RomoOptionListDropdown.prototype._nextListItem = function() {
416
+ var currElem = this._getHighlightedItemElem();
417
+ if (currElem === undefined) {
418
+ return Romo.find(this.optionListContainerElem, this.itemSelector)[0];
419
+ }
420
+
421
+ var nextElem = Romo.next(currElem, this.itemSelector+', UL.romo-option-list-optgroup');
422
+ if (nextElem == undefined) {
423
+ // currElem is either the last ungrouped opt elem in the overall
424
+ // list OR is the last opt elem in a grouped list.
425
+
426
+ // if the hightlighted opt elem is in an opt group list, use
427
+ // its list as the reference elem. otherwise keep using the
428
+ // hightlighted opt elem itself.
429
+ currElem = Romo.closest(currElem, 'UL.romo-option-list-optgroup') || currElem;
430
+ nextElem = Romo.next(currElem, this.itemSelector+', UL.romo-option-list-optgroup');
431
+ }
432
+ while (
433
+ nextElem !== undefined &&
434
+ Romo.hasClass(nextElem, 'romo-option-list-optgroup') &&
435
+ Romo.children(nextElem).length === 0
436
+ ) {
437
+ // keep trying until you find a opt group list with options or an option or nothing
438
+ currElem = nextElem;
439
+ nextElem = Romo.next(currElem, this.itemSelector+', UL.romo-option-list-optgroup');
440
+ }
441
+ if (nextElem === undefined) {
442
+ // currElem is the last opt elem (grouped or not) in the overall
443
+ // list. get the the first opt elem in the overall list
444
+ nextElem = Romo.find(this.romoDropdown.bodyElem, this.itemSelector)[0];
445
+ } else if (Romo.hasClass(nextElem, 'romo-option-list-optgroup')) {
446
+ // currElem (grouped or not) is before an opt group list. get
447
+ // the first opt elem in that list.
448
+ nextElem = Romo.find(nextElem, this.itemSelector)[0];
449
+ }
450
+ // otherwise currElem (grouped or not) is before an opt elem.
451
+ // use that opt elem.
452
+
453
+ return nextElem;
454
+ }
455
+
456
+ RomoOptionListDropdown.prototype._prevListItem = function() {
457
+ var currElem = this._getHighlightedItemElem();
458
+ if (currElem === undefined) {
459
+ var itemElems = Romo.find(this.optionListContainerElem, this.itemSelector);
460
+ return itemElems[itemElems.length - 1];
461
+ }
462
+
463
+ var prevElem = Romo.prev(currElem, this.itemSelector+', UL.romo-option-list-optgroup');
464
+ if (prevElem === undefined) {
465
+ // currElem is either the first ungrouped opt elem in the overall
466
+ // list OR is the first opt elem in a grouped list
467
+
468
+ // if the hightlighted opt elem is in an opt group list, use
469
+ // its list as the reference elem. otherwise keep using the
470
+ // hightlighted opt elem itself.
471
+ currElem = Romo.closest(currElem, 'UL.romo-option-list-optgroup') || currElem;
472
+ prevElem = Romo.prev(currElem, this.itemSelector+', UL.romo-option-list-optgroup');
473
+ }
474
+ while (
475
+ prevElem !== undefined &&
476
+ Romo.hasClass(prevElem, 'romo-option-list-optgroup') &&
477
+ Romo.children(prevElem).length === 0
478
+ ) {
479
+ // keep trying until you find a opt group list with options or an option or nothing
480
+ currElem = prevElem;
481
+ prevElem = Romo.prev(currElem, this.itemSelector+', UL.romo-option-list-optgroup');
482
+ }
483
+ if (prevElem === undefined) {
484
+ // currElem is the first opt elem (grouped or not) in the overall
485
+ // list. get the the last opt elem in the overall list
486
+ var itemElems = Romo.find(this.romoDropdown.bodyElem, this.itemSelector);
487
+ prevElem = itemElems[itemElems.length - 1];
488
+ } else if (Romo.hasClass(prevElem, 'romo-option-list-optgroup')) {
489
+ // currElem (grouped or not) is after an opt group list. get
490
+ // the last opt elem in that list.
491
+ var childItemElems = Romo.find(prevElem, this.itemSelector);
492
+ prevElem = childItemElems[childItemElems.length - 1];
493
+ }
494
+ // otherwise currElem (grouped or not) is after an opt elem.
495
+ // use that opt elem.
496
+
497
+ return prevElem;
498
+ }
499
+
500
+ RomoOptionListDropdown.prototype._highlightItem = function(itemElem) {
501
+ var highlightedItemElem = this._getHighlightedItemElem()
502
+ if (highlightedItemElem !== undefined) {
503
+ Romo.removeClass(highlightedItemElem, 'romo-option-list-dropdown-highlight');
504
+ }
505
+ if (itemElem) {
506
+ Romo.addClass(itemElem, 'romo-option-list-dropdown-highlight');
507
+ }
508
+ }
509
+
510
+ RomoOptionListDropdown.prototype._getHighlightedItemElem = function() {
511
+ return Romo.find(this.romoDropdown.bodyElem, 'LI.romo-option-list-dropdown-highlight')[0];
512
+ }
513
+
514
+ // event functions
515
+
516
+ RomoOptionListDropdown.prototype.romoEvFn._onPopupOpen = function(e) {
517
+ if (Romo.hasClass(this.elem, 'disabled') === false) {
397
518
  this._highlightItem(this.selectedItemElem());
398
519
  this._scrollTopToItem(this.selectedItemElem());
399
520
  }
400
- $('body').on('keydown', $.proxy(this._onPopupOpenBodyKeyDown, this));
521
+ Romo.on(Romo.f('body')[0], 'keydown', Romo.proxy(this._onPopupOpenBodyKeyDown, this));
401
522
  }
402
523
 
403
- RomoOptionListDropdown.prototype._onPopupClose = function(e) {
404
- this._highlightItem($());
405
- $('body').off('keydown', $.proxy(this._onPopupOpenBodyKeyDown, this));
524
+ RomoOptionListDropdown.prototype.romoEvFn._onPopupClose = function(e) {
525
+ this._highlightItem(undefined);
526
+ Romo.off(Romo.f('body')[0], 'keydown', Romo.proxy(this._onPopupOpenBodyKeyDown, this));
406
527
  }
407
528
 
408
- RomoOptionListDropdown.prototype._onItemEnter = function(e) {
409
- if (e !== undefined) {
410
- e.preventDefault();
411
- e.stopPropagation();
412
- }
413
- this._highlightItem($(e.target));
529
+ RomoOptionListDropdown.prototype.romoEvFn._onItemEnter = function(e) {
530
+ this._highlightItem(e.target);
531
+ return false;
414
532
  }
415
533
 
416
- RomoOptionListDropdown.prototype._onItemClick = function(e) {
534
+ RomoOptionListDropdown.prototype.romoEvFn._onItemClick = function(e) {
417
535
  if (this.blurTimeoutId !== undefined) {
418
536
  clearTimeout(this.blurTimeoutId);
419
537
  this.blurTimeoutId = undefined;
420
538
  }
421
- if (e !== undefined) {
422
- e.preventDefault();
423
- e.stopPropagation();
424
- }
425
539
  this._selectHighlightedItem();
540
+ return false;
426
541
  }
427
542
 
428
- RomoOptionListDropdown.prototype._onPopupMouseDown = function(e) {
543
+ RomoOptionListDropdown.prototype.romoEvFn._onPopupMouseDown = function(e) {
429
544
  this.popupMouseDown = true;
545
+ return true;
430
546
  }
431
547
 
432
- RomoOptionListDropdown.prototype._onPopupMouseUp = function(e) {
548
+ RomoOptionListDropdown.prototype.romoEvFn._onPopupMouseUp = function(e) {
433
549
  this.popupMouseDown = false;
550
+ return true;
434
551
  }
435
552
 
436
- RomoOptionListDropdown.prototype._onPopupOpenBodyKeyDown = function(e) {
437
- if (e !== undefined) {
438
- e.stopPropagation();
439
- }
553
+ RomoOptionListDropdown.prototype.romoEvFn._onPopupOpenBodyKeyDown = function(e) {
554
+ e.stopPropagation();
440
555
 
441
- var scroll = this.romoDropdown.bodyElem;
556
+ var scrollElem = this.romoDropdown.bodyElem;
557
+ var scrollOffset = Romo.offset(scrollElem);
558
+ var scrollHeight = parseInt(Romo.css(scrollElem, 'height'), 10);
442
559
 
443
560
  if (e.keyCode === 38 /* Up */) {
444
- var prev = this._prevListItem();
561
+ var prevElem = this._prevListItem();
562
+ if(prevElem === undefined){ return false; }
563
+
564
+ var prevOffset = Romo.offset(prevElem);
445
565
 
446
- this._highlightItem(prev);
447
- if (scroll.offset().top > prev.offset().top) {
448
- this._scrollTopToItem(prev);
449
- } else if ((scroll.offset().top + scroll.height()) < prev.offset().top) {
450
- this._scrollTopToItem(prev);
566
+ this._highlightItem(prevElem);
567
+
568
+ if (scrollOffset.top > prevOffset.top) {
569
+ this._scrollTopToItem(prevElem);
570
+ } else if ((scrollOffset.top + scrollHeight) < prevOffset.top) {
571
+ this._scrollTopToItem(prevElem);
451
572
  }
452
573
 
453
574
  return false;
454
575
  } else if(e.keyCode === 40 /* Down */) {
455
- var next = this._nextListItem();
576
+ var nextElem = this._nextListItem();
577
+ if(nextElem === undefined){ return false; }
578
+
579
+ var nextOffset = Romo.offset(nextElem);
580
+ var nextHeight = parseInt(Romo.css(nextElem, 'height'), 10);
456
581
 
457
- this._highlightItem(next);
458
- if ((scroll.offset().top + scroll.height()) < next.offset().top + next.height()) {
459
- this._scrollBottomToItem(next);
460
- } else if (scroll.offset().top > next.offset().top) {
461
- this._scrollTopToItem(next);
582
+ this._highlightItem(nextElem);
583
+
584
+ if ((scrollOffset.top + scrollHeight) < (nextOffset.top + nextHeight)) {
585
+ this._scrollBottomToItem(nextElem);
586
+ } else if (scrollOffset.top > nextOffset.top) {
587
+ this._scrollTopToItem(nextElem);
462
588
  }
463
589
 
464
590
  return false;
@@ -473,19 +599,21 @@ RomoOptionListDropdown.prototype._onPopupOpenBodyKeyDown = function(e) {
473
599
  }
474
600
  }
475
601
 
476
- RomoOptionListDropdown.prototype._onElemKeyDown = function(e) {
477
- if (this.elem.hasClass('disabled') === false) {
602
+ RomoOptionListDropdown.prototype.romoEvFn._onElemKeyDown = function(e) {
603
+ if (Romo.hasClass(this.elem, 'disabled') === false) {
478
604
  if (this.romoDropdown.popupClosed()) {
479
605
  if (e.keyCode === 40 /* Down */ || e.keyCode === 38 /* Up */) {
480
606
  this.romoDropdown.doPopupOpen();
481
607
  return false;
482
- } else if (this.optionFilterElem !== undefined &&
483
- Romo.nonInputTextKeyCodes().indexOf(e.keyCode) === -1 /* Input Text */) {
608
+ } else if (
609
+ this.optionFilterElem !== undefined &&
610
+ Romo.nonInputTextKeyCodes().indexOf(e.keyCode) === -1 /* Input Text */
611
+ ) {
484
612
  // don't prevent default on Cmd-* keys (preserve Cmd-R refresh, etc)
485
613
  if (e.metaKey === false) {
486
614
  e.preventDefault();
487
615
  if (e.keyCode !== 8) { /* Backspace */
488
- this.optionFilterElem.val(e.key);
616
+ this.optionFilterElem.value = e.key;
489
617
  }
490
618
  this.romoDropdown.doPopupOpen();
491
619
  }
@@ -499,114 +627,6 @@ RomoOptionListDropdown.prototype._onElemKeyDown = function(e) {
499
627
  return true;
500
628
  }
501
629
 
502
- RomoOptionListDropdown.prototype._scrollTopToItem = function(item) {
503
- if (item.size() > 0) {
504
- var scroll = this.romoDropdown.bodyElem;
505
- scroll.scrollTop(0);
506
-
507
- var scrollOffsetTop = scroll.offset().top;
508
- var selOffsetTop = item.offset().top;
509
- var selOffset = item.height() / 2;
510
-
511
- scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
512
- }
513
- }
630
+ // init
514
631
 
515
- RomoOptionListDropdown.prototype._scrollBottomToItem = function(item) {
516
- if (item.size() > 0) {
517
- var scroll = this.romoDropdown.bodyElem;
518
- scroll.scrollTop(0);
519
-
520
- var scrollOffsetTop = scroll.offset().top;
521
- var selOffsetTop = item.offset().top;
522
- var selOffset = scroll[0].offsetHeight - item.height();
523
-
524
- scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
525
- }
526
- }
527
-
528
- RomoOptionListDropdown.prototype._nextListItem = function() {
529
- var curr = this._getHighlightedItemElem();
530
- if (curr.length === 0) {
531
- return curr;
532
- }
533
- var next = Romo.selectNext(curr, this.itemSelector+', UL.romo-option-list-optgroup');
534
- if (next.length === 0) {
535
- // curr is either the last ungrouped opt elem in the overall
536
- // list OR is the last opt elem in a grouped list.
537
-
538
- // if the hightlighted opt elem is in an opt group list, use
539
- // its list as the reference elem. otherwise keep using the
540
- // hightlighted opt elem itself.
541
- curr = curr.closest('UL.romo-option-list-optgroup') || curr;
542
- next = Romo.selectNext(curr, this.itemSelector+', UL.romo-option-list-optgroup');
543
- }
544
- while (next.hasClass('romo-option-list-optgroup') && next.children().size() === 0) {
545
- // keep trying until you find a opt group list with options or an option or nothing
546
- curr = next;
547
- next = Romo.selectNext(curr, this.itemSelector+', UL.romo-option-list-optgroup');
548
- }
549
- if (next.length === 0) {
550
- // curr is the last opt elem (grouped or not) in the overall
551
- // list. get the the first opt elem in the overall list
552
- next = this.romoDropdown.bodyElem.find(this.itemSelector).first();
553
- } else if (next.hasClass('romo-option-list-optgroup')) {
554
- // curr (grouped or not) is before an opt group list. get
555
- // the first opt elem in that list.
556
- next = next.find(this.itemSelector).first();
557
- }
558
- // otherwise curr (grouped or not) is before an opt elem.
559
- // use that opt elem.
560
-
561
- return next;
562
- }
563
-
564
- RomoOptionListDropdown.prototype._prevListItem = function() {
565
- var curr = this._getHighlightedItemElem();
566
- if (curr.length === 0) {
567
- return curr;
568
- }
569
-
570
- var prev = Romo.selectPrev(curr, this.itemSelector+', UL.romo-option-list-optgroup');
571
- if (prev.length === 0) {
572
- // curr is either the first ungrouped opt elem in the overall
573
- // list OR is the first opt elem in a grouped list
574
-
575
- // if the hightlighted opt elem is in an opt group list, use
576
- // its list as the reference elem. otherwise keep using the
577
- // hightlighted opt elem itself.
578
- curr = curr.closest('UL.romo-option-list-optgroup') || curr;
579
- prev = Romo.selectPrev(curr, this.itemSelector+', UL.romo-option-list-optgroup');
580
- }
581
- while (prev.hasClass('romo-option-list-optgroup') && prev.children().size() === 0) {
582
- // keep trying until you find a opt group list with options or an option or nothing
583
- curr = prev;
584
- prev = Romo.selectPrev(curr, this.itemSelector+', UL.romo-option-list-optgroup');
585
- }
586
- if (prev.length === 0) {
587
- // curr is the first opt elem (grouped or not) in the overall
588
- // list. get the the last opt elem in the overall list
589
- prev = this.romoDropdown.bodyElem.find(this.itemSelector).last();
590
- } else if (prev.hasClass('romo-option-list-optgroup')) {
591
- // curr (grouped or not) is after an opt group list. get
592
- // the last opt elem in that list.
593
- prev = prev.find(this.itemSelector).last();
594
- }
595
- // otherwise curr (grouped or not) is after an opt elem.
596
- // use that opt elem.
597
-
598
- return prev;
599
- }
600
-
601
- RomoOptionListDropdown.prototype._highlightItem = function(item) {
602
- this._getHighlightedItemElem().removeClass('romo-option-list-dropdown-highlight');
603
- item.addClass('romo-option-list-dropdown-highlight');
604
- }
605
-
606
- RomoOptionListDropdown.prototype._getHighlightedItemElem = function() {
607
- return this.romoDropdown.bodyElem.find('LI.romo-option-list-dropdown-highlight');
608
- }
609
-
610
- Romo.onInitUI(function(e) {
611
- Romo.initUIElems(e, '[data-romo-option-list-dropdown-auto="true"]').romoOptionListDropdown();
612
- });
632
+ Romo.addElemsInitSelector('[data-romo-option-list-dropdown-auto="true"]', RomoOptionListDropdown);