Skip to content

Commit 106e910

Browse files
committed
CLOUDSTACK-9020: Implement sorting for tables
Implements sorting for tables across CloudStack UI; - General alphabetic/string based sorting - Numeric sorting for columns if data appears numeric - Special sorting comparator for state columns - Avoids sorting quick view columns and other specific columns Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
1 parent a48a224 commit 106e910

1 file changed

Lines changed: 72 additions & 19 deletions

File tree

ui/scripts/ui/widgets/dataTable.js

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -141,49 +141,95 @@
141141
* @param columnIndex Index of column (starting at 0) to sort by
142142
*/
143143
var sortTable = function(columnIndex) {
144-
return false;
145144
var direction = 'asc';
146145

147-
if ($table.find('thead th').hasClass('sorted ' + direction)) {
146+
if ($table.find('thead tr:last th').hasClass('sorted ' + direction)) {
148147
direction = 'desc';
149148
}
150149

151-
$table.find('thead th').removeClass('sorted desc asc');
152-
$($table.find('thead th')[columnIndex]).addClass('sorted').addClass(direction);
150+
$table.find('thead tr:last th').removeClass('sorted desc asc');
151+
$($table.find('thead tr:last th')[columnIndex]).addClass('sorted').addClass(direction);
153152

154153
var $elems = $table.find('tbody td').filter(function() {
155154
return $(this).index() == columnIndex;
156155
});
157156

157+
if ($elems.length < 2) {
158+
return;
159+
}
160+
161+
var stringComparator = function(a,b) {
162+
return a.html().localeCompare(b.html());
163+
};
164+
var numericComparator = function(a,b) {
165+
return parseFloat(a.children().html()) < parseFloat(b.children().html()) ? 1 : -1;
166+
};
167+
var stateComparator = function(a,b) {
168+
return a.attr('title').localeCompare(b.attr('title'));
169+
};
170+
var isNumeric = function(obj) {
171+
return !$.isArray(obj) && !isNaN(parseFloat(obj)) && isFinite(parseFloat(obj));
172+
}
173+
174+
var comparator = stringComparator;
175+
var hasAllRowsSameValue = true;
176+
var firstElem = $($elems[0]).html();
158177
var sortData = [];
178+
var numericDataCount = 0;
159179
$elems.each(function() {
160-
sortData.push($(this).html());
161-
sortData.sort();
162-
163-
if (direction == 'asc') {
164-
sortData.reverse();
180+
var text = $(this).html();
181+
if (hasAllRowsSameValue) {
182+
if (firstElem !== text) {
183+
hasAllRowsSameValue = false;
184+
}
185+
}
186+
if (isNumeric(text) || !text) {
187+
numericDataCount++;
165188
}
189+
sortData.push($(this));
166190
});
167191

192+
if ($($elems[0]).hasClass('state')) {
193+
comparator = stateComparator;
194+
} else {
195+
if (hasAllRowsSameValue) {
196+
return;
197+
}
198+
if (columnIndex != 0 && numericDataCount > ($elems.length / 4)) {
199+
comparator = numericComparator;
200+
}
201+
}
202+
203+
sortData.sort(comparator);
204+
205+
if (direction == 'asc') {
206+
sortData.reverse();
207+
}
208+
209+
var elements = [];
168210
$(sortData).each(function() {
169-
var sortKey = this;
170-
var $targetCell = $elems.filter(function() {
171-
return $(this).html() == sortKey;
172-
});
173-
var $targetContainer = $targetCell.parent();
211+
elements.push($(this).parent().clone(true));
212+
});
174213

175-
$targetContainer.remove().appendTo($table.find('tbody'));
214+
var $tbody = $table.find('tbody');
215+
$tbody.empty();
216+
$(elements).each(function() {
217+
$(this).appendTo($tbody);
176218
});
177219

178220
computeEvenOddRows();
179221
};
180222

181223
var resizeHeaders = function() {
182-
var $thead = $table.closest('div.data-table').find('thead');
224+
var $thead = $table.hasClass('no-split') ? $table.find('thead') : $table.closest('div.data-table').find('thead');
183225
var $tbody = $table.find('tbody');
184226
var $ths = $thead.find('th');
185227
var $tds = $tbody.find('tr:first td');
186228

229+
if ($table.hasClass('no-split')) {
230+
$tbody.width($thead.width());
231+
}
232+
187233
if ($ths.size() > $tds.size()) {
188234
$ths.width(
189235
$table.width() / $ths.size()
@@ -194,6 +240,10 @@
194240
$ths.each(function() {
195241
var $th = $(this);
196242

243+
if ($th.hasClass('collapsible-column')) {
244+
return true;
245+
}
246+
197247
var $td = $tds.filter(function() {
198248
return $(this).index() == $th.index();
199249
});
@@ -238,9 +288,12 @@
238288
$table.find('tbody').closest('table').addClass('body');
239289
}
240290

241-
$table.find('th:not(:has(input))').bind('mousemove mouseout', hoverResizableEvent);
242-
$table.find('th:not(:has(input))').bind('mousedown mousemove mouseup mouseout', resizeDragEvent);
243-
$table.find('th:not(:has(input))').bind('click', function(event) {
291+
if (!$table.hasClass('horizontal-overflow')) {
292+
$table.find('th:not(:has(input))').bind('mousemove mouseout', hoverResizableEvent);
293+
$table.find('th:not(:has(input))').bind('mousedown mousemove mouseup mouseout', resizeDragEvent);
294+
}
295+
296+
$table.find('thead tr:last th:not(:has(input)):not(.collapsible-column):not(.quick-view)').unbind('click').bind('click', function(event) {
244297
if ($(this).hasClass('resizable')) {
245298
return false;
246299
}

0 commit comments

Comments
 (0)