{"version":3,"file":"smart-table.min.js","sources":["smart-table.min.js"],"sourcesContent":["(function (ng, undefined){\r\n 'use strict';\r\n\nng.module('smart-table', []).run(['$templateCache', function ($templateCache) {\r\n $templateCache.put('template/smart-table/pagination.html',\r\n '');\r\n}]);\r\n\r\n\nng.module('smart-table')\r\n .constant('stConfig', {\r\n pagination: {\r\n template: 'template/smart-table/pagination.html',\r\n itemsByPage: 10,\r\n displayedPages: 5,\r\n maxPerPage: 1000\r\n },\r\n search: {\r\n delay: 400, // ms\r\n inputEvent: 'input'\r\n },\r\n select: {\r\n mode: 'single',\r\n selectedClass: 'st-selected'\r\n },\r\n sort: {\r\n ascentClass: 'st-sort-ascent',\r\n descentClass: 'st-sort-descent',\r\n descendingFirst: false,\r\n skipNatural: false,\r\n delay:300\r\n },\r\n pipe: {\r\n delay: 100, //ms\r\n executePipeOnLoad: true,\r\n pipeEvent: ''\r\n }\r\n });\nng.module('smart-table')\r\n .controller('stTableController', ['$scope', '$parse', '$filter', '$attrs', function StTableController ($scope, $parse, $filter, $attrs) {\r\n var propertyName = $attrs.stTable;\r\n var displayGetter = $parse(propertyName);\r\n var displaySetter = displayGetter.assign;\r\n var safeGetter;\r\n var orderBy = $filter('orderBy');\r\n var filter = $filter('filter');\r\n var safeCopy = copyRefs(displayGetter($scope));\r\n var tableState = {\r\n sort: {},\r\n search: {},\r\n pagination: {\r\n start: 0,\r\n totalItemCount: 0\r\n }\r\n };\r\n var filtered;\r\n var pipeAfterSafeCopy = true;\r\n var ctrl = this;\r\n var lastSelected;\r\n\r\n function copyRefs (src) {\r\n return src ? [].concat(src) : [];\r\n }\r\n\r\n function updateSafeCopy () {\r\n safeCopy = copyRefs(safeGetter($scope));\r\n if (pipeAfterSafeCopy === true) {\r\n ctrl.pipe();\r\n }\r\n }\r\n\r\n function deepDelete (object, path) {\r\n if (path.indexOf('.') != -1) {\r\n var partials = path.split('.');\r\n var key = partials.pop();\r\n var parentPath = partials.join('.');\r\n var parentObject = $parse(parentPath)(object)\r\n delete parentObject[key];\r\n if (Object.keys(parentObject).length == 0) {\r\n deepDelete(object, parentPath);\r\n }\r\n } else {\r\n delete object[path];\r\n }\r\n }\r\n\r\n if ($attrs.stSafeSrc) {\r\n safeGetter = $parse($attrs.stSafeSrc);\r\n $scope.$watch(function () {\r\n var safeSrc = safeGetter($scope);\r\n return safeSrc && safeSrc.length ? safeSrc[0] : undefined;\r\n }, function (newValue, oldValue) {\r\n if (newValue !== oldValue) {\r\n updateSafeCopy();\r\n }\r\n });\r\n $scope.$watch(function () {\r\n var safeSrc = safeGetter($scope);\r\n return safeSrc ? safeSrc.length : 0;\r\n }, function (newValue, oldValue) {\r\n if (newValue !== safeCopy.length) {\r\n updateSafeCopy();\r\n }\r\n });\r\n $scope.$watch(function () {\r\n return safeGetter($scope);\r\n }, function (newValue, oldValue) {\r\n if (newValue !== oldValue) {\r\n tableState.pagination.start = 0;\r\n updateSafeCopy();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * sort the rows\r\n * @param {Function | String} predicate - function or string which will be used as predicate for the sorting\r\n * @param [reverse] - if you want to reverse the order\r\n */\r\n this.sortBy = function sortBy (predicate, reverse) {\r\n tableState.sort.predicate = predicate;\r\n tableState.sort.reverse = reverse === true;\r\n\r\n if (ng.isFunction(predicate)) {\r\n tableState.sort.functionName = predicate.name;\r\n } else {\r\n delete tableState.sort.functionName;\r\n }\r\n\r\n tableState.pagination.start = 0;\r\n return this.pipe();\r\n };\r\n\r\n /**\r\n * search matching rows\r\n * @param {String} input - the input string\r\n * @param {String} [predicate] - the property name against you want to check the match, otherwise it will search on all properties\r\n */\r\n this.search = function search (input, predicate) {\r\n var predicateObject = tableState.search.predicateObject || {};\r\n var prop = predicate ? predicate : '$';\r\n\r\n input = ng.isString(input) ? input.trim() : input;\r\n $parse(prop).assign(predicateObject, input);\r\n // to avoid to filter out null value\r\n if (!input) {\r\n deepDelete(predicateObject, prop);\r\n }\r\n tableState.search.predicateObject = predicateObject;\r\n tableState.pagination.start = 0;\r\n return this.pipe();\r\n };\r\n\r\n /**\r\n * this will chain the operations of sorting and filtering based on the current table state (sort options, filtering, ect)\r\n */\r\n this.pipe = function pipe () {\r\n var pagination = tableState.pagination;\r\n var output;\r\n filtered = tableState.search.predicateObject ? filter(safeCopy, tableState.search.predicateObject) : safeCopy;\r\n if (tableState.sort.predicate) {\r\n filtered = orderBy(filtered, tableState.sort.predicate, tableState.sort.reverse);\r\n }\r\n pagination.totalItemCount = filtered.length;\r\n if (pagination.number !== undefined) {\r\n pagination.numberOfPages = filtered.length > 0 ? Math.ceil(filtered.length / pagination.number) : 1;\r\n pagination.start = pagination.start >= filtered.length ? (pagination.numberOfPages - 1) * pagination.number : pagination.start;\r\n output = filtered.slice(pagination.start, pagination.start + parseInt(pagination.number));\r\n }\r\n displaySetter($scope, output || filtered);\r\n };\r\n\r\n /**\r\n * select a dataRow (it will add the attribute isSelected to the row object)\r\n * @param {Object} row - the row to select\r\n * @param {String} [mode] - \"single\" or \"multiple\" (multiple by default)\r\n */\r\n this.select = function select (row, mode) {\r\n var rows = copyRefs(displayGetter($scope));\r\n var index = rows.indexOf(row);\r\n if (index !== -1) {\r\n if (mode === 'single') {\r\n row.isSelected = row.isSelected !== true;\r\n if (lastSelected) {\r\n lastSelected.isSelected = false;\r\n }\r\n lastSelected = row.isSelected === true ? row : undefined;\r\n } else {\r\n rows[index].isSelected = !rows[index].isSelected;\r\n }\r\n }\r\n };\r\n\r\n /**\r\n * take a slice of the current sorted/filtered collection (pagination)\r\n *\r\n * @param {Number} start - start index of the slice\r\n * @param {Number} number - the number of item in the slice\r\n */\r\n this.slice = function splice (start, number) {\r\n tableState.pagination.start = start;\r\n tableState.pagination.number = number;\r\n return this.pipe();\r\n };\r\n\r\n /**\r\n * return the current state of the table\r\n * @returns {{sort: {}, search: {}, pagination: {start: number}}}\r\n */\r\n this.tableState = function getTableState () {\r\n return tableState;\r\n };\r\n\r\n this.getFilteredCollection = function getFilteredCollection () {\r\n return filtered || safeCopy;\r\n };\r\n\r\n /**\r\n * Use a different filter function than the angular FilterFilter\r\n * @param filterName the name under which the custom filter is registered\r\n */\r\n this.setFilterFunction = function setFilterFunction (filterName) {\r\n filter = $filter(filterName);\r\n };\r\n\r\n /**\r\n * Use a different function than the angular orderBy\r\n * @param sortFunctionName the name under which the custom order function is registered\r\n */\r\n this.setSortFunction = function setSortFunction (sortFunctionName) {\r\n orderBy = $filter(sortFunctionName);\r\n };\r\n\r\n /**\r\n * Usually when the safe copy is updated the pipe function is called.\r\n * Calling this method will prevent it, which is something required when using a custom pipe function\r\n */\r\n this.preventPipeOnWatch = function preventPipe () {\r\n pipeAfterSafeCopy = false;\r\n };\r\n }])\r\n .directive('stTable', function () {\r\n return {\r\n restrict: 'A',\r\n controller: 'stTableController',\r\n link: function (scope, element, attr, ctrl) {\r\n\r\n if (attr.stSetFilter) {\r\n ctrl.setFilterFunction(attr.stSetFilter);\r\n }\r\n\r\n if (attr.stSetSort) {\r\n ctrl.setSortFunction(attr.stSetSort);\r\n }\r\n }\r\n };\r\n });\r\n\nng.module('smart-table')\r\n .directive('stSearch', ['stConfig', '$timeout','$parse', function (stConfig, $timeout, $parse) {\r\n return {\r\n require: '^stTable',\r\n link: function (scope, element, attr, ctrl) {\r\n var tableCtrl = ctrl;\r\n var promise = null;\r\n var throttle = attr.stDelay || stConfig.search.delay;\r\n var event = attr.stInputEvent || stConfig.search.inputEvent;\r\n\r\n attr.$observe('stSearch', function (newValue, oldValue) {\r\n var input = element[0].value;\r\n if (newValue !== oldValue && input) {\r\n ctrl.tableState().search = {};\r\n tableCtrl.search(input, newValue);\r\n }\r\n });\r\n\r\n //table state -> view\r\n scope.$watch(function () {\r\n return ctrl.tableState().search;\r\n }, function (newValue, oldValue) {\r\n var predicateExpression = attr.stSearch || '$';\r\n if (newValue.predicateObject && $parse(predicateExpression)(newValue.predicateObject) !== element[0].value) {\r\n element[0].value = $parse(predicateExpression)(newValue.predicateObject) || '';\r\n }\r\n }, true);\r\n\r\n // view -> table state\r\n element.bind(event, function (evt) {\r\n evt = evt.originalEvent || evt;\r\n if (promise !== null) {\r\n $timeout.cancel(promise);\r\n }\r\n\r\n promise = $timeout(function () {\r\n tableCtrl.search(evt.target.value, attr.stSearch || '');\r\n promise = null;\r\n }, throttle);\r\n });\r\n }\r\n };\r\n }]);\r\n\nng.module('smart-table')\r\n .directive('stSelectRow', ['stConfig', function (stConfig) {\r\n return {\r\n restrict: 'A',\r\n require: '^stTable',\r\n scope: {\r\n row: '=stSelectRow'\r\n },\r\n link: function (scope, element, attr, ctrl) {\r\n var mode = attr.stSelectMode || stConfig.select.mode;\r\n element.bind('click', function () {\r\n scope.$apply(function () {\r\n ctrl.select(scope.row, mode);\r\n });\r\n });\r\n\r\n scope.$watch('row.isSelected', function (newValue) {\r\n if (newValue === true) {\r\n element.addClass(stConfig.select.selectedClass);\r\n } else {\r\n element.removeClass(stConfig.select.selectedClass);\r\n }\r\n });\r\n }\r\n };\r\n }]);\r\n\nng.module('smart-table')\r\n .directive('stSort', ['stConfig', '$parse', '$timeout', function (stConfig, $parse, $timeout) {\r\n return {\r\n restrict: 'A',\r\n require: '^stTable',\r\n link: function (scope, element, attr, ctrl) {\r\n\r\n var predicate = attr.stSort;\r\n var getter = $parse(predicate);\r\n var index = 0;\r\n var classAscent = attr.stClassAscent || stConfig.sort.ascentClass;\r\n var classDescent = attr.stClassDescent || stConfig.sort.descentClass;\r\n var stateClasses = [classAscent, classDescent];\r\n var sortDefault;\r\n var skipNatural = attr.stSkipNatural !== undefined ? attr.stSkipNatural : stConfig.sort.skipNatural;\r\n var descendingFirst = attr.stDescendingFirst !== undefined ? attr.stDescendingFirst : stConfig.sort.descendingFirst;\r\n var promise = null;\r\n var throttle = attr.stDelay || stConfig.sort.delay;\r\n\r\n if (attr.stSortDefault) {\r\n sortDefault = scope.$eval(attr.stSortDefault) !== undefined ? scope.$eval(attr.stSortDefault) : attr.stSortDefault;\r\n }\r\n\r\n //view --> table state\r\n function sort () {\r\n if (descendingFirst) {\r\n index = index === 0 ? 2 : index - 1;\r\n } else {\r\n index++;\r\n }\r\n\r\n var func;\r\n predicate = ng.isFunction(getter(scope)) || ng.isArray(getter(scope)) ? getter(scope) : attr.stSort;\r\n if (index % 3 === 0 && !!skipNatural !== true) {\r\n //manual reset\r\n index = 0;\r\n ctrl.tableState().sort = {};\r\n ctrl.tableState().pagination.start = 0;\r\n func = ctrl.pipe.bind(ctrl);\r\n } else {\r\n func = ctrl.sortBy.bind(ctrl, predicate, index % 2 === 0);\r\n }\r\n if (promise !== null) {\r\n $timeout.cancel(promise);\r\n }\r\n if (throttle < 0) {\r\n func();\r\n } else {\r\n promise = $timeout(func, throttle);\r\n }\r\n }\r\n\r\n element.bind('click', function sortClick () {\r\n if (predicate) {\r\n scope.$apply(sort);\r\n }\r\n });\r\n\r\n if (sortDefault) {\r\n index = sortDefault === 'reverse' ? 1 : 0;\r\n sort();\r\n }\r\n\r\n //table state --> view\r\n scope.$watch(function () {\r\n return ctrl.tableState().sort;\r\n }, function (newValue) {\r\n if (newValue.predicate !== predicate) {\r\n index = 0;\r\n element\r\n .removeClass(classAscent)\r\n .removeClass(classDescent);\r\n } else {\r\n index = newValue.reverse === true ? 2 : 1;\r\n element\r\n .removeClass(stateClasses[index % 2])\r\n .addClass(stateClasses[index - 1]);\r\n }\r\n }, true);\r\n }\r\n };\r\n }]);\r\n\nng.module('smart-table')\r\n .directive('stPagination', ['stConfig', function (stConfig) {\r\n return {\r\n restrict: 'EA',\r\n require: '^stTable',\r\n scope: {\r\n stItemsByPage: '=?',\r\n stDisplayedPages: '=?',\r\n stMaxPerPage: '=?',\r\n stPageChange: '&'\r\n },\r\n templateUrl: function (element, attrs) {\r\n if (attrs.stTemplate) {\r\n return attrs.stTemplate;\r\n }\r\n return stConfig.pagination.template;\r\n },\r\n link: function (scope, element, attrs, ctrl) {\r\n\r\n scope.stItemsByPage = scope.stItemsByPage ? +(scope.stItemsByPage) : stConfig.pagination.itemsByPage;\r\n scope.stDisplayedPages = scope.stDisplayedPages ? +(scope.stDisplayedPages) : stConfig.pagination.displayedPages;\r\n scope.stMaxPerPage = scope.stMaxPerPage ? scope.stMaxPerPage : stConfig.pagination.maxPerPage;\r\n\r\n scope.currentPage = 1;\r\n scope.pages = [];\r\n\r\n function redraw () {\r\n var paginationState = ctrl.tableState().pagination;\r\n var start = 1;\r\n var end;\r\n var i;\r\n var prevPage = scope.currentPage;\r\n scope.totalItemCount = paginationState.totalItemCount;\r\n scope.currentPage = Math.floor(paginationState.start / paginationState.number) + 1;\r\n\r\n start = Math.max(start, scope.currentPage - Math.abs(Math.floor(scope.stDisplayedPages / 2)));\r\n end = start + scope.stDisplayedPages;\r\n\r\n if (end > paginationState.numberOfPages) {\r\n end = paginationState.numberOfPages + 1;\r\n start = Math.max(1, end - scope.stDisplayedPages);\r\n }\r\n\r\n scope.pages = [];\r\n scope.numPages = paginationState.numberOfPages;\r\n\r\n for (i = start; i < end; i++) {\r\n scope.pages.push(i);\r\n }\r\n\r\n if (prevPage !== scope.currentPage) {\r\n scope.stPageChange({newPage: scope.currentPage});\r\n }\r\n }\r\n\r\n //table state --> view\r\n scope.$watch(function () {\r\n return ctrl.tableState().pagination;\r\n }, redraw, true);\r\n\r\n //scope --> table state (--> view)\r\n scope.$watch('stItemsByPage', function (newValue, oldValue) {\r\n if (newValue !== oldValue) {\r\n scope.selectPage(1);\r\n }\r\n });\r\n\r\n scope.$watch('stDisplayedPages', redraw);\r\n\r\n //view -> table state\r\n scope.selectPage = function (page) {\r\n if (page > 0 && page <= scope.numPages) {\r\n ctrl.slice((page - 1) * scope.stItemsByPage, scope.stItemsByPage);\r\n }\r\n };\r\n\r\n var pipeOnLoad = attrs.stExecutePipeOnLoad === \"false\" ? false : stConfig.pipe.executePipeOnLoad;\r\n if (!ctrl.tableState().pagination.number && pipeOnLoad) {\r\n ctrl.slice(0, scope.stItemsByPage);\r\n }\r\n }\r\n };\r\n }]);\r\n\nng.module('smart-table')\r\n .directive('stPipe', ['stConfig', '$timeout', function (config, $timeout) {\r\n return {\r\n require: 'stTable',\r\n scope: {\r\n stPipe: '='\r\n },\r\n link: {\r\n\r\n pre: function (scope, element, attrs, ctrl) {\r\n\r\n var pipePromise = null;\r\n var pipeEvent = attrs.stPipeEvent || config.pipe.pipeEvent;\r\n\r\n if (ng.isFunction(scope.stPipe)) {\r\n ctrl.preventPipeOnWatch();\r\n ctrl.pipe = function () {\r\n\r\n if (pipePromise !== null) {\r\n $timeout.cancel(pipePromise)\r\n }\r\n\r\n pipePromise = $timeout(function () {\r\n scope.stPipe(ctrl.tableState(), ctrl);\r\n }, config.pipe.delay);\r\n\r\n return pipePromise;\r\n }\r\n\r\n if (pipeEvent) {\r\n scope.$on(pipeEvent, function () {\r\n ctrl.pipe();\r\n });\r\n }\r\n }\r\n },\r\n\r\n post: function (scope, element, attrs, ctrl) {\r\n var pipeOnLoad = attrs.stExecutePipeOnLoad === \"false\" ? false : config.pipe.executePipeOnLoad;\r\n if (pipeOnLoad) {\r\n ctrl.pipe();\r\n }\r\n }\r\n }\r\n };\r\n }]);\r\n\n})(angular);"],"names":["ng","undefined","module","run","$templateCache","put","constant","pagination","template","itemsByPage","displayedPages","maxPerPage","search","delay","inputEvent","select","mode","selectedClass","sort","ascentClass","descentClass","descendingFirst","skipNatural","pipe","executePipeOnLoad","pipeEvent","controller","$scope","$parse","$filter","$attrs","safeGetter","filtered","lastSelected","propertyName","stTable","displayGetter","displaySetter","assign","orderBy","filter","safeCopy","copyRefs","tableState","start","totalItemCount","pipeAfterSafeCopy","ctrl","this","src","concat","updateSafeCopy","stSafeSrc","$watch","safeSrc","length","newValue","oldValue","sortBy","predicate","reverse","isFunction","functionName","name","input","predicateObject","prop","isString","trim","deepDelete","object","path","key","parentPath","parentObject","indexOf","partials","split","pop","join","Object","keys","output","number","numberOfPages","Math","ceil","slice","parseInt","row","rows","index","isSelected","getFilteredCollection","setFilterFunction","filterName","setSortFunction","sortFunctionName","preventPipeOnWatch","directive","restrict","link","scope","element","attr","stSetFilter","stSetSort","stConfig","$timeout","require","tableCtrl","promise","throttle","stDelay","event","stInputEvent","$observe","value","predicateExpression","stSearch","bind","evt","originalEvent","cancel","target","stSelectMode","$apply","addClass","removeClass","sortDefault","stSort","getter","classAscent","stClassAscent","classDescent","stClassDescent","stateClasses","stSkipNatural","stDescendingFirst","func","isArray","stSortDefault","$eval","stItemsByPage","stDisplayedPages","stMaxPerPage","stPageChange","templateUrl","attrs","stTemplate","redraw","end","i","paginationState","prevPage","currentPage","floor","max","abs","pages","numPages","push","newPage","selectPage","page","pipeOnLoad","stExecutePipeOnLoad","config","stPipe","pre","pipePromise","stPipeEvent","$on","post","angular"],"mappings":"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"}