UNPKG

ng-grid

Version:

__Contributors:__

168 lines (166 loc) 6.32 kB
ngGridServices.factory('SortService', ['$parse', function($parse) { var sortService = {}; sortService.colSortFnCache = {}; // cache of sorting functions. Once we create them, we don't want to keep re-doing it // this takes an piece of data from the cell and tries to determine its type and what sorting // function to use for it // @item - the cell data sortService.guessSortFn = function(item) { var itemType = typeof(item); //check for numbers and booleans switch (itemType) { case "number": return sortService.sortNumber; case "boolean": return sortService.sortBool; case "string": // if number string return number string sort fn. else return the str return item.match(/^-?[£$¤]?[\d,.]+%?$/) ? sortService.sortNumberStr : sortService.sortAlpha; default: //check if the item is a valid Date if (Object.prototype.toString.call(item) === '[object Date]') { return sortService.sortDate; } else { //finally just sort the basic sort... return sortService.basicSort; } } }; //#region Sorting Functions sortService.basicSort = function(a, b) { if (a == b) { return 0; } if (a < b) { return -1; } return 1; }; sortService.sortNumber = function(a, b) { return a - b; }; sortService.sortNumberStr = function(a, b) { var numA, numB, badA = false, badB = false; numA = parseFloat(a.replace(/[^0-9.-]/g, '')); if (isNaN(numA)) { badA = true; } numB = parseFloat(b.replace(/[^0-9.-]/g, '')); if (isNaN(numB)) { badB = true; } // we want bad ones to get pushed to the bottom... which effectively is "greater than" if (badA && badB) { return 0; } if (badA) { return 1; } if (badB) { return -1; } return numA - numB; }; sortService.sortAlpha = function(a, b) { var strA = a.toLowerCase(), strB = b.toLowerCase(); return strA == strB ? 0 : (strA < strB ? -1 : 1); }; sortService.sortDate = function(a, b) { var timeA = a.getTime(), timeB = b.getTime(); return timeA == timeB ? 0 : (timeA < timeB ? -1 : 1); }; sortService.sortBool = function(a, b) { if (a && b) { return 0; } if (!a && !b) { return 0; } else { return a ? 1 : -1; } }; //#endregion // the core sorting logic trigger sortService.sortData = function(sortInfo, data /*datasource*/) { // first make sure we are even supposed to do work if (!data || !sortInfo) { return; } var l = sortInfo.fields.length, order = sortInfo.fields, col, direction, // IE9 HACK.... omg, I can't reference data array within the sort fn below. has to be a separate reference....!!!! d = data.slice(0); //now actually sort the data data.sort(function (itemA, itemB) { var tem = 0, indx = 0, sortFn; while (tem == 0 && indx < l) { // grab the metadata for the rest of the logic col = sortInfo.columns[indx]; direction = sortInfo.directions[indx], sortFn = sortService.getSortFn(col, d); var propA = $parse(order[indx])(itemA); var propB = $parse(order[indx])(itemB); // we want to allow zero values to be evaluated in the sort function if ((!propA && propA != 0) || (!propB && propB != 0)) { // we want to force nulls and such to the bottom when we sort... which effectively is "greater than" if (!propB && !propA) { tem = 0; } else if (!propA) { tem = 1; } else if (!propB) { tem = -1; } } else { tem = sortFn(propA, propB); } indx++; } //made it this far, we don't have to worry about null & undefined if (direction === ASC) { return tem; } else { return 0 - tem; } }); }; sortService.Sort = function(sortInfo, data) { if (sortService.isSorting) { return; } sortService.isSorting = true; sortService.sortData(sortInfo, data); sortService.isSorting = false; }; sortService.getSortFn = function(col, data) { var sortFn = undefined, item; //see if we already figured out what to use to sort the column if (sortService.colSortFnCache[col.field]) { sortFn = sortService.colSortFnCache[col.field]; } else if (col.sortingAlgorithm != undefined) { sortFn = col.sortingAlgorithm; sortService.colSortFnCache[col.field] = col.sortingAlgorithm; } else { // try and guess what sort function to use item = data[0]; if (!item) { return sortFn; } sortFn = sortService.guessSortFn($parse(col.field)(item)); //cache it if (sortFn) { sortService.colSortFnCache[col.field] = sortFn; } else { // we assign the alpha sort because anything that is null/undefined will never get passed to // the actual sorting function. It will get caught in our null check and returned to be sorted // down to the bottom sortFn = sortService.sortAlpha; } } return sortFn; }; return sortService; }]);