UNPKG

19.4 kBJavaScriptView Raw
1(function (global, factory) {
2 if (typeof define === "function" && define.amd) {
3 define([], factory);
4 } else if (typeof exports !== "undefined") {
5 factory();
6 } else {
7 var mod = {
8 exports: {}
9 };
10 factory();
11 global.bootstrapTableMultipleSort = mod.exports;
12 }
13})(this, function () {
14 'use strict';
15
16 var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
17 return typeof obj;
18 } : function (obj) {
19 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
20 };
21
22 /**
23 * @author Nadim Basalamah <dimbslmh@gmail.com>
24 * @version: v1.1.0
25 * https://github.com/dimbslmh/bootstrap-table/tree/master/src/extensions/multiple-sort/bootstrap-table-multiple-sort.js
26 * Modification: ErwannNevou <https://github.com/ErwannNevou>
27 */
28
29 (function ($) {
30 'use strict';
31
32 var isSingleSort = false;
33
34 var showSortModal = function showSortModal(that) {
35 var _selector = that.sortModalSelector,
36 _id = '#' + _selector;
37
38 if (!$(_id).hasClass("modal")) {
39 var sModal = ' <div class="modal fade" id="' + _selector + '" tabindex="-1" role="dialog" aria-labelledby="' + _selector + 'Label" aria-hidden="true">';
40 sModal += ' <div class="modal-dialog">';
41 sModal += ' <div class="modal-content">';
42 sModal += ' <div class="modal-header">';
43 sModal += ' <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>';
44 sModal += ' <h4 class="modal-title" id="' + _selector + 'Label">' + that.options.formatMultipleSort() + '</h4>';
45 sModal += ' </div>';
46 sModal += ' <div class="modal-body">';
47 sModal += ' <div class="bootstrap-table">';
48 sModal += ' <div class="fixed-table-toolbar">';
49 sModal += ' <div class="bars">';
50 sModal += ' <div id="toolbar">';
51 sModal += ' <button id="add" type="button" class="btn btn-default"><i class="' + that.options.iconsPrefix + ' ' + that.options.icons.plus + '"></i> ' + that.options.formatAddLevel() + '</button>';
52 sModal += ' <button id="delete" type="button" class="btn btn-default" disabled><i class="' + that.options.iconsPrefix + ' ' + that.options.icons.minus + '"></i> ' + that.options.formatDeleteLevel() + '</button>';
53 sModal += ' </div>';
54 sModal += ' </div>';
55 sModal += ' </div>';
56 sModal += ' <div class="fixed-table-container">';
57 sModal += ' <table id="multi-sort" class="table">';
58 sModal += ' <thead>';
59 sModal += ' <tr>';
60 sModal += ' <th></th>';
61 sModal += ' <th><div class="th-inner">' + that.options.formatColumn() + '</div></th>';
62 sModal += ' <th><div class="th-inner">' + that.options.formatOrder() + '</div></th>';
63 sModal += ' </tr>';
64 sModal += ' </thead>';
65 sModal += ' <tbody></tbody>';
66 sModal += ' </table>';
67 sModal += ' </div>';
68 sModal += ' </div>';
69 sModal += ' </div>';
70 sModal += ' <div class="modal-footer">';
71 sModal += ' <button type="button" class="btn btn-default" data-dismiss="modal">' + that.options.formatCancel() + '</button>';
72 sModal += ' <button type="button" class="btn btn-primary">' + that.options.formatSort() + '</button>';
73 sModal += ' </div>';
74 sModal += ' </div>';
75 sModal += ' </div>';
76 sModal += ' </div>';
77
78 $('body').append($(sModal));
79
80 that.$sortModal = $(_id);
81 var $rows = that.$sortModal.find('tbody > tr');
82
83 that.$sortModal.off('click', '#add').on('click', '#add', function () {
84 var total = that.$sortModal.find('.multi-sort-name:first option').length,
85 current = that.$sortModal.find('tbody tr').length;
86
87 if (current < total) {
88 current++;
89 that.addLevel();
90 that.setButtonStates();
91 }
92 });
93
94 that.$sortModal.off('click', '#delete').on('click', '#delete', function () {
95 var total = that.$sortModal.find('.multi-sort-name:first option').length,
96 current = that.$sortModal.find('tbody tr').length;
97
98 if (current > 1 && current <= total) {
99 current--;
100 that.$sortModal.find('tbody tr:last').remove();
101 that.setButtonStates();
102 }
103 });
104
105 that.$sortModal.off('click', '.btn-primary').on('click', '.btn-primary', function () {
106 var $rows = that.$sortModal.find('tbody > tr'),
107 $alert = that.$sortModal.find('div.alert'),
108 fields = [],
109 results = [];
110
111 that.options.sortPriority = $.map($rows, function (row) {
112 var $row = $(row),
113 name = $row.find('.multi-sort-name').val(),
114 order = $row.find('.multi-sort-order').val();
115
116 fields.push(name);
117
118 return {
119 sortName: name,
120 sortOrder: order
121 };
122 });
123
124 var sorted_fields = fields.sort();
125
126 for (var i = 0; i < fields.length - 1; i++) {
127 if (sorted_fields[i + 1] == sorted_fields[i]) {
128 results.push(sorted_fields[i]);
129 }
130 }
131
132 if (results.length > 0) {
133 if ($alert.length === 0) {
134 $alert = '<div class="alert alert-danger" role="alert"><strong>' + that.options.formatDuplicateAlertTitle() + '</strong> ' + that.options.formatDuplicateAlertDescription() + '</div>';
135 $($alert).insertBefore(that.$sortModal.find('.bars'));
136 }
137 } else {
138 if ($alert.length === 1) {
139 $($alert).remove();
140 }
141
142 that.$sortModal.modal('hide');
143 that.options.sortName = '';
144
145 if (that.options.sidePagination === 'server') {
146 var t = that.options.queryParams;
147 that.options.queryParams = function (params) {
148 params.multiSort = that.options.sortPriority;
149 return t(params);
150 };
151 isSingleSort = false;
152 that.initServer(that.options.silentSort);
153 return;
154 }
155 that.onMultipleSort();
156 }
157 });
158
159 if (that.options.sortPriority === null || that.options.sortPriority.length === 0) {
160 if (that.options.sortName) {
161 that.options.sortPriority = [{
162 sortName: that.options.sortName,
163 sortOrder: that.options.sortOrder
164 }];
165 }
166 }
167
168 if (that.options.sortPriority !== null && that.options.sortPriority.length > 0) {
169 if ($rows.length < that.options.sortPriority.length && _typeof(that.options.sortPriority) === 'object') {
170 for (var i = 0; i < that.options.sortPriority.length; i++) {
171 that.addLevel(i, that.options.sortPriority[i]);
172 }
173 }
174 } else {
175 that.addLevel(0);
176 }
177
178 that.setButtonStates();
179 }
180 };
181
182 $.fn.bootstrapTable.methods.push('multipleSort');
183
184 $.extend($.fn.bootstrapTable.defaults, {
185 showMultiSort: false,
186 showMultiSortButton: true,
187 sortPriority: null,
188 onMultipleSort: function onMultipleSort() {
189 return false;
190 }
191 });
192
193 $.extend($.fn.bootstrapTable.defaults.icons, {
194 sort: 'glyphicon-sort',
195 plus: 'glyphicon-plus',
196 minus: 'glyphicon-minus'
197 });
198
199 $.extend($.fn.bootstrapTable.Constructor.EVENTS, {
200 'multiple-sort.bs.table': 'onMultipleSort'
201 });
202
203 $.extend($.fn.bootstrapTable.locales, {
204 formatMultipleSort: function formatMultipleSort() {
205 return 'Multiple Sort';
206 },
207 formatAddLevel: function formatAddLevel() {
208 return 'Add Level';
209 },
210 formatDeleteLevel: function formatDeleteLevel() {
211 return 'Delete Level';
212 },
213 formatColumn: function formatColumn() {
214 return 'Column';
215 },
216 formatOrder: function formatOrder() {
217 return 'Order';
218 },
219 formatSortBy: function formatSortBy() {
220 return 'Sort by';
221 },
222 formatThenBy: function formatThenBy() {
223 return 'Then by';
224 },
225 formatSort: function formatSort() {
226 return 'Sort';
227 },
228 formatCancel: function formatCancel() {
229 return 'Cancel';
230 },
231 formatDuplicateAlertTitle: function formatDuplicateAlertTitle() {
232 return 'Duplicate(s) detected!';
233 },
234 formatDuplicateAlertDescription: function formatDuplicateAlertDescription() {
235 return 'Please remove or change any duplicate column.';
236 },
237 formatSortOrders: function formatSortOrders() {
238 return {
239 asc: 'Ascending',
240 desc: 'Descending'
241 };
242 }
243 });
244
245 $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales);
246
247 var BootstrapTable = $.fn.bootstrapTable.Constructor,
248 _initToolbar = BootstrapTable.prototype.initToolbar;
249
250 BootstrapTable.prototype.initToolbar = function () {
251 this.showToolbar = this.showToolbar || this.options.showMultiSort;
252 var that = this,
253 sortModalSelector = 'sortModal_' + this.$el.attr('id'),
254 sortModalId = '#' + sortModalSelector;
255 this.$sortModal = $(sortModalId);
256 this.sortModalSelector = sortModalSelector;
257
258 _initToolbar.apply(this, Array.prototype.slice.apply(arguments));
259
260 if (that.options.sidePagination === 'server' && !isSingleSort && that.options.sortPriority !== null) {
261 var t = that.options.queryParams;
262 that.options.queryParams = function (params) {
263 params.multiSort = that.options.sortPriority;
264 return t(params);
265 };
266 }
267
268 if (this.options.showMultiSort) {
269 var $btnGroup = this.$toolbar.find('>.btn-group').first(),
270 $multiSortBtn = this.$toolbar.find('div.multi-sort');
271
272 if (!$multiSortBtn.length && this.options.showMultiSortButton) {
273 $multiSortBtn = ' <button class="multi-sort btn btn-default' + (this.options.iconSize === undefined ? '' : ' btn-' + this.options.iconSize) + '" type="button" data-toggle="modal" data-target="' + sortModalId + '" title="' + this.options.formatMultipleSort() + '">';
274 $multiSortBtn += ' <i class="' + this.options.iconsPrefix + ' ' + this.options.icons.sort + '"></i>';
275 $multiSortBtn += '</button>';
276
277 $btnGroup.append($multiSortBtn);
278
279 showSortModal(that);
280 }
281
282 this.$el.on('sort.bs.table', function () {
283 isSingleSort = true;
284 });
285
286 this.$el.on('multiple-sort.bs.table', function () {
287 isSingleSort = false;
288 });
289
290 this.$el.on('load-success.bs.table', function () {
291 if (!isSingleSort && that.options.sortPriority !== null && _typeof(that.options.sortPriority) === 'object' && that.options.sidePagination !== 'server') {
292 that.onMultipleSort();
293 }
294 });
295
296 this.$el.on('column-switch.bs.table', function (field, checked) {
297 for (var i = 0; i < that.options.sortPriority.length; i++) {
298 if (that.options.sortPriority[i].sortName === checked) {
299 that.options.sortPriority.splice(i, 1);
300 }
301 }
302
303 that.assignSortableArrows();
304 that.$sortModal.remove();
305 showSortModal(that);
306 });
307
308 this.$el.on('reset-view.bs.table', function () {
309 if (!isSingleSort && that.options.sortPriority !== null && _typeof(that.options.sortPriority) === 'object') {
310 that.assignSortableArrows();
311 }
312 });
313 }
314 };
315
316 BootstrapTable.prototype.multipleSort = function () {
317 var that = this;
318 if (!isSingleSort && that.options.sortPriority !== null && _typeof(that.options.sortPriority) === 'object' && that.options.sidePagination !== 'server') {
319 that.onMultipleSort();
320 }
321 };
322
323 BootstrapTable.prototype.onMultipleSort = function () {
324 var that = this;
325
326 var cmp = function cmp(x, y) {
327 return x > y ? 1 : x < y ? -1 : 0;
328 };
329
330 var arrayCmp = function arrayCmp(a, b) {
331 var arr1 = [],
332 arr2 = [];
333
334 for (var i = 0; i < that.options.sortPriority.length; i++) {
335 var order = that.options.sortPriority[i].sortOrder === 'desc' ? -1 : 1,
336 aa = a[that.options.sortPriority[i].sortName],
337 bb = b[that.options.sortPriority[i].sortName];
338
339 if (aa === undefined || aa === null) {
340 aa = '';
341 }
342 if (bb === undefined || bb === null) {
343 bb = '';
344 }
345 if ($.isNumeric(aa) && $.isNumeric(bb)) {
346 aa = parseFloat(aa);
347 bb = parseFloat(bb);
348 }
349 if (typeof aa !== 'string') {
350 aa = aa.toString();
351 }
352
353 arr1.push(order * cmp(aa, bb));
354 arr2.push(order * cmp(bb, aa));
355 }
356
357 return cmp(arr1, arr2);
358 };
359
360 this.data.sort(function (a, b) {
361 return arrayCmp(a, b);
362 });
363
364 this.initBody();
365 this.assignSortableArrows();
366 this.trigger('multiple-sort');
367 };
368
369 BootstrapTable.prototype.addLevel = function (index, sortPriority) {
370 var text = index === 0 ? this.options.formatSortBy() : this.options.formatThenBy();
371
372 this.$sortModal.find('tbody').append($('<tr>').append($('<td>').text(text)).append($('<td>').append($('<select class="form-control multi-sort-name">'))).append($('<td>').append($('<select class="form-control multi-sort-order">'))));
373
374 var $multiSortName = this.$sortModal.find('.multi-sort-name').last(),
375 $multiSortOrder = this.$sortModal.find('.multi-sort-order').last();
376
377 $.each(this.columns, function (i, column) {
378 if (column.sortable === false || column.visible === false) {
379 return true;
380 }
381 $multiSortName.append('<option value="' + column.field + '">' + column.title + '</option>');
382 });
383
384 $.each(this.options.formatSortOrders(), function (value, order) {
385 $multiSortOrder.append('<option value="' + value + '">' + order + '</option>');
386 });
387
388 if (sortPriority !== undefined) {
389 $multiSortName.find('option[value="' + sortPriority.sortName + '"]').attr("selected", true);
390 $multiSortOrder.find('option[value="' + sortPriority.sortOrder + '"]').attr("selected", true);
391 }
392 };
393
394 BootstrapTable.prototype.assignSortableArrows = function () {
395 var that = this,
396 headers = that.$header.find('th');
397
398 for (var i = 0; i < headers.length; i++) {
399 for (var c = 0; c < that.options.sortPriority.length; c++) {
400 if ($(headers[i]).data('field') === that.options.sortPriority[c].sortName) {
401 $(headers[i]).find('.sortable').removeClass('desc asc').addClass(that.options.sortPriority[c].sortOrder);
402 }
403 }
404 }
405 };
406
407 BootstrapTable.prototype.setButtonStates = function () {
408 var total = this.$sortModal.find('.multi-sort-name:first option').length,
409 current = this.$sortModal.find('tbody tr').length;
410
411 if (current == total) {
412 this.$sortModal.find('#add').attr('disabled', 'disabled');
413 }
414 if (current > 1) {
415 this.$sortModal.find('#delete').removeAttr('disabled');
416 }
417 if (current < total) {
418 this.$sortModal.find('#add').removeAttr('disabled');
419 }
420 if (current == 1) {
421 this.$sortModal.find('#delete').attr('disabled', 'disabled');
422 }
423 };
424 })(jQuery);
425});
\No newline at end of file