File: example-widget-sort-to-hash.html

package info (click to toggle)
jquery-tablesorter 1%3A2.31.3%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,056 kB
  • sloc: javascript: 19,495; sh: 14; makefile: 8
file content (594 lines) | stat: -rw-r--r-- 29,871 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>jQuery tablesorter 2.0 - Sort2Hash Widget (Beta)</title>

	<!-- jQuery -->
	<script src="js/jquery-latest.min.js"></script>

	<!-- Demo stuff -->
	<link class="ui-theme" rel="stylesheet" href="css/jquery-ui.min.css">
	<script src="js/jquery-ui.min.js"></script>
	<link rel="stylesheet" href="css/jq.css">
	<link href="css/prettify.css" rel="stylesheet">
	<script src="js/prettify.js"></script>
	<script src="js/docs.js"></script>

	<!-- Tablesorter: required -->
	<link rel="stylesheet" href="../css/theme.blue.css">
	<script src="../js/jquery.tablesorter.js"></script>
	<script src="../js/jquery.tablesorter.widgets.js"></script>
	<script src="../js/widgets/widget-sort2Hash.js"></script>

	<link rel="stylesheet" href="../addons/pager/jquery.tablesorter.pager.css">
	<script src="../js/widgets/widget-pager.js"></script>

<script id="js">$(function() {

	$( 'table' ).tablesorter({
		theme: 'blue',
		widgets: [ 'zebra', 'sort2Hash', 'filter' ],
		widgetOptions : {
			// hash prefix
			sort2Hash_hash              : '#',
			// don't '#' or '=' here
			sort2Hash_separator         : ',',
			// this option > table ID > table index on page
			sort2Hash_tableId           : null,
			// data attribute containing alternate header text
			sort2Hash_headerTextAttr    : 'data-header',
			// direction text shown in the URL e.g. [ 'asc', 'desc' ]
			sort2Hash_directionText     : [ 0, 1 ], // default values
			// if true, override saveSort widget sort, if used & stored sort is available
			sort2Hash_overrideSaveSort  : true, // default = false
			// if true, hash changes are not saved to browser history
			sort2Hash_replaceHistory    : false,

			sort2Hash_encodeHash        : null,
			/* how to use encodeHash
			sort2Hash_encodeHash : function( config, tableId, component, value, rawValue ) {
				// config = table.config settings
				// tableId = processed table ID
				// component: 'sort', 'page', 'size' or 'filter'
				// value = string value that has encodeURIComponent applied
				// rawValue = value ( array or number )
				// return false to let the widget encode the string
				return '&' + component + '[' + tableId + ']=' + value;
			},
			*/
			sort2Hash_decodeHash        : null,
			/*
			sort2Hash_decodeHash : function( config, tableId, component ) {
				// config = table.config settings
				// tableId = processed table ID
				// component: 'sort', 'page', 'size' or 'filter'
				// return false to let the widget decode the hash

				// $.tablesorter.sort2Hash.getParam( parameter, url ); function added in v2.24.4
				// parameter = desired parameter to extract
				// url (optional) = hash or href string to extract the parameter value from
				return $.tablesorter.sort2Hash.getParam( component + '[' + tableId + ']' ) || '';
			}
			*/
			sort2Hash_cleanHash         : null,
			/*
			sort2Hash_cleanHash : function( config, tableId, component, hash ) {
				// config = table.config settings
				// tableId = processed table ID
				// component: 'sort', 'page', 'size' or 'filter'
				// return false to let the widget decode the hash

				// removeParam function added v2.24.4
				return $.tablesorter.sort2Hash.removeParam( component + '[' + tableId + ']' );
			}
			*/
			pager_output : '{startRow:input} to {endRow} ({filteredRows})',
			pager_size   : 2
		}
	});

});</script>
</head>
<body>
<div id="banner">
	<h1>table<em>sorter</em></h1>
	<h2>Sort2Hash Widget (Beta)</h2>
	<h3>Flexible client-side table sorting</h3>
	<a href="index.html">Back to documentation</a>
</div>
<div id="main">

	<p></p>
	<br>

	<div id="root" class="accordion">

		<h3><a href="#">Notes</a></h3>
		<div>
		<ul>
			<li>In <span class="version">v2.24.4</span>,
				<ul>
					<li>Added a <code>getParam</code> (get URL parameter) &amp; a <code>removeParam</code>  utility function to help deal with parameters in the URL hash. See the "Functions" section below for more details.</li>
					<li><a href="https://github.com/alexweissman">Alex Weissman</a> has also provided code for a custom hash transformation in <a href="https://gist.github.com/alexweissman/04eebe93706d3c64d89b">this gist</a>; this code sets hash parameters that include the table id &amp; named columns, e.g. <code>&filter[table0][first_name]=foobar</code>.</li>
				</ul>
			</li>
			<li>In <span class="version">v2.24.0</span>, lots of changes were made:
				<ul>
					<li>Removed <code class="alert">sort2Hash_useHeaderText</code> and <code class="alert">sort2Hash_processHeaderText</code> options.</li>
					<li>Added <code>sort2Hash_headerTextAttr</code> option to replace the above two options.</li>
					<li>Added <code>sort2Hash_encodeHash</code>, <code>sort2Hash_decodeHash</code> and <code>sort2Hash_cleanHash</code> options to allow custom value to hash processing.</li>
					<li>This widget now works with the pager &amp; filter, so the hash now includes pager current page, pager page size and current filters in the hash.</li>
					<li>Lots of internal tweaks.</li>
				</ul>
			</li>
			<li>Added <span class="version">v2.22.4</span>. Instead of using the <a href="example-widget-savesort.html">saveSort</a> widget, this widget updates the hash tag to allow saving &amp; sharing a sort applied to a tablesorter table.</li>
			<li>Sort the tables in the demo below. Notice the changes made to the location hash, then reload the page to have the hash applied to the tables.</li>
			<li>This widget requires jQuery version 1.7+.</li>
			<li>This widget does NOT work with tablesorter v2.0.5.</li>
		</ul>
		</div>

		<h3><a href="#">Options</a></h3>
		<div>
			<h3>Sort2Hash widget default options (added inside of tablesorter <code>widgetOptions</code>)</h3>
			<div class="tip">
				<span class="label label-info">TIP!</span> Click on the link in the option column to reveal full details (or <a href="#" class="toggleAll">toggle</a>|<a href="#" class="showAll">show</a>|<a href="#" class="hideAll">hide</a> all) or double click to update the browser location.
			</div>
			<table class="tablesorter-blue options">
				<thead>
					<tr><th>Option</th><th>Default</th><th class="sorter-false">Description</th></tr>
				</thead>
				<tbody>

					<tr id="sort2hash_hash">
						<td><span class="permalink">sort2hash_hash</span></td>
						<td><code>'#'</code></td>
						<td>
							The hash should always be there. This option was added to allow setting extra hash parameters and/or hashbang or whatever.
						</td>
					</tr>

					<tr id="sort2hash_separator">
						<td><a href="#" class="permalink">sort2Hash_separator</a></td>
						<td><code>','</code></td>
						<td>
							Change the hash separator using this option. There are some limitations.
							<div class="collapsible">
							<br>
							In the location hash, the sort parameters are added as <code>&tableID=column,direction, ... ,column,direction</code> (no spaces). This option allows changing the column-direction separator, a comma by default, into the chosen separator.
							<p><span class="label alert">*NOTE*</span> Do not set this option to use a hash (<code>#</code>), ampersand (<code>&</code>) or equal sign (<code>=</code>) as it will interfere with how the hash parameters are set up.</p>
							</div>
						</td>
					</tr>

					<tr id="sort2hash_tableid">
						<td><a href="#" class="permalink">sort2Hash_tableId</a></td>
						<td><code>null</code></td>
						<td>
							Set an ID here to override the table id attribute.
							<div class="collapsible">
							<br>
							In the location hash, the sort parameters are added as <code>&tableID=column,direction, ... ,column,direction</code> (no spaces). The <code>tableID</code> is set by this option.
							<p>This option setting is prioritized over the actual table ID attribute. If neither are set, the <code>tableID</code> will be set as the table's zero-based index on the page.</p>
							<pre class="prettyprint">sort2Hash_tableID &gt; table.id attribute &gt; table index</pre>
							</div>
						</td>
					</tr>

					<tr id="sort2hash_headertextattr">
						<td><a href="#" class="permalink">sort2Hash_headerTextAttr</a></td>
						<td><code>'data-header'</code></td>
						<td>
							Data attribute on header cell containing alternate column identifier added to location hash.
							<div class="collapsible">
								<br>
								This option replaces both <code>sort2Hash_useHeaderText</code> and <code>sort2Hash_processHeaderText</code> options.
								<p>The contents of this attribute will be used in the hash to identify a sorted column.</p>
								<p>Use the header attribute as follows:</p>
								<pre class="prettyprint lang-js">&lt;th data-header="first"&gt;First Name&lt;/th&gt;</pre>
							</div>
						</td>
					</tr>

					<tr id="sort2hash_directiontext">
						<td><a href="#" class="permalink">sort2Hash_directionText</a></td>
						<td><code>[ 0, 1 ]</code></td>
						<td>
							Set the direction text shown in the URL.
							<div class="collapsible">
							<br>
							Only the first two values will be used from this array. The first value is assigned to ascending sorts and the second is assigned to descending sorts.
							<p>Use the option as follows:</p>
							<pre class="prettyprint lang-js">sort2Hash_directionText : [ 'asc', 'desc' ]</pre>
							<span class="label warning">*NOTE*</span> When converting the hash into a value, if the direction hash does not match the second value (<code>'desc'</code> in the example above), it will fallback to an ascending sort no matter what text in contained within the first value.
							</div>
						</td>
					</tr>

					<tr id="sort2hash_overridesavesort">
						<td><span class="permalink">sort2Hash_overrideSaveSort</span></td>
						<td><code>false</code></td>
						<td>if <code>true</code>, the hash sort will override any stored sort (saveSort widget).</td>
					</tr>

					<tr id="sort2hash_replacehistory">
						<td><a href="#" class="permalink">sort2Hash_replaceHistory</a></td>
						<td><code>false</code></td>
						<td>Change how the browser history is managed (<span class="version">v2.29.0</span>)
							<div class="collapsible">
								<p>If <code>true</code>, all hash changes are not saved to browser history, so when the user presses the back arrow, they will be returned to the previous page.</p>
								If <code>false</code>, all hash changes are preserved in the browser history, so when the user presses the back arrow, the hash will show the previous state, but the table won't update unless the page is refreshed.
							</div>
						</td>
					</tr>

					<tr id="sort2hash_encodehash">
						<td><a href="#" class="permalink">sort2Hash_encodeHash</a></td>
						<td><code>null</code></td>
						<td>
							Add a function to create a custom hash (<span class="version updated">v2.24.4</span>).
							<div class="collapsible">
								<br>
								The following example is a duplicate of the internal code that encodes the hash. Adapt to fit your needs:
								<pre class="prettyprint lang-js">sort2Hash_encodeHash : function( config, tableId, component, value, rawValue ) {
  // config = table.config settings
  // tableId = processed table ID
  // component: 'sort', 'page', 'size' or 'filter'
  // value = string value that has encodeURIComponent applied
  // rawValue = value ( array or number )
  // return false to let the widget encode the string
  return '&' + component + '[' + tableId + ']=' + value;
}</pre>
								Return a string to add to the <code>window.location.hash</code> directly.
								<p>If this function returns <code>false</code>, then the internal code will encode the hash for that component. This was done in case only one parameter needs special handling:</p>
								<pre class="prettyprint lang-js">sort2Hash_encodeHash : function( config, tableId, component, value, rawValue ) {
  // only the filter gets special handling
  if ( component === 'filter' ) {
    // if working with rawValue, make sure to use
    // encodeURIComponent on the results
    var newValue = encodeURIComponent( rawValue.join( '--' ) );
    return tableId + 'filter=' + newValue;
  }
  return false;
}</pre>
							</div>
						</td>
					</tr>

					<tr id="sort2hash_decodehash">
						<td><a href="#" class="permalink">sort2Hash_decodeHash</a></td>
						<td><code>null</code></td>
						<td>
							Add a function to process a custom hash (<span class="version updated">v2.24.4</span>).
							<div class="collapsible">
								<br>
								The following example is a duplicate of the internal code that decodes the hash. Adapt to fit your needs:
								<pre class="prettyprint lang-js">sort2Hash_decodeHash : function( config, tableId, component ) {
  // config = table.config settings
  // tableId = processed table ID
  // component: 'sort', 'page', 'size' or 'filter'
  // return false to let the widget decode the hash

  // $.tablesorter.sort2Hash.getParam( parameter, url ); function added in v2.24.4
  // parameter = desired parameter to extract
  // url (optional) = hash or href string to extract the parameter value from
  return $.tablesorter.sort2Hash.getParam( component + '[' + tableId + ']' ) || '';
}</pre>
								Return the component value or an empty string.
								<p>If this function returns <code>false</code>, then the internal code will attempt to decode the hash for that component. This was done in case only one parameter needs special handling:</p>
								<pre class="prettyprint lang-js">sort2Hash_decodeHash : function( config, tableId, component ) {
  // only the filter gets special handling
  if ( component === 'filter' ) {
    return $.tablesorter.sort2Hash.getParam( tableId + 'filter' ) || '';
  }
  return false;
}</pre>
							</div>
						</td>
					</tr>

					<tr id="sort2hash_cleanhash">
						<td><a href="#" class="permalink">sort2Hash_cleanHash</a></td>
						<td><code>null</code></td>
						<td>
							Add a function to remove a custom hash (<span class="version updated">v2.24.4</span>).
							<div class="collapsible">
								<br>
								The following example is a duplicate of the internal code that removes unused values in the hash. Adapt to fit your needs:
								<pre class="prettyprint lang-js">sort2Hash_cleanHash : function( config, tableId, component, hash ) {
  // removeParam function added v2.24.4
  return $.tablesorter.sort2Hash.removeParam( component + '[' + tableId + ']' );
}</pre>
								Return a string of the remaining components or an empty string.
								<p>If this function returns <code>false</code>, then the internal code will attempt to clean the hash for that component. This was done in case only one parameter needs special handling:</p>
								<pre class="prettyprint lang-js">sort2Hash_cleanHash : function( config, tableId, component, hash ) {
  // config = table.config settings
  // tableId = processed table ID
  // component: 'sort', 'page', 'size' or 'filter'
  // return false to let the widget decode the hash

  if ( component === 'filter' ) {
    // removeParam function added v2.24.4
    return $.tablesorter.sort2Hash.removeParam( tableId + 'filter' );
    /* ORIGINAL METHOD, use if the "getParam" function doesn't work on your custom parameter
    var index,
      result = [],
      // regular expression to match the component & value
      regex = new RegExp( tableId + 'filter=([^&]*)' );
      // split hash into component parts
      parts = ( hash || '' ).slice(1).split( '&' ),
      len = parts.length;
    // cycle through each component part
    for ( index = 0; index < len; index++ ) {
      // if the component doesn't match the regular expression...
      if ( !regex.test( parts[ index ] ) ) {
        // then save it
        result.push( parts[ index ] );
      }
    }
    // if we still have something left, join the components back together
    // and return it so the next component can be processed
    // we don't update the window.location.hash, or the page jumps to the top!
    return result.length ? c.widgetOptions.sort2Hash_hash + result.join( '&' ) : '';
    */
  }
  return false;
}</pre>
							</div>
						</td>
					</tr>

				</tbody>

				<!-- non-sorting tbody -->
				<tbody id="deprecated" class="tablesorter-infoOnly">
					<tr><th colspan="5">Deprecated/Removed Options</th></tr>
				</tbody>

				<tbody>
					<tr id="sort2hash_useheadertext">
						<td><a href="#" class="permalink alert">sort2Hash_useHeaderText</a></td>
						<td><code>false</code></td>
						<td>
							This option has been <span class="label alert">removed</span> in v2.24.0! It has been replaced by <a href="#"><code>sort2Hash_headerTextAttr</code></a>.
							<div class="collapsible">
							<p>If <code>true</code>, text from the header is used instead of a zero-based column index.</p>
							Please be aware that if the column text contains spaces or special characters, they will be encoded in the URL. So, <code>"First &#xa3;$&#x20ac;&#x00a4;&#x00a5;&#xa2; Name"</code> will become <code>"First%20%C2%A3$%E2%82%AC%C2%A4%C2%A5%C2%A2%20Name"</code>. This would make the hash very difficult to read.
							<p>Further processing of this header cell text can be done using the <code>sort2Hash_processHeaderText</code> function.</p>
							</div>
						</td>
					</tr>

					<tr id="sort2hash_processheadertext">
						<td><a href="#" class="permalink alert">sort2Hash_processHeaderText</a></td>
						<td><code>null</code></td>
						<td>
							This option has been <span class="label alert">removed</span> in v2.24.0! It has been replaced by <a href="#"><code>sort2Hash_headerTextAttr</code></a>.
							<div class="collapsible">
							<p>If the <code>sort2Hash_useHeaderText</code> option is <code>true</code>, a function here will further process the header cell text.</p>
							Use this function to perform any processing on the header cell text, as desired.
							<p>At this point, the header cell text has not been encoded.</p>
							<p>Here is one example:</p>
							<pre class="prettyprint lang-js">sort2Hash_processHeaderText : function( text, config, columnIndex ) {
  // remove all non-alphanumeric characters (including spaces)
  return text.replace( /[^a-z0-9]/gi, '' );
}</pre>
							Another example:
							<pre class="prettyprint lang-js">sort2Hash_processHeaderText : function( text, config, columnIndex ) {
  // completely custom text to use for the hash
  // this method assumes that the table layout is constant
  // (i.e. columns are not added, removed or rearranged)
  return [ 'first', 'last', 'age', 'total', 'disc', 'date' ][ columnIndex ];
}</pre>
							</div>
						</td>
					</tr>
				</tbody>

			</table>
		</div>

		<h3><a href="#">Functions</a></h3>
		<div>
			<h3>Sort2Hash utility functions (added to <code>$.tablesorter.sort2Hash</code>)</h3>
			<div class="tip">
				<span class="label label-info">TIP!</span> Click on the link in the function column to reveal full details (or <a href="#" class="toggleAll">toggle</a>|<a href="#" class="showAll">show</a>|<a href="#" class="hideAll">hide</a> all) or double click to update the browser location.
			</div>
			<table class="tablesorter-blue options">
				<thead>
					<tr><th>Function</th><th class="sorter-false">Description</th></tr>
				</thead>
				<tbody>

					<tr id="getparam">
						<td><a href="#" class="permalink">getParam</a></td>
						<td>
							Get URL Parameter (getParam) function
							<div class="collapsible">
								<p>This function will extract the value of the name passed to the function. Use it as follows:</p>
								<pre class="prettyprint lang-js">// $.tablesorter.sort2Hash.getParam( name, hash );
// name = parameter name (key)
// hash = (optional) if undefined, it will get the string value from window.location.hash
var hash = '&sort[table-users][user_name]=asc&page[table-users]=1&size[table-users]=10&filter[table-users][user_name]=ad',
	result = $.tablesorter.sort2Hash.getParam( 'filter[table-users][user_name]', hash );
// result = "ad";</pre>
							</div>
						</td>
					</tr>

					<tr id="removeparam">
						<td><a href="#" class="permalink">removeParam</a></td>
						<td>
							Remove parameter from hash
							<div class="collapsible">
								<p>This function will remove the key &amp; value from the passed hash. Use it as follows:</p>
								<pre class="prettyprint lang-js">// $.tablesorter.sort2Hash.removeParam( name, hash );
// name = parameter name (key)
// hash = (optional) if undefined, it will get the string value from window.location.hash
var hash = '&sort[table-users][user_name]=asc&page[table-users]=1&size[table-users]=10&filter[table-users][user_name]=ad',
	result = $.tablesorter.sort2Hash.removeParam( 'filter[table-users][user_name]', hash );
// result = "&sort[table-users][user_name]=asc&page[table-users]=1&size[table-users]=10";</pre>
								<span class="label warning">*NOTE*</span> This function does not update <code>window.location.hash</code>.
							</div>
						</td>
					</tr>
				</tbody>
			</table>
		</div>

	</div>

	<h1>Demo</h1>
	<div id="demo"><h3>Basic Usage <sup class="results">&dagger;</sup></h3>
<table>
	<thead>
		<tr>
			<th>First Name</th>
			<th>Last Name</th>
			<th>Age</th>
			<th>Total</th>
			<th>Discount</th>
			<th>Date</th>
		</tr>
	</thead>
	<tbody>
		<tr><td>Peter</td><td>Parker</td><td>28</td><td>$9.99</td><td>20%</td><td>Jul 6, 2006 8:14 AM</td></tr>
		<tr><td>John</td><td>Hood</td><td>33</td><td>$19.99</td><td>25%</td><td>Dec 10, 2002 5:14 AM</td></tr>
		<tr><td>Clark</td><td>Kent</td><td>18</td><td>$15.89</td><td>44%</td><td>Jan 12, 2003 11:14 AM</td></tr>
		<tr><td>Bruce</td><td>Almighty</td><td>45</td><td>$153.19</td><td>44%</td><td>Jan 18, 2001 9:12 AM</td></tr>
		<tr><td>Bruce</td><td>Evans</td><td>22</td><td>$13.19</td><td>11%</td><td>Jan 18, 2007 9:12 AM</td></tr>
	</tbody>
</table>
<span class="results">&dagger;</span> <span class="xsmall">This table shows up as "table4" because there is no ID assigned, and it is the fifth table (zero-based index) on the page. The first table is in the "Options" section. The second is actually the stickyheader table for "Options". The third & forth (sticky header) are in the "Functions" section.</span>

<h3>Data Header (Using symbols for headers)</h3>
<table id="second">
	<thead>
		<tr>
			<th data-header="^">First Name (^)</th>
			<th data-header="&">Last Name (&)</th>
			<th data-header="#">Age (#)</th>
			<th data-header="$">Total ($)</th>
			<th data-header="%">Discount (%)</th>
			<th data-header="*">Date (*)</th>
		</tr>
	</thead>
	<tbody>
		<tr><td>Peter</td><td>Parker</td><td>28</td><td>$9.99</td><td>20%</td><td>Jul 6, 2006 8:14 AM</td></tr>
		<tr><td>John</td><td>Hood</td><td>33</td><td>$19.99</td><td>25%</td><td>Dec 10, 2002 5:14 AM</td></tr>
		<tr><td>Clark</td><td>Kent</td><td>18</td><td>$15.89</td><td>44%</td><td>Jan 12, 2003 11:14 AM</td></tr>
		<tr><td>Bruce</td><td>Almighty</td><td>45</td><td>$153.19</td><td>44%</td><td>Jan 18, 2001 9:12 AM</td></tr>
		<tr><td>Bruce</td><td>Evans</td><td>22</td><td>$13.19</td><td>11%</td><td>Jan 18, 2007 9:12 AM</td></tr>
	</tbody>
</table>

<hr>
<h3>Pager (page &amp; size)</h3>
<div class="pager">
	<img src="../addons/pager/icons/first.png" class="first" alt="First" />
	<img src="../addons/pager/icons/prev.png" class="prev" alt="Prev" />
	<span class="pagedisplay"></span> <!-- this can be any element, including an input -->
	<img src="../addons/pager/icons/next.png" class="next" alt="Next" />
	<img src="../addons/pager/icons/last.png" class="last" alt="Last" />
	<select class="pagesize" title="Select page size">
		<option value="10">10</option>
		<option value="20">20</option>
		<option value="30">30</option>
		<option value="all">All rows</option>
	</select>
	<select class="gotoPage" title="Select page number"></select>
</div>
<table id="third" class="widget-pager">
	<thead>
		<tr>
			<th data-header="name">Name</th>
			<th data-header="major">Major</th>
			<th data-header="gender">Sex</th>
			<th data-header="english">English</th>
			<th data-header="japanese">Japanese</th>
			<th data-header="calculus">Calculus</th>
			<th data-header="geometry">Geometry</th>
		</tr>
	</thead>
	<tfoot>
		<tr>
			<th>Name</th>
			<th>Major</th>
			<th>Sex</th>
			<th>English</th>
			<th>Japanese</th>
			<th>Calculus</th>
			<th>Geometry</th>
		</tr>
	</tfoot>
	<tbody>
		<tr><td>Student01</td><td>Languages</td><td>male</td><td>80</td><td>70</td><td>75</td><td>80</td></tr>
		<tr><td>Student02</td><td>Mathematics</td><td>male</td><td>90</td><td>88</td><td>100</td><td>90</td></tr>
		<tr><td>Student03</td><td>Languages</td><td>female</td><td>85</td><td>95</td><td>80</td><td>85</td></tr>
		<tr><td>Student04</td><td>Languages</td><td>male</td><td>60</td><td>55</td><td>100</td><td>100</td></tr>
		<tr><td>Student05</td><td>Languages</td><td>female</td><td>68</td><td>80</td><td>95</td><td>80</td></tr>
		<tr><td>Student06</td><td>Mathematics</td><td>male</td><td>100</td><td>99</td><td>100</td><td>90</td></tr>
		<tr><td>Student07</td><td>Mathematics</td><td>male</td><td>85</td><td>68</td><td>90</td><td>90</td></tr>
		<tr><td>Student08</td><td>Languages</td><td>male</td><td>100</td><td>90</td><td>90</td><td>85</td></tr>
		<tr><td>Student09</td><td>Mathematics</td><td>male</td><td>80</td><td>50</td><td>65</td><td>75</td></tr>
		<tr><td>Student10</td><td>Languages</td><td>male</td><td>85</td><td>100</td><td>100</td><td>90</td></tr>
		<tr><td>Student11</td><td>Languages</td><td>male</td><td>86</td><td>85</td><td>100</td><td>100</td></tr>
		<tr><td>Student12</td><td>Mathematics</td><td>female</td><td>100</td><td>75</td><td>70</td><td>85</td></tr>
		<tr><td>Student13</td><td>Languages</td><td>female</td><td>100</td><td>80</td><td>100</td><td>90</td></tr>
		<tr><td>Student14</td><td>Languages</td><td>female</td><td>50</td><td>45</td><td>55</td><td>90</td></tr>
		<tr><td>Student15</td><td>Languages</td><td>male</td><td>95</td><td>35</td><td>100</td><td>90</td></tr>
		<tr><td>Student16</td><td>Languages</td><td>female</td><td>100</td><td>50</td><td>30</td><td>70</td></tr>
		<tr><td>Student17</td><td>Languages</td><td>female</td><td>80</td><td>100</td><td>55</td><td>65</td></tr>
		<tr><td>Student18</td><td>Mathematics</td><td>male</td><td>30</td><td>49</td><td>55</td><td>75</td></tr>
		<tr><td>Student19</td><td>Languages</td><td>male</td><td>68</td><td>90</td><td>88</td><td>70</td></tr>
		<tr><td>Student20</td><td>Mathematics</td><td>male</td><td>40</td><td>45</td><td>40</td><td>80</td></tr>
		<tr><td>Student21</td><td>Languages</td><td>male</td><td>50</td><td>45</td><td>100</td><td>100</td></tr>
		<tr><td>Student22</td><td>Mathematics</td><td>male</td><td>100</td><td>99</td><td>100</td><td>90</td></tr>
		<tr><td>Student23</td><td>Mathematics</td><td>male</td><td>82</td><td>77</td><td>0</td><td>79</td></tr>
		<tr><td>Student24</td><td>Languages</td><td>female</td><td>100</td><td>91</td><td>13</td><td>82</td></tr>
		<tr><td>Student25</td><td>Mathematics</td><td>male</td><td>22</td><td>96</td><td>82</td><td>53</td></tr>
		<tr><td>Student26</td><td>Languages</td><td>female</td><td>37</td><td>29</td><td>56</td><td>59</td></tr>
		<tr><td>Student27</td><td>Mathematics</td><td>male</td><td>86</td><td>82</td><td>69</td><td>23</td></tr>
		<tr><td>Student28</td><td>Languages</td><td>female</td><td>44</td><td>25</td><td>43</td><td>1</td></tr>
		<tr><td>Student29</td><td>Mathematics</td><td>male</td><td>77</td><td>47</td><td>22</td><td>38</td></tr>
		<tr><td>Student30</td><td>Languages</td><td>female</td><td>19</td><td>35</td><td>23</td><td>10</td></tr>
		<tr><td>Student31</td><td>Mathematics</td><td>male</td><td>90</td><td>27</td><td>17</td><td>50</td></tr>
		<tr><td>Student32</td><td>Languages</td><td>female</td><td>60</td><td>75</td><td>33</td><td>38</td></tr>
		<tr><td>Student33</td><td>Mathematics</td><td>male</td><td>4</td><td>31</td><td>37</td><td>15</td></tr>
		<tr><td>Student34</td><td>Languages</td><td>female</td><td>77</td><td>97</td><td>81</td><td>44</td></tr>
		<tr><td>Student35</td><td>Mathematics</td><td>male</td><td>5</td><td>81</td><td>51</td><td>95</td></tr>
		<tr><td>Student36</td><td>Languages</td><td>female</td><td>70</td><td>61</td><td>70</td><td>94</td></tr>
		<tr><td>Student37</td><td>Mathematics</td><td>male</td><td>60</td><td>3</td><td>61</td><td>84</td></tr>
		<tr><td>Student38</td><td>Languages</td><td>female</td><td>63</td><td>39</td><td>0</td><td>11</td></tr>
		<tr><td>Student39</td><td>Mathematics</td><td>male</td><td>50</td><td>46</td><td>32</td><td>38</td></tr>
		<tr><td>Student40</td><td>Languages</td><td>female</td><td>51</td><td>75</td><td>25</td><td>3</td></tr>
		<tr><td>Student41</td><td>Mathematics</td><td>male</td><td>43</td><td>34</td><td>28</td><td>78</td></tr>
		<tr><td>Student42</td><td>Languages</td><td>female</td><td>11</td><td>89</td><td>60</td><td>95</td></tr>
		<tr><td>Student43</td><td>Mathematics</td><td>male</td><td>48</td><td>92</td><td>18</td><td>88</td></tr>
		<tr><td>Student44</td><td>Languages</td><td>female</td><td>82</td><td>2</td><td>59</td><td>73</td></tr>
		<tr><td>Student45</td><td>Mathematics</td><td>male</td><td>91</td><td>73</td><td>37</td><td>39</td></tr>
		<tr><td>Student46</td><td>Languages</td><td>female</td><td>4</td><td>8</td><td>12</td><td>10</td></tr>
		<tr><td>Student47</td><td>Mathematics</td><td>male</td><td>89</td><td>10</td><td>6</td><td>11</td></tr>
		<tr><td>Student48</td><td>Languages</td><td>female</td><td>90</td><td>32</td><td>21</td><td>18</td></tr>
		<tr><td>Student49</td><td>Mathematics</td><td>male</td><td>42</td><td>49</td><td>49</td><td>72</td></tr>
		<tr><td>Student50</td><td>Languages</td><td>female</td><td>56</td><td>37</td><td>67</td><td>54</td></tr>
	</tbody>
</table>

</div>

	<h1>Javascript</h1>
	<div id="javascript">
		<pre class="prettyprint lang-javascript"></pre>
	</div>

	<h1>HTML</h1>
	<div id="html">
		<pre class="prettyprint lang-html"></pre>
	</div>

</div>

</body>
</html>