Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('datatable-paginator', function (Y, NAME) {
2
 
3
/**
4
 Adds support for paging through data in the DataTable.
5
 
6
 @module datatable
7
 @submodule datatable-paginator
8
 @since 3.11.0
9
 */
10
 
11
var Model,
12
    View,
13
    PaginatorTemplates = Y.DataTable.Templates.Paginator,
14
    sub = Y.Lang.sub,
15
    getClassName = Y.ClassNameManager.getClassName,
16
    CLASS_DISABLED = getClassName(NAME, 'control-disabled'),
17
    EVENT_UI = 'paginator:ui';
18
 
19
 
20
/**
21
 @class DataTable.Paginator.Model
22
 @extends Model
23
 @since 3.11.0
24
 */
25
Model = Y.Base.create('dt-pg-model', Y.Model, [Y.Paginator.Core]),
26
 
27
/**
28
 @class DataTable.Paginator.View
29
 @extends View
30
 @since 3.11.0
31
 */
32
View = Y.Base.create('dt-pg-view', Y.View, [], {
33
    /**
34
     Array of event handles to keep track of what should be destroyed later
35
     @protected
36
     @property _eventHandles
37
     @type {Array}
38
     @since 3.11.0
39
     */
40
    _eventHandles: [],
41
 
42
    /**
43
     Template for this view's container.
44
     @property containerTemplate
45
     @type {String}
46
     @default '<div class="yui3-datatable-paginator"/>'
47
     @since 3.11.0
48
     */
49
    containerTemplate: '<div class="{paginator}"/>',
50
 
51
    /**
52
     Template for content. Helps maintain order of controls.
53
     @property contentTemplate
54
     @type {String}
55
     @default '{buttons}{goto}{perPage}'
56
     @since 3.11.0
57
     */
58
    contentTemplate: '{buttons}{goto}{perPage}',
59
 
60
    /**
61
     Disables ad-hoc ATTRS for our view.
62
     @protected
63
     @property _allowAdHocAttrs
64
     @type {Boolean}
65
     @default false
66
     @since 3.11.0
67
     */
68
    _allowAdHocAttrs: false,
69
 
70
    /**
71
     Sets classnames on the templates and bind events
72
     @method initializer
73
     @since 3.11.0
74
     */
75
    initializer: function () {
76
        this.containerTemplate = sub(this.containerTemplate, {
77
            paginator: getClassName(NAME)
78
        });
79
 
80
        this._initStrings();
81
        this._initClassNames();
82
 
83
        this.attachEvents();
84
    },
85
 
86
    /**
87
     @method render
88
     @chainable
89
     @since 3.11.0
90
     */
91
    render: function () {
92
        var model = this.get('model'),
93
            content = sub(this.contentTemplate, {
94
                'buttons': this._buildButtonsGroup(),
95
                'goto': this._buildGotoGroup(),
96
                'perPage': this._buildPerPageGroup()
97
            });
98
 
99
        this.get('container').append(content);
100
        this.attachEvents();
101
 
102
        this._rendered = true;
103
 
104
        this._updateControlsUI(model.get('page'));
105
        this._updateItemsPerPageUI(model.get('itemsPerPage'));
106
 
107
        return this;
108
    },
109
 
110
    /**
111
     @method attachEvents
112
     @since 3.11.0
113
     */
114
    attachEvents: function () {
115
        View.superclass.attachEvents.apply(this, arguments);
116
 
117
        var container = this.get('container');
118
 
119
        if (!this.classNames) {
120
            this._initClassNames();
121
        }
122
 
123
        this._attachedViewEvents.push(
124
            container.delegate('click', this._controlClick, '.' + this.classNames.control, this),
125
            this.get('model').after('change', this._modelChange, this)
126
        );
127
 
128
        container.all('form').each(Y.bind(function (frm) {
129
            this._attachedViewEvents.push(
130
                frm.after('submit', this._controlSubmit, this)
131
            );
132
        }, this));
133
 
134
        container.all('select').each(Y.bind(function (sel) {
135
            this._attachedViewEvents.push(
136
                sel.after('change', this._controlChange, this)
137
            );
138
        }, this));
139
 
140
    },
141
 
142
    /**
143
     Returns a string built from the button and buttons templates.
144
     @protected
145
     @method _buildButtonsGroup
146
     @return {String}
147
     @since 3.11.0
148
     */
149
    _buildButtonsGroup: function () {
150
        var strings = this.get('strings'),
151
            classNames = this.classNames,
152
            buttons;
153
 
154
        buttons = PaginatorTemplates.button({
155
                    type: 'first', label: strings.first, classNames: classNames
156
                }) +
157
                PaginatorTemplates.button({
158
                    type: 'prev',  label: strings.prev,  classNames: classNames
159
                }) +
160
                PaginatorTemplates.button({
161
                    type: 'next',  label: strings.next,  classNames: classNames
162
                }) +
163
                PaginatorTemplates.button({
164
                    type: 'last',  label: strings.last,  classNames: classNames
165
                });
166
 
167
        return PaginatorTemplates.buttons({
168
            classNames: classNames,
169
            buttons: buttons
170
        });
171
 
172
    },
173
 
174
    /**
175
     Returns a string built from the gotoPage template.
176
     @protected
177
     @method _buildGotoGroup
178
     @return {String}
179
     @since 3.11.0
180
     */
181
    _buildGotoGroup: function () {
182
 
183
        return PaginatorTemplates.gotoPage({
184
            classNames: this.classNames,
185
            strings: this.get('strings'),
186
            page: this.get('model').get('page')
187
        });
188
    },
189
 
190
    /**
191
     Returns a string built from the perPage template
192
     @protected
193
     @method _buildPerPageGroup
194
     @return {String}
195
     @since 3.11.0
196
     */
197
    _buildPerPageGroup: function () {
198
        var options = this.get('pageSizes'),
199
            rowsPerPage = this.get('model').get('rowsPerPage'),
200
            option,
201
            len,
202
            i;
203
 
204
        for (i = 0, len = options.length; i < len; i++ ) {
205
            option = options[i];
206
 
207
            if (typeof option !== 'object') {
208
                option = {
209
                    value: option,
210
                    label: option
211
                };
212
            }
213
            option.selected = (option.value === rowsPerPage) ? ' selected' : '';
214
        }
215
 
216
        return PaginatorTemplates.perPage({
217
            classNames: this.classNames,
218
            strings: this.get('strings'),
219
            options: this.get('pageSizes')
220
        });
221
 
222
    },
223
 
224
    /**
225
     Update the UI after the model has changed.
226
     @protected
227
     @method _modelChange
228
     @param {EventFacade} e
229
     @since 3.11.0
230
     */
231
    _modelChange: function (e) {
232
        var changed = e.changed,
233
            page = (changed && changed.page),
234
            itemsPerPage = (changed && changed.itemsPerPage);
235
 
236
        if (page) {
237
            this._updateControlsUI(page.newVal);
238
        }
239
        if (itemsPerPage) {
240
            this._updateItemsPerPageUI(itemsPerPage.newVal);
241
            if (!page) {
242
                this._updateControlsUI(e.target.get('page'));
243
            }
244
        }
245
 
246
    },
247
 
248
    /**
249
     Updates the button controls and the gotoPage form
250
     @protected
251
     @method _updateControlsUI
252
     @param {Number} val Page number to set the UI input to
253
     @since 3.11.0
254
     */
255
    _updateControlsUI: function (val) {
256
        if (!this._rendered) {
257
            return;
258
        }
259
 
260
        var model = this.get('model'),
261
            controlClass = '.' + this.classNames.control,
262
            container = this.get('container'),
263
            hasPrev = model.hasPrevPage(),
264
            hasNext = model.hasNextPage();
265
 
266
        container.one(controlClass + '-first')
267
                 .toggleClass(CLASS_DISABLED, !hasPrev)
268
                 .set('disabled', !hasPrev);
269
 
270
        container.one(controlClass + '-prev')
271
                 .toggleClass(CLASS_DISABLED, !hasPrev)
272
                 .set('disabled', !hasPrev);
273
 
274
        container.one(controlClass + '-next')
275
                 .toggleClass(CLASS_DISABLED, !hasNext)
276
                 .set('disabled', !hasNext);
277
 
278
        container.one(controlClass + '-last')
279
                 .toggleClass(CLASS_DISABLED, !hasNext)
280
                 .set('disabled', !hasNext);
281
 
282
        container.one('form input').set('value', val);
283
    },
284
 
285
    /**
286
     Updates the drop down select for items per page
287
     @protected
288
     @method _updateItemsPerPageUI
289
     @param {Number} val Number of items to display per page
290
     @since 3.11.0
291
     */
292
    _updateItemsPerPageUI: function (val) {
293
        if (!this._rendered) {
294
            return;
295
        }
296
 
297
        this.get('container').one('select').set('value', val);
298
    },
299
 
300
    /**
301
     Fire EVENT_UI when an enabled control button is clicked
302
     @protected
303
     @method _controlClick
304
     @param {EventFacade} e
305
     @since 3.11.0
306
     */
307
    _controlClick: function (e) { // buttons
308
        e.preventDefault();
309
        var control = e.currentTarget;
310
        // register click events from the four control buttons
311
        if (control.hasClass(CLASS_DISABLED)) {
312
            return;
313
        }
314
        this.fire(EVENT_UI, {
315
            type: control.getData('type'),
316
            val: control.getData('page') || null
317
        });
318
    },
319
 
320
    /**
321
     Fire EVENT_UI with `type:perPage` after the select drop down changes
322
     @protected
323
     @method _controlChange
324
     @param {EventFacade} e
325
     @since 3.11.0
326
     */
327
    _controlChange: function (e) {
328
 
329
        // register change events from the perPage select
330
        if ( e.target.hasClass(CLASS_DISABLED) ) {
331
            return;
332
        }
333
 
334
        val = e.target.get('value');
335
        this.fire(EVENT_UI, { type: 'perPage', val: parseInt(val, 10) });
336
    },
337
 
338
    /**
339
     Fire EVENT_UI with `type:page` after form is submitted
340
     @protected
341
     @method _controlSubmit
342
     @param {EventFacade} e
343
     @since 3.11.0
344
     */
345
    _controlSubmit: function (e) {
346
        if ( e.target.hasClass(CLASS_DISABLED) ) {
347
            return;
348
        }
349
 
350
        // the only form we have is the go to page form
351
        e.preventDefault();
352
 
353
        input = e.target.one('input');
354
 
355
        // Note: Convert input's value into a number.
356
        this.fire(EVENT_UI, { type: 'page', val: +input.get('value') });
357
    },
358
 
359
    /**
360
     Initializes classnames to be used with the templates
361
     @protected
362
     @method _initClassNames
363
     @since 3.11.0
364
     */
365
    _initClassNames: function () {
366
        this.classNames = {
367
            control: getClassName(NAME, 'control'),
368
            controls: getClassName(NAME, 'controls'),
369
            group: getClassName(NAME, 'group'),
370
            perPage: getClassName(NAME, 'per-page')
371
        };
372
    },
373
 
374
    /**
375
     Initializes strings used for internationalization
376
     @protected
377
     @method _initStrings
378
     @since 3.11.0
379
     */
380
    _initStrings: function () {
381
        // Not a valueFn because other class extensions may want to add to it
382
        this.set('strings', Y.mix((this.get('strings') || {}),
383
            Y.Intl.get('datatable-paginator')));
384
    },
385
 
386
 
387
    /**
388
     Returns an Array with default values for the Rows Per Page select option.
389
     We had to use a valueFn to enable language string replacement.
390
 
391
     @protected
392
     @method _defPageSizeVal
393
     @since 3.13.0
394
     */
395
    _defPageSizeVal: function () {
396
        this._initStrings();
397
 
398
        var str = this.get('strings');
399
 
400
        return [10, 50, 100, { label: str.showAll, value: -1 }]
401
    }
402
 
403
}, {
404
    ATTRS: {
405
        /**
406
         Array of values used to populate the drop down for items per page
407
         @attribute pageSizes
408
         @type {Array}
409
         @default [ 10, 50, 100, { label: 'Show All', value: -1 } ]
410
         @since 3.11.0
411
         */
412
        pageSizes: {
413
            valueFn: '_defPageSizeVal'
414
        },
415
 
416
        /**
417
         Model used for this view
418
         @attribute model
419
         @type {Model}
420
         @default null
421
         @since 3.11.0
422
         */
423
        model: {}
424
    }
425
});
426
 
427
/**
428
 @class DataTable.Paginator
429
 @since 3.11.0
430
 */
431
function Controller () {}
432
 
433
Controller.ATTRS = {
434
    /**
435
     A model instance or a configuration object for the Model.
436
     @attribute paginatorModel
437
     @type {Model|Object}
438
     @default null
439
     @since 3.11.0
440
     */
441
    paginatorModel: {
442
        setter: '_setPaginatorModel',
443
        value: null,
444
        writeOnce: 'initOnly'
445
    },
446
 
447
    /**
448
     A pointer to a Model object to be instantiated, or a String off of the
449
     `Y` namespace.
450
 
451
     This is only used if the `paginatorModel` is a configuration object or
452
     is null.
453
     @attribute paginatorModelType
454
     @type {Model|String}
455
     @default 'DataTable.Paginator.Model'
456
     @since 3.11.0
457
     */
458
    paginatorModelType: {
459
        getter: '_getConstructor',
460
        value: 'DataTable.Paginator.Model',
461
        writeOnce: 'initOnly'
462
    },
463
 
464
    /**
465
     A pointer to a `Y.View` object to be instantiated. A new view will be
466
     created for each location provided. Each view created will be given the
467
     same model instance.
468
     @attribute paginatorView
469
     @type {View|String}
470
     @default 'DataTable.Paginator.View'
471
     @since 3.11.0
472
     */
473
    paginatorView: {
474
        getter: '_getConstructor',
475
        value: 'DataTable.Paginator.View',
476
        writeOnce: 'initOnly'
477
    },
478
 
479
    // PAGINATOR CONFIGS
480
    /**
481
     Array of values used to populate the values in the Paginator UI allowing
482
     the end user to select the number of items to display per page.
483
     @attribute pageSizes
484
     @type {Array}
485
     @default [10, 50, 100, { label: 'Show All', value: -1 }]
486
     @since 3.11.0
487
     */
488
    pageSizes: {
489
        setter: '_setPageSizesFn',
490
        valueFn: '_defPageSizeVal'
491
    },
492
 
493
    paginatorStrings: {},
494
 
495
    /**
496
     Number of rows to display per page. As the UI changes the number of pages
497
     to display, this will update to reflect the value selected in the UI
498
     @attribute rowsPerPage
499
     @type {Number | null}
500
     @default null
501
     @since 3.11.0
502
     */
503
    rowsPerPage: {
504
        value: null
505
    },
506
 
507
    /**
508
     String of `footer` or `header`, a Y.Node, or an Array or any combination
509
     of those values.
510
     @attribute paginatorLocation
511
     @type {String|Array|Node}
512
     @default footer
513
     @since 3.11.0
514
     */
515
    paginatorLocation: {
516
        value: 'footer'
517
    }
518
};
519
 
520
Y.mix(Controller.prototype, {
521
    /**
522
     Sets the `paginatorModel` to the first page.
523
     @method firstPage
524
     @chainable
525
     @since 3.11.0
526
     */
527
    firstPage: function () {
528
        this.get('paginatorModel').set('page', 1);
529
        return this;
530
    },
531
 
532
    /**
533
     Sets the `paginatorModel` to the last page.
534
     @method lastPage
535
     @chainable
536
     @since 3.11.0
537
     */
538
    lastPage: function () {
539
        var model = this.get('paginatorModel');
540
        model.set('page', model.get('totalPages'));
541
        return this;
542
    },
543
 
544
    /**
545
     Sets the `paginatorModel` to the previous page.
546
     @method previousPage
547
     @chainable
548
     @since 3.11.0
549
     */
550
    previousPage: function () {
551
        this.get('paginatorModel').prevPage();
552
        return this;
553
    },
554
 
555
    /**
556
     Sets the `paginatorModel` to the next page.
557
     @method nextPage
558
     @chainable
559
     @since 3.11.0
560
     */
561
    nextPage: function () {
562
        this.get('paginatorModel').nextPage();
563
        return this;
564
    },
565
 
566
 
567
    /// Init and protected
568
    /**
569
     Constructor logic
570
     @protected
571
     @method initializer
572
     @since 3.11.0
573
     */
574
    initializer: function () {
575
        // allow DT to use paged data
576
        this._initPaginatorStrings();
577
        this._augmentData();
578
 
579
        if (!this._eventHandles.paginatorRender) {
580
            this._eventHandles.paginatorRender = Y.Do.after(this._paginatorRender, this, 'render');
581
        }
582
    },
583
 
584
    /**
585
     Renders the paginator into locations and attaches events.
586
     @protected
587
     @method _paginatorRender
588
     @since 3.11.0
589
     */
590
    _paginatorRender: function () {
591
        var model = this.get('paginatorModel');
592
 
593
        this._paginatorRenderUI();
594
        model.after('change', this._afterPaginatorModelChange, this);
595
        this.after('dataChange', this._afterDataChangeWithPaginator, this);
596
        this.after('rowsPerPageChange', this._afterRowsPerPageChange, this);
597
        this.data.after(['add', 'remove', 'change'], this._afterDataUpdatesWithPaginator, this);
598
 
599
        // ensure our model has the correct totalItems set
600
        model.set('itemsPerPage', this.get('rowsPerPage'));
601
        model.set('totalItems', this.get('data').size());
602
    },
603
 
604
    /**
605
     After the data changes, we ensure we are on the first page and the data
606
     is augmented
607
     @protected
608
     @method _afterDataChangeWithPaginator
609
     @since 3.11.0
610
     */
611
    _afterDataChangeWithPaginator: function () {
612
        var data = this.get('data'),
613
            model = this.get('paginatorModel');
614
 
615
        model.set('totalItems', data.size());
616
 
617
        if (model.get('page') !== 1) {
618
            this.firstPage();
619
        } else {
620
            this._augmentData();
621
 
622
            data.fire.call(data, 'reset', {
623
                src: 'reset',
624
                models: data._items.concat()
625
            });
626
        }
627
    },
628
 
629
    /**
630
     After data has changed due to a model being added, removed, or changed,
631
     update paginator model totalItems to reflect the changes.
632
     @protected
633
     @method _afterDataUpdatesWithPaginator
634
     @param {EventFacade} e
635
     @since 3.13.0
636
    */
637
    _afterDataUpdatesWithPaginator: function () {
638
        var model = this.get('paginatorModel'),
639
            data = this.get('data');
640
 
641
        model.set('totalItems', data.size());
642
    },
643
 
644
    /**
645
     After the rowsPerPage changes, update the UI to reflect the new number of
646
     rows to be displayed. If the new value is `null`, destroy all instances
647
     of the paginators.
648
     @protected
649
     @method _afterRowsPerPageChange
650
     @param {EventFacade} e
651
     @since 3.11.0
652
     */
653
    _afterRowsPerPageChange: function (e) {
654
        var data = this.get('data'),
655
            model = this.get('paginatorModel'),
656
            view;
657
 
658
        if (e.newVal !== null) {
659
            // turning on
660
            this._paginatorRenderUI();
661
 
662
            if (!(data._paged)) {
663
                this._augmentData();
664
            }
665
 
666
            data._paged.index = (model.get('page') - 1) * model.get('itemsPerPage');
667
            data._paged.length = model.get('itemsPerPage');
668
 
669
        } else { // e.newVal === null
670
            // destroy!
671
            while(this._pgViews.length) {
672
                view = this._pgViews.shift();
673
                view.destroy({ remove: true });
674
                view._rendered = null;
675
            }
676
 
677
            data._paged.index = 0;
678
            data._paged.length = null;
679
        }
680
 
681
        this.get('paginatorModel').set('itemsPerPage', parseInt(e.newVal, 10));
682
    },
683
 
684
    /**
685
     Parse each location and render a new view into each area.
686
     @protected
687
     @method _paginatorRenderUI
688
     @since 3.11.0
689
     */
690
    _paginatorRenderUI: function () {
691
        if (!this.get('rowsPerPage')) {
692
            return;
693
        }
694
        var views = this._pgViews,
695
            ViewClass = this.get('paginatorView'),
696
            viewConfig = {
697
                pageSizes: this.get('pageSizes'),
698
                model: this.get('paginatorModel')
699
            },
700
            locations = this.get('paginatorLocation');
701
 
702
        if (!Y.Lang.isArray(locations)) {
703
            locations = [locations];
704
        }
705
 
706
        if (!views) { // set up initial rendering of views
707
            views = this._pgViews = [];
708
        }
709
 
710
        // for each placement area, push to views
711
        Y.Array.each(locations, function (location) {
712
            var view = new ViewClass(viewConfig),
713
                container = view.render().get('container'),
714
                row;
715
 
716
            view.after('*:ui', this._uiPgHandler, this);
717
            views.push(view);
718
 
719
            if (location._node) { // assume Y.Node
720
                location.append(container);
721
                // remove this container row if the view is ever destroyed
722
                this.after('destroy', function (/* e */) {
723
                    view.destroy({ remove: true });
724
                });
725
            } else if (location === 'footer') { // DT Footer
726
                // Render a table footer if there isn't one
727
                if (!this.foot) {
728
                    this.foot = new Y.DataTable.FooterView({ host: this });
729
                    this.foot.render();
730
                    this.fire('renderFooter', { view: this.foot });
731
                }
732
 
733
                // create a row for the paginator to sit in
734
                row = Y.Node.create(PaginatorTemplates.rowWrapper({
735
                    wrapperClass: getClassName(NAME, 'wrapper'),
736
                    numOfCols: this.get('columns').length
737
                }));
738
 
739
                row.one('td').append(container);
740
                this.foot.tfootNode.append(row);
741
 
742
                // remove this container row if the view is ever destroyed
743
                view.after('destroy', function (/* e */) {
744
                    row.remove(true);
745
                });
746
            } else if (location === 'header') {
747
                // 'header' means insert before the table
748
                // placement with the caption may need to be addressed
749
                if (this.view && this.view.tableNode) {
750
                    this.view.tableNode.insert(container, 'before');
751
                } else {
752
                    this.get('contentBox').prepend(container);
753
                }
754
            }
755
        }, this);
756
 
757
    },
758
 
759
    /**
760
     Handles the paginator's UI event into a single location. Updates the
761
     `paginatorModel` according to what type is provided.
762
     @protected
763
     @method _uiPgHandler
764
     @param {EventFacade} e
765
     @since 3.11.0
766
     */
767
    _uiPgHandler: function (e) {
768
        // e.type = control type (first|prev|next|last|page|perPage)
769
        // e.val = value based on the control type to pass to the model
770
        var model = this.get('paginatorModel');
771
 
772
        switch (e.type) {
773
            case 'first':
774
                model.set('page', 1);
775
                break;
776
            case 'last':
777
                model.set('page', model.get('totalPages'));
778
                break;
779
            case 'prev':
780
            case 'next': // overflow intentional
781
                model[e.type + 'Page']();
782
                break;
783
            case 'page':
784
                model.set('page', e.val);
785
                break;
786
            case 'perPage':
787
                model.set('itemsPerPage', e.val);
788
                model.set('page', 1);
789
                break;
790
        }
791
    },
792
 
793
    /**
794
     Augments the model list with a paged structure, or updates the paged
795
     data. Then fires reset on the model list.
796
     @protected
797
     @method _afterPaginatorModelChange
798
     @param {EventFacade} [e]
799
     @since 3.11.0
800
     */
801
    _afterPaginatorModelChange: function () {
802
        var model = this.get('paginatorModel'),
803
            data = this.get('data');
804
 
805
        if (!data._paged) {
806
            this._augmentData();
807
        } else {
808
            data._paged.index = (model.get('page') - 1) * model.get('itemsPerPage');
809
            data._paged.length = model.get('itemsPerPage');
810
        }
811
 
812
        data.fire.call(data, 'reset', {
813
            src: 'reset',
814
            models: data._items.concat()
815
        });
816
    },
817
 
818
    /**
819
     Augments the model list data structure with paged implementations.
820
 
821
     The model list will contain a method for `getPage` that will return the
822
     given number of items listed within the range.
823
 
824
     `each` will also loop over the items in the page
825
     @protected
826
     @method _augmentData
827
     @since 3.11.0
828
     */
829
    _augmentData: function () {
830
        var model = this.get('paginatorModel');
831
 
832
        if (this.get('rowsPerPage') === null) {
833
            return;
834
        }
835
 
836
        Y.mix(this.get('data'), {
837
 
838
            _paged: {
839
                index: (model.get('page') - 1) * model.get('itemsPerPage'),
840
                length: model.get('itemsPerPage')
841
            },
842
 
843
            getPage: function () {
844
                var _pg = this._paged,
845
                    min = _pg.index;
846
 
847
                // IE LTE 8 doesn't allow "undefined" as a second param - gh890
848
                return (_pg.length >= 0) ?
849
                        this._items.slice(min, min + _pg.length) :
850
                        this._items.slice(min);
851
            },
852
 
853
            size: function (paged) {
854
                return (paged && this._paged.length >=0 ) ?
855
                    this._paged.length :
856
                    this._items.length;
857
            },
858
 
859
            each: function () {
860
                var args = Array.prototype.slice.call(arguments);
861
                args.unshift(this.getPage());
862
 
863
                Y.Array.each.apply(null, args);
864
 
865
                return this;
866
            }
867
        }, true);
868
    },
869
 
870
    /**
871
     Ensures `pageSizes` value is an array of objects to be used in the
872
     paginator view.
873
     @protected
874
     @method _setPageSizesFn
875
     @param {Array} val
876
     @return Array
877
     @since 3.11.0
878
     */
879
    _setPageSizesFn: function (val) {
880
        var i,
881
            len = val.length,
882
            label,
883
            value;
884
 
885
        if (!Y.Lang.isArray(val)) {
886
            val = [val];
887
            len = val.length;
888
        }
889
 
890
        for ( i = 0; i < len; i++ ) {
891
            if (typeof val[i] !== 'object') {
892
                label = val[i];
893
                value = val[i];
894
 
895
                // We want to check to see if we have a number or a string
896
                // of a number. If we do not, we want the value to be -1 to
897
                // indicate "all rows"
898
                /*jshint eqeqeq:false */
899
                if (parseInt(value, 10) != value) {
900
                    value = -1;
901
                }
902
                /*jshint eqeqeq:true */
903
                val[i] = { label: label, value: value };
904
            }
905
        }
906
 
907
        return val;
908
    },
909
 
910
    /**
911
     Ensures the object provided is an instance of a `Y.Model`. If it is not,
912
     it assumes it is the configuration of a model, and gets the new model
913
     type from `paginatorModelType`.
914
     @protected
915
     @method _setPaginatorModel
916
     @param {Model|Object} model
917
     @return Y.Model instance
918
     @since 3.11.0
919
     */
920
    _setPaginatorModel: function (model) {
921
        if (!(model && model._isYUIModel)) {
922
            var ModelConstructor = this.get('paginatorModelType');
923
            model = new ModelConstructor(model);
924
        }
925
 
926
        return model;
927
    },
928
 
929
    /**
930
     Returns a pointer to an object to be instantiated if the provided type is
931
     a string
932
     @protected
933
     @method _getConstructor
934
     @param {Object | String} type Type of Object to contruct. If `type` is a
935
       String, we assume it is a namespace off the Y object
936
     @return
937
     @since 3.11.0
938
     */
939
    _getConstructor: function (type) {
940
        return typeof type === 'string' ?
941
            Y.Object.getValue(Y, type.split('.')) :
942
            type;
943
    },
944
 
945
    /**
946
     Initializes paginatorStrings used for internationalization
947
     @protected
948
     @method _initPaginatorStrings
949
     @since 3.13.0
950
     */
951
    _initPaginatorStrings: function () {
952
        // Not a valueFn because other class extensions may want to add to it
953
        this.set('paginatorStrings', Y.mix((this.get('paginatorStrings') || {}),
954
            Y.Intl.get('datatable-paginator')));
955
    },
956
 
957
    /**
958
     Returns an Array with default values for the Rows Per Page select option.
959
     We had to use a valueFn to enable language string replacement.
960
 
961
     @protected
962
     @method _defPageSizeVal
963
     @since 3.13.0
964
     */
965
    _defPageSizeVal: function () {
966
        this._initPaginatorStrings();
967
 
968
        var str = this.get('paginatorStrings');
969
 
970
        return [10, 50, 100, { label: str.showAll, value: -1 }]
971
    }
972
}, true);
973
 
974
 
975
Y.DataTable.Paginator = Controller;
976
Y.DataTable.Paginator.Model = Model;
977
Y.DataTable.Paginator.View = View;
978
 
979
Y.Base.mix(Y.DataTable, [Y.DataTable.Paginator]);
980
 
981
 
982
}, '3.18.1', {
983
    "requires": [
984
        "model",
985
        "view",
986
        "paginator-core",
987
        "datatable-foot",
988
        "datatable-paginator-templates"
989
    ],
990
    "lang": [
991
        "en",
992
        "fr"
993
    ],
994
    "skinnable": true
995
});