Skip to content

Commit

Permalink
Merge pull request #439 from UCF/sort
Browse files Browse the repository at this point in the history
Sortable Library Swap
  • Loading branch information
jmbarne3 authored Jul 30, 2024
2 parents a498ab1 + 6eca624 commit deffcdc
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
//

// =require media-background-lazyload.js
// =require sortable.js
236 changes: 236 additions & 0 deletions src/js/sortable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
(function () {
let SELECTOR, addEventListener, clickEvents, numberRegExp, sortable, touchDevice, trimRegExp;

SELECTOR = 'table[data-sortable]';

numberRegExp = /^-?[£$¤]?[\d,.]+%?$/;

trimRegExp = /^\s+|\s+$/g;

clickEvents = ['click'];

touchDevice = 'ontouchstart' in document.documentElement;

if (touchDevice) {
clickEvents.push('touchstart');
}

addEventListener = function (el, event, handler) {
if (el.addEventListener != null) {
return el.addEventListener(event, handler, false);
}
return el.attachEvent(`on${event}`, handler);

};

sortable = {
init: function (options) {
let _i, _len, _results, table, tables;
if (options == null) {
options = {};
}
if (options.selector == null) {
options.selector = SELECTOR;
}
tables = document.querySelectorAll(options.selector);
_results = [];
for (_i = 0, _len = tables.length; _i < _len; _i++) {
table = tables[_i];
_results.push(sortable.initTable(table));
}
return _results;
},
initTable: function (table) {
let _i, _len, _ref, i, th, ths;
if (((_ref = table.tHead) != null ? _ref.rows.length : void 0) !== 1) {
return;
}
if (table.getAttribute('data-sortable-initialized') === 'true') {
return;
}
table.setAttribute('data-sortable-initialized', 'true');
ths = table.querySelectorAll('th');
for (i = _i = 0, _len = ths.length; _i < _len; i = ++_i) {
th = ths[i];
if (th.getAttribute('data-sortable') !== 'false') {
sortable.setupClickableTH(table, th, i);
}
}
return table;
},
setupClickableTH: function (table, th, i) {
let _i, _len, _results, eventName, onClick, type;
type = sortable.getColumnType(table, i);
onClick = function (e) {
let _compare, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, compare, item, newSortedDirection, position, row, rowArray, sorted, sortedDirection, tBody, ths, value;
if (e.handled !== true) {
e.handled = true;
} else {
return false;
}
sorted = this.getAttribute('data-sorted') === 'true';
sortedDirection = this.getAttribute('data-sorted-direction');
if (sorted) {
newSortedDirection = sortedDirection === 'ascending' ? 'descending' : 'ascending';
} else {
newSortedDirection = type.defaultSortDirection;
}
ths = this.parentNode.querySelectorAll('th');
for (_i = 0, _len = ths.length; _i < _len; _i++) {
th = ths[_i];
th.setAttribute('data-sorted', 'false');
th.removeAttribute('data-sorted-direction');
}
this.setAttribute('data-sorted', 'true');
this.setAttribute('data-sorted-direction', newSortedDirection);
tBody = table.tBodies[0];
rowArray = [];
if (!sorted) {
if (type.compare != null) {
_compare = type.compare;
} else {
_compare = function (a, b) {
return b - a;
};
}
compare = function (a, b) {
if (a[0] === b[0]) {
return a[2] - b[2];
}
if (type.reverse) {
return _compare(b[0], a[0]);
}
return _compare(a[0], b[0]);

};
_ref = tBody.rows;
for (position = _j = 0, _len1 = _ref.length; _j < _len1; position = ++_j) {
row = _ref[position];
value = sortable.getNodeValue(row.cells[i]);
if (type.comparator != null) {
value = type.comparator(value);
}
rowArray.push([value, row, position]);
}
rowArray.sort(compare);
for (_k = 0, _len2 = rowArray.length; _k < _len2; _k++) {
row = rowArray[_k];
tBody.appendChild(row[1]);
}
} else {
_ref1 = tBody.rows;
for (_l = 0, _len3 = _ref1.length; _l < _len3; _l++) {
item = _ref1[_l];
rowArray.push(item);
}
rowArray.reverse();
for (_m = 0, _len4 = rowArray.length; _m < _len4; _m++) {
row = rowArray[_m];
tBody.appendChild(row);
}
}
if (typeof window.CustomEvent === 'function') {
return typeof table.dispatchEvent === 'function' ? table.dispatchEvent(new CustomEvent('Sortable.sorted', {
bubbles: true
})) : void 0;
}
};
_results = [];
for (_i = 0, _len = clickEvents.length; _i < _len; _i++) {
eventName = clickEvents[_i];
_results.push(addEventListener(th, eventName, onClick));
}
return _results;
},
getColumnType: function (table, i) {
let _i, _j, _len, _len1, _ref, _ref1, _ref2, row, specified, text, type;
specified = (_ref = table.querySelectorAll('th')[i]) != null ? _ref.getAttribute('data-sortable-type') : void 0;
if (specified != null) {
return sortable.typesObject[specified];
}
_ref1 = table.tBodies[0].rows;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
row = _ref1[_i];
text = sortable.getNodeValue(row.cells[i]);
_ref2 = sortable.types;
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
type = _ref2[_j];
if (type.match(text)) {
return type;
}
}
}
return sortable.typesObject.alpha;
},
getNodeValue: function (node) {
let dataValue;
if (!node) {
return '';
}
dataValue = node.getAttribute('data-value');
if (dataValue !== null) {
return dataValue;
}
if (typeof node.innerText !== 'undefined') {
return node.innerText.replace(trimRegExp, '');
}
return node.textContent.replace(trimRegExp, '');
},
setupTypes: function (types) {
let _i, _len, _results, type;
sortable.types = types;
sortable.typesObject = {};
_results = [];
for (_i = 0, _len = types.length; _i < _len; _i++) {
type = types[_i];
_results.push(sortable.typesObject[type.name] = type);
}
return _results;
}
};

sortable.setupTypes([
{
name: 'numeric',
defaultSortDirection: 'descending',
match: function (a) {
return a.match(numberRegExp);
},
comparator: function (a) {
return parseFloat(a.replace(/[^0-9.-]/g, ''), 10) || 0;
}
}, {
name: 'date',
defaultSortDirection: 'ascending',
reverse: true,
match: function (a) {
return !isNaN(Date.parse(a));
},
comparator: function (a) {
return Date.parse(a) || 0;
}
}, {
name: 'alpha',
defaultSortDirection: 'ascending',
match: function () {
return true;
},
compare: function (a, b) {
return a.localeCompare(b);
}
}
]);

setTimeout(sortable.init, 0);

if (typeof define === 'function' && define.amd) {
define(() => {
return sortable;
});
} else if (typeof exports !== 'undefined') {
module.exports = sortable;
} else {
window.Sortable = sortable;
}

}).call(this);
49 changes: 49 additions & 0 deletions src/scss/sortable/_sortable.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
=sortable
table[data-sortable]
border-collapse: collapse
border-spacing: 0

th
vertical-align: bottom
font-weight: bold

th, td
text-align: left
padding: 10px

th:not([data-sortable="false"])
-webkit-user-select: none
-moz-user-select: none
-ms-user-select: none
-o-user-select: none
user-select: none
-webkit-tap-highlight-color: rgba(0, 0, 0, 0)
-webkit-touch-callout: none
cursor: pointer

th

&:after
content: ""
visibility: hidden
display: inline-block
vertical-align: inherit
height: 0
width: 0
border-width: 5px
border-style: solid
border-color: transparent
margin-right: 1px
margin-left: 10px
float: right

&[data-sorted="true"]:after
visibility: visible

&[data-sorted-direction="descending"]:after
border-top-color: inherit
margin-top: 8px

&[data-sorted-direction="ascending"]:after
border-bottom-color: inherit
margin-top: 8px - 5px
32 changes: 32 additions & 0 deletions src/scss/sortable/sortable-theme-bootstrap.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@import sortable

+sortable

table[data-sortable].sortable-theme-bootstrap
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
font-size: 14px
line-height: 20px
color: #333
background: #fff

thead th
border-bottom: 2px solid #e0e0e0

tbody td
border-top: 1px solid #e0e0e0

th[data-sorted="true"]
color: #3a87ad
background: #d9edf7
border-bottom-color: #bce8f1

&[data-sorted-direction="descending"]:after
border-top-color: #3a87ad

&[data-sorted-direction="ascending"]:after
border-bottom-color: #3a87ad

&.sortable-theme-bootstrap-striped

tbody > tr:nth-child(odd) > td
background-color: #f9f9f9
13 changes: 13 additions & 0 deletions src/scss/sortable/sortable-theme-dark.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@import sortable

+sortable

table[data-sortable].sortable-theme-dark
color: #b9b9b9
background: #252525

tbody td
border-top: 1px solid #2e2e2e

th[data-sorted="true"]
background: #2e2e2e
51 changes: 51 additions & 0 deletions src/scss/sortable/sortable-theme-finder.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
@import compass/css3
@import sortable

+sortable

table[data-sortable].sortable-theme-finder
font-family: "Lucida Grande", sans-serif
font-size: 12px
line-height: 18px
color: #000
background: #fff
border: 1px solid #cfcfcf

th, td
padding: 2px 8px

thead th
+background-image(linear-gradient(#fff 0%, #f6f6f6 50%, #f0f0f0 50%, #eee 100%))
background-color: #f0f0f0
border-bottom: 1px solid #ccc
font-weight: normal

tbody > tr:nth-child(odd) > td
background-color: #f3f6fa

th

&:after
border-width: 4px
margin-right: 0

&[data-sorted="true"]
+background-image(linear-gradient(#c5e2f6 0%, #80c1f0 50%, #b8e7f5 100%))
+background-size(28px 100%)
+box-shadow(inset 1px 0 #7eb3d3, inset -1px 0 #7eb3d3)
border-bottom-color: #7eb3d3
background-color: #78c0f0

&:first-child
+box-shadow(inset -1px 0 #7eb3d3)

&:last-child
+box-shadow(inset 1px 0 #7eb3d3)

&[data-sorted-direction="descending"]:after
border-top-color: #548ec0
margin-top: 6px

&[data-sorted-direction="ascending"]:after
border-bottom-color: #548ec0
margin-top: 6px - 4px
Loading

0 comments on commit deffcdc

Please sign in to comment.