├── .gitignore
├── .travis.yml
├── Contents
└── bootstrap-sortable.css
├── README.md
├── Scripts
├── bootstrap-sortable.js
└── moment.min.js
├── Tests
├── avoidFlippingOrder.html
├── avoidFlippingOrder.js
├── disableSortingOnRows.html
├── disableSortingOnRows.js
├── emptyRowsSorting.html
├── emptyRowsSorting.js
├── eventsRaising.html
├── eventsRaising.js
├── initializeSortingValues.html
├── initializeSortingValues.js
├── rowSpan.html
├── rowSpan.js
├── tableInsideTable.html
└── tableInsideTable.js
├── bower.json
├── karma.conf.js
├── license.md
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | npm-debug.log
3 | bower_components/*
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "4.2"
4 |
--------------------------------------------------------------------------------
/Contents/bootstrap-sortable.css:
--------------------------------------------------------------------------------
1 | /**
2 | * adding sorting ability to HTML tables with Bootstrap styling
3 | * @summary HTML tables sorting ability
4 | * @version 2.0.0
5 | * @requires tinysort, moment.js, jQuery
6 | * @license MIT
7 | * @author Matus Brlit (drvic10k)
8 | * @copyright Matus Brlit (drvic10k), bootstrap-sortable contributors
9 | */
10 |
11 | table.sortable span.sign {
12 | display: block;
13 | position: absolute;
14 | top: 50%;
15 | right: 5px;
16 | font-size: 12px;
17 | margin-top: -10px;
18 | color: #bfbfc1;
19 | }
20 |
21 | table.sortable th:after {
22 | display: block;
23 | position: absolute;
24 | top: 50%;
25 | right: 5px;
26 | font-size: 12px;
27 | margin-top: -10px;
28 | color: #bfbfc1;
29 | }
30 |
31 | table.sortable th.arrow:after {
32 | content: '';
33 | }
34 |
35 | table.sortable span.arrow, span.reversed, th.arrow.down:after, th.reversedarrow.down:after, th.arrow.up:after, th.reversedarrow.up:after {
36 | border-style: solid;
37 | border-width: 5px;
38 | font-size: 0;
39 | border-color: #ccc transparent transparent transparent;
40 | line-height: 0;
41 | height: 0;
42 | width: 0;
43 | margin-top: -2px;
44 | }
45 |
46 | table.sortable span.arrow.up, th.arrow.up:after {
47 | border-color: transparent transparent #ccc transparent;
48 | margin-top: -7px;
49 | }
50 |
51 | table.sortable span.reversed, th.reversedarrow.down:after {
52 | border-color: transparent transparent #ccc transparent;
53 | margin-top: -7px;
54 | }
55 |
56 | table.sortable span.reversed.up, th.reversedarrow.up:after {
57 | border-color: #ccc transparent transparent transparent;
58 | margin-top: -2px;
59 | }
60 |
61 | table.sortable span.az:before, th.az.down:after {
62 | content: "a .. z";
63 | }
64 |
65 | table.sortable span.az.up:before, th.az.up:after {
66 | content: "z .. a";
67 | }
68 |
69 | table.sortable th.az.nosort:after, th.AZ.nosort:after, th._19.nosort:after, th.month.nosort:after {
70 | content: "..";
71 | }
72 |
73 | table.sortable span.AZ:before, th.AZ.down:after {
74 | content: "A .. Z";
75 | }
76 |
77 | table.sortable span.AZ.up:before, th.AZ.up:after {
78 | content: "Z .. A";
79 | }
80 |
81 | table.sortable span._19:before, th._19.down:after {
82 | content: "1 .. 9";
83 | }
84 |
85 | table.sortable span._19.up:before, th._19.up:after {
86 | content: "9 .. 1";
87 | }
88 |
89 | table.sortable span.month:before, th.month.down:after {
90 | content: "jan .. dec";
91 | }
92 |
93 | table.sortable span.month.up:before, th.month.up:after {
94 | content: "dec .. jan";
95 | }
96 |
97 | table.sortable>thead th:not([data-defaultsort=disabled]) {
98 | cursor: pointer;
99 | position: relative;
100 | top: 0;
101 | left: 0;
102 | }
103 |
104 | table.sortable>thead th:hover:not([data-defaultsort=disabled]) {
105 | background: #efefef;
106 | }
107 |
108 | table.sortable>thead th div.mozilla {
109 | position: relative;
110 | }
111 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/drvic10k/bootstrap-sortable)
2 |
3 | If you like the plugin, you can send tips here
4 |
5 | [](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=M8EBWZL2QHN7Y¤cy_code=EUR&source=url)
6 |
7 | bootstrap-sortable
8 | ==================
9 | adding sorting ability to HTML tables with Bootstrap styling
10 | Current version: 1.12.0 / 2.1.0
11 |
12 | Sorting provided by [TinySort](https://github.com/Sjeiti/TinySort).
13 | Date parsing provided by [moment.js](https://github.com/timrwood/moment/).
14 |
15 | Available for download with NuGet, search for `bootstrap-sortable`.
16 | Working [demo](http://drvic10k.github.io/bootstrap-sortable/).
17 |
18 | For compatibility issues with older browsers and possible workarounds, please look into the [issues list](https://github.com/drvic10k/bootstrap-sortable/issues?labels=compatibility&page=1&state=closed).
19 |
20 | In version 2, the parameters to `$.bootstrapSortable` function were changed to single Object. For basic compatibility, you can still use single Boolean parameter (applyLast), other parameters are passed as properties of the Object.
21 |
22 | #### Dependencies:
23 | You should add the provided "moment.js" library, or get yourself a copy from http://momentjs.com.
24 |
25 | #### Basic usage:
26 |
27 | Add references to bootstrap-sortable.css and bootstrap-sortable.js to your page. Add class "sortable" to your bootstrap table.
28 | HTML table has to be properly formated, using ``, `` and ` |
` elements.
29 |
30 | You can disable sorting for a column by using `data-defaultsort='disabled'` attribute in the `` element.
31 |
32 | You can disable sorting for a row by using `data-disablesort='true'` attribute in the ` | ` element.
33 |
34 | When you add table rows or whole table from client side, use `$.bootstrapSortable({ applyLast: true })` function to add sortability to parts/tables that were not present at document.ready.
35 | Use optional paramater `applyLast=true` if you want to preserve the last used sorting.
36 |
37 | After sorting a column, the table triggers an event `sorted`.
38 |
39 | #### Cell with `colspan` and multiple header rows:
40 | When you have multiple header rows, all header cells in the same column can be used to sort that column.
41 |
42 | Cells with `colspan` can also be used for sorting. When not specified, the first column of the colspan will be used for sorting. You can override this by using `data-mainsort` attribute. (Use zero-based index as the value, `data-mainsort='1'` will sort the second column of the span.)
43 |
44 | If this cell is in the last row of the header, the sorting will be done according to this cell. If there is another row below, the cell in this row will be used. (i.e. the sorting sign, default-sort setting...)
45 |
46 | ##### !BREAKING CHANGE!
47 | This changes the previous behaviour, where it only worked if the `colspan` cell was not in the last row and the `mainsort` had to be set on the cell in the next row. Now the `mainsort` is set on the `colspan` cell.
48 |
49 | #### Sorting direction signs:
50 | You can choose the sign that show the sort direcion. Default is the arrow pointing towards the higher value.
51 |
52 | This proved to be counterintuitive for some, so you can change it to opposite using the second parameter: `$.bootstrapSortable({ sign: 'reversed' })`.
53 |
54 | Other possible values are `'az'`, `'AZ'`, `'_19'`, `'month'`. (See [demo](http://drvic10k.github.io/bootstrap-sortable/index.html) to see how it looks.)
55 |
56 | You can set individual signs for each column using `data-defaultsign` attribute in the `` element.
57 |
58 | ##### Alternative way of styling the sorting signs:
59 | Set `data-defaultsign='nospan'` and set a `class` on ` | ` elements. Then the sorting signs will be shown using `:after` pseudoelement on ` | `. This can be seen on the first column in the demo page.
60 | For this purpose, sorted column headers have classes `up`, `down` and `nosort` respectively and all previous styles are supported.
61 | You can also do your own styling in `css`.
62 |
63 | #### Optional attributes:
64 |
65 | You can preset one column to be sorted when table is loaded using `data-defaultsort` attribute:
66 | ```html
67 | | Column 1 |
68 | Column 2 |
69 | Column 3 |
70 | ```
71 |
72 | To change the initial direction when sorting a column for the first time, use the `data-firstsort` attribute:
73 | ```html
74 | Column 1 |
75 | Column 2 |
76 | Column 3 |
77 | ```
78 |
79 | You can change the value that is used for sorting for each `` using `data-value` attribute:
80 | ```html
81 | | 5,45 |
82 | ```
83 |
84 | You can sort dates, even if they are in different formats. Specify date formats according to moment.js documentation. This only works if you include any version of Moment.js. If Moment.js is not found it will fallback to the usual sorting.
85 | ```html
86 | 2013-06-24 |
87 | 26 June 2013 |
88 | ```
89 |
--------------------------------------------------------------------------------
/Scripts/bootstrap-sortable.js:
--------------------------------------------------------------------------------
1 | /**
2 | * adding sorting ability to HTML tables with Bootstrap styling
3 | * @summary HTML tables sorting ability
4 | * @version 2.0.1
5 | * @requires tinysort, moment.js, jQuery
6 | * @license MIT
7 | * @author Matus Brlit (drvic10k)
8 | * @copyright Matus Brlit (drvic10k), bootstrap-sortable contributors
9 | */
10 |
11 | /**
12 | * TinySort is a small script that sorts HTML elements. It sorts by text- or attribute value, or by that of one of it's children.
13 | * @summary A nodeElement sorting script.
14 | * @version 2.3.6
15 | * @license MIT
16 | * @author Ron Valstar
17 | * @copyright Ron Valstar
18 | * @namespace tinysort
19 | */
20 | !function (e, t) { "use strict"; function r() { return t } "function" == typeof define && define.amd ? define("tinysort", r) : e.tinysort = t }(this, function () { "use strict"; function e(e, n) { function s() { 0 === arguments.length ? v({}) : t(arguments, function (e) { v(x(e) ? { selector: e } : e) }), d = $.length } function v(e) { var t = !!e.selector, n = t && ":" === e.selector[0], o = r(e || {}, m); $.push(r({ hasSelector: t, hasAttr: !(o.attr === l || "" === o.attr), hasData: o.data !== l, hasFilter: n, sortReturnNumber: "asc" === o.order ? 1 : -1 }, o)) } function S() { t(e, function (e, t) { M ? M !== e.parentNode && (k = !1) : M = e.parentNode; var r = $[0], n = r.hasFilter, o = r.selector, a = !o || n && e.matchesSelector(o) || o && e.querySelector(o), l = a ? R : V, s = { elm: e, pos: t, posn: l.length }; B.push(s), l.push(s) }), D = R.slice(0) } function y(e, t, r) { for (var n = r(e.toString()), o = r(t.toString()), a = 0; n[a] && o[a]; a++) if (n[a] !== o[a]) { var l = Number(n[a]), s = Number(o[a]); return l == n[a] && s == o[a] ? l - s : n[a] > o[a] ? 1 : -1 } return n.length - o.length } function N(e) { for (var t, r, n = [], o = 0, a = -1, l = 0; t = (r = e.charAt(o++)).charCodeAt(0) ;) { var s = 46 == t || t >= 48 && 57 >= t; s !== l && (n[++a] = "", l = s), n[a] += r } return n } function C(e, r) { var n = 0; for (0 !== p && (p = 0) ; 0 === n && d > p;) { var l = $[p], s = l.ignoreDashes ? f : u; if (t(h, function (e) { var t = e.prepare; t && t(l) }), l.sortFunction) n = l.sortFunction(e, r); else if ("rand" == l.order) n = Math.random() < .5 ? 1 : -1; else { var c = a, g = w(e, l), m = w(r, l), v = "" === g || g === o, S = "" === m || m === o; if (g === m) n = 0; else if (l.emptyEnd && (v || S)) n = v && S ? 0 : v ? 1 : -1; else { if (!l.forceStrings) { var C = x(g) ? g && g.match(s) : a, b = x(m) ? m && m.match(s) : a; if (C && b) { var A = g.substr(0, g.length - C[0].length), F = m.substr(0, m.length - b[0].length); A == F && (c = !a, g = i(C[0]), m = i(b[0])) } } n = g === o || m === o ? 0 : l.natural && (isNaN(g) || isNaN(m)) ? y(g, m, N) : m > g ? -1 : g > m ? 1 : 0 } } t(h, function (e) { var t = e.sort; t && (n = t(l, c, g, m, n)) }), n *= l.sortReturnNumber, 0 === n && p++ } return 0 === n && (n = e.pos > r.pos ? 1 : -1), n } function b() { var e = R.length === B.length; if (k && e) O ? R.forEach(function (e, t) { e.elm.style.order = t }) : M ? M.appendChild(A()) : console.warn("parentNode has been removed"); else { var t = $[0], r = t.place, n = "org" === r, o = "start" === r, a = "end" === r, l = "first" === r, s = "last" === r; if (n) R.forEach(F), R.forEach(function (e, t) { E(D[t], e.elm) }); else if (o || a) { var c = D[o ? 0 : D.length - 1], i = c && c.elm.parentNode, u = i && (o && i.firstChild || i.lastChild); u && (u !== c.elm && (c = { elm: u }), F(c), a && i.appendChild(c.ghost), E(c, A())) } else if (l || s) { var f = D[l ? 0 : D.length - 1]; E(F(f), A()) } } } function A() { return R.forEach(function (e) { q.appendChild(e.elm) }), q } function F(e) { var t = e.elm, r = c.createElement("div"); return e.ghost = r, t.parentNode.insertBefore(r, t), e } function E(e, t) { var r = e.ghost, n = r.parentNode; n.insertBefore(t, r), n.removeChild(r), delete e.ghost } function w(e, t) { var r, n = e.elm; return t.selector && (t.hasFilter ? n.matchesSelector(t.selector) || (n = l) : n = n.querySelector(t.selector)), t.hasAttr ? r = n.getAttribute(t.attr) : t.useVal ? r = n.value || n.getAttribute("value") : t.hasData ? r = n.getAttribute("data-" + t.data) : n && (r = n.textContent), x(r) && (t.cases || (r = r.toLowerCase()), r = r.replace(/\s+/g, " ")), null === r && (r = g), r } function x(e) { return "string" == typeof e } x(e) && (e = c.querySelectorAll(e)), 0 === e.length && console.warn("No elements to sort"); var D, M, q = c.createDocumentFragment(), B = [], R = [], V = [], $ = [], k = !0, z = e.length && e[0].parentNode, L = z.rootNode !== document, O = e.length && (n === o || n.useFlex !== !1) && !L && -1 !== getComputedStyle(z, null).display.indexOf("flex"); return s.apply(l, Array.prototype.slice.call(arguments, 1)), S(), R.sort(C), b(), R.map(function (e) { return e.elm }) } function t(e, t) { for (var r, n = e.length, o = n; o--;) r = n - o - 1, t(e[r], r) } function r(e, t, r) { for (var n in t) (r || e[n] === o) && (e[n] = t[n]); return e } function n(e, t, r) { h.push({ prepare: e, sort: t, sortBy: r }) } var o, a = !1, l = null, s = window, c = s.document, i = parseFloat, u = /(-?\d+\.?\d*)\s*$/g, f = /(\d+\.?\d*)\s*$/g, h = [], d = 0, p = 0, g = String.fromCharCode(4095), m = { selector: l, order: "asc", attr: l, data: l, useVal: a, place: "org", returns: a, cases: a, natural: a, forceStrings: a, ignoreDashes: a, sortFunction: l, useFlex: a, emptyEnd: a }; return s.Element && function (e) { e.matchesSelector = e.matchesSelector || e.mozMatchesSelector || e.msMatchesSelector || e.oMatchesSelector || e.webkitMatchesSelector || function (e) { for (var t = this, r = (t.parentNode || t.document).querySelectorAll(e), n = -1; r[++n] && r[n] != t;); return !!r[n] } }(Element.prototype), r(n, { loop: t }), r(e, { plugin: n, defaults: m }) }());
21 |
22 | (function (global, factory) {
23 | if (typeof define === 'function' && define.amd) {
24 | define(['jquery', 'tinysort', 'moment'], factory);
25 | } else {
26 | factory(global.jQuery, global.tinysort, global.moment || undefined);
27 | }
28 | })(this, function ($, tinysort, moment) {
29 |
30 | var $document = $(document),
31 | signClass,
32 | sortEngine,
33 | emptyEnd;
34 |
35 | $.bootstrapSortable = function (options) {
36 | if (options == undefined) {
37 | initialize({});
38 | }
39 | else if (options.constructor === Boolean) {
40 | initialize({ applyLast: options });
41 | }
42 | else if (options.sortingHeader !== undefined) {
43 | sortByColumn(options.sortingHeader);
44 | }
45 | else {
46 | initialize(options);
47 | }
48 | };
49 |
50 | function initialize(options) {
51 | // Check if moment.js is available
52 | var momentJsAvailable = (typeof moment !== 'undefined');
53 |
54 | // Set class based on sign parameter
55 | signClass = !options.sign ? "arrow" : options.sign;
56 |
57 | // Set sorting algorithm
58 | if (options.customSort == 'default')
59 | options.customSort = defaultSortEngine;
60 | sortEngine = options.customSort || sortEngine || defaultSortEngine;
61 |
62 | emptyEnd = options.emptyEnd;
63 |
64 | // Set attributes needed for sorting
65 | $('table.sortable').each(function () {
66 | var $this = $(this);
67 | var applyLast = (options.applyLast === true);
68 | $this.find('span.sign').remove();
69 |
70 | // Add placeholder cells for colspans
71 | $this.find('> thead [colspan]').each(function () {
72 | var colspan = parseFloat($(this).attr('colspan'));
73 | for (var i = 1; i < colspan; i++) {
74 | $(this).after('');
75 | }
76 | });
77 |
78 | // Add placeholder cells for rowspans in header
79 | $this.find('> thead [rowspan]').each(function () {
80 | var $cell = $(this);
81 | var rowspan = parseFloat($cell.attr('rowspan'));
82 | for (var i = 1; i < rowspan; i++) {
83 | var parentRow = $cell.parent('tr');
84 | var nextRow = parentRow.next('tr');
85 | var index = parentRow.children().index($cell);
86 | nextRow.children().eq(index).before(' | ');
87 | }
88 | });
89 |
90 | // Set indexes to header cells
91 | $this.find('> thead tr').each(function (rowIndex) {
92 | $(this).find('th').each(function (columnIndex) {
93 | var $header = $(this);
94 | $header.addClass('nosort').removeClass('up down');
95 | $header.attr('data-sortcolumn', columnIndex);
96 | $header.attr('data-sortkey', columnIndex + '-' + rowIndex);
97 | });
98 | });
99 |
100 | // Cleanup placeholder cells
101 | $this.find('> thead .rowspan-compensate, .colspan-compensate').remove();
102 |
103 | // Initialize sorting values specified in header
104 | $this.find('th').each(function () {
105 | var $header = $(this);
106 | if ($header.attr('data-dateformat') !== undefined && momentJsAvailable) {
107 | var colNumber = parseFloat($header.attr('data-sortcolumn'));
108 | $this.find('td:nth-child(' + (colNumber + 1) + ')').each(function () {
109 | var $cell = $(this);
110 | $cell.attr('data-value', moment($cell.text(), $header.attr('data-dateformat')).format('YYYY/MM/DD/HH/mm/ss'));
111 | });
112 | }
113 | else if ($header.attr('data-valueprovider') !== undefined) {
114 | var colNumber = parseFloat($header.attr('data-sortcolumn'));
115 | $this.find('td:nth-child(' + (colNumber + 1) + ')').each(function () {
116 | var $cell = $(this);
117 | $cell.attr('data-value', new RegExp($header.attr('data-valueprovider')).exec($cell.text())[0]);
118 | });
119 | }
120 | });
121 |
122 | // Initialize sorting values
123 | $this.find('td').each(function () {
124 | var $cell = $(this);
125 | if ($cell.attr('data-dateformat') !== undefined && momentJsAvailable) {
126 | $cell.attr('data-value', moment($cell.text(), $cell.attr('data-dateformat')).format('YYYY/MM/DD/HH/mm/ss'));
127 | }
128 | else if ($cell.attr('data-valueprovider') !== undefined) {
129 | $cell.attr('data-value', new RegExp($cell.attr('data-valueprovider')).exec($cell.text())[0]);
130 | }
131 | else {
132 | $cell.attr('data-value') === undefined && $cell.attr('data-value', $cell.text());
133 | }
134 | });
135 |
136 | var context = lookupSortContext($this),
137 | bsSort = context.bsSort;
138 |
139 | $this.find('> thead th[data-defaultsort!="disabled"]').each(function (index) {
140 | var $header = $(this);
141 | var $sortTable = $header.closest('table.sortable');
142 | $header.data('sortTable', $sortTable);
143 | var sortKey = $header.attr('data-sortkey');
144 | var thisLastSort = applyLast ? context.lastSort : -1;
145 | bsSort[sortKey] = applyLast ? bsSort[sortKey] : $header.attr('data-defaultsort');
146 | if (bsSort[sortKey] !== undefined && (applyLast === (sortKey === thisLastSort))) {
147 | bsSort[sortKey] = bsSort[sortKey] === 'asc' ? 'desc' : 'asc';
148 | doSort($header, $sortTable);
149 | }
150 | });
151 | });
152 | }
153 |
154 | // Clean up placeholder cells for rowspans in body
155 | function removeRowspanPlaceholders(table) {
156 | table.find('> tbody [rowspan-group]').each(function () {
157 | var $this = $(this);
158 | var id = $this.attr('rowspan-group');
159 | var parentRow = $this.parent('tr');
160 | var index = parentRow.children().index($this);
161 |
162 | while(true) {
163 | var nextRow = parentRow.next('tr');
164 | if (!nextRow.is('tr'))
165 | break;
166 | var nextCell = nextRow.children().eq(index);
167 |
168 | if (nextCell.attr('rowspan-group') === id) {
169 | var rowspan = parseFloat($this.attr('rowspan')) || 1;
170 | $this.attr('rowspan', rowspan + 1);
171 | nextCell.remove();
172 | } else {
173 | break;
174 | }
175 | parentRow = nextRow;
176 | }
177 | });
178 | }
179 |
180 | // Add placeholder cells for rowspans in body
181 | function addRowspanPlaceholders(table) {
182 | table.find('> tbody [rowspan]').each(function () {
183 | var $cell = $(this);
184 | var rowspan = parseFloat($cell.attr('rowspan'));
185 | $cell.removeAttr('rowspan');
186 | var rowSpanId = $cell.attr('rowspan-group') || guid();
187 | $cell.attr('rowspan-group', rowSpanId);
188 | $cell.attr('rowspan-value', rowspan);
189 | var parentRow = $cell.parent('tr');
190 | var index = parentRow.children().index($cell);
191 | for (var i = 1; i < rowspan; i++) {
192 | var compemnsationCell = $cell.clone(false);
193 | var nextRow = parentRow.next('tr');
194 | nextRow.children().eq(index).before(compemnsationCell);
195 | parentRow = nextRow;
196 | }
197 | });
198 | }
199 |
200 | // Add click event to table header
201 | $document.on('click', 'table.sortable>thead th[data-defaultsort!="disabled"]', function (e) {
202 | sortByColumn(this);
203 | });
204 |
205 | // element is the header of the column to sort (the clicked header)
206 | function sortByColumn(element) {
207 | var $this = $(element), $table = $this.data('sortTable') || $this.closest('table.sortable');
208 | doSort($this, $table);
209 | }
210 |
211 | // Look up sorting data appropriate for the specified table (jQuery element).
212 | // This allows multiple tables on one page without collisions.
213 | function lookupSortContext($table) {
214 | var context = $table.data("bootstrap-sortable-context");
215 | if (context === undefined) {
216 | context = { bsSort: [], lastSort: undefined };
217 | $table.find('> thead th[data-defaultsort!="disabled"]').each(function (index) {
218 | var $this = $(this);
219 | var sortKey = $this.attr('data-sortkey');
220 | context.bsSort[sortKey] = $this.attr('data-defaultsort');
221 | if (context.bsSort[sortKey] !== undefined) {
222 | context.lastSort = sortKey;
223 | }
224 | });
225 | $table.data("bootstrap-sortable-context", context);
226 | }
227 | return context;
228 | }
229 |
230 | function defaultSortEngine(rows, sortingParams) {
231 | tinysort(rows, sortingParams);
232 | }
233 |
234 | // Sorting mechanism separated
235 | function doSort($this, $table) {
236 | $table.trigger('before-sort');
237 |
238 | addRowspanPlaceholders($table);
239 |
240 | var sortColumn = parseFloat($this.attr('data-sortcolumn')),
241 | context = lookupSortContext($table),
242 | bsSort = context.bsSort;
243 |
244 | var colspan = $this.attr('colspan');
245 | if (colspan) {
246 | var mainSort = parseFloat($this.data('mainsort')) || 0;
247 | var rowIndex = parseFloat($this.data('sortkey').split('-').pop());
248 |
249 | // If there is one more row in header, delve deeper
250 | if ($table.find('> thead tr').length - 1 > rowIndex) {
251 | doSort($table.find('[data-sortkey="' + (sortColumn + mainSort) + '-' + (rowIndex + 1) + '"]'), $table);
252 | return;
253 | }
254 | // Otherwise, just adjust the sortColumn
255 | sortColumn = sortColumn + mainSort;
256 | }
257 |
258 | var localSignClass = $this.attr('data-defaultsign') || signClass;
259 |
260 | // update arrow icon
261 | $table.find('> thead th').each(function () {
262 | $(this).removeClass('up').removeClass('down').addClass('nosort');
263 | });
264 |
265 | if ($.browser.mozilla) {
266 | var moz_arrow = $table.find('> thead div.mozilla');
267 | if (moz_arrow !== undefined) {
268 | moz_arrow.find('.sign').remove();
269 | moz_arrow.parent().html(moz_arrow.html());
270 | }
271 | $this.wrapInner('');
272 | $this.children().eq(0).append('');
273 | }
274 | else {
275 | $table.find('> thead span.sign').remove();
276 | $this.append('');
277 | }
278 |
279 | // sort direction
280 | var sortKey = $this.attr('data-sortkey');
281 | var initialDirection = $this.attr('data-firstsort') !== 'desc' ? 'desc' : 'asc';
282 |
283 | var newDirection = (bsSort[sortKey] || initialDirection);
284 | if (context.lastSort === sortKey || bsSort[sortKey] === undefined) {
285 | newDirection = newDirection === 'asc' ? 'desc' : 'asc';
286 | }
287 | bsSort[sortKey] = newDirection;
288 | context.lastSort = sortKey;
289 |
290 | if (bsSort[sortKey] === 'desc') {
291 | $this.find('span.sign').addClass('up');
292 | $this.addClass('up').removeClass('down nosort');
293 | } else {
294 | $this.addClass('down').removeClass('up nosort');
295 | }
296 |
297 | // remove rows that should not be sorted
298 | var rows = $table.children('tbody').children('tr');
299 | var fixedRows = [];
300 | $(rows.filter('[data-disablesort="true"]').get().reverse()).each(function (index, fixedRow) {
301 | var $fixedRow = $(fixedRow);
302 | fixedRows.push({ index: rows.index($fixedRow), row: $fixedRow });
303 | $fixedRow.remove();
304 | });
305 |
306 | // sort rows
307 | var rowsToSort = rows.not('[data-disablesort="true"]');
308 | if (rowsToSort.length != 0) {
309 | var emptySorting = bsSort[sortKey] === 'asc' ? emptyEnd : false;
310 | sortEngine(rowsToSort, { emptyEnd: emptySorting, selector: 'td:nth-child(' + (sortColumn + 1) + ')', order: bsSort[sortKey], data: 'value' });
311 | }
312 |
313 | // add back the fixed rows
314 | $(fixedRows.reverse()).each(function (index, row) {
315 | if (row.index === 0) {
316 | $table.children('tbody').prepend(row.row);
317 | } else {
318 | $table.children('tbody').children('tr').eq(row.index - 1).after(row.row);
319 | }
320 | });
321 |
322 | // add class to sorted column cells
323 | $table.find('> tbody > tr > td.sorted,> thead th.sorted').removeClass('sorted');
324 | rowsToSort.find('td:eq(' + sortColumn + ')').addClass('sorted');
325 | $this.addClass('sorted');
326 |
327 | removeRowspanPlaceholders($table);
328 | $table.trigger('sorted');
329 | }
330 |
331 | // jQuery 1.9 removed this object
332 | if (!$.browser) {
333 | $.browser = { chrome: false, mozilla: false, opera: false, msie: false, safari: false };
334 | var ua = navigator.userAgent;
335 | $.each($.browser, function (c) {
336 | $.browser[c] = ((new RegExp(c, 'i').test(ua))) ? true : false;
337 | if ($.browser.mozilla && c === 'mozilla') { $.browser.mozilla = ((new RegExp('firefox', 'i').test(ua))) ? true : false; }
338 | if ($.browser.chrome && c === 'safari') { $.browser.safari = false; }
339 | });
340 | }
341 |
342 | function guid() {
343 | function s4() {
344 | return Math.floor((1 + Math.random()) * 0x10000)
345 | .toString(16)
346 | .substring(1);
347 | }
348 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
349 | s4() + '-' + s4() + s4() + s4();
350 | }
351 |
352 | // Initialise on DOM ready
353 | $($.bootstrapSortable);
354 |
355 | });
356 |
--------------------------------------------------------------------------------
/Scripts/moment.min.js:
--------------------------------------------------------------------------------
1 | //! moment.js
2 | //! version : 2.3.1
3 | //! authors : Tim Wood, Iskren Chernev, Moment.js contributors
4 | //! license : MIT
5 | //! momentjs.com
6 | (function(a){function b(a,b){return function(c){return i(a.call(this,c),b)}}function c(a,b){return function(c){return this.lang().ordinal(a.call(this,c),b)}}function d(){}function e(a){u(a),g(this,a)}function f(a){var b=o(a),c=b.year||0,d=b.month||0,e=b.week||0,f=b.day||0,g=b.hour||0,h=b.minute||0,i=b.second||0,j=b.millisecond||0;this._input=a,this._milliseconds=+j+1e3*i+6e4*h+36e5*g,this._days=+f+7*e,this._months=+d+12*c,this._data={},this._bubble()}function g(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return b.hasOwnProperty("toString")&&(a.toString=b.toString),b.hasOwnProperty("valueOf")&&(a.valueOf=b.valueOf),a}function h(a){return 0>a?Math.ceil(a):Math.floor(a)}function i(a,b){for(var c=a+"";c.lengthd;d++)(c&&a[d]!==b[d]||!c&&q(a[d])!==q(b[d]))&&g++;return g+f}function n(a){if(a){var b=a.toLowerCase().replace(/(.)s$/,"$1");a=Jb[a]||Kb[b]||b}return a}function o(a){var b,c,d={};for(c in a)a.hasOwnProperty(c)&&(b=n(c),b&&(d[b]=a[c]));return d}function p(b){var c,d;if(0===b.indexOf("week"))c=7,d="day";else{if(0!==b.indexOf("month"))return;c=12,d="month"}bb[b]=function(e,f){var g,h,i=bb.fn._lang[b],j=[];if("number"==typeof e&&(f=e,e=a),h=function(a){var b=bb().utc().set(d,a);return i.call(bb.fn._lang,b,e||"")},null!=f)return h(f);for(g=0;c>g;g++)j.push(h(g));return j}}function q(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=b>=0?Math.floor(b):Math.ceil(b)),c}function r(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function s(a){return t(a)?366:365}function t(a){return 0===a%4&&0!==a%100||0===a%400}function u(a){var b;a._a&&-2===a._pf.overflow&&(b=a._a[gb]<0||a._a[gb]>11?gb:a._a[hb]<1||a._a[hb]>r(a._a[fb],a._a[gb])?hb:a._a[ib]<0||a._a[ib]>23?ib:a._a[jb]<0||a._a[jb]>59?jb:a._a[kb]<0||a._a[kb]>59?kb:a._a[lb]<0||a._a[lb]>999?lb:-1,a._pf._overflowDayOfYear&&(fb>b||b>hb)&&(b=hb),a._pf.overflow=b)}function v(a){a._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1}}function w(a){return null==a._isValid&&(a._isValid=!isNaN(a._d.getTime())&&a._pf.overflow<0&&!a._pf.empty&&!a._pf.invalidMonth&&!a._pf.nullInput&&!a._pf.invalidFormat&&!a._pf.userInvalidated,a._strict&&(a._isValid=a._isValid&&0===a._pf.charsLeftOver&&0===a._pf.unusedTokens.length)),a._isValid}function x(a){return a?a.toLowerCase().replace("_","-"):a}function y(a,b){return b.abbr=a,mb[a]||(mb[a]=new d),mb[a].set(b),mb[a]}function z(a){delete mb[a]}function A(a){var b,c,d,e,f=0,g=function(a){if(!mb[a]&&nb)try{require("./lang/"+a)}catch(b){}return mb[a]};if(!a)return bb.fn._lang;if(!k(a)){if(c=g(a))return c;a=[a]}for(;f0;){if(c=g(e.slice(0,b).join("-")))return c;if(d&&d.length>=b&&m(e,d,!0)>=b-1)break;b--}f++}return bb.fn._lang}function B(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function C(a){var b,c,d=a.match(rb);for(b=0,c=d.length;c>b;b++)d[b]=Ob[d[b]]?Ob[d[b]]:B(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function D(a,b){return a.isValid()?(b=E(b,a.lang()),Lb[b]||(Lb[b]=C(b)),Lb[b](a)):a.lang().invalidDate()}function E(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(sb.lastIndex=0;d>=0&&sb.test(a);)a=a.replace(sb,c),sb.lastIndex=0,d-=1;return a}function F(a,b){var c;switch(a){case"DDDD":return vb;case"YYYY":case"GGGG":case"gggg":return wb;case"YYYYY":case"GGGGG":case"ggggg":return xb;case"S":case"SS":case"SSS":case"DDD":return ub;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":return yb;case"a":case"A":return A(b._l)._meridiemParse;case"X":return Bb;case"Z":case"ZZ":return zb;case"T":return Ab;case"MM":case"DD":case"YY":case"GG":case"gg":case"HH":case"hh":case"mm":case"ss":case"M":case"D":case"d":case"H":case"h":case"m":case"s":case"w":case"ww":case"W":case"WW":case"e":case"E":return tb;default:return c=new RegExp(N(M(a.replace("\\","")),"i"))}}function G(a){var b=(zb.exec(a)||[])[0],c=(b+"").match(Gb)||["-",0,0],d=+(60*c[1])+q(c[2]);return"+"===c[0]?-d:d}function H(a,b,c){var d,e=c._a;switch(a){case"M":case"MM":null!=b&&(e[gb]=q(b)-1);break;case"MMM":case"MMMM":d=A(c._l).monthsParse(b),null!=d?e[gb]=d:c._pf.invalidMonth=b;break;case"D":case"DD":null!=b&&(e[hb]=q(b));break;case"DDD":case"DDDD":null!=b&&(c._dayOfYear=q(b));break;case"YY":e[fb]=q(b)+(q(b)>68?1900:2e3);break;case"YYYY":case"YYYYY":e[fb]=q(b);break;case"a":case"A":c._isPm=A(c._l).isPM(b);break;case"H":case"HH":case"h":case"hh":e[ib]=q(b);break;case"m":case"mm":e[jb]=q(b);break;case"s":case"ss":e[kb]=q(b);break;case"S":case"SS":case"SSS":e[lb]=q(1e3*("0."+b));break;case"X":c._d=new Date(1e3*parseFloat(b));break;case"Z":case"ZZ":c._useUTC=!0,c._tzm=G(b);break;case"w":case"ww":case"W":case"WW":case"d":case"dd":case"ddd":case"dddd":case"e":case"E":a=a.substr(0,1);case"gg":case"gggg":case"GG":case"GGGG":case"GGGGG":a=a.substr(0,2),b&&(c._w=c._w||{},c._w[a]=b)}}function I(a){var b,c,d,e,f,g,h,i,j,k,l=[];if(!a._d){for(d=K(a),a._w&&null==a._a[hb]&&null==a._a[gb]&&(f=function(b){return b?b.length<3?parseInt(b,10)>68?"19"+b:"20"+b:b:null==a._a[fb]?bb().weekYear():a._a[fb]},g=a._w,null!=g.GG||null!=g.W||null!=g.E?h=X(f(g.GG),g.W||1,g.E,4,1):(i=A(a._l),j=null!=g.d?T(g.d,i):null!=g.e?parseInt(g.e,10)+i._week.dow:0,k=parseInt(g.w,10)||1,null!=g.d&&js(e)&&(a._pf._overflowDayOfYear=!0),c=S(e,0,a._dayOfYear),a._a[gb]=c.getUTCMonth(),a._a[hb]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=l[b]=d[b];for(;7>b;b++)a._a[b]=l[b]=null==a._a[b]?2===b?1:0:a._a[b];l[ib]+=q((a._tzm||0)/60),l[jb]+=q((a._tzm||0)%60),a._d=(a._useUTC?S:R).apply(null,l)}}function J(a){var b;a._d||(b=o(a._i),a._a=[b.year,b.month,b.day,b.hour,b.minute,b.second,b.millisecond],I(a))}function K(a){var b=new Date;return a._useUTC?[b.getUTCFullYear(),b.getUTCMonth(),b.getUTCDate()]:[b.getFullYear(),b.getMonth(),b.getDate()]}function L(a){a._a=[],a._pf.empty=!0;var b,c,d,e,f,g=A(a._l),h=""+a._i,i=h.length,j=0;for(d=E(a._f,g).match(rb)||[],b=0;b0&&a._pf.unusedInput.push(f),h=h.slice(h.indexOf(c)+c.length),j+=c.length),Ob[e]?(c?a._pf.empty=!1:a._pf.unusedTokens.push(e),H(e,c,a)):a._strict&&!c&&a._pf.unusedTokens.push(e);a._pf.charsLeftOver=i-j,h.length>0&&a._pf.unusedInput.push(h),a._isPm&&a._a[ib]<12&&(a._a[ib]+=12),a._isPm===!1&&12===a._a[ib]&&(a._a[ib]=0),I(a),u(a)}function M(a){return a.replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e})}function N(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function O(a){var b,c,d,e,f;if(0===a._f.length)return a._pf.invalidFormat=!0,a._d=new Date(0/0),void 0;for(e=0;ef)&&(d=f,c=b));g(a,c||b)}function P(a){var b,c=a._i,d=Cb.exec(c);if(d){for(b=4;b>0;b--)if(d[b]){a._f=Eb[b-1]+(d[6]||" ");break}for(b=0;4>b;b++)if(Fb[b][1].exec(c)){a._f+=Fb[b][0];break}zb.exec(c)&&(a._f+=" Z"),L(a)}else a._d=new Date(c)}function Q(b){var c=b._i,d=ob.exec(c);c===a?b._d=new Date:d?b._d=new Date(+d[1]):"string"==typeof c?P(b):k(c)?(b._a=c.slice(0),I(b)):l(c)?b._d=new Date(+c):"object"==typeof c?J(b):b._d=new Date(c)}function R(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 1970>a&&h.setFullYear(a),h}function S(a){var b=new Date(Date.UTC.apply(null,arguments));return 1970>a&&b.setUTCFullYear(a),b}function T(a,b){if("string"==typeof a)if(isNaN(a)){if(a=b.weekdaysParse(a),"number"!=typeof a)return null}else a=parseInt(a,10);return a}function U(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function V(a,b,c){var d=eb(Math.abs(a)/1e3),e=eb(d/60),f=eb(e/60),g=eb(f/24),h=eb(g/365),i=45>d&&["s",d]||1===e&&["m"]||45>e&&["mm",e]||1===f&&["h"]||22>f&&["hh",f]||1===g&&["d"]||25>=g&&["dd",g]||45>=g&&["M"]||345>g&&["MM",eb(g/30)]||1===h&&["y"]||["yy",h];return i[2]=b,i[3]=a>0,i[4]=c,U.apply({},i)}function W(a,b,c){var d,e=c-b,f=c-a.day();return f>e&&(f-=7),e-7>f&&(f+=7),d=bb(a).add("d",f),{week:Math.ceil(d.dayOfYear()/7),year:d.year()}}function X(a,b,c,d,e){var f,g,h=new Date(Date.UTC(a,0)).getUTCDay();return c=null!=c?c:e,f=e-h+(h>d?7:0),g=7*(b-1)+(c-e)+f+1,{year:g>0?a:a-1,dayOfYear:g>0?g:s(a-1)+g}}function Y(a){var b=a._i,c=a._f;return"undefined"==typeof a._pf&&v(a),null===b?bb.invalid({nullInput:!0}):("string"==typeof b&&(a._i=b=A().preparse(b)),bb.isMoment(b)?(a=g({},b),a._d=new Date(+b._d)):c?k(c)?O(a):L(a):Q(a),new e(a))}function Z(a,b){bb.fn[a]=bb.fn[a+"s"]=function(a){var c=this._isUTC?"UTC":"";return null!=a?(this._d["set"+c+b](a),bb.updateOffset(this),this):this._d["get"+c+b]()}}function $(a){bb.duration.fn[a]=function(){return this._data[a]}}function _(a,b){bb.duration.fn["as"+a]=function(){return+this/b}}function ab(){"undefined"==typeof ender&&(this.moment=bb)}for(var bb,cb,db="2.3.1",eb=Math.round,fb=0,gb=1,hb=2,ib=3,jb=4,kb=5,lb=6,mb={},nb="undefined"!=typeof module&&module.exports,ob=/^\/?Date\((\-?\d+)/i,pb=/(\-)?(?:(\d*)\.)?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?)?/,qb=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,rb=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,sb=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,tb=/\d\d?/,ub=/\d{1,3}/,vb=/\d{3}/,wb=/\d{1,4}/,xb=/[+\-]?\d{1,6}/,yb=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,zb=/Z|[\+\-]\d\d:?\d\d/i,Ab=/T/i,Bb=/[\+\-]?\d+(\.\d{1,3})?/,Cb=/^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?$/,Db="YYYY-MM-DDTHH:mm:ssZ",Eb=["YYYY-MM-DD","GGGG-[W]WW","GGGG-[W]WW-E","YYYY-DDD"],Fb=[["HH:mm:ss.S",/(T| )\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],Gb=/([\+\-]|\d\d)/gi,Hb="Date|Hours|Minutes|Seconds|Milliseconds".split("|"),Ib={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},Jb={ms:"millisecond",s:"second",m:"minute",h:"hour",d:"day",D:"date",w:"week",W:"isoWeek",M:"month",y:"year",DDD:"dayOfYear",e:"weekday",E:"isoWeekday",gg:"weekYear",GG:"isoWeekYear"},Kb={dayofyear:"dayOfYear",isoweekday:"isoWeekday",isoweek:"isoWeek",weekyear:"weekYear",isoweekyear:"isoWeekYear"},Lb={},Mb="DDD w W M D d".split(" "),Nb="M D H h m s w W".split(" "),Ob={M:function(){return this.month()+1},MMM:function(a){return this.lang().monthsShort(this,a)},MMMM:function(a){return this.lang().months(this,a)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(a){return this.lang().weekdaysMin(this,a)},ddd:function(a){return this.lang().weekdaysShort(this,a)},dddd:function(a){return this.lang().weekdays(this,a)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return i(this.year()%100,2)},YYYY:function(){return i(this.year(),4)},YYYYY:function(){return i(this.year(),5)},gg:function(){return i(this.weekYear()%100,2)},gggg:function(){return this.weekYear()},ggggg:function(){return i(this.weekYear(),5)},GG:function(){return i(this.isoWeekYear()%100,2)},GGGG:function(){return this.isoWeekYear()},GGGGG:function(){return i(this.isoWeekYear(),5)},e:function(){return this.weekday()},E:function(){return this.isoWeekday()},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return q(this.milliseconds()/100)},SS:function(){return i(q(this.milliseconds()/10),2)},SSS:function(){return i(this.milliseconds(),3)},Z:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+i(q(a/60),2)+":"+i(q(a)%60,2)},ZZ:function(){var a=-this.zone(),b="+";return 0>a&&(a=-a,b="-"),b+i(q(10*a/6),4)},z:function(){return this.zoneAbbr()},zz:function(){return this.zoneName()},X:function(){return this.unix()}},Pb=["months","monthsShort","weekdays","weekdaysShort","weekdaysMin"];Mb.length;)cb=Mb.pop(),Ob[cb+"o"]=c(Ob[cb],cb);for(;Nb.length;)cb=Nb.pop(),Ob[cb+cb]=b(Ob[cb],2);for(Ob.DDDD=b(Ob.DDD,3),g(d.prototype,{set:function(a){var b,c;for(c in a)b=a[c],"function"==typeof b?this[c]=b:this["_"+c]=b},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(a){return this._months[a.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(a){return this._monthsShort[a.month()]},monthsParse:function(a){var b,c,d;for(this._monthsParse||(this._monthsParse=[]),b=0;12>b;b++)if(this._monthsParse[b]||(c=bb.utc([2e3,b]),d="^"+this.months(c,"")+"|^"+this.monthsShort(c,""),this._monthsParse[b]=new RegExp(d.replace(".",""),"i")),this._monthsParse[b].test(a))return b},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(a){return this._weekdays[a.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(a){return this._weekdaysShort[a.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(a){return this._weekdaysMin[a.day()]},weekdaysParse:function(a){var b,c,d;for(this._weekdaysParse||(this._weekdaysParse=[]),b=0;7>b;b++)if(this._weekdaysParse[b]||(c=bb([2e3,1]).day(b),d="^"+this.weekdays(c,"")+"|^"+this.weekdaysShort(c,"")+"|^"+this.weekdaysMin(c,""),this._weekdaysParse[b]=new RegExp(d.replace(".",""),"i")),this._weekdaysParse[b].test(a))return b},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(a){var b=this._longDateFormat[a];return!b&&this._longDateFormat[a.toUpperCase()]&&(b=this._longDateFormat[a.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a]=b),b},isPM:function(a){return"p"===(a+"").toLowerCase().charAt(0)},_meridiemParse:/[ap]\.?m?\.?/i,meridiem:function(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},calendar:function(a,b){var c=this._calendar[a];return"function"==typeof c?c.apply(b):c},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(a,b,c,d){var e=this._relativeTime[c];return"function"==typeof e?e(a,b,c,d):e.replace(/%d/i,a)},pastFuture:function(a,b){var c=this._relativeTime[a>0?"future":"past"];return"function"==typeof c?c(b):c.replace(/%s/i,b)},ordinal:function(a){return this._ordinal.replace("%d",a)},_ordinal:"%d",preparse:function(a){return a},postformat:function(a){return a},week:function(a){return W(a,this._week.dow,this._week.doy).week},_week:{dow:0,doy:6},_invalidDate:"Invalid date",invalidDate:function(){return this._invalidDate}}),bb=function(b,c,d,e){return"boolean"==typeof d&&(e=d,d=a),Y({_i:b,_f:c,_l:d,_strict:e,_isUTC:!1})},bb.utc=function(b,c,d,e){var f;return"boolean"==typeof d&&(e=d,d=a),f=Y({_useUTC:!0,_isUTC:!0,_l:d,_i:b,_f:c,_strict:e}).utc()},bb.unix=function(a){return bb(1e3*a)},bb.duration=function(a,b){var c,d,e,g=bb.isDuration(a),h="number"==typeof a,i=g?a._input:h?{}:a,j=null;return h?b?i[b]=a:i.milliseconds=a:(j=pb.exec(a))?(c="-"===j[1]?-1:1,i={y:0,d:q(j[hb])*c,h:q(j[ib])*c,m:q(j[jb])*c,s:q(j[kb])*c,ms:q(j[lb])*c}):(j=qb.exec(a))&&(c="-"===j[1]?-1:1,e=function(a){var b=a&&parseFloat(a.replace(",","."));return(isNaN(b)?0:b)*c},i={y:e(j[2]),M:e(j[3]),d:e(j[4]),h:e(j[5]),m:e(j[6]),s:e(j[7]),w:e(j[8])}),d=new f(i),g&&a.hasOwnProperty("_lang")&&(d._lang=a._lang),d},bb.version=db,bb.defaultFormat=Db,bb.updateOffset=function(){},bb.lang=function(a,b){var c;return a?(b?y(x(a),b):null===b?(z(a),a="en"):mb[a]||A(a),c=bb.duration.fn._lang=bb.fn._lang=A(a),c._abbr):bb.fn._lang._abbr},bb.langData=function(a){return a&&a._lang&&a._lang._abbr&&(a=a._lang._abbr),A(a)},bb.isMoment=function(a){return a instanceof e},bb.isDuration=function(a){return a instanceof f},cb=Pb.length-1;cb>=0;--cb)p(Pb[cb]);for(bb.normalizeUnits=function(a){return n(a)},bb.invalid=function(a){var b=bb.utc(0/0);return null!=a?g(b._pf,a):b._pf.userInvalidated=!0,b},bb.parseZone=function(a){return bb(a).parseZone()},g(bb.fn=e.prototype,{clone:function(){return bb(this)},valueOf:function(){return+this._d+6e4*(this._offset||0)},unix:function(){return Math.floor(+this/1e3)},toString:function(){return this.clone().lang("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._offset?new Date(+this):this._d},toISOString:function(){return D(bb(this).utc(),"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var a=this;return[a.year(),a.month(),a.date(),a.hours(),a.minutes(),a.seconds(),a.milliseconds()]},isValid:function(){return w(this)},isDSTShifted:function(){return this._a?this.isValid()&&m(this._a,(this._isUTC?bb.utc(this._a):bb(this._a)).toArray())>0:!1},parsingFlags:function(){return g({},this._pf)},invalidAt:function(){return this._pf.overflow},utc:function(){return this.zone(0)},local:function(){return this.zone(0),this._isUTC=!1,this},format:function(a){var b=D(this,a||bb.defaultFormat);return this.lang().postformat(b)},add:function(a,b){var c;return c="string"==typeof a?bb.duration(+b,a):bb.duration(a,b),j(this,c,1),this},subtract:function(a,b){var c;return c="string"==typeof a?bb.duration(+b,a):bb.duration(a,b),j(this,c,-1),this},diff:function(a,b,c){var d,e,f=this._isUTC?bb(a).zone(this._offset||0):bb(a).local(),g=6e4*(this.zone()-f.zone());return b=n(b),"year"===b||"month"===b?(d=432e5*(this.daysInMonth()+f.daysInMonth()),e=12*(this.year()-f.year())+(this.month()-f.month()),e+=(this-bb(this).startOf("month")-(f-bb(f).startOf("month")))/d,e-=6e4*(this.zone()-bb(this).startOf("month").zone()-(f.zone()-bb(f).startOf("month").zone()))/d,"year"===b&&(e/=12)):(d=this-f,e="second"===b?d/1e3:"minute"===b?d/6e4:"hour"===b?d/36e5:"day"===b?(d-g)/864e5:"week"===b?(d-g)/6048e5:d),c?e:h(e)},from:function(a,b){return bb.duration(this.diff(a)).lang(this.lang()._abbr).humanize(!b)},fromNow:function(a){return this.from(bb(),a)},calendar:function(){var a=this.diff(bb().zone(this.zone()).startOf("day"),"days",!0),b=-6>a?"sameElse":-1>a?"lastWeek":0>a?"lastDay":1>a?"sameDay":2>a?"nextDay":7>a?"nextWeek":"sameElse";return this.format(this.lang().calendar(b,this))},isLeapYear:function(){return t(this.year())},isDST:function(){return this.zone()+bb(a).startOf(b)},isBefore:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)<+bb(a).startOf(b)},isSame:function(a,b){return b="undefined"!=typeof b?b:"millisecond",+this.clone().startOf(b)===+bb(a).startOf(b)},min:function(a){return a=bb.apply(null,arguments),this>a?this:a},max:function(a){return a=bb.apply(null,arguments),a>this?this:a},zone:function(a){var b=this._offset||0;return null==a?this._isUTC?b:this._d.getTimezoneOffset():("string"==typeof a&&(a=G(a)),Math.abs(a)<16&&(a=60*a),this._offset=a,this._isUTC=!0,b!==a&&j(this,bb.duration(b-a,"m"),1,!0),this)},zoneAbbr:function(){return this._isUTC?"UTC":""},zoneName:function(){return this._isUTC?"Coordinated Universal Time":""},parseZone:function(){return"string"==typeof this._i&&this.zone(this._i),this},hasAlignedHourOffset:function(a){return a=a?bb(a).zone():0,0===(this.zone()-a)%60},daysInMonth:function(){return r(this.year(),this.month())},dayOfYear:function(a){var b=eb((bb(this).startOf("day")-bb(this).startOf("year"))/864e5)+1;return null==a?b:this.add("d",a-b)},weekYear:function(a){var b=W(this,this.lang()._week.dow,this.lang()._week.doy).year;return null==a?b:this.add("y",a-b)},isoWeekYear:function(a){var b=W(this,1,4).year;return null==a?b:this.add("y",a-b)},week:function(a){var b=this.lang().week(this);return null==a?b:this.add("d",7*(a-b))},isoWeek:function(a){var b=W(this,1,4).week;return null==a?b:this.add("d",7*(a-b))},weekday:function(a){var b=(this.day()+7-this.lang()._week.dow)%7;return null==a?b:this.add("d",a-b)},isoWeekday:function(a){return null==a?this.day()||7:this.day(this.day()%7?a:a-7)},get:function(a){return a=n(a),this[a]()},set:function(a,b){return a=n(a),"function"==typeof this[a]&&this[a](b),this},lang:function(b){return b===a?this._lang:(this._lang=A(b),this)}}),cb=0;cb
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 | h1 |
11 | h2 |
12 |
13 |
14 |
15 |
16 | a |
17 | z |
18 |
19 |
20 | b |
21 | y |
22 |
23 |
24 | c |
25 | x |
26 |
27 |
28 | d |
29 | w |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Tests/avoidFlippingOrder.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Avoid flipping order', function () {
4 | beforeEach(function () {
5 | jasmine.getFixtures().load('avoidFlippingOrder.html');
6 | $.bootstrapSortable();
7 | });
8 |
9 | it("Initially 'a' is first", function () {
10 | var index = $('#az').index('tbody tr');
11 | expect(index).toBe(0);
12 | });
13 |
14 | it("Click h2, 'w' is first", function () {
15 | $.bootstrapSortable({ sortingHeader: $('#h2') });
16 | var index = $('#dw').index('tbody tr');
17 | expect(index).toBe(0);
18 | });
19 |
20 | it("Click h2 twice, 'a' is first", function () {
21 | $.bootstrapSortable({ sortingHeader: $('#h2') });
22 | $.bootstrapSortable({ sortingHeader: $('#h2') });
23 | var index = $('#az').index('tbody tr');
24 | expect(index).toBe(0);
25 | });
26 |
27 | it("Click h2 and h1, 'a' is first", function () {
28 | $.bootstrapSortable({ sortingHeader: $('#h2') });
29 | $.bootstrapSortable({ sortingHeader: $('#h1') });
30 | var index = $('#az').index('tbody tr');
31 | expect(index).toBe(0);
32 | });
33 | })
--------------------------------------------------------------------------------
/Tests/disableSortingOnRows.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 | |
11 |
12 |
13 |
14 |
15 | a |
16 |
17 |
18 | b |
19 |
20 |
21 | c |
22 |
23 |
24 | z |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Tests/disableSortingOnRows.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Disable sorting on rows', function () {
4 | beforeEach(function () {
5 | jasmine.getFixtures().load('disableSortingOnRows.html');
6 | $.bootstrapSortable();
7 | });
8 |
9 | it("First row stays first", function () {
10 | var index = $('#first').index('tbody tr td');
11 | expect(index).toBe(0);
12 | });
13 |
14 | it("Last row stays last", function () {
15 | var index = $('#last').index('tbody tr td');
16 | expect(index).toBe(3);
17 | });
18 |
19 | it("Middle rows are ordered", function () {
20 | var index = $('#b').index('tbody tr td');
21 | expect(index).toBe(2);
22 | });
23 | })
--------------------------------------------------------------------------------
/Tests/emptyRowsSorting.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | |
16 |
17 |
18 | |
19 |
20 |
21 | |
22 |
23 |
24 | a |
25 |
26 |
27 | z |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Tests/emptyRowsSorting.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Empty rows sorting', function () {
4 |
5 | describe('Empty rows are sorted at the end { emptyEnd: true }', function () {
6 | beforeEach(function () {
7 | jasmine.getFixtures().load('emptyRowsSorting.html');
8 | $.bootstrapSortable({ emptyEnd: true });
9 | });
10 |
11 | it("Sort ascending", function () {
12 | var header = $('#header');
13 | $.bootstrapSortable({ sortingHeader: header });
14 | var indexA = $('#a').index('tbody tr td');
15 | var indexZ = $('#z').index('tbody tr td');
16 | expect(indexA).toBe(0);
17 | expect(indexZ).toBe(1);
18 | });
19 |
20 | it("Sort descending", function () {
21 | $.bootstrapSortable({ sortingHeader: header });
22 | $.bootstrapSortable({ sortingHeader: header });
23 | var indexZ = $('#z').index('tbody tr td');
24 | var indexA = $('#a').index('tbody tr td');
25 | expect(indexZ).toBe(0);
26 | expect(indexA).toBe(1);
27 | });
28 | });
29 |
30 | describe('Empty rows are sorted as default (beginning of the alphabet)', function () {
31 | beforeEach(function () {
32 | jasmine.getFixtures().load('emptyRowsSorting.html');
33 | $.bootstrapSortable();
34 | });
35 |
36 | it("Sort ascending", function () {
37 | var header = $('#header');
38 | $.bootstrapSortable({ sortingHeader: header });
39 | var indexA = $('#a').index('tbody tr td');
40 | var indexZ = $('#z').index('tbody tr td');
41 | expect(indexA).toBe(3);
42 | expect(indexZ).toBe(4);
43 | });
44 |
45 | it("Sort descending", function () {
46 | $.bootstrapSortable({ sortingHeader: header });
47 | $.bootstrapSortable({ sortingHeader: header });
48 | var indexA = $('#a').index('tbody tr td');
49 | var indexZ = $('#z').index('tbody tr td');
50 | expect(indexZ).toBe(0);
51 | expect(indexA).toBe(1);
52 | });
53 | });
54 | });
--------------------------------------------------------------------------------
/Tests/eventsRaising.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 | h1 |
11 | h2 |
12 |
13 |
14 |
15 |
16 | a |
17 | z |
18 |
19 |
20 | b |
21 | y |
22 |
23 |
24 | c |
25 | x |
26 |
27 |
28 | d |
29 | w |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Tests/eventsRaising.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Events raising', function () {
4 | beforeEach(function () {
5 | jasmine.getFixtures().load('eventsRaising.html');
6 | });
7 |
8 | it("before-sort is raised on initialization", function () {
9 | var table = $('table.sortable');
10 | var wasRaised = false;
11 | table.on('before-sort', function() {
12 | wasRaised = true;
13 | });
14 | $.bootstrapSortable();
15 | expect(wasRaised).toBe(true);
16 | });
17 |
18 | it("sorted is raised on initialization", function () {
19 | var table = $('table.sortable');
20 | var wasRaised = false;
21 | table.on('sorted', function () {
22 | wasRaised = true;
23 | });
24 | $.bootstrapSortable();
25 | expect(wasRaised).toBe(true);
26 | });
27 |
28 | it("before-sort is raised on manual sorting", function () {
29 | var table = $('table.sortable');
30 | var wasRaised = false;
31 | $.bootstrapSortable();
32 | table.on('before-sort', function () {
33 | wasRaised = true;
34 | });
35 | $.bootstrapSortable({ sortingHeader: $('#h2') });
36 | expect(wasRaised).toBe(true);
37 | });
38 |
39 | it("sorted is raised on manual sorting", function () {
40 | var table = $('table.sortable');
41 | var wasRaised = false;
42 | $.bootstrapSortable();
43 | table.on('sorted', function () {
44 | wasRaised = true;
45 | });
46 | $.bootstrapSortable({ sortingHeader: $('#h2') });
47 | expect(wasRaised).toBe(true);
48 | });
49 | })
--------------------------------------------------------------------------------
/Tests/initializeSortingValues.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 |
17 |
18 |
19 |
20 | 22/3/2012 |
21 | direct value |
22 | direct value |
23 | 10% |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/Tests/initializeSortingValues.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Initializing sorting values', function () {
4 | beforeEach(function () {
5 | jasmine.getFixtures().load('initializeSortingValues.html');
6 | $.bootstrapSortable();
7 | });
8 |
9 | it("Date value", function () {
10 | var cell = $('#date');
11 | expect(cell).toHaveData('value', '2012/03/22/00/00/00');
12 | });
13 |
14 | it("Automatic value", function () {
15 | var cell = $('#auto');
16 | expect(cell).toHaveData('value', 'direct value');
17 | });
18 |
19 | it("Specified value", function () {
20 | var cell = $('#specified');
21 | expect(cell).toHaveData('value', 'specified value');
22 | });
23 |
24 | it("Regex value", function () {
25 | var cell = $('#regex');
26 | expect(cell).toHaveData('value', 10);
27 | });
28 |
29 | describe('Format in header', function() {
30 | it("Correctly applied date format", function () {
31 | var cell = $('#dateHeader');
32 | expect(cell).toHaveData('value', '2012/03/22/00/00/00');
33 | });
34 |
35 | it("Correctly applied regex value", function () {
36 | var cell = $('#regexHeader');
37 | expect(cell).toHaveData('value', 10);
38 | });
39 | });
40 | })
--------------------------------------------------------------------------------
/Tests/rowSpan.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 | column a |
11 | column b |
12 | column c |
13 |
14 |
15 |
16 |
17 | cell a1 |
18 | cell b1 |
19 | cell c1 |
20 |
21 |
22 | cell b2 |
23 | cell c2 |
24 |
25 |
26 | cell b3 |
27 | cell c3 |
28 |
29 |
30 | cell a4 |
31 | cell b4 |
32 | cell c4 |
33 |
34 |
35 | cell a5 |
36 | cell b5 |
37 | cell c5 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Tests/rowSpan.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Sorting cells with rowspan', function() {
4 | beforeEach(function() {
5 | jasmine.getFixtures().load('rowSpan.html');
6 | $.bootstrapSortable();
7 | });
8 |
9 | it("Sort 1st column, cells are correct in first row", function() {
10 | $.bootstrapSortable({ sortingHeader: $('#ha') });
11 | $.bootstrapSortable({ sortingHeader: $('#ha') });
12 |
13 | expect($('#a1').index('#row1 td')).toBe(0);
14 | expect($('#b1').index('#row1 td')).toBe(1);
15 | expect($('#c1').index('#row1 td')).toBe(2);
16 | });
17 |
18 | it("Sort 1st column, cells are correct in second row", function () {
19 | $.bootstrapSortable({ sortingHeader: $('#ha') });
20 | $.bootstrapSortable({ sortingHeader: $('#ha') });
21 |
22 | expect($('#b2').index('#row2 td')).toBe(0);
23 | expect($('#c2').index('#row2 td')).toBe(1);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/Tests/tableInsideTable.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bootstrap Sortable Tables
5 |
6 |
7 |
8 |
9 |
10 | head1 |
11 | head2 |
12 | head3 |
13 | head4 |
14 |
15 |
16 |
17 |
18 | 2 |
19 | hi |
20 | 2015/04/08 |
21 | 5.234 |
22 |
23 |
24 | 5 |
25 | yeah |
26 | 2013/03/16 |
27 | 548.2154 |
28 |
29 |
30 | 1 |
31 | test |
32 | 2005/10/24 |
33 | 1.547 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | head1 |
41 | head2 |
42 | head3 |
43 | head4 |
44 |
45 |
46 |
47 |
48 | 2 |
49 | hi |
50 | 2015/04/08 |
51 | 5.234 |
52 |
53 |
54 | 5 |
55 | yeah |
56 | 2013/03/16 |
57 | 548.2154 |
58 |
59 |
60 | 1 |
61 | test |
62 | 2005/10/24 |
63 | 1.547 |
64 |
65 |
66 |
67 | |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/Tests/tableInsideTable.js:
--------------------------------------------------------------------------------
1 | jasmine.getFixtures().fixturesPath = 'base/Tests/';
2 |
3 | describe('Table inside table sorting', function() {
4 | beforeEach(function() {
5 | jasmine.getFixtures().load('tableInsideTable.html');
6 | $.bootstrapSortable();
7 | });
8 |
9 | it("Outer table has correct order of rows", function() {
10 | var index = $('#outerFirst').index('#outer > tr');
11 | expect(index).toBe(1);
12 | });
13 |
14 | it("Inner table has correct order of rows", function() {
15 | var index = $('#innerFirst').index('#inner > tr');
16 | expect(index).toBe(0);
17 | });
18 |
19 | it("Inner table header keeps sorted class after outer sorting", function() {
20 | var innerHeader = $('#innerh1');
21 | expect(innerHeader.hasClass('sorted')).toBe(true);
22 |
23 | $.bootstrapSortable({ sortingHeader: $('#outerh2') });
24 | expect(innerHeader.hasClass('sorted')).toBe(true);
25 | });
26 |
27 | it("Inner table header keeps sorted icon after outer sorting", function() {
28 | var innerHeader = $('#innerh1');
29 | expect(innerHeader.children('.sign').length).toBe(1);
30 |
31 | $.bootstrapSortable({ sortingHeader: $('#outerh2') });
32 | expect(innerHeader.children('.sign').length).toBe(1);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap-sortable",
3 | "version": "2.0.0",
4 | "homepage": "https://github.com/drvic10k/bootstrap-sortable",
5 | "authors": [
6 | "Matus Brlit "
7 | ],
8 | "description": "Adding sorting ability to HTML tables",
9 | "main": "Scripts/bootstrap-sortable.js",
10 | "keywords": [
11 | "sort table", "sortable", "sortable table", "bootstrap sortable", "bootstrap-sortable"
12 | ],
13 | "license": "MIT",
14 | "ignore": [
15 | "Scripts/moment.min.js"
16 | ],
17 | "dependencies": {
18 | "jquery": ">= 1.9.0",
19 | "moment": ">= 2.3.1"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | var configuration = {
3 |
4 | // base path that will be used to resolve all patterns (eg. files, exclude)
5 | basePath: '',
6 |
7 |
8 | // frameworks to use
9 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
10 | frameworks: ['jasmine'],
11 |
12 |
13 | // list of files / patterns to load in the browser
14 | files: [
15 | 'node_modules/jquery/dist/jquery.js',
16 | 'node_modules/jasmine-jquery/lib/jasmine-jquery.js',
17 | 'node_modules/jasmine2-custom-message/jasmine2-custom-message.js',
18 | { pattern: 'Tests/*.html', included: true },
19 | { pattern: 'Tests/*.js', included: true },
20 | 'Scripts/moment.min.js',
21 | 'Scripts/bootstrap-sortable.js'
22 | ],
23 |
24 |
25 | // list of files to exclude
26 | exclude: [
27 | ],
28 |
29 |
30 | // preprocess matching files before serving them to the browser
31 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
32 | preprocessors: {
33 | },
34 |
35 |
36 | // test results reporter to use
37 | // possible values: 'dots', 'progress'
38 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
39 | reporters: ['mocha'],
40 |
41 |
42 | // enable / disable colors in the output (reporters and logs)
43 | colors: true,
44 |
45 |
46 | // level of logging
47 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
48 | logLevel: config.LOG_INFO,
49 |
50 |
51 | // enable / disable watching file and executing tests whenever any file changes
52 | autoWatch: false,
53 |
54 |
55 | // start these browsers
56 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
57 | browsers: ['PhantomJS'],
58 |
59 | // Continuous Integration mode
60 | // if true, Karma captures browsers, runs the tests and exits
61 | singleRun: true
62 | };
63 |
64 | config.set(configuration);
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Matúš Brliť (drvic10k), bootstrap-sortable contributors
2 |
3 | Copyright (c) 2011-2013 Tim Wood, Iskren Chernev, Moment.js contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap-sortable",
3 | "version": "1.11.2",
4 | "description": "adding sorting ability to HTML tables",
5 | "main": "Scripts/bootstrap-sortable.js",
6 | "scripts": {
7 | "test": "karma start karma.conf.js --single-run"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/drvic10k/bootstrap-sortable.git"
12 | },
13 | "author": "Matus Brlit ",
14 | "license": "MIT",
15 | "bugs": {
16 | "url": "https://github.com/drvic10k/bootstrap-sortable/issues"
17 | },
18 | "homepage": "https://github.com/drvic10k/bootstrap-sortable#readme",
19 | "devDependencies": {
20 | "grunt": "^0.4.5",
21 | "jasmine-core": "^2.4.1",
22 | "jasmine-jquery": "^2.1.1",
23 | "jasmine2-custom-message": "^0.8.0",
24 | "jquery": "^2.1.4",
25 | "karma": "^0.13.16",
26 | "karma-jasmine": "^0.3.6",
27 | "karma-mocha-reporter": "^1.1.3",
28 | "karma-phantomjs-launcher": "^0.2.2",
29 | "phantomjs": "^1.9.19"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
|