Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 espaco 1
<!DOCTYPE html>
2
<html>
3
<head>
4
        <meta charset="utf-8">
5
        <link rel="shortcut icon" type="image/ico" href="http://www.datatables.net/favicon.ico">
6
        <meta name="viewport" content="initial-scale=1.0, maximum-scale=2.0">
7
 
8
        <title>DataTables example - Pipelining data to reduce Ajax calls for paging</title>
9
        <link rel="stylesheet" type="text/css" href="../../media/css/jquery.dataTables.css">
10
        <link rel="stylesheet" type="text/css" href="../resources/syntax/shCore.css">
11
        <link rel="stylesheet" type="text/css" href="../resources/demo.css">
12
        <style type="text/css" class="init">
13
 
14
        </style>
15
        <script type="text/javascript" language="javascript" src="../../media/js/jquery.js"></script>
16
        <script type="text/javascript" language="javascript" src="../../media/js/jquery.dataTables.js"></script>
17
        <script type="text/javascript" language="javascript" src="../resources/syntax/shCore.js"></script>
18
        <script type="text/javascript" language="javascript" src="../resources/demo.js"></script>
19
        <script type="text/javascript" language="javascript" class="init">
20
 
21
 
22
//
23
// Pipelining function for DataTables. To be used to the `ajax` option of DataTables
24
//
25
$.fn.dataTable.pipeline = function ( opts ) {
26
        // Configuration options
27
        var conf = $.extend( {
28
                pages: 5,     // number of pages to cache
29
                url: '',      // script url
30
                data: null,   // function or object with parameters to send to the server
31
                              // matching how `ajax.data` works in DataTables
32
                method: 'GET' // Ajax HTTP method
33
        }, opts );
34
 
35
        // Private variables for storing the cache
36
        var cacheLower = -1;
37
        var cacheUpper = null;
38
        var cacheLastRequest = null;
39
        var cacheLastJson = null;
40
 
41
        return function ( request, drawCallback, settings ) {
42
                var ajax          = false;
43
                var requestStart  = request.start;
44
                var drawStart     = request.start;
45
                var requestLength = request.length;
46
                var requestEnd    = requestStart + requestLength;
47
 
48
                if ( settings.clearCache ) {
49
                        // API requested that the cache be cleared
50
                        ajax = true;
51
                        settings.clearCache = false;
52
                }
53
                else if ( cacheLower < 0 || requestStart < cacheLower || requestEnd > cacheUpper ) {
54
                        // outside cached data - need to make a request
55
                        ajax = true;
56
                }
57
                else if ( JSON.stringify( request.order )   !== JSON.stringify( cacheLastRequest.order ) ||
58
                          JSON.stringify( request.columns ) !== JSON.stringify( cacheLastRequest.columns ) ||
59
                          JSON.stringify( request.search )  !== JSON.stringify( cacheLastRequest.search )
60
                ) {
61
                        // properties changed (ordering, columns, searching)
62
                        ajax = true;
63
                }
64
 
65
                // Store the request for checking next time around
66
                cacheLastRequest = $.extend( true, {}, request );
67
 
68
                if ( ajax ) {
69
                        // Need data from the server
70
                        if ( requestStart < cacheLower ) {
71
                                requestStart = requestStart - (requestLength*(conf.pages-1));
72
 
73
                                if ( requestStart < 0 ) {
74
                                        requestStart = 0;
75
                                }
76
                        }
77
 
78
                        cacheLower = requestStart;
79
                        cacheUpper = requestStart + (requestLength * conf.pages);
80
 
81
                        request.start = requestStart;
82
                        request.length = requestLength*conf.pages;
83
 
84
                        // Provide the same `data` options as DataTables.
85
                        if ( $.isFunction ( conf.data ) ) {
86
                                // As a function it is executed with the data object as an arg
87
                                // for manipulation. If an object is returned, it is used as the
88
                                // data object to submit
89
                                var d = conf.data( request );
90
                                if ( d ) {
91
                                        $.extend( request, d );
92
                                }
93
                        }
94
                        else if ( $.isPlainObject( conf.data ) ) {
95
                                // As an object, the data given extends the default
96
                                $.extend( request, conf.data );
97
                        }
98
 
99
                        settings.jqXHR = $.ajax( {
100
                                "type":     conf.method,
101
                                "url":      conf.url,
102
                                "data":     request,
103
                                "dataType": "json",
104
                                "cache":    false,
105
                                "success":  function ( json ) {
106
                                        cacheLastJson = $.extend(true, {}, json);
107
 
108
                                        if ( cacheLower != drawStart ) {
109
                                                json.data.splice( 0, drawStart-cacheLower );
110
                                        }
111
                                        json.data.splice( requestLength, json.data.length );
112
 
113
                                        drawCallback( json );
114
                                }
115
                        } );
116
                }
117
                else {
118
                        json = $.extend( true, {}, cacheLastJson );
119
                        json.draw = request.draw; // Update the echo for each response
120
                        json.data.splice( 0, requestStart-cacheLower );
121
                        json.data.splice( requestLength, json.data.length );
122
 
123
                        drawCallback(json);
124
                }
125
        }
126
};
127
 
128
// Register an API method that will empty the pipelined data, forcing an Ajax
129
// fetch on the next draw (i.e. `table.clearPipeline().draw()`)
130
$.fn.dataTable.Api.register( 'clearPipeline()', function () {
131
        return this.iterator( 'table', function ( settings ) {
132
                settings.clearCache = true;
133
        } );
134
} );
135
 
136
 
137
//
138
// DataTables initialisation
139
//
140
$(document).ready(function() {
141
        $('#example').dataTable( {
142
                "processing": true,
143
                "serverSide": true,
144
                "ajax": $.fn.dataTable.pipeline( {
145
                        url: 'scripts/server_processing.php',
146
                        pages: 5 // number of pages to cache
147
                } )
148
        } );
149
} );
150
 
151
 
152
        </script>
153
</head>
154
 
155
<body class="dt-example">
156
        <div class="container">
157
                <section>
158
                        <h1>DataTables example <span>Pipelining data to reduce Ajax calls for paging</span></h1>
159
 
160
                        <div class="info">
161
                                <p>Sever-side processing can be quite hard on your server, since it makes an Ajax call to the server
162
                                for every draw request that is made. On sites with a large number of page views, you could potentially
163
                                end up DDoSing your own server with your own applications!</p>
164
 
165
                                <p>This example shows one technique to reduce the number of Ajax calls that are made to the server by
166
                                caching more data than is needed for each draw. This is done by intercepting the Ajax call and routing
167
                                it through a data cache control; using the data from the cache if available, and making the Ajax
168
                                request if not. This intercept of the Ajax request is performed by giving the <a href=
169
                                "//datatables.net/reference/option/ajax"><code class="option" title=
170
                                "DataTables initialisation option">ajax<span>DT</span></code></a> option as a function. This function
171
                                then performs the logic of deciding if another Ajax call is needed, or if data from the cache can be
172
                                used.</p>
173
 
174
                                <p>Keep in mind that this caching is for paging only; the pipeline must be cleared for other
175
                                interactions such as ordering and searching since the full data set, when using server-side processing,
176
                                is only available at the server.</p>
177
                        </div>
178
 
179
                        <table id="example" class="display" cellspacing="0" width="100%">
180
                                <thead>
181
                                        <tr>
182
                                                <th>Name</th>
183
                                                <th>Position</th>
184
                                                <th>Office</th>
185
                                                <th>Extn.</th>
186
                                                <th>Start date</th>
187
                                                <th>Salary</th>
188
                                        </tr>
189
                                </thead>
190
 
191
                                <tfoot>
192
                                        <tr>
193
                                                <th>Name</th>
194
                                                <th>Position</th>
195
                                                <th>Office</th>
196
                                                <th>Extn.</th>
197
                                                <th>Start date</th>
198
                                                <th>Salary</th>
199
                                        </tr>
200
                                </tfoot>
201
                        </table>
202
 
203
                        <ul class="tabs">
204
                                <li class="active">Javascript</li>
205
                                <li>HTML</li>
206
                                <li>CSS</li>
207
                                <li>Ajax</li>
208
                                <li>Server-side script</li>
209
                        </ul>
210
 
211
                        <div class="tabs">
212
                                <div class="js">
213
                                        <p>The Javascript shown below is used to initialise the table shown in this
214
                                        example:</p><code class="multiline brush: js;">//
215
// Pipelining function for DataTables. To be used to the `ajax` option of DataTables
216
//
217
$.fn.dataTable.pipeline = function ( opts ) {
218
        // Configuration options
219
        var conf = $.extend( {
220
                pages: 5,     // number of pages to cache
221
                url: '',      // script url
222
                data: null,   // function or object with parameters to send to the server
223
                              // matching how `ajax.data` works in DataTables
224
                method: 'GET' // Ajax HTTP method
225
        }, opts );
226
 
227
        // Private variables for storing the cache
228
        var cacheLower = -1;
229
        var cacheUpper = null;
230
        var cacheLastRequest = null;
231
        var cacheLastJson = null;
232
 
233
        return function ( request, drawCallback, settings ) {
234
                var ajax          = false;
235
                var requestStart  = request.start;
236
                var drawStart     = request.start;
237
                var requestLength = request.length;
238
                var requestEnd    = requestStart + requestLength;
239
 
240
                if ( settings.clearCache ) {
241
                        // API requested that the cache be cleared
242
                        ajax = true;
243
                        settings.clearCache = false;
244
                }
245
                else if ( cacheLower &lt; 0 || requestStart &lt; cacheLower || requestEnd &gt; cacheUpper ) {
246
                        // outside cached data - need to make a request
247
                        ajax = true;
248
                }
249
                else if ( JSON.stringify( request.order )   !== JSON.stringify( cacheLastRequest.order ) ||
250
                          JSON.stringify( request.columns ) !== JSON.stringify( cacheLastRequest.columns ) ||
251
                          JSON.stringify( request.search )  !== JSON.stringify( cacheLastRequest.search )
252
                ) {
253
                        // properties changed (ordering, columns, searching)
254
                        ajax = true;
255
                }
256
 
257
                // Store the request for checking next time around
258
                cacheLastRequest = $.extend( true, {}, request );
259
 
260
                if ( ajax ) {
261
                        // Need data from the server
262
                        if ( requestStart &lt; cacheLower ) {
263
                                requestStart = requestStart - (requestLength*(conf.pages-1));
264
 
265
                                if ( requestStart &lt; 0 ) {
266
                                        requestStart = 0;
267
                                }
268
                        }
269
 
270
                        cacheLower = requestStart;
271
                        cacheUpper = requestStart + (requestLength * conf.pages);
272
 
273
                        request.start = requestStart;
274
                        request.length = requestLength*conf.pages;
275
 
276
                        // Provide the same `data` options as DataTables.
277
                        if ( $.isFunction ( conf.data ) ) {
278
                                // As a function it is executed with the data object as an arg
279
                                // for manipulation. If an object is returned, it is used as the
280
                                // data object to submit
281
                                var d = conf.data( request );
282
                                if ( d ) {
283
                                        $.extend( request, d );
284
                                }
285
                        }
286
                        else if ( $.isPlainObject( conf.data ) ) {
287
                                // As an object, the data given extends the default
288
                                $.extend( request, conf.data );
289
                        }
290
 
291
                        settings.jqXHR = $.ajax( {
292
                                &quot;type&quot;:     conf.method,
293
                                &quot;url&quot;:      conf.url,
294
                                &quot;data&quot;:     request,
295
                                &quot;dataType&quot;: &quot;json&quot;,
296
                                &quot;cache&quot;:    false,
297
                                &quot;success&quot;:  function ( json ) {
298
                                        cacheLastJson = $.extend(true, {}, json);
299
 
300
                                        if ( cacheLower != drawStart ) {
301
                                                json.data.splice( 0, drawStart-cacheLower );
302
                                        }
303
                                        json.data.splice( requestLength, json.data.length );
304
 
305
                                        drawCallback( json );
306
                                }
307
                        } );
308
                }
309
                else {
310
                        json = $.extend( true, {}, cacheLastJson );
311
                        json.draw = request.draw; // Update the echo for each response
312
                        json.data.splice( 0, requestStart-cacheLower );
313
                        json.data.splice( requestLength, json.data.length );
314
 
315
                        drawCallback(json);
316
                }
317
        }
318
};
319
 
320
// Register an API method that will empty the pipelined data, forcing an Ajax
321
// fetch on the next draw (i.e. `table.clearPipeline().draw()`)
322
$.fn.dataTable.Api.register( 'clearPipeline()', function () {
323
        return this.iterator( 'table', function ( settings ) {
324
                settings.clearCache = true;
325
        } );
326
} );
327
 
328
 
329
//
330
// DataTables initialisation
331
//
332
$(document).ready(function() {
333
        $('#example').dataTable( {
334
                &quot;processing&quot;: true,
335
                &quot;serverSide&quot;: true,
336
                &quot;ajax&quot;: $.fn.dataTable.pipeline( {
337
                        url: 'scripts/server_processing.php',
338
                        pages: 5 // number of pages to cache
339
                } )
340
        } );
341
} );</code>
342
 
343
                                        <p>In addition to the above code, the following Javascript library files are loaded for use in this
344
                                        example:</p>
345
 
346
                                        <ul>
347
                                                <li><a href="../../media/js/jquery.js">../../media/js/jquery.js</a></li>
348
                                                <li><a href="../../media/js/jquery.dataTables.js">../../media/js/jquery.dataTables.js</a></li>
349
                                        </ul>
350
                                </div>
351
 
352
                                <div class="table">
353
                                        <p>The HTML shown below is the raw HTML table element, before it has been enhanced by
354
                                        DataTables:</p>
355
                                </div>
356
 
357
                                <div class="css">
358
                                        <div>
359
                                                <p>This example uses a little bit of additional CSS beyond what is loaded from the library
360
                                                files (below), in order to correctly display the table. The additional CSS used is shown
361
                                                below:</p><code class="multiline brush: js;"></code>
362
                                        </div>
363
 
364
                                        <p>The following CSS library files are loaded for use in this example to provide the styling of the
365
                                        table:</p>
366
 
367
                                        <ul>
368
                                                <li><a href=
369
                                                "../../media/css/jquery.dataTables.css">../../media/css/jquery.dataTables.css</a></li>
370
                                        </ul>
371
                                </div>
372
 
373
                                <div class="ajax">
374
                                        <p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data
375
                                        will update automatically as any additional data is loaded.</p>
376
                                </div>
377
 
378
                                <div class="php">
379
                                        <p>The script used to perform the server-side processing for this table is shown below. Please note
380
                                        that this is just an example script using PHP. Server-side processing scripts can be written in any
381
                                        language, using <a href="//datatables.net/manual/server-side">the protocol described in the
382
                                        DataTables documentation</a>.</p>
383
                                </div>
384
                        </div>
385
                </section>
386
        </div>
387
 
388
        <section>
389
                <div class="footer">
390
                        <div class="gradient"></div>
391
 
392
                        <div class="liner">
393
                                <h2>Other examples</h2>
394
 
395
                                <div class="toc">
396
                                        <div class="toc-group">
397
                                                <h3><a href="../basic_init/index.html">Basic initialisation</a></h3>
398
                                                <ul class="toc">
399
                                                        <li><a href="../basic_init/zero_configuration.html">Zero configuration</a></li>
400
                                                        <li><a href="../basic_init/filter_only.html">Feature enable / disable</a></li>
401
                                                        <li><a href="../basic_init/table_sorting.html">Default ordering (sorting)</a></li>
402
                                                        <li><a href="../basic_init/multi_col_sort.html">Multi-column ordering</a></li>
403
                                                        <li><a href="../basic_init/multiple_tables.html">Multiple tables</a></li>
404
                                                        <li><a href="../basic_init/hidden_columns.html">Hidden columns</a></li>
405
                                                        <li><a href="../basic_init/complex_header.html">Complex headers (rowspan and
406
                                                        colspan)</a></li>
407
                                                        <li><a href="../basic_init/dom.html">DOM positioning</a></li>
408
                                                        <li><a href="../basic_init/flexible_width.html">Flexible table width</a></li>
409
                                                        <li><a href="../basic_init/state_save.html">State saving</a></li>
410
                                                        <li><a href="../basic_init/alt_pagination.html">Alternative pagination</a></li>
411
                                                        <li><a href="../basic_init/scroll_y.html">Scroll - vertical</a></li>
412
                                                        <li><a href="../basic_init/scroll_x.html">Scroll - horizontal</a></li>
413
                                                        <li><a href="../basic_init/scroll_xy.html">Scroll - horizontal and vertical</a></li>
414
                                                        <li><a href="../basic_init/scroll_y_theme.html">Scroll - vertical with jQuery UI
415
                                                        ThemeRoller</a></li>
416
                                                        <li><a href="../basic_init/comma-decimal.html">Language - Comma decimal place</a></li>
417
                                                        <li><a href="../basic_init/language.html">Language options</a></li>
418
                                                </ul>
419
                                        </div>
420
 
421
                                        <div class="toc-group">
422
                                                <h3><a href="../advanced_init/index.html">Advanced initialisation</a></h3>
423
                                                <ul class="toc">
424
                                                        <li><a href="../advanced_init/events_live.html">DOM / jQuery events</a></li>
425
                                                        <li><a href="../advanced_init/dt_events.html">DataTables events</a></li>
426
                                                        <li><a href="../advanced_init/column_render.html">Column rendering</a></li>
427
                                                        <li><a href="../advanced_init/length_menu.html">Page length options</a></li>
428
                                                        <li><a href="../advanced_init/dom_multiple_elements.html">Multiple table control
429
                                                        elements</a></li>
430
                                                        <li><a href="../advanced_init/complex_header.html">Complex headers (rowspan /
431
                                                        colspan)</a></li>
432
                                                        <li><a href="../advanced_init/html5-data-attributes.html">HTML5 data-* attributes</a></li>
433
                                                        <li><a href="../advanced_init/language_file.html">Language file</a></li>
434
                                                        <li><a href="../advanced_init/defaults.html">Setting defaults</a></li>
435
                                                        <li><a href="../advanced_init/row_callback.html">Row created callback</a></li>
436
                                                        <li><a href="../advanced_init/row_grouping.html">Row grouping</a></li>
437
                                                        <li><a href="../advanced_init/footer_callback.html">Footer callback</a></li>
438
                                                        <li><a href="../advanced_init/dom_toolbar.html">Custom toolbar elements</a></li>
439
                                                        <li><a href="../advanced_init/sort_direction_control.html">Order direction sequence
440
                                                        control</a></li>
441
                                                </ul>
442
                                        </div>
443
 
444
                                        <div class="toc-group">
445
                                                <h3><a href="../styling/index.html">Styling</a></h3>
446
                                                <ul class="toc">
447
                                                        <li><a href="../styling/display.html">Base style</a></li>
448
                                                        <li><a href="../styling/no-classes.html">Base style - no styling classes</a></li>
449
                                                        <li><a href="../styling/cell-border.html">Base style - cell borders</a></li>
450
                                                        <li><a href="../styling/compact.html">Base style - compact</a></li>
451
                                                        <li><a href="../styling/hover.html">Base style - hover</a></li>
452
                                                        <li><a href="../styling/order-column.html">Base style - order-column</a></li>
453
                                                        <li><a href="../styling/row-border.html">Base style - row borders</a></li>
454
                                                        <li><a href="../styling/stripe.html">Base style - stripe</a></li>
455
                                                        <li><a href="../styling/bootstrap.html">Bootstrap</a></li>
456
                                                        <li><a href="../styling/foundation.html">Foundation</a></li>
457
                                                        <li><a href="../styling/jqueryUI.html">jQuery UI ThemeRoller</a></li>
458
                                                </ul>
459
                                        </div>
460
 
461
                                        <div class="toc-group">
462
                                                <h3><a href="../data_sources/index.html">Data sources</a></h3>
463
                                                <ul class="toc">
464
                                                        <li><a href="../data_sources/dom.html">HTML (DOM) sourced data</a></li>
465
                                                        <li><a href="../data_sources/ajax.html">Ajax sourced data</a></li>
466
                                                        <li><a href="../data_sources/js_array.html">Javascript sourced data</a></li>
467
                                                        <li><a href="../data_sources/server_side.html">Server-side processing</a></li>
468
                                                </ul>
469
                                        </div>
470
 
471
                                        <div class="toc-group">
472
                                                <h3><a href="../api/index.html">API</a></h3>
473
                                                <ul class="toc">
474
                                                        <li><a href="../api/add_row.html">Add rows</a></li>
475
                                                        <li><a href="../api/multi_filter.html">Individual column searching (text inputs)</a></li>
476
                                                        <li><a href="../api/multi_filter_select.html">Individual column searching (select
477
                                                        inputs)</a></li>
478
                                                        <li><a href="../api/highlight.html">Highlighting rows and columns</a></li>
479
                                                        <li><a href="../api/row_details.html">Child rows (show extra / detailed
480
                                                        information)</a></li>
481
                                                        <li><a href="../api/select_row.html">Row selection (multiple rows)</a></li>
482
                                                        <li><a href="../api/select_single_row.html">Row selection and deletion (single
483
                                                        row)</a></li>
484
                                                        <li><a href="../api/form.html">Form inputs</a></li>
485
                                                        <li><a href="../api/counter_columns.html">Index column</a></li>
486
                                                        <li><a href="../api/show_hide.html">Show / hide columns dynamically</a></li>
487
                                                        <li><a href="../api/api_in_init.html">Using API in callbacks</a></li>
488
                                                        <li><a href="../api/tabs_and_scrolling.html">Scrolling and jQuery UI tabs</a></li>
489
                                                        <li><a href="../api/regex.html">Search API (regular expressions)</a></li>
490
                                                </ul>
491
                                        </div>
492
 
493
                                        <div class="toc-group">
494
                                                <h3><a href="../ajax/index.html">Ajax</a></h3>
495
                                                <ul class="toc">
496
                                                        <li><a href="../ajax/simple.html">Ajax data source (arrays)</a></li>
497
                                                        <li><a href="../ajax/objects.html">Ajax data source (objects)</a></li>
498
                                                        <li><a href="../ajax/deep.html">Nested object data (objects)</a></li>
499
                                                        <li><a href="../ajax/objects_subarrays.html">Nested object data (arrays)</a></li>
500
                                                        <li><a href="../ajax/orthogonal-data.html">Orthogonal data</a></li>
501
                                                        <li><a href="../ajax/null_data_source.html">Generated content for a column</a></li>
502
                                                        <li><a href="../ajax/custom_data_property.html">Custom data source property</a></li>
503
                                                        <li><a href="../ajax/custom_data_flat.html">Flat array data source</a></li>
504
                                                        <li><a href="../ajax/defer_render.html">Deferred rendering for speed</a></li>
505
                                                </ul>
506
                                        </div>
507
 
508
                                        <div class="toc-group">
509
                                                <h3><a href="./index.html">Server-side</a></h3>
510
                                                <ul class="toc active">
511
                                                        <li><a href="./simple.html">Server-side processing</a></li>
512
                                                        <li><a href="./custom_vars.html">Custom HTTP variables</a></li>
513
                                                        <li><a href="./post.html">POST data</a></li>
514
                                                        <li><a href="./ids.html">Automatic addition of row ID attributes</a></li>
515
                                                        <li><a href="./object_data.html">Object data source</a></li>
516
                                                        <li><a href="./row_details.html">Row details</a></li>
517
                                                        <li><a href="./select_rows.html">Row selection</a></li>
518
                                                        <li><a href="./jsonp.html">JSONP data source for remote domains</a></li>
519
                                                        <li><a href="./defer_loading.html">Deferred loading of data</a></li>
520
                                                        <li class="active"><a href="./pipeline.html">Pipelining data to reduce Ajax calls for
521
                                                        paging</a></li>
522
                                                </ul>
523
                                        </div>
524
 
525
                                        <div class="toc-group">
526
                                                <h3><a href="../plug-ins/index.html">Plug-ins</a></h3>
527
                                                <ul class="toc">
528
                                                        <li><a href="../plug-ins/api.html">API plug-in methods</a></li>
529
                                                        <li><a href="../plug-ins/sorting_auto.html">Ordering plug-ins (with type
530
                                                        detection)</a></li>
531
                                                        <li><a href="../plug-ins/sorting_manual.html">Ordering plug-ins (no type
532
                                                        detection)</a></li>
533
                                                        <li><a href="../plug-ins/range_filtering.html">Custom filtering - range search</a></li>
534
                                                        <li><a href="../plug-ins/dom_sort.html">Live DOM ordering</a></li>
535
                                                </ul>
536
                                        </div>
537
                                </div>
538
 
539
                                <div class="epilogue">
540
                                        <p>Please refer to the <a href="http://www.datatables.net">DataTables documentation</a> for full
541
                                        information about its API properties and methods.<br>
542
                                        Additionally, there are a wide range of <a href="http://www.datatables.net/extras">extras</a> and
543
                                        <a href="http://www.datatables.net/plug-ins">plug-ins</a> which extend the capabilities of
544
                                        DataTables.</p>
545
 
546
                                        <p class="copyright">DataTables designed and created by <a href=
547
                                        "http://www.sprymedia.co.uk">SpryMedia Ltd</a> &#169; 2007-2014<br>
548
                                        DataTables is licensed under the <a href="http://www.datatables.net/mit">MIT license</a>.</p>
549
                                </div>
550
                        </div>
551
                </div>
552
        </section>
553
</body>
554
</html>