romo 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile +9 -1
- data/README.md +1 -1
- data/assets/css/romo/_mixins.scss +486 -0
- data/assets/css/romo/_vars.scss +159 -0
- data/assets/css/romo/base.scss +454 -0
- data/assets/css/romo/buttons.scss +211 -0
- data/assets/css/romo/datepicker.scss +73 -0
- data/assets/css/romo/dropdown.scss +33 -0
- data/assets/css/romo/forms.scss +193 -0
- data/assets/css/romo/grid.scss +271 -0
- data/assets/css/romo/grid_table.scss +129 -0
- data/assets/css/romo/labels.scss +41 -0
- data/assets/css/romo/lists.scss +37 -0
- data/assets/css/romo/modal.scss +32 -0
- data/assets/css/romo/normalize.scss +425 -0
- data/assets/css/romo/select.scss +89 -0
- data/assets/css/romo/sortable.scss +14 -0
- data/assets/css/romo/table.scss +99 -0
- data/assets/css/romo/tabs.scss +71 -0
- data/assets/css/romo/tooltip.scss +89 -0
- data/assets/css/romo/z_index.scss +26 -0
- data/assets/js/romo/base.js +177 -0
- data/assets/js/romo/datepicker.js +541 -0
- data/assets/js/romo/dropdown.js +309 -0
- data/assets/js/romo/dropdown_form.js +92 -0
- data/assets/js/romo/form.js +182 -0
- data/assets/js/romo/indicator.js +88 -0
- data/assets/js/romo/inline.js +77 -0
- data/assets/js/romo/inline_form.js +86 -0
- data/assets/js/romo/invoke.js +87 -0
- data/assets/js/romo/modal.js +311 -0
- data/assets/js/romo/modal_form.js +101 -0
- data/assets/js/romo/select.js +139 -0
- data/assets/js/romo/select_dropdown.js +325 -0
- data/assets/js/romo/sortable.js +201 -0
- data/assets/js/romo/tooltip.js +258 -0
- data/lib/romo/dassets.rb +64 -0
- data/lib/romo/version.rb +1 -1
- data/lib/romo.rb +9 -0
- data/romo.gemspec +4 -2
- data/test/support/.gitkeep +0 -0
- data/test/system/.gitkeep +0 -0
- data/test/unit/dassets_tests.rb +67 -0
- data/test/unit/romo_tests.rb +21 -0
- metadata +53 -10
@@ -0,0 +1,139 @@
|
|
1
|
+
$.fn.romoSelect = function() {
|
2
|
+
return $.map(this, function(element) {
|
3
|
+
return new RomoSelect(element);
|
4
|
+
});
|
5
|
+
}
|
6
|
+
|
7
|
+
var RomoSelect = function(element) {
|
8
|
+
this.elem = $(element);
|
9
|
+
|
10
|
+
this.doInit();
|
11
|
+
this.doBindSelectDropdown();
|
12
|
+
this.doRefreshUI();
|
13
|
+
|
14
|
+
if (this.elem.attr('id') !== undefined) {
|
15
|
+
$('label[for="'+this.elem.attr('id')+'"]').on('click', $.proxy(function(e) {
|
16
|
+
this.romoSelectDropdown.elem.focus();
|
17
|
+
}, this));
|
18
|
+
}
|
19
|
+
|
20
|
+
$(window).on("pageshow", $.proxy(function(e) {
|
21
|
+
var selectedVal = this.elem.find('option[selected]').attr('value');
|
22
|
+
if (selectedVal === undefined) {
|
23
|
+
selectedVal = '';
|
24
|
+
}
|
25
|
+
if (selectedVal !== this.elem[0].value) {
|
26
|
+
this.romoSelectDropdown.doSetNewValue(selectedVal);
|
27
|
+
this._setNewValue(selectedVal);
|
28
|
+
}
|
29
|
+
}, this));
|
30
|
+
|
31
|
+
this.elem.trigger('select:ready', [this]);
|
32
|
+
}
|
33
|
+
|
34
|
+
RomoSelect.prototype.doInit = function() {
|
35
|
+
// override as needed
|
36
|
+
}
|
37
|
+
|
38
|
+
RomoSelect.prototype.doBindSelectDropdown = function() {
|
39
|
+
this.romoSelectDropdown = this._buildSelectDropdownElem().romoSelectDropdown(this.elem)[0];
|
40
|
+
|
41
|
+
this.romoSelectDropdown.elem.on('selectDropdown:dropdown:toggle', $.proxy(function(e, dropdown, selectDropdown) {
|
42
|
+
this.elem.trigger('select:dropdown:toggle', [dropdown, this]);
|
43
|
+
}, this));
|
44
|
+
this.romoSelectDropdown.elem.on('selectDropdown:dropdown:popupOpen', $.proxy(function(e, dropdown, selectDropdown) {
|
45
|
+
this.elem.trigger('select:dropdown:popupOpen', [dropdown, this]);
|
46
|
+
}, this));
|
47
|
+
this.romoSelectDropdown.elem.on('selectDropdown:dropdown:popupClose', $.proxy(function(e, dropdown, selectDropdown) {
|
48
|
+
this.elem.trigger('select:dropdown:popupClose', [dropdown, this]);
|
49
|
+
}, this));
|
50
|
+
|
51
|
+
this.romoSelectDropdown.elem.on('selectDropdown:itemSelected', $.proxy(function(e, newValue, prevValue, selectDropdown) {
|
52
|
+
this.romoSelectDropdown.elem.focus();
|
53
|
+
this.elem.trigger('select:itemSelected', [newValue, prevValue, this]);
|
54
|
+
}, this));
|
55
|
+
this.romoSelectDropdown.elem.on('selectDropdown:change', $.proxy(function(e, newValue, prevValue, selectDropdown) {
|
56
|
+
this._setNewValue(newValue);
|
57
|
+
this.elem.trigger('change');
|
58
|
+
this.elem.trigger('select:change', [newValue, prevValue, this]);
|
59
|
+
}, this));
|
60
|
+
|
61
|
+
this.elem.on('select:triggerToggle', $.proxy(function(e) {
|
62
|
+
this.romoSelectDropdown.elem.trigger('selectDropdown:triggerToggle', []);
|
63
|
+
}, this));
|
64
|
+
this.elem.on('select:triggerPopupOpen', $.proxy(function(e) {
|
65
|
+
this.romoSelectDropdown.elem.trigger('selectDropdown:triggerPopupOpen', []);
|
66
|
+
}, this));
|
67
|
+
this.elem.on('select:triggerPopupClose', $.proxy(function(e) {
|
68
|
+
this.romoSelectDropdown.elem.trigger('selectDropdown:triggerPopupClose', []);
|
69
|
+
}, this));
|
70
|
+
}
|
71
|
+
|
72
|
+
RomoSelect.prototype.doRefreshUI = function() {
|
73
|
+
var text = this.romoSelectDropdown.selectedListing().text() || ' ';
|
74
|
+
this.romoSelectDropdown.elem.find('.romo-select-text').html(text);
|
75
|
+
}
|
76
|
+
|
77
|
+
RomoSelect.prototype.onCaretClick = function(e) {
|
78
|
+
if (this.elem.prop('disabled') === false) {
|
79
|
+
this.romoSelectDropdown.elem.focus();
|
80
|
+
this.elem.trigger('select:triggerPopupOpen');
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
RomoSelect.prototype._setNewValue = function(newValue) {
|
85
|
+
this.elem[0].value = newValue;
|
86
|
+
this.doRefreshUI();
|
87
|
+
}
|
88
|
+
|
89
|
+
RomoSelect.prototype._buildSelectDropdownElem = function() {
|
90
|
+
var romoSelectDropdownElem = $('<div class="romo-select romo-btn" tabindex="0"><span class="romo-select-text"></span></div>');
|
91
|
+
|
92
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-position', this.elem.data('romo-select-dropdown-position'));
|
93
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-style-class', this.elem.data('romo-select-dropdown-style-class'));
|
94
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-min-height', this.elem.data('romo-select-dropdown-min-height'));
|
95
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-max-height', this.elem.data('romo-select-dropdown-max-height'));
|
96
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-height', this.elem.data('romo-select-dropdown-height'));
|
97
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-overflow-x', 'hidden');
|
98
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-width', 'elem');
|
99
|
+
if (romoSelectDropdownElem.data('romo-dropdown-max-height') === undefined) {
|
100
|
+
romoSelectDropdownElem.attr('data-romo-dropdown-max-height', 'detect');
|
101
|
+
}
|
102
|
+
|
103
|
+
var classList = this.elem.attr('class') !== undefined ? this.elem.attr('class').split(/\s+/) : [];
|
104
|
+
$.each(classList, function(idx, classItem) {
|
105
|
+
romoSelectDropdownElem.addClass(classItem);
|
106
|
+
});
|
107
|
+
if (this.elem.attr('style') !== undefined) {
|
108
|
+
romoSelectDropdownElem.attr('style', this.elem.attr('style'));
|
109
|
+
}
|
110
|
+
romoSelectDropdownElem.css({'width': this.elem.css('width')});
|
111
|
+
if (this.elem.attr('disabled') !== undefined) {
|
112
|
+
this.romoSelectDropdown.elem.attr('disabled', this.elem.attr('disabled'));
|
113
|
+
}
|
114
|
+
|
115
|
+
this.elem.after(romoSelectDropdownElem);
|
116
|
+
this.elem.hide();
|
117
|
+
|
118
|
+
this.elemWrapper = $('<div class="romo-select-wrapper"></div>');
|
119
|
+
if (this.elem.data('romo-select-btn-group') === true) {
|
120
|
+
this.elemWrapper.addClass('romo-btn-group');
|
121
|
+
}
|
122
|
+
romoSelectDropdownElem.before(this.elemWrapper);
|
123
|
+
this.elemWrapper.append(romoSelectDropdownElem);
|
124
|
+
|
125
|
+
var caretClass = this.elem.data('romo-select-caret') || this.defaultCaretClass;
|
126
|
+
if (caretClass !== undefined && caretClass !== 'none') {
|
127
|
+
var caret = $('<i class="romo-select-caret '+caretClass+'"></i>');
|
128
|
+
caret.css({'line-height': romoSelectDropdownElem.css('line-height')});
|
129
|
+
caret.on('click', $.proxy(this.onCaretClick, this));
|
130
|
+
romoSelectDropdownElem.css({'padding-right': '22px'});
|
131
|
+
romoSelectDropdownElem.append(caret);
|
132
|
+
}
|
133
|
+
|
134
|
+
return romoSelectDropdownElem;
|
135
|
+
}
|
136
|
+
|
137
|
+
Romo.onInitUI(function(e) {
|
138
|
+
Romo.initUIElems(e, '[data-romo-select-auto="true"]').romoSelect();
|
139
|
+
});
|
@@ -0,0 +1,325 @@
|
|
1
|
+
$.fn.romoSelectDropdown = function(optionElemsParent) {
|
2
|
+
return $.map(this, function(element) {
|
3
|
+
return new RomoSelectDropdown(element, optionElemsParent);
|
4
|
+
});
|
5
|
+
}
|
6
|
+
|
7
|
+
var RomoSelectDropdown = function(element, optionElemsParent) {
|
8
|
+
this.elem = $(element);
|
9
|
+
this.defaultCaretClass = '';
|
10
|
+
this.itemSelector = 'LI[data-romo-select-item="opt"]:not(.disabled)';
|
11
|
+
this.prevValue = undefined;
|
12
|
+
|
13
|
+
var optsParent = (optionElemsParent || this.elem.find('.romo-select-dropdown-options-parent'));
|
14
|
+
this.optionElems = optsParent.children();
|
15
|
+
this.optionList = this._buildOptionList(this.optionElems);
|
16
|
+
|
17
|
+
this.doInit();
|
18
|
+
this.doBindDropdown();
|
19
|
+
|
20
|
+
if (this.elem.attr('id') !== undefined) {
|
21
|
+
$('label[for="'+this.elem.attr('id')+'"]').on('click', $.proxy(function(e) {
|
22
|
+
this.elem.focus();
|
23
|
+
}, this));
|
24
|
+
}
|
25
|
+
|
26
|
+
this.elem.trigger('selectDropdown:ready', [this]);
|
27
|
+
}
|
28
|
+
|
29
|
+
RomoSelectDropdown.prototype.selectedListing = function() {
|
30
|
+
return this.romoDropdown.bodyElem.find('LI.selected');
|
31
|
+
}
|
32
|
+
|
33
|
+
RomoSelectDropdown.prototype.doInit = function() {
|
34
|
+
// override as needed
|
35
|
+
}
|
36
|
+
|
37
|
+
RomoSelectDropdown.prototype.doSetNewValue = function(newValue) {
|
38
|
+
this.selectedListing().removeClass('selected');
|
39
|
+
this.romoDropdown.bodyElem.find('LI[data-romo-select-option-value="'+newValue+'"]').addClass('selected');
|
40
|
+
|
41
|
+
this.prevValue = newValue;
|
42
|
+
}
|
43
|
+
|
44
|
+
RomoSelectDropdown.prototype.doBindDropdown = function() {
|
45
|
+
this.romoDropdown = this.elem.romoDropdown()[0];
|
46
|
+
this.romoDropdown.doSetPopupZIndex(this.elem);
|
47
|
+
this.romoDropdown.bodyElem.addClass('romo-select-option-list');
|
48
|
+
this.romoDropdown.elem.on('dropdown:popupOpen', $.proxy(this.onPopupOpen, this));
|
49
|
+
this.romoDropdown.elem.on('dropdown:popupClose', $.proxy(this.onPopupClose, this));
|
50
|
+
this.romoDropdown.elem.on('blur', $.proxy(function(e) {
|
51
|
+
this.blurTimeoutId = setTimeout($.proxy(function() {
|
52
|
+
if (this.popupMouseDown !== true) {
|
53
|
+
this.romoDropdown.elem.trigger('dropdown:triggerPopupClose', []);
|
54
|
+
}
|
55
|
+
}, this), 10);
|
56
|
+
}, this));
|
57
|
+
this.romoDropdown.elem.on('keydown', $.proxy(this.onElemKeyDown, this));
|
58
|
+
this.romoDropdown.popupElem.on('keydown', $.proxy(this.onElemKeyDown, this));
|
59
|
+
|
60
|
+
this.romoDropdown.elem.on('dropdown:toggle', $.proxy(function(e, dropdown) {
|
61
|
+
this.elem.trigger('selectDropdown:dropdown:toggle', [dropdown, this]);
|
62
|
+
}, this));
|
63
|
+
this.romoDropdown.elem.on('dropdown:popupOpen', $.proxy(function(e, dropdown) {
|
64
|
+
this.elem.trigger('selectDropdown:dropdown:popupOpen', [dropdown, this]);
|
65
|
+
}, this));
|
66
|
+
this.romoDropdown.elem.on('dropdown:popupClose', $.proxy(function(e, dropdown) {
|
67
|
+
this.elem.trigger('selectDropdown:dropdown:popupClose', [dropdown, this]);
|
68
|
+
}, this));
|
69
|
+
|
70
|
+
this.elem.on('selectDropdown:triggerToggle', $.proxy(function(e) {
|
71
|
+
this.romoDropdown.elem.trigger('dropdown:triggerToggle', []);
|
72
|
+
}, this));
|
73
|
+
this.elem.on('selectDropdown:triggerPopupOpen', $.proxy(function(e) {
|
74
|
+
this.romoDropdown.elem.trigger('dropdown:triggerPopupOpen', []);
|
75
|
+
}, this));
|
76
|
+
this.elem.on('selectDropdown:triggerPopupClose', $.proxy(function(e) {
|
77
|
+
this.romoDropdown.elem.trigger('dropdown:triggerPopupClose', []);
|
78
|
+
}, this));
|
79
|
+
|
80
|
+
this.romoDropdown.bodyElem.html('');
|
81
|
+
this.romoDropdown.bodyElem.append(this.optionList);
|
82
|
+
|
83
|
+
this.romoDropdown.bodyElem.find(this.itemSelector).on('hover', $.proxy(this.onItemHover, this));
|
84
|
+
this.romoDropdown.bodyElem.find(this.itemSelector).on('click', $.proxy(this.onItemClick, this));
|
85
|
+
|
86
|
+
this.romoDropdown.popupElem.on('mousedown', $.proxy(this.onPopupMouseDown, this));
|
87
|
+
this.romoDropdown.popupElem.on('mouseup', $.proxy(this.onPopupMouseUp, this));
|
88
|
+
}
|
89
|
+
|
90
|
+
RomoSelectDropdown.prototype.doSelectHighlightedItem = function() {
|
91
|
+
var prevValue = this.prevValue;
|
92
|
+
var newValue = this.romoDropdown.bodyElem.find('LI.romo-select-highlight').data('romo-select-option-value');
|
93
|
+
|
94
|
+
this.romoDropdown.doPopupClose();
|
95
|
+
this.elem.trigger('selectDropdown:itemSelected', [newValue, prevValue, this]);
|
96
|
+
|
97
|
+
if (newValue !== prevValue) {
|
98
|
+
this.doSetNewValue(newValue);
|
99
|
+
this.elem.trigger('selectDropdown:change', [newValue, prevValue, this]);
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
RomoSelectDropdown.prototype.onPopupOpen = function(e) {
|
104
|
+
if (this.elem.hasClass('disabled') === false) {
|
105
|
+
this._highlightItem(this.selectedListing());
|
106
|
+
this._scrollTopToItem(this.selectedListing());
|
107
|
+
}
|
108
|
+
$('body').on('keydown', $.proxy(this.onPopupOpenBodyKeyDown, this));
|
109
|
+
}
|
110
|
+
|
111
|
+
RomoSelectDropdown.prototype.onPopupClose = function(e) {
|
112
|
+
this._highlightItem($());
|
113
|
+
$('body').off('keydown', $.proxy(this.onPopupOpenBodyKeyDown, this));
|
114
|
+
}
|
115
|
+
|
116
|
+
RomoSelectDropdown.prototype.onItemHover = function(e) {
|
117
|
+
if (e !== undefined) {
|
118
|
+
e.preventDefault();
|
119
|
+
e.stopPropagation();
|
120
|
+
}
|
121
|
+
this._highlightItem($(e.target));
|
122
|
+
}
|
123
|
+
|
124
|
+
RomoSelectDropdown.prototype.onItemClick = function(e) {
|
125
|
+
if (this.blurTimeoutId !== undefined) {
|
126
|
+
clearTimeout(this.blurTimeoutId);
|
127
|
+
this.blurTimeoutId = undefined;
|
128
|
+
}
|
129
|
+
if (e !== undefined) {
|
130
|
+
e.preventDefault();
|
131
|
+
e.stopPropagation();
|
132
|
+
}
|
133
|
+
this.doSelectHighlightedItem();
|
134
|
+
}
|
135
|
+
|
136
|
+
RomoSelectDropdown.prototype.onPopupMouseDown = function(e) {
|
137
|
+
this.popupMouseDown = true;
|
138
|
+
}
|
139
|
+
|
140
|
+
RomoSelectDropdown.prototype.onPopupMouseUp = function(e) {
|
141
|
+
this.popupMouseDown = false;
|
142
|
+
}
|
143
|
+
|
144
|
+
RomoSelectDropdown.prototype.onPopupOpenBodyKeyDown = function(e) {
|
145
|
+
if (e !== undefined) {
|
146
|
+
e.stopPropagation();
|
147
|
+
}
|
148
|
+
|
149
|
+
var scroll = this.romoDropdown.bodyElem;
|
150
|
+
|
151
|
+
if (e.keyCode === 38 /* Up */) {
|
152
|
+
var prev = this._prevListItem();
|
153
|
+
|
154
|
+
this._highlightItem(prev);
|
155
|
+
if (scroll.offset().top > prev.offset().top) {
|
156
|
+
this._scrollTopToItem(prev);
|
157
|
+
} else if ((scroll.offset().top + scroll.height()) < prev.offset().top) {
|
158
|
+
this._scrollTopToItem(prev);
|
159
|
+
}
|
160
|
+
|
161
|
+
return false;
|
162
|
+
} else if(e.keyCode === 40 /* Down */) {
|
163
|
+
var next = this._nextListItem();
|
164
|
+
|
165
|
+
this._highlightItem(next);
|
166
|
+
if ((scroll.offset().top + scroll.height()) < next.offset().top + next.height()) {
|
167
|
+
this._scrollBottomToItem(next);
|
168
|
+
} else if (scroll.offset().top > next.offset().top) {
|
169
|
+
this._scrollTopToItem(next);
|
170
|
+
}
|
171
|
+
|
172
|
+
return false;
|
173
|
+
} else if (e.keyCode === 13 /* Enter */ ) {
|
174
|
+
this.doSelectHighlightedItem();
|
175
|
+
return false;
|
176
|
+
} else {
|
177
|
+
return true;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
|
181
|
+
RomoSelectDropdown.prototype.onElemKeyDown = function(e) {
|
182
|
+
if (this.elem.hasClass('disabled') === false) {
|
183
|
+
if (this.romoDropdown.popupElem.hasClass('romo-dropdown-open') === false) {
|
184
|
+
if(e.keyCode === 40 /* Down */ ) {
|
185
|
+
this.romoDropdown.doPopupOpen();
|
186
|
+
return false;
|
187
|
+
} else {
|
188
|
+
return true;
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
return true;
|
193
|
+
}
|
194
|
+
|
195
|
+
RomoSelectDropdown.prototype._scrollTopToItem = function(item) {
|
196
|
+
if (item.size() > 0) {
|
197
|
+
var scroll = this.romoDropdown.bodyElem;
|
198
|
+
scroll.scrollTop(0);
|
199
|
+
|
200
|
+
var scrollOffsetTop = scroll.offset().top;
|
201
|
+
var selOffsetTop = item.offset().top;
|
202
|
+
var selOffset = item.height() / 2;
|
203
|
+
|
204
|
+
scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
|
205
|
+
}
|
206
|
+
}
|
207
|
+
|
208
|
+
RomoSelectDropdown.prototype._scrollBottomToItem = function(item) {
|
209
|
+
if (item.size() > 0) {
|
210
|
+
var scroll = this.romoDropdown.bodyElem;
|
211
|
+
scroll.scrollTop(0);
|
212
|
+
|
213
|
+
var scrollOffsetTop = scroll.offset().top;
|
214
|
+
var selOffsetTop = item.offset().top;
|
215
|
+
var selOffset = scroll[0].offsetHeight - item.height();
|
216
|
+
|
217
|
+
scroll.scrollTop(selOffsetTop - scrollOffsetTop - selOffset);
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
RomoSelectDropdown.prototype._buildOptionList = function(optionElems, listClass) {
|
222
|
+
var list = $('<ul></ul>');
|
223
|
+
list.addClass(listClass);
|
224
|
+
$.each(optionElems, $.proxy(function(idx, elem) {
|
225
|
+
if (elem.tagName === "OPTION") {
|
226
|
+
list.append(this._buildOptionListItem(elem));
|
227
|
+
} else if (elem.tagName === "OPTGROUP") {
|
228
|
+
list.append(this._buildOptGroupListItem(elem));
|
229
|
+
list.append(this._buildOptionList($(elem).children(), 'romo-select-optgroup'));
|
230
|
+
}
|
231
|
+
}, this));
|
232
|
+
return list;
|
233
|
+
}
|
234
|
+
|
235
|
+
RomoSelectDropdown.prototype._buildOptionListItem = function(optionElem) {
|
236
|
+
var opt = $(optionElem);
|
237
|
+
var item = $('<li data-romo-select-item="opt"></li>');
|
238
|
+
|
239
|
+
item.attr('data-romo-select-option-value', opt.attr('value'));
|
240
|
+
item.html(opt.text().trim() || ' ');
|
241
|
+
if (opt.prop('selected')) {
|
242
|
+
item.addClass('selected');
|
243
|
+
}
|
244
|
+
if (opt.attr('disabled') !== undefined) {
|
245
|
+
item.addClass('disabled');
|
246
|
+
}
|
247
|
+
|
248
|
+
return item;
|
249
|
+
}
|
250
|
+
|
251
|
+
RomoSelectDropdown.prototype._buildOptGroupListItem = function(optGroupElem) {
|
252
|
+
var optgroup = $(optGroupElem);
|
253
|
+
var item = $('<li data-romo-select-item="optgroup"></li>');
|
254
|
+
|
255
|
+
item.text(optgroup.attr('label'));
|
256
|
+
|
257
|
+
return item;
|
258
|
+
}
|
259
|
+
|
260
|
+
RomoSelectDropdown.prototype._nextListItem = function() {
|
261
|
+
var listOrItemSelector = 'UL, '+this.itemSelector;
|
262
|
+
var curr = this.romoDropdown.bodyElem.find('LI.romo-select-highlight');
|
263
|
+
var next = this._nextAll(curr, listOrItemSelector).first();
|
264
|
+
|
265
|
+
if (next.size() === 0) {
|
266
|
+
next = this._nextAll(curr.closest('UL'), listOrItemSelector).first();
|
267
|
+
}
|
268
|
+
if (next.size() !== 0 && next[0].tagName === 'UL') {
|
269
|
+
next = next.find(this.itemSelector).first()
|
270
|
+
}
|
271
|
+
if (next.size() === 0) {
|
272
|
+
next = this.romoDropdown.bodyElem.find(this.itemSelector).first();
|
273
|
+
}
|
274
|
+
return next;
|
275
|
+
}
|
276
|
+
|
277
|
+
RomoSelectDropdown.prototype._prevListItem = function() {
|
278
|
+
var listOrItemSelector = 'UL, '+this.itemSelector;
|
279
|
+
var curr = this.romoDropdown.bodyElem.find('LI.romo-select-highlight');
|
280
|
+
var prev = this._prevAll(curr, listOrItemSelector).last();
|
281
|
+
|
282
|
+
if (prev.size() === 0) {
|
283
|
+
prev = this._prevAll(curr.closest('UL'), listOrItemSelector).last();
|
284
|
+
}
|
285
|
+
if (prev.size() !== 0 && prev[0].tagName === 'UL') {
|
286
|
+
prev = prev.find(this.itemSelector).last()
|
287
|
+
}
|
288
|
+
if (prev.size() === 0) {
|
289
|
+
prev = this.romoDropdown.bodyElem.find(this.itemSelector).last();
|
290
|
+
}
|
291
|
+
return prev;
|
292
|
+
}
|
293
|
+
|
294
|
+
RomoSelectDropdown.prototype._nextAll = function(elem, selector) {
|
295
|
+
var els = $();
|
296
|
+
var el = elem.next();
|
297
|
+
while( el.length ) {
|
298
|
+
if (selector === undefined || el.is(selector)) {
|
299
|
+
els = els.add(el);
|
300
|
+
}
|
301
|
+
el = el.next();
|
302
|
+
}
|
303
|
+
return els;
|
304
|
+
}
|
305
|
+
|
306
|
+
RomoSelectDropdown.prototype._prevAll = function(elem, selector) {
|
307
|
+
var els = $();
|
308
|
+
var el = elem.prev();
|
309
|
+
while( el.length ) {
|
310
|
+
if (selector === undefined || el.is(selector)) {
|
311
|
+
els = els.add(el);
|
312
|
+
}
|
313
|
+
el = el.prev();
|
314
|
+
}
|
315
|
+
return els;
|
316
|
+
}
|
317
|
+
|
318
|
+
RomoSelectDropdown.prototype._highlightItem = function(item) {
|
319
|
+
this.romoDropdown.bodyElem.find('LI.romo-select-highlight').removeClass('romo-select-highlight');
|
320
|
+
item.addClass('romo-select-highlight');
|
321
|
+
}
|
322
|
+
|
323
|
+
Romo.onInitUI(function(e) {
|
324
|
+
Romo.initUIElems(e, '[data-romo-select-dropdown-auto="true"]').romoSelectDropdown();
|
325
|
+
});
|
@@ -0,0 +1,201 @@
|
|
1
|
+
$.fn.romoSortable = function() {
|
2
|
+
return $.map(this, function(element) {
|
3
|
+
return new RomoSortable(element);
|
4
|
+
});
|
5
|
+
}
|
6
|
+
|
7
|
+
var RomoSortable = function(element) {
|
8
|
+
this.elem = $(element);
|
9
|
+
|
10
|
+
this.draggableSelector = '[data-romo-sortable-item="true"]';
|
11
|
+
this.handleSelector = '[data-romo-sortable-handle="true"]';
|
12
|
+
|
13
|
+
this.draggableElems = this.elem.find(this.draggableSelector);
|
14
|
+
this.draggableElems.prop('draggable', 'true');
|
15
|
+
|
16
|
+
this.draggingClass = this.elem.data('romo-sortable-dragging-class') || '';
|
17
|
+
this.dragOverClass = this.elem.data('romo-sortable-dragover-class') || '';
|
18
|
+
this.placeholderClass = this.elem.data('romo-sortable-placeholder-class') || '';
|
19
|
+
|
20
|
+
this.draggedElem = this.draggedIndex = this.draggableSelected = null;
|
21
|
+
this.draggedOverElem = this.dragDirection = this.lastY = null;
|
22
|
+
|
23
|
+
this.elem.on('dragenter', $.proxy(this.onDragEnter, this));
|
24
|
+
this.elem.on('dragover', $.proxy(this.onDragOver, this));
|
25
|
+
this.elem.on('dragend', $.proxy(this.onDragEnd, this));
|
26
|
+
this.elem.on('drop', $.proxy(this.onDragDrop, this));
|
27
|
+
|
28
|
+
this.draggableElems.on('dragstart', $.proxy(this.onDragStart, this));
|
29
|
+
this.draggableElems.on('dragenter', $.proxy(this.onDragEnter, this));
|
30
|
+
this.draggableElems.on('dragover', $.proxy(this.onDragOver, this));
|
31
|
+
this.draggableElems.on('dragend', $.proxy(this.onDragEnd, this));
|
32
|
+
this.draggableElems.on('drop', $.proxy(this.onDragDrop, this));
|
33
|
+
|
34
|
+
this.draggableElems.on('mousedown', $.proxy(this.onDraggableMouseDown, this));
|
35
|
+
var handleElems = this.draggableElems.find(this.handleSelector)
|
36
|
+
handleElems.on('mousedown', $.proxy(this.onHandleMouseDown, this));
|
37
|
+
$('body').on('mouseup', $.proxy(this.onWindowBodyMouseUp, this));
|
38
|
+
|
39
|
+
this._resetGrabClasses();
|
40
|
+
this.doInit();
|
41
|
+
this.doInitPlaceholder();
|
42
|
+
|
43
|
+
this.elem.trigger('sortable:ready', [this]);
|
44
|
+
}
|
45
|
+
|
46
|
+
RomoSortable.prototype.doInit = function() {
|
47
|
+
// override as needed
|
48
|
+
}
|
49
|
+
|
50
|
+
RomoSortable.prototype.doInitPlaceholder = function() {
|
51
|
+
var tag;
|
52
|
+
try {
|
53
|
+
tag = this.draggableElems.get(0).tagName;
|
54
|
+
} catch(e) {
|
55
|
+
tag = /^ul|ol$/i.test(this.elem.tagName) ? 'li' : 'div';
|
56
|
+
}
|
57
|
+
this.placeholderElem = $('<' + tag + '/>');
|
58
|
+
this.placeholderElem.addClass(this.placeholderClass);
|
59
|
+
|
60
|
+
this.placeholderElem.on('dragover', $.proxy(this.onDragOver, this));
|
61
|
+
this.placeholderElem.on('drop', $.proxy(this.onDragDrop, this));
|
62
|
+
}
|
63
|
+
|
64
|
+
RomoSortable.prototype.onDragStart = function(e) {
|
65
|
+
if(!this.draggableSelected){ return false; }
|
66
|
+
|
67
|
+
e.stopPropagation();
|
68
|
+
e.originalEvent.dataTransfer.effectAllowed = 'move';
|
69
|
+
|
70
|
+
// IE fix
|
71
|
+
try {
|
72
|
+
// FF fix, it won't drag without some data being set
|
73
|
+
e.originalEvent.dataTransfer.setData('text/plain', null);
|
74
|
+
} catch(e) {}
|
75
|
+
|
76
|
+
this.draggedElem = $(e.target);
|
77
|
+
this.draggedElem.addClass(this.draggingClass);
|
78
|
+
this.draggedIndex = this.draggedElem.index();
|
79
|
+
|
80
|
+
this.placeholderElem.css({ 'height': this.draggedElem.height() });
|
81
|
+
|
82
|
+
this.elem.trigger('sortable:dragStart', [this.draggedElem, this]);
|
83
|
+
}
|
84
|
+
|
85
|
+
RomoSortable.prototype.onDragEnter = function(e) {
|
86
|
+
e.preventDefault();
|
87
|
+
e.stopPropagation();
|
88
|
+
|
89
|
+
// return if event is fired on the placeholder
|
90
|
+
if(this.placeholderElem.get(0) === e.currentTarget){ return; }
|
91
|
+
|
92
|
+
this.placeholderElem.show();
|
93
|
+
this.draggedElem.hide();
|
94
|
+
|
95
|
+
// if event is not fired on the sortable
|
96
|
+
var overSortableElem = this.elem.get(0) === e.currentTarget;
|
97
|
+
var clientX = e.originalEvent.clientX;
|
98
|
+
var clientY = e.originalEvent.clientY;
|
99
|
+
if (!overSortableElem) {
|
100
|
+
// if we are in the same elem and moving the same direction, exit out
|
101
|
+
var overSameElem = this.draggedOverElem &&
|
102
|
+
this.draggedOverElem.get(0) === e.currentTarget;
|
103
|
+
var sameDirection = (this.dragDirection === 'down' && clientY > this.lastY) ||
|
104
|
+
(this.dragDirection === 'up' && clientY < this.lastY);
|
105
|
+
if(overSameElem && sameDirection){ return; }
|
106
|
+
|
107
|
+
// remove dragged over classes from previous elem
|
108
|
+
if(this.draggedOverElem){ this.draggedOverElem.removeClass(this.dragOverClass); }
|
109
|
+
this.draggedOverElem = $(e.currentTarget);
|
110
|
+
this.lastY = clientY;
|
111
|
+
this.draggedOverElem.addClass(this.dragOverClass);
|
112
|
+
|
113
|
+
// insert the placeholder according to the dragging direction
|
114
|
+
if (this.placeholderElem.index() < this.draggedOverElem.index()) {
|
115
|
+
this.dragDirection = 'down';
|
116
|
+
} else {
|
117
|
+
this.dragDirection = 'up';
|
118
|
+
}
|
119
|
+
var insertMethod = this.dragDirection === 'down' ? 'after' : 'before';
|
120
|
+
this.draggedOverElem[insertMethod](this.placeholderElem);
|
121
|
+
}
|
122
|
+
|
123
|
+
this.elem.trigger('sortable:dragMove', [clientX, clientY, this.draggedElem, this]);
|
124
|
+
}
|
125
|
+
|
126
|
+
RomoSortable.prototype.onDragOver = function(e) {
|
127
|
+
// This is how you allow an element to receive a drop event.
|
128
|
+
e.preventDefault();
|
129
|
+
e.stopPropagation();
|
130
|
+
}
|
131
|
+
|
132
|
+
RomoSortable.prototype.onDragEnd = function(e) {
|
133
|
+
e.stopPropagation();
|
134
|
+
e.preventDefault();
|
135
|
+
|
136
|
+
if(!this.draggedElem){ return; }
|
137
|
+
|
138
|
+
this.draggableElems.removeClass(this.dragOverClass);
|
139
|
+
this.draggedElem.removeClass(this.draggingClass);
|
140
|
+
this.draggedElem.show();
|
141
|
+
this.placeholderElem.hide();
|
142
|
+
this._resetGrabClasses();
|
143
|
+
|
144
|
+
this.elem.trigger('sortable:dragStop', [this.draggedElem, this]);
|
145
|
+
|
146
|
+
this.draggedElem = this.draggedIndex = this.draggableSelected = null;
|
147
|
+
this.draggedOverElem = this.dragDirection = this.lastY = null;
|
148
|
+
}
|
149
|
+
|
150
|
+
RomoSortable.prototype.onDragDrop = function(e) {
|
151
|
+
e.stopPropagation();
|
152
|
+
e.preventDefault();
|
153
|
+
|
154
|
+
if(!this.draggedElem){ return; }
|
155
|
+
|
156
|
+
this.draggedElem.insertBefore(this.placeholderElem);
|
157
|
+
this.draggedElem.show();
|
158
|
+
|
159
|
+
var newIndex = this.draggedElem.index();
|
160
|
+
if (newIndex !== this.draggedIndex) {
|
161
|
+
this.elem.trigger('sortable:change', [this.draggedElem, this]);
|
162
|
+
}
|
163
|
+
this.elem.trigger('sortable:dragDrop', [this.draggedElem, this]);
|
164
|
+
}
|
165
|
+
|
166
|
+
RomoSortable.prototype.onDraggableMouseDown = function(e) {
|
167
|
+
// if our draggable elem doesn't have a handle then it's draggable
|
168
|
+
var draggableElem = $(e.currentTarget);
|
169
|
+
if(draggableElem.find(this.handleSelector).size() === 0) {
|
170
|
+
draggableElem.removeClass('romo-sortable-grab');
|
171
|
+
draggableElem.addClass('romo-sortable-grabbing');
|
172
|
+
this.draggableSelected = true;
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
RomoSortable.prototype.onHandleMouseDown = function(e) {
|
177
|
+
this.draggableSelected = true;
|
178
|
+
var handleElem = $(e.currentTarget);
|
179
|
+
handleElem.removeClass('romo-sortable-grab');
|
180
|
+
handleElem.addClass('romo-sortable-grabbing');
|
181
|
+
}
|
182
|
+
|
183
|
+
RomoSortable.prototype.onWindowBodyMouseUp = function(e) {
|
184
|
+
this.draggableSelected = false;
|
185
|
+
}
|
186
|
+
|
187
|
+
RomoSortable.prototype._resetGrabClasses = function() {
|
188
|
+
this.draggableElems.each($.proxy(function(index, item) {
|
189
|
+
|
190
|
+
draggableElem = $(item);
|
191
|
+
handleElem = draggableElem.find(this.handleSelector);
|
192
|
+
if(handleElem.size() === 0){ handleElem = draggableElem; }
|
193
|
+
handleElem.addClass('romo-sortable-grab');
|
194
|
+
handleElem.removeClass('romo-sortable-grabbing');
|
195
|
+
|
196
|
+
}, this));
|
197
|
+
}
|
198
|
+
|
199
|
+
Romo.onInitUI(function(e) {
|
200
|
+
$(e.target).find('[data-romo-sortable-auto="true"]').romoSortable();
|
201
|
+
});
|