/*______________ | ______ | U I Z E J A V A S C R I P T F R A M E W O R K | / / | --------------------------------------------------- | / O / | MODULE : Uize.Widget.Pagination Class | / / / | | / / / /| | ONLINE : http://uize.com | /____/ /__/_| | COPYRIGHT : (c)2007-2016 UIZE | /___ | LICENSE : Available under MIT License or GNU General Public License |_______________| http://uize.com/license.html */ /* Module Meta Data type: Class importance: 5 codeCompleteness: 0 docCompleteness: 0 */ /*? Introduction The =Uize.Widget.Pagination= class implements support for client-side pagination *DEVELOPERS:* `Ben Ilegbodu` The =Uize.Widget.Pagination= module defines the =Uize.Widget.Pagination= widget class, a subclass of =Uize.Widget=. */ Uize.module ({ name:'Uize.Widget.Pagination', required:[ 'Uize.Widget.Button', 'Uize.Dom.Basics', 'Uize.Dom.Classes', 'Uize.Url' ], builder:function (_superclass) { 'use strict'; /*** Utility Functions ***/ function _formatNumber (_number) { var _numberString = _number + '', _numberStringLength = _numberString.length, _formattedStringBuilder = [] ; for (var _count = 0; ++_count <= _numberStringLength;) { _formattedStringBuilder.unshift(_numberString.charAt(_numberStringLength - _count)); !(_count % 3) && _count < _numberStringLength && _formattedStringBuilder.unshift(','); } return _formattedStringBuilder.join(''); } /*** Private Methods ***/ function _addChildButton (m,_buttonName,_clickHandler) { return Uize.Widget.Button.addChildButton.call (m,_buttonName,_clickHandler); } function _calculateMaxPages (m) { return Math.ceil(m._numResults / m._pageSize) } function _calculatePagesStart (m) { var _value = m._value, _numPagesToShow = m._numPagesToShow, _maxPages = _calculateMaxPages(m), _minPagesStart = 1 + (m._showFirstPage && _value > 1), // i.e. if we're shhowing the first page we want to start at 2 _maxPagesEnd = _maxPages - (m._showLastPage && _value < _maxPages), // i.e. if we're showing the last page we want to end at the page before _deltaFromCurrentPage = Math.ceil(_numPagesToShow / 2), _deltaLeft = _value - _deltaFromCurrentPage + 1, _deltaRight = _value + (_numPagesToShow - _deltaFromCurrentPage) ; return ( _deltaLeft >= _minPagesStart && _deltaRight <= _maxPagesEnd ? _deltaLeft : _deltaLeft >= _minPagesStart ? Math.max(_minPagesStart, _maxPagesEnd - _numPagesToShow + 1) : _minPagesStart ); } function _gotoPage (m,_pageNumber) { m.set({_value:_pageNumber}) } function _updatePages () { var m = this, _children = m.children, _value = m._value, _maxPages = _calculateMaxPages(m), _hasMultiplePages = _maxPages > 1, _numResults = m._numResults ; if (m.isWired && m.getNode()) { m.displayNode('displayShell', _numResults > 0); m.displayNode('paginationShell', _hasMultiplePages); m.setNodeInnerHtml( 'displayShell', m.localize( 'displayInfo', { number:_formatNumber((_value - 1) * m._pageSize + 1), toNumber:_formatNumber(Math.min(_numResults, _value * m._pageSize)), total:m.localize('numResultsDisplay', {numResults:_formatNumber(_numResults)}) || _formatNumber(_numResults) } ) ); m.setNodeInnerHtml( 'pageDisplay', m.localize( 'pageDisplayInfo', { page:_formatNumber(_value), totalPages:_formatNumber(m.localize('numResultsDisplay', {numResults:_maxPages}) || _maxPages) } ) ); if (_hasMultiplePages) { var _display = function (_pageButtonName, _mustDisplay) { _children[_pageButtonName] && _children[_pageButtonName].displayNode('', _mustDisplay); }, _setText = function (_pageButtonName, _pageNumber) { _children[_pageButtonName] && _children[_pageButtonName].set({text:_formatNumber(_pageNumber)}); } ; _display('prev', _value > 1); _display('next', _value < _maxPages); m._setEdgeButtons && _setText('first', 1); _display('first', _value > 1); _display('last', _value < _maxPages); m._setEdgeButtons && _setText('last', _maxPages); var _pagesStart = _calculatePagesStart(m); m.displayNode('less', _pagesStart > (1 + m._showFirstPage)); m.displayNode('more', (_pagesStart + m._numPagesToShow) < (_maxPages - m._showLastPage)); for (var _pageNo = -1; ++_pageNo < m._numPagesToShow;) { var _pageName = 'page' + _pageNo, _pageLinkNode = _children[_pageName].getNode(), _pageNumber = _pagesStart + _pageNo, _isCurrentPage = _pageNumber == _value ; _setText( _pageName, _isCurrentPage ? m.localize('selectedPage', {page:_pageNumber}) || _pageNumber : _pageNumber ); _display(_pageName, _pageNumber == _value || _pageNumber <= (_maxPages - m._showLastPage)); Uize.Dom.Classes.setState(_pageLinkNode, m._classSelected, _isCurrentPage); } } } } return _superclass.subclass ({ omegastructor:function () { var m = this; _addChildButton(m, 'prev', function () { _gotoPage(m,m._value - 1) } ); _addChildButton(m, 'next', function () { _gotoPage(m,m._value + 1) } ); }, instanceMethods:{ updateUi:function () { var m = this; if (m.isWired) { _updatePages.call(m); _superclass.doMy (m,'updateUi'); } }, wireUi:function () { var m = this; if (!m.isWired) { /*** Determine which page links exist ***/ var _childExists = function (_childName) { return !!Uize.Dom.Basics.getById(m.get('idPrefix') + '_' + _childName); }, _addPageButton = function (_pageNo) { _addChildButton( m, 'page' + _pageNo, function () { _gotoPage(m,_calculatePagesStart(m) + _pageNo) } ); } ; m._showFirstPage = _childExists('first'); m._showLastPage = _childExists('last'); /** Calculate how many inner page linkss there are to show ***/ m._numPagesToShow = -1; while (_childExists('page' + ++m._numPagesToShow)); m._showFirstPage && _addChildButton(m, 'first', function () { _gotoPage(m,1) } ); m._showLastPage && _addChildButton(m, 'last', function () { _gotoPage(m,_calculateMaxPages(m)) } ); for (var _pageNo = -1; ++_pageNo < m._numPagesToShow;) _addPageButton(_pageNo) ; _superclass.doMy (m,'wireUi'); } } }, stateProperties:{ _classSelected:{ name:'classSelected', value:'selected' }, _numResults:{ name:'numResults', onChange:_updatePages }, _pageSize:{ name:'pageSize', conformer:function (_newPageSize) { return _newPageSize ? _newPageSize : 30 }, onChange:_updatePages, value:30 }, _setEdgeButtons:{ name:'setEdgeButtons', value:true }, _thousandsSeparator:{ name:'thousandsSeparator', onChange:_updatePages, value:',' }, _urlAnchor:'urlAnchor', _urlBase:'urlBase', _urlParam:{ name:'urlParam', value:'pg' }, _value:{ name:'value', conformer:function (_newValue) { var _maxPages = _calculateMaxPages(this); return _newValue ? (!_maxPages || _newValue < _maxPages ? Math.floor(_newValue) : _maxPages) : 1; }, onChange:[ function () { var m = this; if (m._urlBase && m.isWired) location.href = Uize.Url.resolve( m._urlBase, Uize.pairUp(m._urlParam, m._value) ) ; }, _updatePages ], value:1 } } }); } });