If you have a UI where it doesn't make sense to place all controls in a single container (or set of containers), you can place individual UI Components manually outside Paginator's configured container(s).
For this example, we'll create a table from a data array and render a few controls into the generated <tfoot>
using the Paginator's template
. We'll also subscribe to the Paginator's render
event with a callback that renders a CurrentPageReport UI Component into a <div>
above the table.
Item | Quantity | Description |
---|---|---|
previousnext | ||
Helmet | 43 | Red baseball helmet. Size: Large. |
Football | 84 | Leather football. |
Goggles | 31 | Light blue swim goggles |
Badminton Set | 56 | Set of 2 badminton rackets, net, and 3 birdies. |
Tennis Balls | 128 | Canister of 3 tennis balls. |
In this example, we'll be working with a data array stored in YAHOO.example.data.inventory
.
1 | YAHOO.namespace('example.data').inventory = [ |
2 | {SKU:"23-23874", Quantity:43, Item:"Helmet", Description:"Red baseball helmet. Size: Large."}, |
3 | {SKU:"48-38835", Quantity:84, Item:"Football", Description:"Leather football."}, |
4 | ... |
5 | ]; |
view plain | print | ? |
We'll start with two empty divs:
1 | <div id="demo"> |
2 | <div id="report"></div> |
3 | <div id="tbl"></div> |
4 | </div> |
view plain | print | ? |
To populate div#tbl
we write some application code to generate a table with a tfoot. The table will be wrapped in an object with an API including a showPage(pageNumber)
method.
1 | YAHOO.util.Event.onDOMReady(function () { |
2 | |
3 | var Ex = YAHOO.namespace('example'), |
4 | d = document; |
5 | |
6 | // API for generating the table |
7 | Ex.table = { |
8 | table : null, |
9 | columns : ['Item','Quantity','Description'], |
10 | pageSize: 5, |
11 | data : null, |
12 | tbody : null, |
13 | tfoot : null, |
14 | |
15 | load : function (data) { ... }, |
16 | render : function (container) { ... }, |
17 | showPage : function (page) { ... } |
18 | }; |
19 | |
20 | ... |
view plain | print | ? |
Create a Paginator and a method to subscribe to its changeRequest
event. Note the configured container is a generated <div>
and is not yet on the page. We'll append this to the <tfoot>
when it is available.
1 | Ex.handlePagination = function (state) { |
2 | // Update the content via API call |
3 | Ex.table.showPage(state.page); |
4 | |
5 | // Confirm page change with Paginator |
6 | Ex.paginator.setState(state); |
7 | }; |
8 | |
9 | // Create a Paginator and configure the UI Components included |
10 | // in the template and the CurrentPageReport we'll render manually |
11 | Ex.paginator = new YAHOO.widget.Paginator({ |
12 | rowsPerPage : Ex.table.pageSize, |
13 | totalRecords : Ex.data.inventory.length, |
14 | containers : d.createElement('div'), |
15 | |
16 | template : "{PreviousPageLink}{NextPageLink}", |
17 | pageReportTemplate : "Page {currentPage} of {totalPages}", |
18 | previousPageLinkLabel : "previous", |
19 | nextPageLinkLabel : "next" |
20 | }); |
21 | |
22 | Ex.paginator.subscribe('changeRequest', Ex.handlePagination); |
view plain | print | ? |
To synchronize the rendering of all UI Components, we subscribe to the Paginator's render
event with a callback to add a CurrentPageReport into div#report
.
UI Components' render
methods take a string seed usually used by Paginator to guarantee uniqueness of generated IDs when rendering into multiple containers. When rendering them manually, you'll need to provide your own seed. If you render more than one of the same type of UI Component, respective render
calls must be passed different seeds.
1 | Ex.paginator.subscribe('render', function () { |
2 | var pageReport, pageReportNode, report; |
3 | |
4 | report = YAHOO.util.Dom.get('report'); |
5 | |
6 | // Instantiate the UI Component |
7 | pageReport = new YAHOO.widget.Paginator.ui.CurrentPageReport(Ex.paginator); |
8 | |
9 | // render the UI Component, passing an arbitrary ID seed (the ID of the |
10 | // destination container by convention) |
11 | pageReportNode = pageReport.render('report'); |
12 | |
13 | // Append the generated node into the container |
14 | report.appendChild(pageReportNode); |
15 | }); |
view plain | print | ? |
Render the table and the Paginator. The CurrentPageReport will be rendered in response to the Paginator's emitted render
event.
The Paginator was configured to use a <div>
created off the page DOM, so the template
controls are not visible until the <div>
is then added to the table's <tfoot>
.
1 | // Render the UI |
2 | Ex.table.load(Ex.data.inventory).render('tbl'); |
3 | |
4 | // Render the Paginator controls into the off DOM div passed as a container |
5 | // just to illustrate that it is possible to do so. |
6 | Ex.paginator.render(); |
7 | |
8 | // Add the Paginator's configured container to the table's tfoot. |
9 | Ex.DOM.add(Ex.table.tfoot.rows[0].cells[0],Ex.paginator.getContainerNodes()[0]); |
view plain | print | ? |
Some convenience methods were created to aid in the DOM structure assembly.
1 | YAHOO.util.Event.onDOMReady(function () { |
2 | |
3 | var Ex = YAHOO.namespace('example'), |
4 | d = document; |
5 | |
6 | /* Convenience functions for building the DOM structure */ |
7 | Ex.DOM = { |
8 | create : function (el,innerHTML) { |
9 | el = el && el.nodeName ? el : d.createElement(el); |
10 | |
11 | if (el && innerHTML !== undefined) { |
12 | el.innerHTML = innerHTML; |
13 | } |
14 | |
15 | return el; |
16 | }, |
17 | add : function (par, child, innerHTML) { |
18 | par = par && YAHOO.util.Dom.get(par); |
19 | if (par && par.appendChild) { |
20 | child = Ex.DOM.create(child,innerHTML); |
21 | if (child) { |
22 | par.appendChild(child); |
23 | } |
24 | } |
25 | |
26 | return child; |
27 | } |
28 | }; |
29 | |
30 | /* Table generation/maintenance API */ |
31 | Ex.table = { |
32 | table : null, |
33 | columns : ['Item','Quantity','Description'], |
34 | pageSize: 5, |
35 | data : null, |
36 | tbody : [], |
37 | tfoot : null, |
38 | |
39 | load : function (data) { |
40 | if (YAHOO.lang.isArray(data)) { |
41 | this.data = data; |
42 | this.tbody = []; |
43 | } |
44 | return this; |
45 | }, |
46 | render : function (container) { |
47 | if (!this.table) { |
48 | container = (container && YAHOO.util.Dom.get(container)) || d.body; |
49 | |
50 | var thead, tbody, row, cell, i, len; |
51 | |
52 | this.table = Ex.DOM.create('table'); |
53 | thead = Ex.DOM.add(this.table,'thead'); |
54 | row = Ex.DOM.add(thead,'tr'); |
55 | |
56 | for (i=0,len=this.columns.length; i<len; ++i) { |
57 | Ex.DOM.add(row,'th',this.columns[i]); |
58 | } |
59 | |
60 | this.tfoot = Ex.DOM.add(this.table,'tfoot'); |
61 | cell = Ex.DOM.add(Ex.DOM.add(this.tfoot,'tr'),'td'); |
62 | cell.colSpan = this.columns.length; |
63 | |
64 | if (this.data) { |
65 | this.showPage(1); |
66 | } else { |
67 | row = Ex.DOM.create('tr'); |
68 | cell = Ex.DOM.add(row,'td','No Data'); |
69 | cell.colSpan = this.columns.length; |
70 | |
71 | Ex.DOM.add(Ex.DOM.add(this.table,'tbody'),row); |
72 | } |
73 | |
74 | container.innerHTML = ''; |
75 | Ex.DOM.add(container,this.table); |
76 | } |
77 | return this; |
78 | }, |
79 | showPage : function (page) { |
80 | var cur, tbody, row, i, j, len, limit; |
81 | |
82 | if (this.table) { |
83 | cur = this.table.getElementsByTagName('tbody')[0]; |
84 | |
85 | if (YAHOO.lang.isNumber(page)) { |
86 | tbody = this.tbody[page]; |
87 | if (!cur || cur !== tbody) { |
88 | if (!tbody) { |
89 | tbody = this.tbody[page] = Ex.DOM.create('tbody'); |
90 | |
91 | i = (page - 1) * this.pageSize; |
92 | limit = Math.min(Ex.data.inventory.length, |
93 | i + this.pageSize); |
94 | for (; i < limit; ++i) { |
95 | row = Ex.DOM.add(tbody,'tr'); |
96 | for (j=0,len=this.columns.length; j<len; ++j) { |
97 | Ex.DOM.add(row,'td', |
98 | this.data[i][this.columns[j]]); |
99 | } |
100 | } |
101 | } |
102 | |
103 | if (cur) { |
104 | this.table.replaceChild(tbody,cur); |
105 | } else { |
106 | Ex.DOM.add(this.table,tbody); |
107 | } |
108 | } |
109 | } |
110 | } |
111 | return this; |
112 | } |
113 | }; |
114 | |
115 | Ex.handlePagination = function (state) { |
116 | Ex.table.showPage(state.page); |
117 | |
118 | Ex.paginator.setState(state); |
119 | }; |
120 | |
121 | Ex.paginator = new YAHOO.widget.Paginator({ |
122 | rowsPerPage : Ex.table.pageSize, |
123 | totalRecords : Ex.data.inventory.length, |
124 | containers : d.createElement('div'), |
125 | |
126 | template : "{PreviousPageLink}{NextPageLink}", |
127 | pageReportTemplate : "Page {currentPage} of {totalPages}", |
128 | previousPageLinkLabel : "previous", |
129 | nextPageLinkLabel : "next" |
130 | }); |
131 | |
132 | Ex.paginator.subscribe('changeRequest', Ex.handlePagination); |
133 | Ex.paginator.subscribe('render', function () { |
134 | var pageReport, pageReportNode, report; |
135 | |
136 | report = YAHOO.util.Dom.get('report'); |
137 | |
138 | // Instantiate the UI Component |
139 | pageReport = new YAHOO.widget.Paginator.ui.CurrentPageReport(Ex.paginator); |
140 | |
141 | // render the UI Component, passing an arbitrary string (the ID of the |
142 | // destination container by convention) |
143 | pageReportNode = pageReport.render('report'); |
144 | |
145 | // Append the generated node into the container |
146 | report.appendChild(pageReportNode); |
147 | }); |
148 | |
149 | |
150 | // Render the UI |
151 | Ex.table.load(Ex.data.inventory).render('tbl'); |
152 | |
153 | // Render the Paginator controls into the off DOM div passed as a container |
154 | // just to illustrate that it is possible to do so. |
155 | Ex.paginator.render(); |
156 | |
157 | // Add the Paginator's configured container to the table's tfoot. |
158 | Ex.DOM.add(Ex.table.tfoot.rows[0].cells[0],Ex.paginator.getContainerNodes()[0]); |
159 | |
160 | }); |
view plain | print | ? |
Custom positioning and style were added to the UI Components used. You'll see the Sam skin overrides as the rules with selectors beginning with .yui-skin-sam
.
1 | /* Sam skin rule overrides */ |
2 | .yui-skin-sam .yui-pg-container { margin: 0; } |
3 | .yui-skin-sam .yui-pg-current { margin-right: 15px; } |
4 | |
5 | .yui-skin-sam .yui-pg-previous { |
6 | float: left; |
7 | padding: 3px 5px; |
8 | } |
9 | .yui-skin-sam .yui-pg-next { |
10 | float: right; |
11 | padding: 3px 5px; |
12 | } |
13 | .yui-skin-sam span.yui-pg-next, |
14 | .yui-skin-sam span.yui-pg-previous { |
15 | display: none; |
16 | } |
17 | |
18 | /* content specific styles */ |
19 | #tbl, |
20 | #report, |
21 | #paging { |
22 | width: 400px; |
23 | margin: 0 auto; |
24 | } |
25 | #report { |
26 | color: #fff; |
27 | background: #ccc; |
28 | font-size: 200%; |
29 | margin-bottom: 1em; |
30 | text-align: right; |
31 | } |
32 | #demo table { |
33 | border-collapse: collapse; |
34 | color: #333; |
35 | width: 100%; |
36 | } |
37 | #demo th { |
38 | border-bottom: 4px solid #999; |
39 | color: #444; |
40 | font: normal 125%/100% Trebuchet MS, Arial, sans-serif; |
41 | padding: 0 6px; |
42 | } |
43 | #demo tbody { |
44 | background: #fff; |
45 | border-left: 1px solid #ccc; |
46 | border-right: 1px solid #ccc; |
47 | } |
48 | #demo tbody td { |
49 | border-bottom: 1px solid #eee; |
50 | padding: 5px; |
51 | } |
52 | #demo tfoot td { |
53 | overflow: hidden; |
54 | } |
view plain | print | ? |
You can load the necessary JavaScript and CSS for this example from Yahoo's servers. Click here to load the YUI Dependency Configurator with all of this example's dependencies preconfigured.
Note: Logging and debugging is currently turned off for this example.
Copyright © 2009 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Copyright Policy - Job Openings