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