source: Dev/branches/rest-dojo-ui/client/dojox/widget/Pager.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 16.5 KB
Line 
1dojo.provide("dojox.widget.Pager");
2dojo.experimental("dojox.widget.Pager");
3
4dojo.require("dijit._Widget");
5dojo.require("dijit._Templated");
6dojo.require("dojo.fx");
7
8dojo.declare("dojox.widget.Pager",
9        [dijit._Widget, dijit._Templated],
10        {
11        // summary: A Pager, displaying a list of sized nodes
12       
13       
14        templateString: dojo.cache("dojox.widget", "Pager/Pager.html"),
15
16/*=====
17        // iconPrevious: String?
18        //              The url of the previous page icon
19        iconPrevious: "",
20       
21        // iconNext: String?
22        //              The url of the next page icon
23        iconNext: "",
24=====*/
25
26        iconPage: dojo.moduleUrl("dojox.widget", "Pager/images/pageInactive.png"),
27        iconPageActive: dojo.moduleUrl("dojox.widget", "Pager/images/pageActive.png"),
28       
29        // store: Object
30        //              A dojo.data Data store
31        store: null, // data store for items
32
33        // orientation: String
34        //              Either "horizontal or "vertical" to define the direction the pages will slide
35        orientation: "horizontal", // or vertical
36       
37        // statusPos: String
38        //              A string describing where to put the Pager "current page" indicator. Options are
39        //              "leading" or "trailing". In the case of horiztonal orientation, "leading" indicates
40        //              positioned above the PageItems. In the case of vertical, "leading" indicates "before".
41        statusPos: "leading",
42       
43        // pagerPos: String
44        //              TODOC
45        pagerPos: "center",
46
47        // duration: Integer
48        //              Time in milliseconds to transition the pages
49        duration: 500,
50       
51        // itemSpace: Integer
52        //              Spacing between items? TODOC
53        itemSpace: 2,
54       
55        // resizeChildren: Boolean
56        //              TODOC
57        resizeChildren: true,
58       
59        // itemClass: String
60        //              The full dotted named of a Class to use for the internal Pager Items.
61        itemClass: "dojox.widget._PagerItem",
62       
63        // itemsPage: Integer
64        //              The numbers of items to display in each "Page"
65        itemsPage: 3,
66       
67        postMixInProperties: function(){
68                var h = (this.orientation == "horizontal");
69                dojo.mixin(this,{
70                        _totalPages:0,
71                        _currentPage:1,
72                        dirClass: "pager" + (h ? "Horizontal" : "Vertical"),
73                        iconNext: dojo.moduleUrl("dojox.widget", "Pager/images/" + (h ? "h" : "v") + "Next.png"),
74                        iconPrevious: dojo.moduleUrl("dojox.widget", "Pager/images/" + (h ? "h" : "v") + "Previous.png")
75                });
76        },
77               
78        postCreate: function(){
79                this.inherited(arguments);
80                //this.connect(this.domNode,"onkeypress","_handleKey");
81                this.store.fetch({
82                        onComplete: dojo.hitch(this, "_init")
83                });
84               
85        },
86       
87        _a11yStyle: function(e){
88                // summary: top level onfocus/onblur listen to set a class "pagerFocus" on some node
89                //              and remove it onblur
90                dojo[(e.type == "focus" ? "addClass" : "removeClass")](e.target,"pagerFocus");
91        },
92       
93        _handleKey: function(e){
94                // summary: Handle keyboard navigation internally
95
96                var dk = dojo.keys;
97                var key = (e.charCode == dk.SPACE ? dk.SPACE : e.keyCode);
98                switch(key){
99                       
100                        case dk.UP_ARROW:
101                        case dk.RIGHT_ARROW:
102                        case 110:
103                        case 78: // key "n"
104                                e.preventDefault();
105                                this._pagerNext();
106                                break;
107
108                        case dk.DOWN_ARROW:
109                        case dk.LEFT_ARROW:
110                        case 112:
111                        case 80: // key "p"
112                                e.preventDefault();
113                                this._pagerPrevious();
114                                break;
115                       
116                        case dk.ENTER:
117                                switch(e.target){
118                                        case this.pagerNext : this._pagerNext(); break;
119                                        case this.pagerPrevious : this._pagerPrevious(); break;
120                                }
121                                break;
122                }
123        },
124       
125        _init: function(items) {
126                this.items = items;
127                this._renderPages();
128                this._renderStatus();
129                this._renderPager();
130        },
131       
132        _renderPages: function(){
133                var pcv = this.pagerContainerView;
134                var _h = (this.orientation == "horizontal");
135                var style = dojo.style;
136                if(_h){
137
138                        var pagerH = dojo.marginBox(this.pagerContainerPager).h;
139                        var statusH = dojo.marginBox(this.pagerContainerStatus).h;
140                        if (this.pagerPos != 'center'){
141                                var addonHeight = pagerH+statusH;
142                        }else{
143                                var addonHeight = statusH;
144                                var widthSub = this.pagerIconNext.width;
145                                var containerWidth = style(pcv, 'width');
146                                var newWidth = containerWidth-(2*widthSub);
147                                style(pcv, {
148                                        width: newWidth+'px',
149                                        marginLeft: this.pagerIconNext.width+'px',
150                                        marginRight: this.pagerIconNext.width+'px'
151                                });
152                        }
153                        var totalH = style(this.pagerContainer, 'height') - addonHeight;
154                        style(this.pagerContainerView, 'height', totalH+'px');
155                       
156                        var itemSpace = Math.floor(style(pcv, 'width') / this.itemsPage);
157                        if(this.statusPos == 'trailing'){
158                                if(this.pagerPos != 'center'){
159                                        style(pcv, 'marginTop', pagerH+'px');
160                                }
161                                style(pcv, 'marginBottom', statusH+'px');
162                        }else{
163                                style(pcv, 'marginTop', statusH+'px');
164                                if (this.pagerPos != 'center'){
165                                        style(pcv, 'marginTop', pagerH+'px');
166                                }
167                        }
168                       
169                }else{
170
171                        var pagerW = dojo.marginBox(this.pagerContainerPager).w;
172                        var statusW = dojo.marginBox(this.pagerContainerStatus).w;
173                        var containerW = style(this.pagerContainer, 'width');
174                        if(this.pagerPos != 'center'){
175                                var addonWidth = pagerW + statusW;
176                        }else{
177                                var addonWidth = statusW;
178                                var heightSub = this.pagerIconNext.height;
179                                var containerHeight = style(pcv, 'height');
180                                var newHeight = containerHeight - (2 * heightSub);
181                                style(pcv,{
182                                        height: newHeight+'px',
183                                        marginTop: this.pagerIconNext.height+'px',
184                                        marginBottom: this.pagerIconNext.height+'px'
185                                });
186                        }
187                        var totalW = style(this.pagerContainer, 'width') - addonWidth;
188                        style(pcv, 'width', totalW+'px');
189                       
190                        var itemSpace = Math.floor(style(pcv, 'height') / this.itemsPage);
191                        if(this.statusPos == 'trailing'){
192                                if (this.pagerPos != 'center'){
193                                        style(pcv, 'marginLeft', pagerW + 'px');
194                                }
195                                style(pcv, 'marginRight', statusW + 'px');
196                        }else{
197                                style(pcv, 'marginLeft', statusW + 'px');
198                                if(this.pagerPos != 'center'){
199                                        style(pcv, 'marginRight', pagerW+'px');
200                                }
201                        }
202                }
203               
204                var _PagerItem = dojo.getObject(this.itemClass);
205                var paddingLead = "padding" + (_h ? "Left" : "Top");
206                var paddingTrail = "padding" + (_h ? "Right" : "Bottom");
207                       
208                dojo.forEach(this.items, function(item, cnt){
209                       
210                        var contentContainer = dojo.create('div', {
211                                innerHTML: item.content
212                        });
213
214                        var pagerItem = new _PagerItem({
215                                id: this.id + '-item-' + (cnt + 1)
216                        }, contentContainer);
217                       
218                        this.pagerItems.appendChild(pagerItem.domNode);
219                       
220                        var containerProps = {};
221                        containerProps[(_h ? "width" : "height")] = (itemSpace - this.itemSpace) + "px";
222                        var p = (_h ? "height" : "width");
223                        containerProps[p] = style(pcv, p) + "px";
224                        style(pagerItem.containerNode, containerProps);
225
226                        if(this.resizeChildren){
227                                pagerItem.resizeChildren();
228                        }
229                        pagerItem.parseChildren();
230                       
231                        // only display amount of items as defined in itemsPage
232                        style(pagerItem.domNode, "position", "absolute");
233
234                        if (cnt < this.itemsPage){
235                                var pos = (cnt) * itemSpace;
236                                var trailingDir = (_h ? "left" : "top");
237                                var dir = (_h ? "top" : "left");
238                                style(pagerItem.domNode, dir, "0px");
239                                style(pagerItem.domNode, trailingDir, pos+"px");
240                        }else{
241                                style(pagerItem.domNode, "top", "-1000px");
242                                style(pagerItem.domNode, "left", "-1000px");
243                        }
244
245                        style(pagerItem.domNode, paddingTrail, (this.itemSpace/2)+"px");
246                        style(pagerItem.domNode, paddingLead, (this.itemSpace/2)+"px");
247                       
248                }, this);
249        },
250       
251        _renderPager: function() {
252                var tcp = this.pagerContainerPager;
253                var zero = "0px";
254                var _h = (this.orientation == "horizontal");
255                if(_h){
256
257                        if(this.statusPos == 'center'){
258                               
259                        }else if (this.statusPos == 'trailing'){
260                                dojo.style(tcp, 'top', zero);
261                        }else{
262                                dojo.style(tcp, 'bottom', zero);
263                        }
264                        dojo.style(this.pagerNext, 'right', zero);
265                        dojo.style(this.pagerPrevious, 'left', zero);
266                       
267                }else{
268                       
269                        if (this.statusPos == 'trailing'){
270                                dojo.style(tcp, 'left', zero);
271                        }else{
272                                dojo.style(tcp, 'right', zero);
273                        }
274                        dojo.style(this.pagerNext, 'bottom', zero);
275                        dojo.style(this.pagerPrevious, 'top', zero);
276                }
277               
278        },
279       
280        _renderStatus: function() {
281                this._totalPages = Math.ceil(this.items.length / this.itemsPage);
282                // FIXME!!
283                this.iconWidth = 0;
284                this.iconHeight = 0;
285                this.iconsLoaded = 0;
286                this._iconConnects = [];
287               
288                for (var i = 1; i <= this._totalPages; i++){
289                        var icon = new Image();
290                       
291                        var pointer = i;
292                        dojo.connect(icon, 'onclick', dojo.hitch(this, function(pointer) {
293                                this._pagerSkip(pointer);
294                        }, pointer));
295                       
296                        this._iconConnects[pointer] = dojo.connect(icon, 'onload', dojo.hitch(this,function(pointer){
297                                this.iconWidth += icon.width;
298                                this.iconHeight += icon.height;
299                                this.iconsLoaded++;
300
301                                if (this._totalPages == this.iconsLoaded){
302                                        if (this.orientation == "horizontal"){
303                                                if (this.statusPos == 'trailing'){
304                                                        if (this.pagerPos == 'center'){
305                                                                var containerHeight = dojo.style(this.pagerContainer, 'height');
306                                                                var statusHeight = dojo.style(this.pagerContainerStatus, 'height');
307                                                                dojo.style(this.pagerContainerPager, 'top', ((containerHeight/2)-(statusHeight/2))+'px');
308                                                        }
309                                                        dojo.style(this.pagerContainerStatus, 'bottom', '0px');
310                                                }else{
311                                                        if (this.pagerPos == 'center'){
312                                                                var containerHeight = dojo.style(this.pagerContainer, 'height');
313                                                                var statusHeight = dojo.style(this.pagerContainerStatus, 'height');
314                                                                dojo.style(this.pagerContainerPager, 'bottom', ((containerHeight/2)-(statusHeight/2))+'px');
315                                                        }
316                                                        dojo.style(this.pagerContainerStatus, 'top', '0px');
317                                                }
318                                       
319                                                var position = (dojo.style(this.pagerContainer, 'width')/2)-(this.iconWidth/2);
320                                                dojo.style(this.pagerContainerStatus, 'paddingLeft', position+'px');
321                                        }else{
322                                                if (this.statusPos == 'trailing'){
323                                                        if (this.pagerPos == 'center'){
324                                                                var containerWidth = dojo.style(this.pagerContainer, 'width');
325                                                                var statusWidth = dojo.style(this.pagerContainerStatus, 'width');
326                                                                dojo.style(this.pagerContainerPager, 'left', ((containerWidth/2)-(statusWidth/2))+'px');
327                                                        }
328                                                        dojo.style(this.pagerContainerStatus, 'right', '0px');
329                                                }else{
330                                                        if (this.pagerPos == 'center'){
331                                                                var containerWidth = dojo.style(this.pagerContainer, 'width');
332                                                                var statusWidth = dojo.style(this.pagerContainerStatus, 'width');
333                                                                dojo.style(this.pagerContainerPager, 'right', ((containerWidth/2)-(statusWidth/2))+'px');
334                                                        }
335                                                        dojo.style(this.pagerContainerStatus, 'left', '0px');
336                                                }
337                                                var position = (dojo.style(this.pagerContainer, 'height')/2)-(this.iconHeight/2);
338                                                dojo.style(this.pagerContainerStatus, 'paddingTop', position+'px');
339                                        }
340                                }
341                                dojo.disconnect(this._iconConnects[pointer]);
342                        }, pointer));
343                       
344                        if (i==this._currentPage){
345                                icon.src=this.iconPageActive;
346                        }else{
347                                icon.src=this.iconPage;
348                        }
349                        var pointer = i;
350
351                        dojo.addClass(icon, this.orientation+'PagerIcon');
352                        dojo.attr(icon, 'id', this.id+'-status-'+i);
353                        this.pagerContainerStatus.appendChild(icon);
354                                       
355                        if (this.orientation == "vertical"){
356                                dojo.style(icon, 'display', 'block');
357                        }
358                }
359        },
360       
361        _pagerSkip: function(page){
362                if (this._currentPage == page){
363                        return;
364                }else{
365                        // calculate whether to go left or right, take shortest way
366                        var distanceP; var distanceN;
367                        if (page < this._currentPage){
368                                distanceP = this._currentPage - page;
369                                distanceN = (this._totalPages + page) - this._currentPage;
370                        }else{
371                                distanceP = (this._totalPages + this._currentPage) - page;
372                                distanceN = page - this._currentPage;
373                        }
374                       
375                        var b = (distanceN > distanceP);
376                        this._toScroll = (b ? distanceP : distanceN);
377                        var cmd = (b ? "_pagerPrevious" : "_pagerNext");
378                        var connect = this.connect(this, "onScrollEnd", function(){
379                                this._toScroll--;
380                                if(this._toScroll < 1){
381                                        this.disconnect(connect);
382                                }else{
383                                        this[cmd]();
384                                }
385                        });
386                        this[cmd]();
387                       
388                }
389        },
390       
391        _pagerNext: function(){
392                if(this._anim) return;
393
394                /**
395                 * fade slide out current items
396                 * make sure that next items are ligned up nicely before sliding them in
397                 */
398                var _anims = [];
399                for (var i = this._currentPage * this.itemsPage; i > (this._currentPage - 1) * this.itemsPage; i--){
400                        if (!dojo.byId(this.id+'-item-'+i)) continue;
401                       
402                        var currentItem = dojo.byId(this.id+'-item-'+i);
403                        var marginBox = dojo.marginBox(currentItem);
404                        if (this.orientation == "horizontal") {
405                                var move = marginBox.l - (this.itemsPage * marginBox.w);
406                                _anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
407                        }else{
408                                var move = marginBox.t - (this.itemsPage * marginBox.h);
409                                _anims.push(dojo.fx.slideTo({node: currentItem, top: move, duration: this.duration}));
410                        }
411
412                }
413                var previousPage = this._currentPage;
414                if (this._currentPage == this._totalPages){
415                        this._currentPage = 1;
416                }else{
417                        this._currentPage++;
418                }
419               
420                var cnt = this.itemsPage;
421                for (var i=this._currentPage*this.itemsPage; i>(this._currentPage-1)*this.itemsPage; i--){
422                        if (dojo.byId(this.id+'-item-'+i)){
423                                var currentItem = dojo.byId(this.id+'-item-'+i);
424                                var marginBox = dojo.marginBox(currentItem);
425                                if (this.orientation == "horizontal") {
426                                        var newPos = (dojo.style(this.pagerContainerView, 'width')+((cnt-1)*marginBox.w))-1;
427                                        dojo.style(currentItem, 'left', newPos+'px');
428                                        dojo.style(currentItem, 'top', '0px');
429                                       
430                                        var move = newPos-(this.itemsPage*marginBox.w);
431                                        _anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
432                                }else{
433                                        newPos = (dojo.style(this.pagerContainerView, 'height')+((cnt-1)*marginBox.h))-1;
434                                        dojo.style(currentItem, 'top', newPos+'px');
435                                        dojo.style(currentItem, 'left', '0px');
436                                       
437                                        var move = newPos-(this.itemsPage*marginBox.h);
438                                        _anims.push(dojo.fx.slideTo({ node: currentItem, top: move, duration: this.duration}));
439                                }
440                        }
441                        cnt--;
442                }
443               
444                this._anim = dojo.fx.combine(_anims);
445                var animConnect = this.connect(this._anim, "onEnd", function(){
446                        delete this._anim;
447                        this.onScrollEnd();
448                        this.disconnect(animConnect);
449                });
450                this._anim.play();
451               
452                // set pager icons
453                dojo.byId(this.id+'-status-'+previousPage).src = this.iconPage;
454                dojo.byId(this.id+'-status-'+this._currentPage).src = this.iconPageActive;
455        },
456
457    _pagerPrevious: function(){
458                if(this._anim) return;
459   
460                var _anims = [];
461                for (var i=this._currentPage*this.itemsPage; i>(this._currentPage-1)*this.itemsPage; i--){
462                                if (!dojo.byId(this.id+'-item-'+i)) continue;
463                   
464                                var currentItem = dojo.byId(this.id+'-item-'+i);
465                                var marginBox = dojo.marginBox(currentItem);
466                                if (this.orientation == "horizontal") {
467                                                var move = dojo.style(currentItem, 'left')+(this.itemsPage*marginBox.w);
468                                                _anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
469                                }else{
470                                                var move = dojo.style(currentItem, 'top')+(this.itemsPage*marginBox.h);
471                                                _anims.push(dojo.fx.slideTo({node: currentItem, top: move, duration: this.duration}));
472                                }
473                }
474
475                var previousPage = this._currentPage;
476                if (this._currentPage == 1){
477                                this._currentPage = this._totalPages;
478                }else{
479                                this._currentPage--;
480                }
481   
482                var cnt = this.itemsPage;
483                var j=1;
484                for (var i=this._currentPage*this.itemsPage; i>(this._currentPage-1)*this.itemsPage; i--){
485                        if(dojo.byId(this.id+'-item-'+i)){
486                                var currentItem = dojo.byId(this.id+'-item-'+i);
487                                var marginBox = dojo.marginBox(currentItem);
488   
489                                if (this.orientation == "horizontal") {
490                                        var newPos = -(j * marginBox.w) + 1;
491                                        dojo.style(currentItem, 'left', newPos+'px');
492                                        dojo.style(currentItem, 'top', '0px');
493                           
494                                        var move = ((cnt - 1) * marginBox.w);
495                                        _anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
496                           
497                                        var move = newPos+(this.itemsPage * marginBox.w);
498                                        _anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
499                                }else{
500                                        newPos = -((j * marginBox.h) + 1);
501                                        dojo.style(currentItem, 'top', newPos+'px');
502                                        dojo.style(currentItem, 'left', '0px');
503                           
504                                        var move = ((cnt - 1) * marginBox.h);
505                                        _anims.push(dojo.fx.slideTo({node: currentItem, top: move, duration: this.duration}));
506                                }
507                   
508                        }
509                        cnt--;
510                        j++;
511                }
512   
513                this._anim = dojo.fx.combine(_anims);
514                var animConnect = dojo.connect(this._anim, "onEnd", dojo.hitch(this, function(){
515                        delete this._anim;
516                        this.onScrollEnd();
517                        dojo.disconnect(animConnect);
518                }));
519                this._anim.play();
520   
521                // set pager icons
522                dojo.byId(this.id + '-status-' + previousPage).src = this.iconPage;
523                dojo.byId(this.id + '-status-' + this._currentPage).src = this.iconPageActive;
524
525        },
526       
527        onScrollEnd: function(){
528                // summary: Stub Function. Fired after the slide is complete. Override or connect.
529        }
530
531});
532
533dojo.declare("dojox.widget._PagerItem",
534        [dijit._Widget, dijit._Templated],
535        {
536       
537        templateString: '<li class="pagerItem" dojoAttachPoint="containerNode"></li>',
538       
539        resizeChildren: function(){
540                var box = dojo.marginBox(this.containerNode);
541                dojo.style(this.containerNode.firstChild, {
542                        width: box.w +'px',
543                        height: box.h + 'px'
544                });
545        },
546       
547        parseChildren: function(){
548                dojo.parser.parse(this.containerNode);
549        }
550});
Note: See TracBrowser for help on using the repository browser.