2015-04-25 14:52:52 -07:00
/ * *
* dirPagination - AngularJS module for paginating ( almost ) anything .
*
*
* Credits
* === === =
*
* Daniel Tabuenca : https : //groups.google.com/d/msg/angular/an9QpzqIYiM/r8v-3W1X5vcJ
* for the idea on how to dynamically invoke the ng - repeat directive .
*
* I borrowed a couple of lines and a few attribute names from the AngularUI Bootstrap project :
* https : //github.com/angular-ui/bootstrap/blob/master/src/pagination/pagination.js
*
* Copyright 2014 Michael Bromley < michael @ michaelbromley . co . uk >
2016-05-17 17:10:50 -07:00
*
* 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 :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* 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 .
*
2015-04-25 14:52:52 -07:00
* /
( function ( ) {
/ * *
* Config
* /
var moduleName = 'angularUtils.directives.dirPagination' ;
var DEFAULT _ID = '__default' ;
/ * *
* Module
* /
2016-03-28 03:46:51 -07:00
angular . module ( moduleName , [ ] )
2015-04-25 14:52:52 -07:00
. directive ( 'dirPaginate' , [ '$compile' , '$parse' , 'paginationService' , dirPaginateDirective ] )
. directive ( 'dirPaginateNoCompile' , noCompileDirective )
. directive ( 'dirPaginationControls' , [ 'paginationService' , 'paginationTemplate' , dirPaginationControlsDirective ] )
. filter ( 'itemsPerPage' , [ 'paginationService' , itemsPerPageFilter ] )
. service ( 'paginationService' , paginationService )
. provider ( 'paginationTemplate' , paginationTemplateProvider )
. run ( [ '$templateCache' , dirPaginationControlsTemplateInstaller ] ) ;
function dirPaginateDirective ( $compile , $parse , paginationService ) {
return {
terminal : true ,
multiElement : true ,
2016-03-28 03:46:51 -07:00
priority : 100 ,
2015-04-25 14:52:52 -07:00
compile : dirPaginationCompileFn
} ;
function dirPaginationCompileFn ( tElement , tAttrs ) {
var expression = tAttrs . dirPaginate ;
2016-03-28 03:46:51 -07:00
// regex taken directly from https://github.com/angular/angular.js/blob/v1.4.x/src/ng/directive/ngRepeat.js#L339
var match = expression . match ( /^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/ ) ;
2015-04-25 14:52:52 -07:00
2016-03-28 03:46:51 -07:00
var filterPattern = /\|\s*itemsPerPage\s*:\s*(.*\(\s*\w*\)|([^\)]*?(?=\s+as\s+))|[^\)]*)/ ;
2015-04-25 14:52:52 -07:00
if ( match [ 2 ] . match ( filterPattern ) === null ) {
throw 'pagination directive: the \'itemsPerPage\' filter must be set.' ;
}
var itemsPerPageFilterRemoved = match [ 2 ] . replace ( filterPattern , '' ) ;
var collectionGetter = $parse ( itemsPerPageFilterRemoved ) ;
addNoCompileAttributes ( tElement ) ;
// If any value is specified for paginationId, we register the un-evaluated expression at this stage for the benefit of any
// dir-pagination-controls directives that may be looking for this ID.
var rawId = tAttrs . paginationId || DEFAULT _ID ;
paginationService . registerInstance ( rawId ) ;
return function dirPaginationLinkFn ( scope , element , attrs ) {
// Now that we have access to the `scope` we can interpolate any expression given in the paginationId attribute and
// potentially register a new ID if it evaluates to a different value than the rawId.
var paginationId = $parse ( attrs . paginationId ) ( scope ) || attrs . paginationId || DEFAULT _ID ;
2016-03-28 03:46:51 -07:00
// In case rawId != paginationId we deregister using rawId for the sake of general cleanliness
// before registering using paginationId
paginationService . deregisterInstance ( rawId ) ;
2015-04-25 14:52:52 -07:00
paginationService . registerInstance ( paginationId ) ;
var repeatExpression = getRepeatExpression ( expression , paginationId ) ;
addNgRepeatToElement ( element , attrs , repeatExpression ) ;
removeTemporaryAttributes ( element ) ;
var compiled = $compile ( element ) ;
var currentPageGetter = makeCurrentPageGetterFn ( scope , attrs , paginationId ) ;
paginationService . setCurrentPageParser ( paginationId , currentPageGetter , scope ) ;
if ( typeof attrs . totalItems !== 'undefined' ) {
paginationService . setAsyncModeTrue ( paginationId ) ;
scope . $watch ( function ( ) {
return $parse ( attrs . totalItems ) ( scope ) ;
} , function ( result ) {
if ( 0 <= result ) {
paginationService . setCollectionLength ( paginationId , result ) ;
}
} ) ;
} else {
2016-03-28 03:46:51 -07:00
paginationService . setAsyncModeFalse ( paginationId ) ;
2015-04-25 14:52:52 -07:00
scope . $watchCollection ( function ( ) {
return collectionGetter ( scope ) ;
} , function ( collection ) {
if ( collection ) {
2016-03-28 03:46:51 -07:00
var collectionLength = ( collection instanceof Array ) ? collection . length : Object . keys ( collection ) . length ;
paginationService . setCollectionLength ( paginationId , collectionLength ) ;
2015-04-25 14:52:52 -07:00
}
} ) ;
}
// Delegate to the link function returned by the new compilation of the ng-repeat
compiled ( scope ) ;
2016-03-28 03:46:51 -07:00
// When the scope is destroyed, we make sure to remove the reference to it in paginationService
// so that it can be properly garbage collected
scope . $on ( '$destroy' , function destroyDirPagination ( ) {
paginationService . deregisterInstance ( paginationId ) ;
} ) ;
2015-04-25 14:52:52 -07:00
} ;
}
/ * *
* If a pagination id has been specified , we need to check that it is present as the second argument passed to
* the itemsPerPage filter . If it is not there , we add it and return the modified expression .
*
* @ param expression
* @ param paginationId
* @ returns { * }
* /
function getRepeatExpression ( expression , paginationId ) {
var repeatExpression ,
idDefinedInFilter = ! ! expression . match ( /(\|\s*itemsPerPage\s*:[^|]*:[^|]*)/ ) ;
if ( paginationId !== DEFAULT _ID && ! idDefinedInFilter ) {
2016-03-28 03:46:51 -07:00
repeatExpression = expression . replace ( /(\|\s*itemsPerPage\s*:\s*[^|\s]*)/ , "$1 : '" + paginationId + "'" ) ;
2015-04-25 14:52:52 -07:00
} else {
repeatExpression = expression ;
}
return repeatExpression ;
}
/ * *
* Adds the ng - repeat directive to the element . In the case of multi - element ( - start , - end ) it adds the
* appropriate multi - element ng - repeat to the first and last element in the range .
* @ param element
* @ param attrs
* @ param repeatExpression
* /
function addNgRepeatToElement ( element , attrs , repeatExpression ) {
if ( element [ 0 ] . hasAttribute ( 'dir-paginate-start' ) || element [ 0 ] . hasAttribute ( 'data-dir-paginate-start' ) ) {
// using multiElement mode (dir-paginate-start, dir-paginate-end)
attrs . $set ( 'ngRepeatStart' , repeatExpression ) ;
element . eq ( element . length - 1 ) . attr ( 'ng-repeat-end' , true ) ;
} else {
attrs . $set ( 'ngRepeat' , repeatExpression ) ;
}
}
/ * *
* Adds the dir - paginate - no - compile directive to each element in the tElement range .
* @ param tElement
* /
function addNoCompileAttributes ( tElement ) {
angular . forEach ( tElement , function ( el ) {
2016-03-28 03:46:51 -07:00
if ( el . nodeType === 1 ) {
2015-04-25 14:52:52 -07:00
angular . element ( el ) . attr ( 'dir-paginate-no-compile' , true ) ;
}
} ) ;
}
/ * *
* Removes the variations on dir - paginate ( data - , - start , - end ) and the dir - paginate - no - compile directives .
* @ param element
* /
function removeTemporaryAttributes ( element ) {
angular . forEach ( element , function ( el ) {
2016-03-28 03:46:51 -07:00
if ( el . nodeType === 1 ) {
2015-04-25 14:52:52 -07:00
angular . element ( el ) . removeAttr ( 'dir-paginate-no-compile' ) ;
}
} ) ;
element . eq ( 0 ) . removeAttr ( 'dir-paginate-start' ) . removeAttr ( 'dir-paginate' ) . removeAttr ( 'data-dir-paginate-start' ) . removeAttr ( 'data-dir-paginate' ) ;
element . eq ( element . length - 1 ) . removeAttr ( 'dir-paginate-end' ) . removeAttr ( 'data-dir-paginate-end' ) ;
}
/ * *
* Creates a getter function for the current - page attribute , using the expression provided or a default value if
* no current - page expression was specified .
*
* @ param scope
* @ param attrs
* @ param paginationId
* @ returns { * }
* /
function makeCurrentPageGetterFn ( scope , attrs , paginationId ) {
var currentPageGetter ;
if ( attrs . currentPage ) {
currentPageGetter = $parse ( attrs . currentPage ) ;
} else {
2016-03-28 03:46:51 -07:00
// If the current-page attribute was not set, we'll make our own.
// Replace any non-alphanumeric characters which might confuse
// the $parse service and give unexpected results.
// See https://github.com/michaelbromley/angularUtils/issues/233
var defaultCurrentPage = ( paginationId + '__currentPage' ) . replace ( /\W/g , '_' ) ;
2015-04-25 14:52:52 -07:00
scope [ defaultCurrentPage ] = 1 ;
currentPageGetter = $parse ( defaultCurrentPage ) ;
}
return currentPageGetter ;
}
}
/ * *
* This is a helper directive that allows correct compilation when in multi - element mode ( ie dir - paginate - start , dir - paginate - end ) .
* It is dynamically added to all elements in the dir - paginate compile function , and it prevents further compilation of
* any inner directives . It is then removed in the link function , and all inner directives are then manually compiled .
* /
function noCompileDirective ( ) {
return {
priority : 5000 ,
terminal : true
} ;
}
function dirPaginationControlsTemplateInstaller ( $templateCache ) {
2016-03-28 03:46:51 -07:00
$templateCache . put ( 'angularUtils.directives.dirPagination.template' , '<ul class="pagination" ng-if="1 < pages.length || !autoHide"><li ng-if="boundaryLinks" ng-class="{ disabled : pagination.current == 1 }"><a href="" ng-click="setCurrent(1)">«</a></li><li ng-if="directionLinks" ng-class="{ disabled : pagination.current == 1 }"><a href="" ng-click="setCurrent(pagination.current - 1)">‹</a></li><li ng-repeat="pageNumber in pages track by tracker(pageNumber, $index)" ng-class="{ active : pagination.current == pageNumber, disabled : pageNumber == \'...\' || ( ! autoHide && pages.length === 1 ) }"><a href="" ng-click="setCurrent(pageNumber)">{{ pageNumber }}</a></li><li ng-if="directionLinks" ng-class="{ disabled : pagination.current == pagination.last }"><a href="" ng-click="setCurrent(pagination.current + 1)">›</a></li><li ng-if="boundaryLinks" ng-class="{ disabled : pagination.current == pagination.last }"><a href="" ng-click="setCurrent(pagination.last)">»</a></li></ul>' ) ;
2015-04-25 14:52:52 -07:00
}
function dirPaginationControlsDirective ( paginationService , paginationTemplate ) {
var numberRegex = /^\d+$/ ;
2016-03-28 03:46:51 -07:00
var DDO = {
2015-04-25 14:52:52 -07:00
restrict : 'AE' ,
scope : {
maxSize : '=?' ,
onPageChange : '&?' ,
2016-03-28 03:46:51 -07:00
paginationId : '=?' ,
autoHide : '=?'
2015-04-25 14:52:52 -07:00
} ,
link : dirPaginationControlsLinkFn
} ;
2016-03-28 03:46:51 -07:00
// We need to check the paginationTemplate service to see whether a template path or
// string has been specified, and add the `template` or `templateUrl` property to
// the DDO as appropriate. The order of priority to decide which template to use is
// (highest priority first):
// 1. paginationTemplate.getString()
// 2. attrs.templateUrl
// 3. paginationTemplate.getPath()
var templateString = paginationTemplate . getString ( ) ;
if ( templateString !== undefined ) {
DDO . template = templateString ;
} else {
DDO . templateUrl = function ( elem , attrs ) {
return attrs . templateUrl || paginationTemplate . getPath ( ) ;
} ;
}
return DDO ;
2015-04-25 14:52:52 -07:00
function dirPaginationControlsLinkFn ( scope , element , attrs ) {
// rawId is the un-interpolated value of the pagination-id attribute. This is only important when the corresponding dir-paginate directive has
// not yet been linked (e.g. if it is inside an ng-if block), and in that case it prevents this controls directive from assuming that there is
// no corresponding dir-paginate directive and wrongly throwing an exception.
var rawId = attrs . paginationId || DEFAULT _ID ;
var paginationId = scope . paginationId || attrs . paginationId || DEFAULT _ID ;
if ( ! paginationService . isRegistered ( paginationId ) && ! paginationService . isRegistered ( rawId ) ) {
var idMessage = ( paginationId !== DEFAULT _ID ) ? ' (id: ' + paginationId + ') ' : ' ' ;
2016-03-28 03:46:51 -07:00
if ( window . console ) {
console . warn ( 'Pagination directive: the pagination controls' + idMessage + 'cannot be used without the corresponding pagination directive, which was not found at link time.' ) ;
}
2015-04-25 14:52:52 -07:00
}
if ( ! scope . maxSize ) { scope . maxSize = 9 ; }
2016-03-28 03:46:51 -07:00
scope . autoHide = scope . autoHide === undefined ? true : scope . autoHide ;
2015-04-25 14:52:52 -07:00
scope . directionLinks = angular . isDefined ( attrs . directionLinks ) ? scope . $parent . $eval ( attrs . directionLinks ) : true ;
scope . boundaryLinks = angular . isDefined ( attrs . boundaryLinks ) ? scope . $parent . $eval ( attrs . boundaryLinks ) : false ;
var paginationRange = Math . max ( scope . maxSize , 5 ) ;
scope . pages = [ ] ;
scope . pagination = {
last : 1 ,
current : 1
} ;
scope . range = {
lower : 1 ,
upper : 1 ,
total : 1
} ;
2016-03-28 03:46:51 -07:00
scope . $watch ( 'maxSize' , function ( val ) {
if ( val ) {
paginationRange = Math . max ( scope . maxSize , 5 ) ;
generatePagination ( ) ;
}
} ) ;
2015-04-25 14:52:52 -07:00
scope . $watch ( function ( ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) ) {
return ( paginationService . getCollectionLength ( paginationId ) + 1 ) * paginationService . getItemsPerPage ( paginationId ) ;
}
2015-04-25 14:52:52 -07:00
} , function ( length ) {
if ( 0 < length ) {
generatePagination ( ) ;
}
} ) ;
scope . $watch ( function ( ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) ) {
return ( paginationService . getItemsPerPage ( paginationId ) ) ;
}
2015-04-25 14:52:52 -07:00
} , function ( current , previous ) {
if ( current != previous && typeof previous !== 'undefined' ) {
goToPage ( scope . pagination . current ) ;
}
} ) ;
scope . $watch ( function ( ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) ) {
return paginationService . getCurrentPage ( paginationId ) ;
}
2015-04-25 14:52:52 -07:00
} , function ( currentPage , previousPage ) {
if ( currentPage != previousPage ) {
goToPage ( currentPage ) ;
}
} ) ;
scope . setCurrent = function ( num ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) && isValidPageNumber ( num ) ) {
2015-04-25 14:52:52 -07:00
num = parseInt ( num , 10 ) ;
paginationService . setCurrentPage ( paginationId , num ) ;
}
} ;
2016-03-28 03:46:51 -07:00
/ * *
* Custom "track by" function which allows for duplicate "..." entries on long lists ,
* yet fixes the problem of wrongly - highlighted links which happens when using
* "track by $index" - see https : //github.com/michaelbromley/angularUtils/issues/153
* @ param id
* @ param index
* @ returns { string }
* /
scope . tracker = function ( id , index ) {
return id + '_' + index ;
} ;
2015-04-25 14:52:52 -07:00
function goToPage ( num ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) && isValidPageNumber ( num ) ) {
var oldPageNumber = scope . pagination . current ;
2015-04-25 14:52:52 -07:00
scope . pages = generatePagesArray ( num , paginationService . getCollectionLength ( paginationId ) , paginationService . getItemsPerPage ( paginationId ) , paginationRange ) ;
scope . pagination . current = num ;
updateRangeValues ( ) ;
2016-03-28 03:46:51 -07:00
// if a callback has been set, then call it with the page number as the first argument
// and the previous page number as a second argument
2015-04-25 14:52:52 -07:00
if ( scope . onPageChange ) {
2016-03-28 03:46:51 -07:00
scope . onPageChange ( {
newPageNumber : num ,
oldPageNumber : oldPageNumber
} ) ;
2015-04-25 14:52:52 -07:00
}
}
}
function generatePagination ( ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) ) {
var page = parseInt ( paginationService . getCurrentPage ( paginationId ) ) || 1 ;
scope . pages = generatePagesArray ( page , paginationService . getCollectionLength ( paginationId ) , paginationService . getItemsPerPage ( paginationId ) , paginationRange ) ;
scope . pagination . current = page ;
scope . pagination . last = scope . pages [ scope . pages . length - 1 ] ;
if ( scope . pagination . last < scope . pagination . current ) {
scope . setCurrent ( scope . pagination . last ) ;
} else {
updateRangeValues ( ) ;
}
2015-04-25 14:52:52 -07:00
}
}
/ * *
* This function updates the values ( lower , upper , total ) of the ` scope.range ` object , which can be used in the pagination
* template to display the current page range , e . g . "showing 21 - 40 of 144 results" ;
* /
function updateRangeValues ( ) {
2016-03-28 03:46:51 -07:00
if ( paginationService . isRegistered ( paginationId ) ) {
var currentPage = paginationService . getCurrentPage ( paginationId ) ,
itemsPerPage = paginationService . getItemsPerPage ( paginationId ) ,
totalItems = paginationService . getCollectionLength ( paginationId ) ;
scope . range . lower = ( currentPage - 1 ) * itemsPerPage + 1 ;
scope . range . upper = Math . min ( currentPage * itemsPerPage , totalItems ) ;
scope . range . total = totalItems ;
}
2015-04-25 14:52:52 -07:00
}
function isValidPageNumber ( num ) {
return ( numberRegex . test ( num ) && ( 0 < num && num <= scope . pagination . last ) ) ;
}
}
/ * *
* Generate an array of page numbers ( or the '...' string ) which is used in an ng - repeat to generate the
* links used in pagination
*
* @ param currentPage
* @ param rowsPerPage
* @ param paginationRange
* @ param collectionLength
* @ returns { Array }
* /
function generatePagesArray ( currentPage , collectionLength , rowsPerPage , paginationRange ) {
var pages = [ ] ;
var totalPages = Math . ceil ( collectionLength / rowsPerPage ) ;
var halfWay = Math . ceil ( paginationRange / 2 ) ;
var position ;
if ( currentPage <= halfWay ) {
position = 'start' ;
} else if ( totalPages - halfWay < currentPage ) {
position = 'end' ;
} else {
position = 'middle' ;
}
var ellipsesNeeded = paginationRange < totalPages ;
var i = 1 ;
while ( i <= totalPages && i <= paginationRange ) {
var pageNumber = calculatePageNumber ( i , currentPage , paginationRange , totalPages ) ;
var openingEllipsesNeeded = ( i === 2 && ( position === 'middle' || position === 'end' ) ) ;
var closingEllipsesNeeded = ( i === paginationRange - 1 && ( position === 'middle' || position === 'start' ) ) ;
if ( ellipsesNeeded && ( openingEllipsesNeeded || closingEllipsesNeeded ) ) {
pages . push ( '...' ) ;
} else {
pages . push ( pageNumber ) ;
}
i ++ ;
}
return pages ;
}
/ * *
* Given the position in the sequence of pagination links [ i ] , figure out what page number corresponds to that position .
*
* @ param i
* @ param currentPage
* @ param paginationRange
* @ param totalPages
* @ returns { * }
* /
function calculatePageNumber ( i , currentPage , paginationRange , totalPages ) {
var halfWay = Math . ceil ( paginationRange / 2 ) ;
if ( i === paginationRange ) {
return totalPages ;
} else if ( i === 1 ) {
return i ;
} else if ( paginationRange < totalPages ) {
if ( totalPages - halfWay < currentPage ) {
return totalPages - paginationRange + i ;
} else if ( halfWay < currentPage ) {
return currentPage - halfWay + i ;
} else {
return i ;
}
} else {
return i ;
}
}
}
/ * *
* This filter slices the collection into pages based on the current page number and number of items per page .
* @ param paginationService
* @ returns { Function }
* /
function itemsPerPageFilter ( paginationService ) {
return function ( collection , itemsPerPage , paginationId ) {
if ( typeof ( paginationId ) === 'undefined' ) {
paginationId = DEFAULT _ID ;
}
if ( ! paginationService . isRegistered ( paginationId ) ) {
throw 'pagination directive: the itemsPerPage id argument (id: ' + paginationId + ') does not match a registered pagination-id.' ;
}
var end ;
var start ;
2016-03-28 03:46:51 -07:00
if ( angular . isObject ( collection ) ) {
2015-04-25 14:52:52 -07:00
itemsPerPage = parseInt ( itemsPerPage ) || 9999999999 ;
if ( paginationService . isAsyncMode ( paginationId ) ) {
start = 0 ;
} else {
start = ( paginationService . getCurrentPage ( paginationId ) - 1 ) * itemsPerPage ;
}
end = start + itemsPerPage ;
paginationService . setItemsPerPage ( paginationId , itemsPerPage ) ;
2016-03-28 03:46:51 -07:00
if ( collection instanceof Array ) {
// the array just needs to be sliced
return collection . slice ( start , end ) ;
} else {
// in the case of an object, we need to get an array of keys, slice that, then map back to
// the original object.
var slicedObject = { } ;
angular . forEach ( keys ( collection ) . slice ( start , end ) , function ( key ) {
slicedObject [ key ] = collection [ key ] ;
} ) ;
return slicedObject ;
}
2015-04-25 14:52:52 -07:00
} else {
return collection ;
}
} ;
}
2016-03-28 03:46:51 -07:00
/ * *
* Shim for the Object . keys ( ) method which does not exist in IE < 9
* @ param obj
* @ returns { Array }
* /
function keys ( obj ) {
if ( ! Object . keys ) {
var objKeys = [ ] ;
for ( var i in obj ) {
if ( obj . hasOwnProperty ( i ) ) {
objKeys . push ( i ) ;
}
}
return objKeys ;
} else {
return Object . keys ( obj ) ;
}
}
2015-04-25 14:52:52 -07:00
/ * *
* This service allows the various parts of the module to communicate and stay in sync .
* /
function paginationService ( ) {
var instances = { } ;
var lastRegisteredInstance ;
this . registerInstance = function ( instanceId ) {
if ( typeof instances [ instanceId ] === 'undefined' ) {
instances [ instanceId ] = {
asyncMode : false
} ;
lastRegisteredInstance = instanceId ;
}
} ;
2016-03-28 03:46:51 -07:00
this . deregisterInstance = function ( instanceId ) {
delete instances [ instanceId ] ;
} ;
2015-04-25 14:52:52 -07:00
this . isRegistered = function ( instanceId ) {
return ( typeof instances [ instanceId ] !== 'undefined' ) ;
} ;
this . getLastInstanceId = function ( ) {
return lastRegisteredInstance ;
} ;
this . setCurrentPageParser = function ( instanceId , val , scope ) {
instances [ instanceId ] . currentPageParser = val ;
instances [ instanceId ] . context = scope ;
} ;
this . setCurrentPage = function ( instanceId , val ) {
instances [ instanceId ] . currentPageParser . assign ( instances [ instanceId ] . context , val ) ;
} ;
this . getCurrentPage = function ( instanceId ) {
var parser = instances [ instanceId ] . currentPageParser ;
return parser ? parser ( instances [ instanceId ] . context ) : 1 ;
} ;
this . setItemsPerPage = function ( instanceId , val ) {
instances [ instanceId ] . itemsPerPage = val ;
} ;
this . getItemsPerPage = function ( instanceId ) {
return instances [ instanceId ] . itemsPerPage ;
} ;
this . setCollectionLength = function ( instanceId , val ) {
instances [ instanceId ] . collectionLength = val ;
} ;
this . getCollectionLength = function ( instanceId ) {
return instances [ instanceId ] . collectionLength ;
} ;
this . setAsyncModeTrue = function ( instanceId ) {
instances [ instanceId ] . asyncMode = true ;
} ;
2016-03-28 03:46:51 -07:00
this . setAsyncModeFalse = function ( instanceId ) {
instances [ instanceId ] . asyncMode = false ;
} ;
2015-04-25 14:52:52 -07:00
this . isAsyncMode = function ( instanceId ) {
return instances [ instanceId ] . asyncMode ;
} ;
}
/ * *
* This provider allows global configuration of the template path used by the dir - pagination - controls directive .
* /
function paginationTemplateProvider ( ) {
var templatePath = 'angularUtils.directives.dirPagination.template' ;
2016-03-28 03:46:51 -07:00
var templateString ;
2015-04-25 14:52:52 -07:00
2016-03-28 03:46:51 -07:00
/ * *
* Set a templateUrl to be used by all instances of < dir - pagination - controls >
* @ param { String } path
* /
2015-04-25 14:52:52 -07:00
this . setPath = function ( path ) {
templatePath = path ;
} ;
2016-03-28 03:46:51 -07:00
/ * *
* Set a string of HTML to be used as a template by all instances
* of < dir - pagination - controls > . If both a path * and * a string have been set ,
* the string takes precedence .
* @ param { String } str
* /
this . setString = function ( str ) {
templateString = str ;
} ;
2015-04-25 14:52:52 -07:00
this . $get = function ( ) {
return {
getPath : function ( ) {
return templatePath ;
2016-03-28 03:46:51 -07:00
} ,
getString : function ( ) {
return templateString ;
2015-04-25 14:52:52 -07:00
}
} ;
} ;
}
} ) ( ) ;