diff --git a/airtime_mvc/public/css/datatables/css/TableTools.css b/airtime_mvc/public/css/datatables/css/TableTools.css
new file mode 100755
index 000000000..84ae6363f
--- /dev/null
+++ b/airtime_mvc/public/css/datatables/css/TableTools.css
@@ -0,0 +1,265 @@
+/*
+ * File: TableTools.css
+ * Description: Styles for TableTools 2
+ * Author: Allan Jardine (www.sprymedia.co.uk)
+ * Language: Javascript
+ * License: LGPL / 3 point BSD
+ * Project: DataTables
+ *
+ * Copyright 2010 Allan Jardine, all rights reserved.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * CSS name space:
+ * DTTT DataTables TableTools
+ *
+ * Colour dictionary:
+ * Button border #d0d0d0
+ * Button border hover #999999
+ * Hover background #f0f0f0
+ * Action blue #4b66d9
+ *
+ * Style sheet provides:
+ * CONTAINER TableTools container element and styles applying to all components
+ * BUTTON_STYLES Action specific button styles
+ * SELECTING Row selection styles
+ * COLLECTIONS Drop down list (collection) styles
+ * PRINTING Print display styles
+ * MISC Minor misc styles
+ */
+
+
+/*
+ * CONTAINER
+ * TableTools container element and styles applying to all components
+ */
+div.DTTT_container {
+ position: relative;
+ float: right;
+ margin-bottom: 1em;
+}
+
+button.DTTT_button {
+ position: relative;
+ float: left;
+ height: 30px;
+ margin-right: 3px;
+ padding: 3px 5px;
+ border: 1px solid #d0d0d0;
+ background-color: #fff;
+ cursor: pointer;
+ *cursor: hand;
+}
+
+button.DTTT_button::-moz-focus-inner {
+ border: none !important;
+ padding: 0;
+}
+
+
+/*
+ * BUTTON_STYLES
+ * Action specific button styles
+ */
+
+button.DTTT_button_csv {
+ padding-right: 30px;
+ background: url(../images/csv.png) no-repeat center right;
+}
+
+button.DTTT_button_csv_hover {
+ padding-right: 30px;
+ border: 1px solid #999;
+ background: #f0f0f0 url(../images/csv_hover.png) no-repeat center right;
+}
+
+
+button.DTTT_button_xls {
+ padding-right: 30px;
+ background: url(../images/xls.png) no-repeat center right;
+}
+
+button.DTTT_button_xls_hover {
+ padding-right: 30px;
+ border: 1px solid #999;
+ background: #f0f0f0 url(../images/xls_hover.png) no-repeat center right;
+}
+
+
+button.DTTT_button_copy {
+ padding-right: 30px;
+ background: url(../images/copy.png) no-repeat center right;
+}
+
+button.DTTT_button_copy_hover {
+ padding-right: 30px;
+ border: 1px solid #999;
+ background: #f0f0f0 url(../images/copy_hover.png) no-repeat center right;
+}
+
+
+button.DTTT_button_pdf {
+ padding-right: 30px;
+ background: url(../images/pdf.png) no-repeat center right;
+}
+
+button.DTTT_button_pdf_hover {
+ padding-right: 30px;
+ border: 1px solid #999;
+ background: #f0f0f0 url(../images/pdf_hover.png) no-repeat center right;
+}
+
+
+button.DTTT_button_print {
+ padding-right: 30px;
+ background: url(../images/print.png) no-repeat center right;
+}
+
+button.DTTT_button_print_hover {
+ padding-right: 30px;
+ border: 1px solid #999;
+ background: #f0f0f0 url(../images/print_hover.png) no-repeat center right;
+}
+
+
+button.DTTT_button_text {
+}
+
+button.DTTT_button_text_hover {
+ border: 1px solid #999;
+ background-color: #f0f0f0;
+}
+
+
+button.DTTT_button_collection {
+ padding-right: 17px;
+ background: url(../images/collection.png) no-repeat center right;
+}
+
+button.DTTT_button_collection_hover {
+ padding-right: 17px;
+ border: 1px solid #999;
+ background: #f0f0f0 url(../images/collection_hover.png) no-repeat center right;
+}
+
+
+/*
+ * SELECTING
+ * Row selection styles
+ */
+table.DTTT_selectable tbody tr {
+ cursor: pointer;
+ *cursor: hand;
+}
+
+tr.DTTT_selected.odd {
+ background-color: #9FAFD1;
+}
+
+tr.DTTT_selected.odd td.sorting_1 {
+ background-color: #9FAFD1;
+}
+
+tr.DTTT_selected.odd td.sorting_2 {
+ background-color: #9FAFD1;
+}
+
+tr.DTTT_selected.odd td.sorting_3 {
+ background-color: #9FAFD1;
+}
+
+
+tr.DTTT_selected.even {
+ background-color: #B0BED9;
+}
+
+tr.DTTT_selected.even td.sorting_1 {
+ background-color: #B0BED9;
+}
+
+tr.DTTT_selected.even td.sorting_2 {
+ background-color: #B0BED9;
+}
+
+tr.DTTT_selected.even td.sorting_3 {
+ background-color: #B0BED9;
+}
+
+
+/*
+ * COLLECTIONS
+ * Drop down list (collection) styles
+ */
+
+div.DTTT_collection {
+ width: 150px;
+ padding: 3px;
+ border: 1px solid #ccc;
+ background-color: #f3f3f3;
+ overflow: hidden;
+ z-index: 2002;
+}
+
+div.DTTT_collection_background {
+ background: transparent url(../images/background.png) repeat top left;
+ z-index: 2001;
+}
+
+div.DTTT_collection button.DTTT_button {
+ float: none;
+ width: 100%;
+ margin-bottom: 2px;
+ background-color: white;
+}
+
+
+/*
+ * PRINTING
+ * Print display styles
+ */
+
+.DTTT_print_info {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 400px;
+ height: 150px;
+ margin-left: -200px;
+ margin-top: -75px;
+ text-align: center;
+ background-color: #3f3f3f;
+ color: white;
+ padding: 10px 30px;
+
+ opacity: 0.9;
+
+ border-radius: 5px;
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+}
+
+.DTTT_print_info h6 {
+ font-weight: normal;
+ font-size: 28px;
+ line-height: 28px;
+ margin: 1em;
+}
+
+.DTTT_print_info p {
+ font-size: 14px;
+ line-height: 20px;
+}
+
+
+/*
+ * MISC
+ * Minor misc styles
+ */
+
+.DTTT_disabled {
+ color: #999;
+}
diff --git a/airtime_mvc/public/css/datatables/css/demo_page.css b/airtime_mvc/public/css/datatables/css/demo_page.css
deleted file mode 100644
index aede410ab..000000000
--- a/airtime_mvc/public/css/datatables/css/demo_page.css
+++ /dev/null
@@ -1,92 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * General page setup
- */
-#dt_example {
- font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
- margin: 0;
- padding: 0;
- color: #333;
- background-color: #fff;
-}
-
-
-#dt_example #container {
- width: 800px;
- margin: 30px auto;
- padding: 0;
-}
-
-
-#dt_example #footer {
- margin: 50px auto 0 auto;
- padding: 0;
-}
-
-#dt_example #demo {
- margin: 30px auto 0 auto;
-}
-
-#dt_example .demo_jui {
- margin: 30px auto 0 auto;
-}
-
-#dt_example .big {
- font-size: 1.3em;
- font-weight: bold;
- line-height: 1.6em;
- color: #4E6CA3;
-}
-
-#dt_example .spacer {
- height: 20px;
- clear: both;
-}
-
-#dt_example .clear {
- clear: both;
-}
-
-#dt_example pre {
- padding: 15px;
- background-color: #F5F5F5;
- border: 1px solid #CCCCCC;
-}
-
-#dt_example h1 {
- margin-top: 2em;
- font-size: 1.3em;
- font-weight: normal;
- line-height: 1.6em;
- color: #4E6CA3;
- border-bottom: 1px solid #B0BED9;
- clear: both;
-}
-
-#dt_example h2 {
- font-size: 1.2em;
- font-weight: normal;
- line-height: 1.6em;
- color: #4E6CA3;
- clear: both;
-}
-
-#dt_example a {
- color: #0063DC;
- text-decoration: none;
-}
-
-#dt_example a:hover {
- text-decoration: underline;
-}
-
-#dt_example ul {
- color: #4E6CA3;
-}
-
-.css_right {
- float: right;
-}
-
-.css_left {
- float: left;
-}
\ No newline at end of file
diff --git a/airtime_mvc/public/css/datatables/css/demo_table.css b/airtime_mvc/public/css/datatables/css/demo_table.css
deleted file mode 100644
index 3bc043379..000000000
--- a/airtime_mvc/public/css/datatables/css/demo_table.css
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * File: demo_table.css
- * CVS: $Id$
- * Description: CSS descriptions for DataTables demo pages
- * Author: Allan Jardine
- * Created: Tue May 12 06:47:22 BST 2009
- * Modified: $Date$ by $Author$
- * Language: CSS
- * Project: DataTables
- *
- * Copyright 2009 Allan Jardine. All Rights Reserved.
- *
- * ***************************************************************************
- * DESCRIPTION
- *
- * The styles given here are suitable for the demos that are used with the standard DataTables
- * distribution (see www.datatables.net). You will most likely wish to modify these styles to
- * meet the layout requirements of your site.
- *
- * Common issues:
- * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
- * no conflict between the two pagination types. If you want to use full_numbers pagination
- * ensure that you either have "example_alt_pagination" as a body class name, or better yet,
- * modify that selector.
- * Note that the path used for Images is relative. All images are by default located in
- * ../images/ - relative to this CSS file.
- */
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables features
- */
-
-.dataTables_wrapper {
- position: relative;
- min-height: 302px;
- clear: both;
- _height: 302px;
- zoom: 1; /* Feeling sorry for IE */
-}
-
-.dataTables_processing {
- position: absolute;
- top: 50%;
- left: 50%;
- width: 250px;
- height: 30px;
- margin-left: -125px;
- margin-top: -15px;
- padding: 14px 0 2px 0;
- border: 1px solid #ddd;
- text-align: center;
- color: #999;
- font-size: 14px;
- background-color: white;
-}
-
-.dataTables_length {
- width: 40%;
- float: left;
-}
-
-.dataTables_filter {
- width: 50%;
- float: right;
- text-align: right;
-}
-
-.dataTables_info {
- width: 60%;
- float: left;
-}
-
-.dataTables_paginate {
- width: 44px;
- * width: 50px;
- float: right;
- text-align: right;
-}
-
-/* Pagination nested */
-.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
- height: 19px;
- width: 19px;
- margin-left: 3px;
- float: left;
-}
-
-.paginate_disabled_previous {
- background-image: url('../images/back_disabled.jpg');
-}
-
-.paginate_enabled_previous {
- background-image: url('../images/back_enabled.jpg');
-}
-
-.paginate_disabled_next {
- background-image: url('../images/forward_disabled.jpg');
-}
-
-.paginate_enabled_next {
- background-image: url('../images/forward_enabled.jpg');
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables display
- */
-table.display {
- margin: 0 auto;
- clear: both;
- width: 100%;
-
- /* Note Firefox 3.5 and before have a bug with border-collapse
- * ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 )
- * border-spacing: 0; is one possible option. Conditional-css.com is
- * useful for this kind of thing
- *
- * Further note IE 6/7 has problems when calculating widths with border width.
- * It subtracts one px relative to the other browsers from the first column, and
- * adds one to the end...
- *
- * If you want that effect I'd suggest setting a border-top/left on th/td's and
- * then filling in the gaps with other borders.
- */
-}
-
-table.display thead th {
- padding: 3px 18px 3px 10px;
- border-bottom: 1px solid black;
- font-weight: bold;
- cursor: pointer;
- * cursor: hand;
-}
-
-table.display tfoot th {
- padding: 3px 18px 3px 10px;
- border-top: 1px solid black;
- font-weight: bold;
-}
-
-table.display tr.heading2 td {
- border-bottom: 1px solid #aaa;
-}
-
-table.display td {
- padding: 3px 10px;
-}
-
-table.display td.center {
- text-align: center;
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables sorting
- */
-
-.sorting_asc {
- background: url('../images/sort_asc.png') no-repeat center right;
-}
-
-.sorting_desc {
- background: url('../images/sort_desc.png') no-repeat center right;
-}
-
-.sorting {
- background: url('../images/sort_both.png') no-repeat center right;
-}
-
-.sorting_asc_disabled {
- background: url('../images/sort_asc_disabled.png') no-repeat center right;
-}
-
-.sorting_desc_disabled {
- background: url('../images/sort_desc_disabled.png') no-repeat center right;
-}
-
-
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables row classes
- */
-table.display tr.odd.gradeA {
- background-color: #ddffdd;
-}
-
-table.display tr.even.gradeA {
- background-color: #eeffee;
-}
-
-table.display tr.odd.gradeC {
- background-color: #ddddff;
-}
-
-table.display tr.even.gradeC {
- background-color: #eeeeff;
-}
-
-table.display tr.odd.gradeX {
- background-color: #ffdddd;
-}
-
-table.display tr.even.gradeX {
- background-color: #ffeeee;
-}
-
-table.display tr.odd.gradeU {
- background-color: #ddd;
-}
-
-table.display tr.even.gradeU {
- background-color: #eee;
-}
-
-
-tr.odd {
- background-color: #E2E4FF;
-}
-
-tr.even {
- background-color: white;
-}
-
-
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Misc
- */
-.dataTables_scroll {
- clear: both;
-}
-
-.dataTables_scrollBody {
- *margin-top: -1px;
-}
-
-.top, .bottom {
- padding: 15px;
- background-color: #F5F5F5;
- border: 1px solid #CCCCCC;
-}
-
-.top .dataTables_info {
- float: none;
-}
-
-.clear {
- clear: both;
-}
-
-.dataTables_empty {
- text-align: center;
-}
-
-tfoot input {
- margin: 0.5em 0;
- width: 100%;
- color: #444;
-}
-
-tfoot input.search_init {
- color: #999;
-}
-
-td.group {
- background-color: #d1cfd0;
- border-bottom: 2px solid #A19B9E;
- border-top: 2px solid #A19B9E;
-}
-
-td.details {
- background-color: #d1cfd0;
- border: 2px solid #A19B9E;
-}
-
-
-.example_alt_pagination div.dataTables_info {
- width: 40%;
-}
-
-.paging_full_numbers {
- width: 400px;
- height: 22px;
- line-height: 22px;
-}
-
-.paging_full_numbers span.paginate_button,
- .paging_full_numbers span.paginate_active {
- border: 1px solid #aaa;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- padding: 2px 5px;
- margin: 0 3px;
- cursor: pointer;
- *cursor: hand;
-}
-
-.paging_full_numbers span.paginate_button {
- background-color: #ddd;
-}
-
-.paging_full_numbers span.paginate_button:hover {
- background-color: #ccc;
-}
-
-.paging_full_numbers span.paginate_active {
- background-color: #99B3FF;
-}
-
-table.display tr.even.row_selected td {
- background-color: #B0BED9;
-}
-
-table.display tr.odd.row_selected td {
- background-color: #9FAFD1;
-}
-
-
-/*
- * Sorting classes for columns
- */
-/* For the standard odd/even */
-tr.odd td.sorting_1 {
- background-color: #D3D6FF;
-}
-
-tr.odd td.sorting_2 {
- background-color: #DADCFF;
-}
-
-tr.odd td.sorting_3 {
- background-color: #E0E2FF;
-}
-
-tr.even td.sorting_1 {
- background-color: #EAEBFF;
-}
-
-tr.even td.sorting_2 {
- background-color: #F2F3FF;
-}
-
-tr.even td.sorting_3 {
- background-color: #F9F9FF;
-}
-
-
-/* For the Conditional-CSS grading rows */
-/*
- Colour calculations (based off the main row colours)
- Level 1:
- dd > c4
- ee > d5
- Level 2:
- dd > d1
- ee > e2
- */
-tr.odd.gradeA td.sorting_1 {
- background-color: #c4ffc4;
-}
-
-tr.odd.gradeA td.sorting_2 {
- background-color: #d1ffd1;
-}
-
-tr.odd.gradeA td.sorting_3 {
- background-color: #d1ffd1;
-}
-
-tr.even.gradeA td.sorting_1 {
- background-color: #d5ffd5;
-}
-
-tr.even.gradeA td.sorting_2 {
- background-color: #e2ffe2;
-}
-
-tr.even.gradeA td.sorting_3 {
- background-color: #e2ffe2;
-}
-
-tr.odd.gradeC td.sorting_1 {
- background-color: #c4c4ff;
-}
-
-tr.odd.gradeC td.sorting_2 {
- background-color: #d1d1ff;
-}
-
-tr.odd.gradeC td.sorting_3 {
- background-color: #d1d1ff;
-}
-
-tr.even.gradeC td.sorting_1 {
- background-color: #d5d5ff;
-}
-
-tr.even.gradeC td.sorting_2 {
- background-color: #e2e2ff;
-}
-
-tr.even.gradeC td.sorting_3 {
- background-color: #e2e2ff;
-}
-
-tr.odd.gradeX td.sorting_1 {
- background-color: #ffc4c4;
-}
-
-tr.odd.gradeX td.sorting_2 {
- background-color: #ffd1d1;
-}
-
-tr.odd.gradeX td.sorting_3 {
- background-color: #ffd1d1;
-}
-
-tr.even.gradeX td.sorting_1 {
- background-color: #ffd5d5;
-}
-
-tr.even.gradeX td.sorting_2 {
- background-color: #ffe2e2;
-}
-
-tr.even.gradeX td.sorting_3 {
- background-color: #ffe2e2;
-}
-
-tr.odd.gradeU td.sorting_1 {
- background-color: #c4c4c4;
-}
-
-tr.odd.gradeU td.sorting_2 {
- background-color: #d1d1d1;
-}
-
-tr.odd.gradeU td.sorting_3 {
- background-color: #d1d1d1;
-}
-
-tr.even.gradeU td.sorting_1 {
- background-color: #d5d5d5;
-}
-
-tr.even.gradeU td.sorting_2 {
- background-color: #e2e2e2;
-}
-
-tr.even.gradeU td.sorting_3 {
- background-color: #e2e2e2;
-}
-
-
-/*
- * Row highlighting example
- */
-.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
- background-color: #ECFFB3;
-}
-
-.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
- background-color: #E6FF99;
-}
-
-.ex_highlight_row #example tr.even:hover {
- background-color: #ECFFB3;
-}
-
-.ex_highlight_row #example tr.even:hover td.sorting_1 {
- background-color: #DDFF75;
-}
-
-.ex_highlight_row #example tr.even:hover td.sorting_2 {
- background-color: #E7FF9E;
-}
-
-.ex_highlight_row #example tr.even:hover td.sorting_3 {
- background-color: #E2FF89;
-}
-
-.ex_highlight_row #example tr.odd:hover {
- background-color: #E6FF99;
-}
-
-.ex_highlight_row #example tr.odd:hover td.sorting_1 {
- background-color: #D6FF5C;
-}
-
-.ex_highlight_row #example tr.odd:hover td.sorting_2 {
- background-color: #E0FF84;
-}
-
-.ex_highlight_row #example tr.odd:hover td.sorting_3 {
- background-color: #DBFF70;
-}
-
-
-/*
- * KeyTable
- */
-table.KeyTable td {
- border: 3px solid transparent;
-}
-
-table.KeyTable td.focus {
- border: 3px solid #3366FF;
-}
-
-table.display tr.gradeA {
- background-color: #eeffee;
-}
-
-table.display tr.gradeC {
- background-color: #ddddff;
-}
-
-table.display tr.gradeX {
- background-color: #ffdddd;
-}
-
-table.display tr.gradeU {
- background-color: #ddd;
-}
-
-div.box {
- height: 100px;
- padding: 10px;
- overflow: auto;
- border: 1px solid #8080FF;
- background-color: #E5E5FF;
-}
diff --git a/airtime_mvc/public/css/datatables/css/demo_table_jui.css b/airtime_mvc/public/css/datatables/css/demo_table_jui.css
deleted file mode 100644
index b81a1cf99..000000000
--- a/airtime_mvc/public/css/datatables/css/demo_table_jui.css
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * File: demo_table_jui.css
- * CVS: $Id$
- * Description: CSS descriptions for DataTables demo pages
- * Author: Allan Jardine
- * Created: Tue May 12 06:47:22 BST 2009
- * Modified: $Date$ by $Author$
- * Language: CSS
- * Project: DataTables
- *
- * Copyright 2009 Allan Jardine. All Rights Reserved.
- *
- * ***************************************************************************
- * DESCRIPTION
- *
- * The styles given here are suitable for the demos that are used with the standard DataTables
- * distribution (see www.datatables.net). You will most likely wish to modify these styles to
- * meet the layout requirements of your site.
- *
- * Common issues:
- * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is
- * no conflict between the two pagination types. If you want to use full_numbers pagination
- * ensure that you either have "example_alt_pagination" as a body class name, or better yet,
- * modify that selector.
- * Note that the path used for Images is relative. All images are by default located in
- * ../images/ - relative to this CSS file.
- */
-
-
-/*
- * jQuery UI specific styling
- */
-
-.paging_two_button .ui-button {
- float: left;
- cursor: pointer;
- * cursor: hand;
-}
-
-.paging_full_numbers .ui-button {
- padding: 2px 6px;
- margin: 0;
- cursor: pointer;
- * cursor: hand;
-}
-
-.ui-buttonset .ui-button {
- margin-right: -0.1em !important;
-}
-
-.paging_full_numbers {
- width: 350px !important;
-}
-
-.ui-toolbar {
- padding: 5px;
-}
-
-.dataTables_paginate {
- width: auto;
-}
-
-.dataTables_info {
- padding-top: 3px;
-}
-
-table.display thead th {
- padding: 3px 0px 3px 10px;
- cursor: pointer;
- * cursor: hand;
-}
-
-div.dataTables_wrapper .ui-widget-header {
- font-weight: normal;
-}
-
-
-/*
- * Sort arrow icon positioning
- */
-table.display thead th div.DataTables_sort_wrapper {
- position: relative;
- padding-right: 20px;
- padding-right: 20px;
-}
-
-table.display thead th div.DataTables_sort_wrapper span {
- position: absolute;
- top: 50%;
- margin-top: -8px;
- right: 0;
-}
-
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- *
- * Everything below this line is the same as demo_table.css. This file is
- * required for 'cleanliness' of the markup
- *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables features
- */
-
-.dataTables_wrapper {
- position: relative;
- min-height: 302px;
- _height: 302px;
- clear: both;
-}
-
-.dataTables_processing {
- position: absolute;
- top: 0px;
- left: 50%;
- width: 250px;
- margin-left: -125px;
- border: 1px solid #ddd;
- text-align: center;
- color: #999;
- font-size: 11px;
- padding: 2px 0;
-}
-
-.dataTables_length {
- width: 40%;
- float: left;
-}
-
-.dataTables_filter {
- width: 50%;
- float: right;
- text-align: right;
-}
-
-.dataTables_info {
- width: 50%;
- float: left;
-}
-
-.dataTables_paginate {
- float: right;
- text-align: right;
-}
-
-/* Pagination nested */
-.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next {
- height: 19px;
- width: 19px;
- margin-left: 3px;
- float: left;
-}
-
-.paginate_disabled_previous {
- background-image: url('../images/back_disabled.jpg');
-}
-
-.paginate_enabled_previous {
- background-image: url('../images/back_enabled.jpg');
-}
-
-.paginate_disabled_next {
- background-image: url('../images/forward_disabled.jpg');
-}
-
-.paginate_enabled_next {
- background-image: url('../images/forward_enabled.jpg');
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables display
- */
-table.display {
- margin: 0 auto;
- width: 100%;
- clear: both;
- border-collapse: collapse;
-}
-
-table.display tfoot th {
- padding: 3px 0px 3px 10px;
- font-weight: bold;
- font-weight: normal;
-}
-
-table.display tr.heading2 td {
- border-bottom: 1px solid #aaa;
-}
-
-table.display td {
- padding: 3px 10px;
-}
-
-table.display td.center {
- text-align: center;
-}
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables sorting
- */
-
-.sorting_asc {
- background: url('../images/sort_asc.jpg') no-repeat center right;
-}
-
-.sorting_desc {
- background: url('../images/sort_desc.jpg') no-repeat center right;
-}
-
-.sorting {
- background: url('../images/sort_both.jpg') no-repeat center right;
-}
-
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * DataTables row classes
- */
-table.display tr.odd.gradeA {
- background-color: #ddffdd;
-}
-
-table.display tr.even.gradeA {
- background-color: #eeffee;
-}
-
-
-
-
-table.display tr.odd.gradeA {
- background-color: #ddffdd;
-}
-
-table.display tr.even.gradeA {
- background-color: #eeffee;
-}
-
-table.display tr.odd.gradeC {
- background-color: #ddddff;
-}
-
-table.display tr.even.gradeC {
- background-color: #eeeeff;
-}
-
-table.display tr.odd.gradeX {
- background-color: #ffdddd;
-}
-
-table.display tr.even.gradeX {
- background-color: #ffeeee;
-}
-
-table.display tr.odd.gradeU {
- background-color: #ddd;
-}
-
-table.display tr.even.gradeU {
- background-color: #eee;
-}
-
-
-tr.odd {
- background-color: #E2E4FF;
-}
-
-tr.even {
- background-color: white;
-}
-
-
-
-
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Misc
- */
-.dataTables_scroll {
- clear: both;
-}
-
-.top, .bottom {
- padding: 15px;
- background-color: #F5F5F5;
- border: 1px solid #CCCCCC;
-}
-
-.top .dataTables_info {
- float: none;
-}
-
-.clear {
- clear: both;
-}
-
-.dataTables_empty {
- text-align: center;
-}
-
-tfoot input {
- margin: 0.5em 0;
- width: 100%;
- color: #444;
-}
-
-tfoot input.search_init {
- color: #999;
-}
-
-td.group {
- background-color: #d1cfd0;
- border-bottom: 2px solid #A19B9E;
- border-top: 2px solid #A19B9E;
-}
-
-td.details {
- background-color: #d1cfd0;
- border: 2px solid #A19B9E;
-}
-
-
-.example_alt_pagination div.dataTables_info {
- width: 40%;
-}
-
-.paging_full_numbers span.paginate_button,
- .paging_full_numbers span.paginate_active {
- border: 1px solid #aaa;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- padding: 2px 5px;
- margin: 0 3px;
- cursor: pointer;
- *cursor: hand;
-}
-
-.paging_full_numbers span.paginate_button {
- background-color: #ddd;
-}
-
-.paging_full_numbers span.paginate_button:hover {
- background-color: #ccc;
-}
-
-.paging_full_numbers span.paginate_active {
- background-color: #99B3FF;
-}
-
-table.display tr.even.row_selected td {
- background-color: #B0BED9;
-}
-
-table.display tr.odd.row_selected td {
- background-color: #9FAFD1;
-}
-
-
-/*
- * Sorting classes for columns
- */
-/* For the standard odd/even */
-tr.odd td.sorting_1 {
- background-color: #D3D6FF;
-}
-
-tr.odd td.sorting_2 {
- background-color: #DADCFF;
-}
-
-tr.odd td.sorting_3 {
- background-color: #E0E2FF;
-}
-
-tr.even td.sorting_1 {
- background-color: #EAEBFF;
-}
-
-tr.even td.sorting_2 {
- background-color: #F2F3FF;
-}
-
-tr.even td.sorting_3 {
- background-color: #F9F9FF;
-}
-
-
-/* For the Conditional-CSS grading rows */
-/*
- Colour calculations (based off the main row colours)
- Level 1:
- dd > c4
- ee > d5
- Level 2:
- dd > d1
- ee > e2
- */
-tr.odd.gradeA td.sorting_1 {
- background-color: #c4ffc4;
-}
-
-tr.odd.gradeA td.sorting_2 {
- background-color: #d1ffd1;
-}
-
-tr.odd.gradeA td.sorting_3 {
- background-color: #d1ffd1;
-}
-
-tr.even.gradeA td.sorting_1 {
- background-color: #d5ffd5;
-}
-
-tr.even.gradeA td.sorting_2 {
- background-color: #e2ffe2;
-}
-
-tr.even.gradeA td.sorting_3 {
- background-color: #e2ffe2;
-}
-
-tr.odd.gradeC td.sorting_1 {
- background-color: #c4c4ff;
-}
-
-tr.odd.gradeC td.sorting_2 {
- background-color: #d1d1ff;
-}
-
-tr.odd.gradeC td.sorting_3 {
- background-color: #d1d1ff;
-}
-
-tr.even.gradeC td.sorting_1 {
- background-color: #d5d5ff;
-}
-
-tr.even.gradeC td.sorting_2 {
- background-color: #e2e2ff;
-}
-
-tr.even.gradeC td.sorting_3 {
- background-color: #e2e2ff;
-}
-
-tr.odd.gradeX td.sorting_1 {
- background-color: #ffc4c4;
-}
-
-tr.odd.gradeX td.sorting_2 {
- background-color: #ffd1d1;
-}
-
-tr.odd.gradeX td.sorting_3 {
- background-color: #ffd1d1;
-}
-
-tr.even.gradeX td.sorting_1 {
- background-color: #ffd5d5;
-}
-
-tr.even.gradeX td.sorting_2 {
- background-color: #ffe2e2;
-}
-
-tr.even.gradeX td.sorting_3 {
- background-color: #ffe2e2;
-}
-
-tr.odd.gradeU td.sorting_1 {
- background-color: #c4c4c4;
-}
-
-tr.odd.gradeU td.sorting_2 {
- background-color: #d1d1d1;
-}
-
-tr.odd.gradeU td.sorting_3 {
- background-color: #d1d1d1;
-}
-
-tr.even.gradeU td.sorting_1 {
- background-color: #d5d5d5;
-}
-
-tr.even.gradeU td.sorting_2 {
- background-color: #e2e2e2;
-}
-
-tr.even.gradeU td.sorting_3 {
- background-color: #e2e2e2;
-}
-
-
-/*
- * Row highlighting example
- */
-.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted {
- background-color: #ECFFB3;
-}
-
-.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted {
- background-color: #E6FF99;
-}
\ No newline at end of file
diff --git a/airtime_mvc/public/css/datatables/css/jquery.dataTables.css b/airtime_mvc/public/css/datatables/css/jquery.dataTables.css
new file mode 100644
index 000000000..dda16c419
--- /dev/null
+++ b/airtime_mvc/public/css/datatables/css/jquery.dataTables.css
@@ -0,0 +1,219 @@
+
+/*
+ * Table
+ */
+table.dataTable {
+ margin: 0 auto;
+ clear: both;
+ width: 100%;
+}
+
+table.dataTable thead th {
+ padding: 3px 18px 3px 10px;
+ border-bottom: 1px solid black;
+ font-weight: bold;
+ cursor: pointer;
+ *cursor: hand;
+}
+
+table.dataTable tfoot th {
+ padding: 3px 18px 3px 10px;
+ border-top: 1px solid black;
+ font-weight: bold;
+}
+
+table.dataTable td {
+ padding: 3px 10px;
+}
+
+table.dataTable td.center,
+table.dataTable td.dataTables_empty {
+ text-align: center;
+}
+
+table.dataTable tr.odd { background-color: #E2E4FF; }
+table.dataTable tr.even { background-color: white; }
+
+table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; }
+table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; }
+table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; }
+table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; }
+table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; }
+table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; }
+
+
+/*
+ * Table wrapper
+ */
+.dataTables_wrapper {
+ position: relative;
+ clear: both;
+ *zoom: 1;
+}
+
+
+/*
+ * Page length menu
+ */
+.dataTables_length {
+ float: left;
+}
+
+
+/*
+ * Filter
+ */
+.dataTables_filter {
+ float: right;
+ text-align: right;
+}
+
+
+/*
+ * Table information
+ */
+.dataTables_info {
+ clear: both;
+ float: left;
+}
+
+
+/*
+ * Pagination
+ */
+.dataTables_paginate {
+ float: right;
+ text-align: right;
+}
+
+/* Two button pagination - previous / next */
+.paginate_disabled_previous,
+.paginate_enabled_previous,
+.paginate_disabled_next,
+.paginate_enabled_next {
+ height: 19px;
+ float: left;
+ cursor: pointer;
+ *cursor: hand;
+ color: #111 !important;
+}
+.paginate_disabled_previous:hover,
+.paginate_enabled_previous:hover,
+.paginate_disabled_next:hover,
+.paginate_enabled_next:hover {
+ text-decoration: none !important;
+}
+.paginate_disabled_previous:active,
+.paginate_enabled_previous:active,
+.paginate_disabled_next:active,
+.paginate_enabled_next:active {
+ outline: none;
+}
+
+.paginate_disabled_previous,
+.paginate_disabled_next {
+ color: #666 !important;
+}
+.paginate_disabled_previous,
+.paginate_enabled_previous {
+ padding-left: 23px;
+}
+.paginate_disabled_next,
+.paginate_enabled_next {
+ padding-right: 23px;
+ margin-left: 10px;
+}
+
+.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; }
+.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; }
+.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; }
+
+.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; }
+.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; }
+.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; }
+
+/* Full number pagination */
+.paging_full_numbers {
+ height: 22px;
+ line-height: 22px;
+}
+.paging_full_numbers a:active {
+ outline: none
+}
+.paging_full_numbers a:hover {
+ text-decoration: none;
+}
+
+.paging_full_numbers a.paginate_button,
+.paging_full_numbers a.paginate_active {
+ border: 1px solid #aaa;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ padding: 2px 5px;
+ margin: 0 3px;
+ cursor: pointer;
+ *cursor: hand;
+ color: #333 !important;
+}
+
+.paging_full_numbers a.paginate_button {
+ background-color: #ddd;
+}
+
+.paging_full_numbers a.paginate_button:hover {
+ background-color: #ccc;
+ text-decoration: none !important;
+}
+
+.paging_full_numbers a.paginate_active {
+ background-color: #99B3FF;
+}
+
+
+/*
+ * Processing indicator
+ */
+.dataTables_processing {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 250px;
+ height: 30px;
+ margin-left: -125px;
+ margin-top: -15px;
+ padding: 14px 0 2px 0;
+ border: 1px solid #ddd;
+ text-align: center;
+ color: #999;
+ font-size: 14px;
+ background-color: white;
+}
+
+
+/*
+ * Sorting
+ */
+.sorting { background: url('../images/sort_both.png') no-repeat center right; }
+.sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; }
+.sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; }
+
+.sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; }
+.sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; }
+
+table.dataTable th:active {
+ outline: none;
+}
+
+
+/*
+ * Scrolling
+ */
+.dataTables_scroll {
+ clear: both;
+}
+
+.dataTables_scrollBody {
+ *margin-top: -1px;
+}
+
diff --git a/airtime_mvc/public/css/datatables/css/jquery.dataTables_themeroller.css b/airtime_mvc/public/css/datatables/css/jquery.dataTables_themeroller.css
new file mode 100644
index 000000000..94a24c8c4
--- /dev/null
+++ b/airtime_mvc/public/css/datatables/css/jquery.dataTables_themeroller.css
@@ -0,0 +1,243 @@
+
+
+/*
+ * Table
+ */
+table.dataTable {
+ margin: 0 auto;
+ clear: both;
+ width: 100%;
+}
+
+table.dataTable thead th {
+ padding: 3px 0px 3px 10px;
+ cursor: pointer;
+ *cursor: hand;
+}
+
+table.dataTable tfoot th {
+ padding: 3px 10px;
+}
+
+table.dataTable td {
+ padding: 3px 10px;
+}
+
+table.dataTable td.center,
+table.dataTable td.dataTables_empty {
+ text-align: center;
+}
+
+table.dataTable tr.odd { background-color: #E2E4FF; }
+table.dataTable tr.even { background-color: white; }
+
+table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; }
+table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; }
+table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; }
+table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; }
+table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; }
+table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; }
+
+
+/*
+ * Table wrapper
+ */
+.dataTables_wrapper {
+ position: relative;
+ clear: both;
+ *zoom: 1;
+}
+.dataTables_wrapper .ui-widget-header {
+ font-weight: normal;
+}
+.dataTables_wrapper .ui-toolbar {
+ padding: 5px;
+}
+
+
+/*
+ * Page length menu
+ */
+.dataTables_length {
+ float: left;
+}
+
+
+/*
+ * Filter
+ */
+.dataTables_filter {
+ float: right;
+ text-align: right;
+}
+
+
+/*
+ * Table information
+ */
+.dataTables_info {
+ padding-top: 3px;
+ clear: both;
+ float: left;
+}
+
+
+/*
+ * Pagination
+ */
+.dataTables_paginate {
+ float: right;
+ text-align: right;
+}
+
+.dataTables_paginate .ui-button {
+ margin-right: -0.1em !important;
+}
+
+.paging_two_button .ui-button {
+ float: left;
+ cursor: pointer;
+ * cursor: hand;
+}
+
+.paging_full_numbers .ui-button {
+ padding: 2px 6px;
+ margin: 0;
+ cursor: pointer;
+ * cursor: hand;
+ color: #333 !important;
+}
+
+/* Two button pagination - previous / next */
+.paginate_disabled_previous,
+.paginate_enabled_previous,
+.paginate_disabled_next,
+.paginate_enabled_next {
+ height: 19px;
+ float: left;
+ cursor: pointer;
+ *cursor: hand;
+ color: #111 !important;
+}
+.paginate_disabled_previous:hover,
+.paginate_enabled_previous:hover,
+.paginate_disabled_next:hover,
+.paginate_enabled_next:hover {
+ text-decoration: none !important;
+}
+.paginate_disabled_previous:active,
+.paginate_enabled_previous:active,
+.paginate_disabled_next:active,
+.paginate_enabled_next:active {
+ outline: none;
+}
+
+.paginate_disabled_previous,
+.paginate_disabled_next {
+ color: #666 !important;
+}
+.paginate_disabled_previous,
+.paginate_enabled_previous {
+ padding-left: 23px;
+}
+.paginate_disabled_next,
+.paginate_enabled_next {
+ padding-right: 23px;
+ margin-left: 10px;
+}
+
+.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; }
+.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; }
+.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; }
+
+.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; }
+.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; }
+.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; }
+
+/* Full number pagination */
+.paging_full_numbers a:active {
+ outline: none
+}
+.paging_full_numbers a:hover {
+ text-decoration: none;
+}
+
+.paging_full_numbers a.paginate_button,
+.paging_full_numbers a.paginate_active {
+ border: 1px solid #aaa;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ padding: 2px 5px;
+ margin: 0 3px;
+ cursor: pointer;
+ *cursor: hand;
+ color: #333 !important;
+}
+
+.paging_full_numbers a.paginate_button {
+ background-color: #ddd;
+}
+
+.paging_full_numbers a.paginate_button:hover {
+ background-color: #ccc;
+ text-decoration: none !important;
+}
+
+.paging_full_numbers a.paginate_active {
+ background-color: #99B3FF;
+}
+
+
+/*
+ * Processing indicator
+ */
+.dataTables_processing {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 250px;
+ height: 30px;
+ margin-left: -125px;
+ margin-top: -15px;
+ padding: 14px 0 2px 0;
+ border: 1px solid #ddd;
+ text-align: center;
+ color: #999;
+ font-size: 14px;
+ background-color: white;
+}
+
+
+/*
+ * Sorting
+ */
+table.dataTable thead th div.DataTables_sort_wrapper {
+ position: relative;
+ padding-right: 20px;
+ padding-right: 20px;
+}
+
+table.dataTable thead th div.DataTables_sort_wrapper span {
+ position: absolute;
+ top: 50%;
+ margin-top: -8px;
+ right: 0;
+}
+
+table.dataTable th:active {
+ outline: none;
+}
+
+
+/*
+ * Scrolling
+ */
+.dataTables_scroll {
+ clear: both;
+}
+
+.dataTables_scrollBody {
+ *margin-top: -1px;
+}
+
diff --git a/airtime_mvc/public/css/datatables/images/back_disabled.jpg b/airtime_mvc/public/css/datatables/images/back_disabled.jpg
deleted file mode 100644
index 1e73a546e..000000000
Binary files a/airtime_mvc/public/css/datatables/images/back_disabled.jpg and /dev/null differ
diff --git a/airtime_mvc/public/css/datatables/images/back_disabled.png b/airtime_mvc/public/css/datatables/images/back_disabled.png
new file mode 100644
index 000000000..881de7976
Binary files /dev/null and b/airtime_mvc/public/css/datatables/images/back_disabled.png differ
diff --git a/airtime_mvc/public/css/datatables/images/back_enabled.jpg b/airtime_mvc/public/css/datatables/images/back_enabled.jpg
deleted file mode 100644
index a6d764c79..000000000
Binary files a/airtime_mvc/public/css/datatables/images/back_enabled.jpg and /dev/null differ
diff --git a/airtime_mvc/public/css/datatables/images/back_enabled.png b/airtime_mvc/public/css/datatables/images/back_enabled.png
new file mode 100644
index 000000000..c608682b0
Binary files /dev/null and b/airtime_mvc/public/css/datatables/images/back_enabled.png differ
diff --git a/airtime_mvc/public/css/datatables/images/back_enabled_hover.png b/airtime_mvc/public/css/datatables/images/back_enabled_hover.png
new file mode 100644
index 000000000..d300f1064
Binary files /dev/null and b/airtime_mvc/public/css/datatables/images/back_enabled_hover.png differ
diff --git a/airtime_mvc/public/css/datatables/images/forward_disabled.jpg b/airtime_mvc/public/css/datatables/images/forward_disabled.jpg
deleted file mode 100644
index 28a9dc53f..000000000
Binary files a/airtime_mvc/public/css/datatables/images/forward_disabled.jpg and /dev/null differ
diff --git a/airtime_mvc/public/css/datatables/images/forward_disabled.png b/airtime_mvc/public/css/datatables/images/forward_disabled.png
new file mode 100644
index 000000000..6a6ded7de
Binary files /dev/null and b/airtime_mvc/public/css/datatables/images/forward_disabled.png differ
diff --git a/airtime_mvc/public/css/datatables/images/forward_enabled.jpg b/airtime_mvc/public/css/datatables/images/forward_enabled.jpg
deleted file mode 100644
index 598c075f1..000000000
Binary files a/airtime_mvc/public/css/datatables/images/forward_enabled.jpg and /dev/null differ
diff --git a/airtime_mvc/public/css/datatables/images/forward_enabled.png b/airtime_mvc/public/css/datatables/images/forward_enabled.png
new file mode 100644
index 000000000..a4e6b5384
Binary files /dev/null and b/airtime_mvc/public/css/datatables/images/forward_enabled.png differ
diff --git a/airtime_mvc/public/css/datatables/images/forward_enabled_hover.png b/airtime_mvc/public/css/datatables/images/forward_enabled_hover.png
new file mode 100644
index 000000000..fc46c5ebf
Binary files /dev/null and b/airtime_mvc/public/css/datatables/images/forward_enabled_hover.png differ
diff --git a/airtime_mvc/public/css/datatables/images/sort_asc.png b/airtime_mvc/public/css/datatables/images/sort_asc.png
index a56d0e219..a88d7975f 100644
Binary files a/airtime_mvc/public/css/datatables/images/sort_asc.png and b/airtime_mvc/public/css/datatables/images/sort_asc.png differ
diff --git a/airtime_mvc/public/css/datatables/images/sort_asc_disabled.png b/airtime_mvc/public/css/datatables/images/sort_asc_disabled.png
index b7e621ef1..4e144cf0b 100644
Binary files a/airtime_mvc/public/css/datatables/images/sort_asc_disabled.png and b/airtime_mvc/public/css/datatables/images/sort_asc_disabled.png differ
diff --git a/airtime_mvc/public/css/datatables/images/sort_both.png b/airtime_mvc/public/css/datatables/images/sort_both.png
index 839ac4bb5..18670406b 100644
Binary files a/airtime_mvc/public/css/datatables/images/sort_both.png and b/airtime_mvc/public/css/datatables/images/sort_both.png differ
diff --git a/airtime_mvc/public/css/datatables/images/sort_desc.png b/airtime_mvc/public/css/datatables/images/sort_desc.png
index 90b295159..def071ed5 100644
Binary files a/airtime_mvc/public/css/datatables/images/sort_desc.png and b/airtime_mvc/public/css/datatables/images/sort_desc.png differ
diff --git a/airtime_mvc/public/css/datatables/images/sort_desc_disabled.png b/airtime_mvc/public/css/datatables/images/sort_desc_disabled.png
index 2409653dc..7824973cc 100644
Binary files a/airtime_mvc/public/css/datatables/images/sort_desc_disabled.png and b/airtime_mvc/public/css/datatables/images/sort_desc_disabled.png differ
diff --git a/airtime_mvc/public/css/qtip/jquery.qtip.css b/airtime_mvc/public/css/qtip/jquery.qtip.css
new file mode 100644
index 000000000..778251922
--- /dev/null
+++ b/airtime_mvc/public/css/qtip/jquery.qtip.css
@@ -0,0 +1,557 @@
+/*
+* qTip2 - Pretty powerful tooltips
+* http://craigsworks.com/projects/qtip2/
+*
+* Version: nightly
+* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com
+*
+* Dual licensed under MIT or GPLv2 licenses
+* http://en.wikipedia.org/wiki/MIT_License
+* http://en.wikipedia.org/wiki/GNU_General_Public_License
+*
+* Date: Tue Jan 31 10:16:34.0000000000 2012
+*/
+
+/* Core qTip styles */
+.ui-tooltip, .qtip{
+ position: absolute;
+ left: -28000px;
+ top: -28000px;
+ display: none;
+
+ max-width: 600px;
+ min-width: 50px;
+
+ font-size: 10.5px;
+ line-height: 12px;
+}
+
+ /* Fluid class for determining actual width in IE */
+ .ui-tooltip-fluid{
+ display: block;
+ visibility: hidden;
+ position: static !important;
+ float: left !important;
+ }
+
+ .ui-tooltip-content{
+ position: relative;
+ padding: 5px 9px;
+ overflow: hidden;
+
+ border: 1px solid #000001;
+
+ text-align: left;
+ word-wrap: break-word;
+ overflow: hidden;
+ }
+
+ .ui-tooltip-titlebar{
+ position: relative;
+ min-height: 14px;
+ padding: 5px 35px 5px 10px;
+ overflow: hidden;
+
+ border: 1px solid #000001;
+ border-width: 1px 1px 0;
+
+ font-weight: bold;
+ }
+
+ .ui-tooltip-titlebar + .ui-tooltip-content{ border-top-width: 0px !important; }
+
+ /*! Default close button class */
+ .ui-tooltip-titlebar .ui-state-default{
+ position: absolute;
+ right: 4px;
+ top: 50%;
+ margin-top: -9px;
+
+ cursor: pointer;
+ outline: medium none;
+
+ border-width: 1px;
+ border-style: solid;
+ }
+
+ * html .ui-tooltip-titlebar .ui-state-default{ top: 16px; } /* IE fix */
+
+ .ui-tooltip-titlebar .ui-icon,
+ .ui-tooltip-icon .ui-icon{
+ display: block;
+ text-indent: -1000em;
+ }
+
+ .ui-tooltip-icon, .ui-tooltip-icon .ui-icon{
+ -moz-border-radius: 3px;
+ -webkit-border-radius: 3px;
+ border-radius: 3px;
+ }
+
+ .ui-tooltip-icon .ui-icon{
+ width: 18px;
+ height: 14px;
+
+ text-align: center;
+ text-indent: 0;
+ font: normal bold 10px/13px Tahoma,sans-serif;
+
+ color: inherit;
+ background: transparent none no-repeat -100em -100em;
+ }
+
+
+/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */
+.ui-tooltip-focus{
+
+}
+
+/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */
+.ui-tooltip-hover{
+
+}
+
+
+/*! Default tooltip style */
+.ui-tooltip-default .ui-tooltip-titlebar,
+.ui-tooltip-default .ui-tooltip-content{
+ border-color: #F1D031;
+ background-color: #FFFFA3;
+ color: #555;
+}
+
+ .ui-tooltip-default .ui-tooltip-titlebar{
+ background-color: #FFEF93;
+ }
+
+ .ui-tooltip-default .ui-tooltip-icon{
+ border-color: #CCC;
+ background: #F1F1F1;
+ color: #777;
+ }
+
+ .ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #AAA;
+ color: #111;
+ }
+
+/* Tips plugin */
+.ui-tooltip .ui-tooltip-tip{
+ margin: 0 auto;
+ overflow: hidden;
+ z-index: 10;
+}
+
+ .ui-tooltip .ui-tooltip-tip,
+ .ui-tooltip .ui-tooltip-tip *{
+ position: absolute;
+
+ line-height: 0.1px !important;
+ font-size: 0.1px !important;
+ color: #123456;
+
+ background: transparent;
+ border: 0px dashed transparent;
+ }
+
+ .ui-tooltip .ui-tooltip-tip canvas{ top: 0; left: 0; }
+
+
+/* Modal plugin */
+#qtip-overlay{
+ position: fixed;
+ left: -10000em;
+ top: -10000em;
+}
+
+ /* Applied to modals with show.modal.blur set to true */
+ #qtip-overlay.blurs{ cursor: pointer; }
+
+ /* Change opacity of overlay here */
+ #qtip-overlay div{
+ position: absolute;
+ left: 0; top: 0;
+ width: 100%; height: 100%;
+
+ background-color: black;
+
+ opacity: 0.7;
+ filter:alpha(opacity=70);
+ -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
+ }
+
+/*! Light tooltip style */
+.ui-tooltip-light .ui-tooltip-titlebar,
+.ui-tooltip-light .ui-tooltip-content{
+ border-color: #E2E2E2;
+ color: #454545;
+}
+
+ .ui-tooltip-light .ui-tooltip-content{
+ background-color: white;
+ }
+
+ .ui-tooltip-light .ui-tooltip-titlebar{
+ background-color: #f1f1f1;
+ }
+
+
+/*! Dark tooltip style */
+.ui-tooltip-dark .ui-tooltip-titlebar,
+.ui-tooltip-dark .ui-tooltip-content{
+ border-color: #303030;
+ color: #f3f3f3;
+}
+
+ .ui-tooltip-dark .ui-tooltip-content{
+ background-color: #505050;
+ }
+
+ .ui-tooltip-dark .ui-tooltip-titlebar{
+ background-color: #404040;
+ }
+
+ .ui-tooltip-dark .ui-tooltip-icon{
+ border-color: #444;
+ }
+
+ .ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #303030;
+ }
+
+
+/*! Cream tooltip style */
+.ui-tooltip-cream .ui-tooltip-titlebar,
+.ui-tooltip-cream .ui-tooltip-content{
+ border-color: #F9E98E;
+ color: #A27D35;
+}
+
+ .ui-tooltip-cream .ui-tooltip-content{
+ background-color: #FBF7AA;
+ }
+
+ .ui-tooltip-cream .ui-tooltip-titlebar{
+ background-color: #F0DE7D;
+ }
+
+ .ui-tooltip-cream .ui-state-default .ui-tooltip-icon{
+ background-position: -82px 0;
+ }
+
+
+/*! Red tooltip style */
+.ui-tooltip-red .ui-tooltip-titlebar,
+.ui-tooltip-red .ui-tooltip-content{
+ border-color: #D95252;
+ color: #912323;
+}
+
+ .ui-tooltip-red .ui-tooltip-content{
+ background-color: #F78B83;
+ }
+
+ .ui-tooltip-red .ui-tooltip-titlebar{
+ background-color: #F06D65;
+ }
+
+ .ui-tooltip-red .ui-state-default .ui-tooltip-icon{
+ background-position: -102px 0;
+ }
+
+ .ui-tooltip-red .ui-tooltip-icon{
+ border-color: #D95252;
+ }
+
+ .ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #D95252;
+ }
+
+
+/*! Green tooltip style */
+.ui-tooltip-green .ui-tooltip-titlebar,
+.ui-tooltip-green .ui-tooltip-content{
+ border-color: #90D93F;
+ color: #3F6219;
+}
+
+ .ui-tooltip-green .ui-tooltip-content{
+ background-color: #CAED9E;
+ }
+
+ .ui-tooltip-green .ui-tooltip-titlebar{
+ background-color: #B0DE78;
+ }
+
+ .ui-tooltip-green .ui-state-default .ui-tooltip-icon{
+ background-position: -42px 0;
+ }
+
+
+/*! Blue tooltip style */
+.ui-tooltip-blue .ui-tooltip-titlebar,
+.ui-tooltip-blue .ui-tooltip-content{
+ border-color: #ADD9ED;
+ color: #5E99BD;
+}
+
+ .ui-tooltip-blue .ui-tooltip-content{
+ background-color: #E5F6FE;
+ }
+
+ .ui-tooltip-blue .ui-tooltip-titlebar{
+ background-color: #D0E9F5;
+ }
+
+ .ui-tooltip-blue .ui-state-default .ui-tooltip-icon{
+ background-position: -2px 0;
+ }
+
+/*! Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE6+, Safari 2+ */
+.ui-tooltip-shadow{
+ -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
+ box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15);
+}
+
+ .ui-tooltip-shadow .ui-tooltip-titlebar,
+ .ui-tooltip-shadow .ui-tooltip-content{
+ filter: progid:DXImageTransform.Microsoft.Shadow(Color='gray', Direction=135, Strength=3);
+ -ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Color='gray', Direction=135, Strength=3)";
+
+ _margin-bottom: -3px; /* IE6 */
+ .margin-bottom: -3px; /* IE7 */
+ }
+
+
+/*! Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */
+.ui-tooltip-rounded,
+.ui-tooltip-rounded .ui-tooltip-content,
+.ui-tooltip-tipsy,
+.ui-tooltip-tipsy .ui-tooltip-content,
+.ui-tooltip-youtube,
+.ui-tooltip-youtube .ui-tooltip-content{
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.ui-tooltip-rounded .ui-tooltip-titlebar,
+.ui-tooltip-tipsy .ui-tooltip-titlebar,
+.ui-tooltip-youtube .ui-tooltip-titlebar{
+ -moz-border-radius: 5px 5px 0 0;
+ -webkit-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
+}
+
+.ui-tooltip-rounded .ui-tooltip-titlebar + .ui-tooltip-content,
+.ui-tooltip-tipsy .ui-tooltip-titlebar + .ui-tooltip-content,
+.ui-tooltip-youtube .ui-tooltip-titlebar + .ui-tooltip-content{
+ -moz-border-radius: 0 0 5px 5px;
+ -webkit-border-radius: 0 0 5px 5px;
+ border-radius: 0 0 5px 5px;
+}
+
+
+/*! Youtube tooltip style */
+.ui-tooltip-youtube{
+ -webkit-box-shadow: 0 0 3px #333;
+ -moz-box-shadow: 0 0 3px #333;
+ box-shadow: 0 0 3px #333;
+}
+
+ .ui-tooltip-youtube .ui-tooltip-titlebar,
+ .ui-tooltip-youtube .ui-tooltip-content{
+ _margin-bottom: 0; /* IE6 */
+ .margin-bottom: 0; /* IE7 */
+
+ background: transparent;
+ background: rgba(0, 0, 0, 0.85);
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";
+
+ color: white;
+ border-color: #CCCCCC;
+ }
+
+ .ui-tooltip-youtube .ui-tooltip-icon{
+ border-color: #222;
+ }
+
+ .ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #303030;
+ }
+
+
+/* jQuery TOOLS Tooltip style */
+.ui-tooltip-jtools{
+ background: #232323;
+ background: rgba(0, 0, 0, 0.7);
+ background-image: -moz-linear-gradient(top, #717171, #232323);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323));
+
+ border: 2px solid #ddd;
+ border: 2px solid rgba(241,241,241,1);
+
+ -moz-border-radius: 2px;
+ -webkit-border-radius: 2px;
+ border-radius: 2px;
+
+ -webkit-box-shadow: 0 0 12px #333;
+ -moz-box-shadow: 0 0 12px #333;
+ box-shadow: 0 0 12px #333;
+}
+
+ /* IE Specific */
+ .ui-tooltip-jtools .ui-tooltip-titlebar{
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";
+ }
+ .ui-tooltip-jtools .ui-tooltip-content{
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";
+ }
+
+ .ui-tooltip-jtools .ui-tooltip-titlebar,
+ .ui-tooltip-jtools .ui-tooltip-content{
+ background: transparent;
+ color: white;
+ border: 0 dashed transparent;
+ }
+
+ .ui-tooltip-jtools .ui-tooltip-icon{
+ border-color: #555;
+ }
+
+ .ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #333;
+ }
+
+
+/* Cluetip style */
+.ui-tooltip-cluetip{
+ -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
+ -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
+ box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4);
+}
+
+ .ui-tooltip-cluetip .ui-tooltip-titlebar{
+ background-color: #87876A;
+ color: white;
+ border: 0 dashed transparent;
+ }
+
+ .ui-tooltip-cluetip .ui-tooltip-content{
+ background-color: #D9D9C2;
+ color: #111;
+ border: 0 dashed transparent;
+ }
+
+ .ui-tooltip-cluetip .ui-tooltip-icon{
+ border-color: #808064;
+ }
+
+ .ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #696952;
+ color: #696952;
+ }
+
+
+/* Tipsy style */
+.ui-tooltip-tipsy{
+ border: 0;
+}
+
+ .ui-tooltip-tipsy .ui-tooltip-titlebar,
+ .ui-tooltip-tipsy .ui-tooltip-content{
+ _margin-bottom: 0; /* IE6 */
+ .margin-bottom: 0; /* IE7 */
+
+ background: transparent;
+ background: rgba(0, 0, 0, .87);
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";
+
+ color: white;
+ border: 0px transparent;
+
+ font-size: 11px;
+ font-family: 'Lucida Grande', sans-serif;
+ font-weight: bold;
+ line-height: 16px;
+ text-shadow: 0 1px black;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-titlebar{
+ padding: 6px 35px 0 10;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-content{
+ padding: 6px 10;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-icon{
+ border-color: #222;
+ text-shadow: none;
+ }
+
+ .ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{
+ border-color: #303030;
+ }
+
+
+/* Tipped style */
+.ui-tooltip-tipped{
+
+}
+
+ .ui-tooltip-tipped .ui-tooltip-titlebar,
+ .ui-tooltip-tipped .ui-tooltip-content{
+ border: 3px solid #959FA9;
+
+ filter: none; -ms-filter: none;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-titlebar{
+ background: #3A79B8;
+ background-image: -moz-linear-gradient(top, #3A79B8, #2E629D);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D));
+ filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);
+ -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";
+
+ color: white;
+ font-weight: normal;
+ font-family: serif;
+
+ border-bottom-width: 0;
+ -moz-border-radius: 3px 3px 0 0;
+ -webkit-border-radius: 3px 3px 0 0;
+ border-radius: 3px 3px 0 0;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-content{
+ background-color: #F9F9F9;
+ color: #454545;
+
+ -moz-border-radius: 0 0 3px 3px;
+ -webkit-border-radius: 0 0 3px 3px;
+ border-radius: 0 0 3px 3px;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-icon{
+ border: 2px solid #285589;
+ background: #285589;
+ }
+
+ .ui-tooltip-tipped .ui-tooltip-icon .ui-icon{
+ background-color: #FBFBFB;
+ color: #555;
+ }
+
+/* IE9 fix - removes all filters */
+.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,
+.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{
+ filter: none;
+ -ms-filter: none;
+}
+
diff --git a/airtime_mvc/public/css/qtip/jquery.qtip.min.css b/airtime_mvc/public/css/qtip/jquery.qtip.min.css
index 6b0daf7c2..947c8f9d1 100644
--- a/airtime_mvc/public/css/qtip/jquery.qtip.min.css
+++ b/airtime_mvc/public/css/qtip/jquery.qtip.min.css
@@ -1 +1 @@
-.ui-tooltip,.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px;z-index:15000;}.ui-tooltip-fluid{display:block;visibility:hidden;position:static!important;float:left!important;}.ui-tooltip-content{position:relative;padding:5px 9px;overflow:hidden;border-width:1px;border-style:solid;text-align:left;word-wrap:break-word;overflow:hidden;}.ui-tooltip-titlebar{position:relative;min-height:14px;padding:5px 35px 5px 10px;overflow:hidden;border-width:1px 1px 0;border-style:solid;font-weight:bold;}.ui-tooltip-titlebar+.ui-tooltip-content{border-top-width:0!important;}/*!Default close button class */ .ui-tooltip-titlebar .ui-state-default{position:absolute;right:4px;top:50%;margin-top:-9px;cursor:pointer;outline:medium none;border-width:1px;border-style:solid;}* html .ui-tooltip-titlebar .ui-state-default{top:16px;}.ui-tooltip-titlebar .ui-icon,.ui-tooltip-icon .ui-icon{display:block;text-indent:-1000em;}.ui-tooltip-icon,.ui-tooltip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}.ui-tooltip-icon .ui-icon{width:18px;height:14px;text-align:center;text-indent:0;font:normal bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em;}/*!Default tooltip style */ .ui-tooltip-default .ui-tooltip-titlebar,.ui-tooltip-default .ui-tooltip-content{border-color:#F1D031;background-color:#FFFFA3;color:#555;}.ui-tooltip-default .ui-tooltip-titlebar{background-color:#FFEF93;}.ui-tooltip-default .ui-tooltip-icon{border-color:#CCC;background:#F1F1F1;color:#777;}.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{border-color:#AAA;color:#111;}.ui-tooltip .ui-tooltip-tip{margin:0 auto;overflow:hidden;background:transparent!important;border:0 dashed transparent!important;z-index:10;}.ui-tooltip .ui-tooltip-tip,.ui-tooltip .ui-tooltip-tip *{position:absolute;line-height:.1px!important;font-size:.1px!important;color:#123456;background:transparent;border:0 dashed transparent;}.ui-tooltip .ui-tooltip-tip canvas{top:0;left:0;}#qtip-overlay{position:fixed;left:-10000em;top:-10000em;}#qtip-overlay.blurs{cursor:pointer;}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:black;opacity:.7;filter:alpha(opacity=70);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";}/*!Light tooltip style */ .ui-tooltip-light .ui-tooltip-titlebar,.ui-tooltip-light .ui-tooltip-content{border-color:#E2E2E2;color:#454545;}.ui-tooltip-light .ui-tooltip-content{background-color:white;}.ui-tooltip-light .ui-tooltip-titlebar{background-color:#f1f1f1;}/*!Dark tooltip style */ .ui-tooltip-dark .ui-tooltip-titlebar,.ui-tooltip-dark .ui-tooltip-content{border-color:#303030;color:#f3f3f3;}.ui-tooltip-dark .ui-tooltip-content{background-color:#505050;}.ui-tooltip-dark .ui-tooltip-titlebar{background-color:#404040;}.ui-tooltip-dark .ui-tooltip-icon{border-color:#444;}.ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}/*!Cream tooltip style */ .ui-tooltip-cream .ui-tooltip-titlebar,.ui-tooltip-cream .ui-tooltip-content{border-color:#F9E98E;color:#A27D35;}.ui-tooltip-cream .ui-tooltip-content{background-color:#FBF7AA;}.ui-tooltip-cream .ui-tooltip-titlebar{background-color:#F0DE7D;}.ui-tooltip-cream .ui-state-default .ui-tooltip-icon{background-position:-82px 0;}/*!Red tooltip style */ .ui-tooltip-red .ui-tooltip-titlebar,.ui-tooltip-red .ui-tooltip-content{border-color:#D95252;color:#912323;}.ui-tooltip-red .ui-tooltip-content{background-color:#F78B83;}.ui-tooltip-red .ui-tooltip-titlebar{background-color:#F06D65;}.ui-tooltip-red .ui-state-default .ui-tooltip-icon{background-position:-102px 0;}.ui-tooltip-red .ui-tooltip-icon{border-color:#D95252;}.ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{border-color:#D95252;}/*!Green tooltip style */ .ui-tooltip-green .ui-tooltip-titlebar,.ui-tooltip-green .ui-tooltip-content{border-color:#90D93F;color:#3F6219;}.ui-tooltip-green .ui-tooltip-content{background-color:#CAED9E;}.ui-tooltip-green .ui-tooltip-titlebar{background-color:#B0DE78;}.ui-tooltip-green .ui-state-default .ui-tooltip-icon{background-position:-42px 0;}/*!Blue tooltip style */ .ui-tooltip-blue .ui-tooltip-titlebar,.ui-tooltip-blue .ui-tooltip-content{border-color:#ADD9ED;color:#5E99BD;}.ui-tooltip-blue .ui-tooltip-content{background-color:#E5F6FE;}.ui-tooltip-blue .ui-tooltip-titlebar{background-color:#D0E9F5;}.ui-tooltip-blue .ui-state-default .ui-tooltip-icon{background-position:-2px 0;}/*!Add shadows to your tooltips in:FF3+,Chrome 2+,Opera 10.6+,IE6+,Safari 2+*/ .ui-tooltip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);}.ui-tooltip-shadow .ui-tooltip-titlebar,.ui-tooltip-shadow .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3);-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3)";_margin-bottom:-3px;.margin-bottom:-3px;}/*!Add rounded corners to your tooltips in:FF3+,Chrome 2+,Opera 10.6+,IE9+,Safari 2+*/ .ui-tooltip-rounded,.ui-tooltip-rounded .ui-tooltip-content,.ui-tooltip-tipsy,.ui-tooltip-tipsy .ui-tooltip-content,.ui-tooltip-youtube,.ui-tooltip-youtube .ui-tooltip-content{-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;}.ui-tooltip-rounded .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-titlebar{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;}.ui-tooltip-rounded .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-tipsy .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-youtube .ui-tooltip-titlebar+.ui-tooltip-content{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;}/*!Youtube tooltip style */ .ui-tooltip-youtube{-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;}.ui-tooltip-youtube .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,0.85);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border-color:#CCC;}.ui-tooltip-youtube .ui-tooltip-icon{border-color:#222;}.ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}.ui-tooltip-jtools{background:#232323;background:rgba(0,0,0,0.7);background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333;}.ui-tooltip-jtools .ui-tooltip-titlebar{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";}.ui-tooltip-jtools .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";}.ui-tooltip-jtools .ui-tooltip-titlebar,.ui-tooltip-jtools .ui-tooltip-content{background:transparent;color:white;border:0 dashed transparent;}.ui-tooltip-jtools .ui-tooltip-icon{border-color:#555;}.ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{border-color:#333;}.ui-tooltip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,0.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,0.4);box-shadow:4px 4px 5px rgba(0,0,0,0.4);}.ui-tooltip-cluetip .ui-tooltip-titlebar{background-color:#87876A;color:white;border:0 dashed transparent;}.ui-tooltip-cluetip .ui-tooltip-content{background-color:#D9D9C2;color:#111;border:0 dashed transparent;}.ui-tooltip-cluetip .ui-tooltip-icon{border-color:#808064;}.ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{border-color:#696952;color:#696952;}.ui-tooltip-tipsy{border:0;}.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,.87);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border:0 transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:bold;line-height:16px;text-shadow:0 1px black;}.ui-tooltip-tipsy .ui-tooltip-titlebar{padding:6px 35px 0 10;}.ui-tooltip-tipsy .ui-tooltip-content{padding:6px 10;}.ui-tooltip-tipsy .ui-tooltip-icon{border-color:#222;text-shadow:none;}.ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}.ui-tooltip-tipped .ui-tooltip-titlebar,.ui-tooltip-tipped .ui-tooltip-content{border:3px solid #959FA9;filter:none;-ms-filter:none;}.ui-tooltip-tipped .ui-tooltip-titlebar{background:#3A79B8;background-image:-moz-linear-gradient(top,#3A79B8,#2E629D);background-image:-webkit-gradient(linear,left top,left bottom,from(#3A79B8),to(#2E629D));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";color:white;font-weight:normal;font-family:serif;border-bottom-width:0;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;}.ui-tooltip-tipped .ui-tooltip-content{background-color:#F9F9F9;color:#454545;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;}.ui-tooltip-tipped .ui-tooltip-icon{border:2px solid #285589;background:#285589;}.ui-tooltip-tipped .ui-tooltip-icon .ui-icon{background-color:#FBFBFB;color:#555;}.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{filter:none;-ms-filter:none;}
\ No newline at end of file
+.ui-tooltip,.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px;}.ui-tooltip-fluid{display:block;visibility:hidden;position:static!important;float:left!important;}.ui-tooltip-content{position:relative;padding:5px 9px;overflow:hidden;border:1px solid #000001;text-align:left;word-wrap:break-word;overflow:hidden;}.ui-tooltip-titlebar{position:relative;min-height:14px;padding:5px 35px 5px 10px;overflow:hidden;border:1px solid #000001;border-width:1px 1px 0;font-weight:bold;}.ui-tooltip-titlebar+.ui-tooltip-content{border-top-width:0!important;}/*!Default close button class */ .ui-tooltip-titlebar .ui-state-default{position:absolute;right:4px;top:50%;margin-top:-9px;cursor:pointer;outline:medium none;border-width:1px;border-style:solid;}* html .ui-tooltip-titlebar .ui-state-default{top:16px;}.ui-tooltip-titlebar .ui-icon,.ui-tooltip-icon .ui-icon{display:block;text-indent:-1000em;}.ui-tooltip-icon,.ui-tooltip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;}.ui-tooltip-icon .ui-icon{width:18px;height:14px;text-align:center;text-indent:0;font:normal bold 10px/13px Tahoma,sans-serif;color:inherit;background:transparent none no-repeat -100em -100em;}/*!Default tooltip style */ .ui-tooltip-default .ui-tooltip-titlebar,.ui-tooltip-default .ui-tooltip-content{border-color:#F1D031;background-color:#FFFFA3;color:#555;}.ui-tooltip-default .ui-tooltip-titlebar{background-color:#FFEF93;}.ui-tooltip-default .ui-tooltip-icon{border-color:#CCC;background:#F1F1F1;color:#777;}.ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{border-color:#AAA;color:#111;}.ui-tooltip .ui-tooltip-tip{margin:0 auto;overflow:hidden;z-index:10;}.ui-tooltip .ui-tooltip-tip,.ui-tooltip .ui-tooltip-tip *{position:absolute;line-height:.1px!important;font-size:.1px!important;color:#123456;background:transparent;border:0 dashed transparent;}.ui-tooltip .ui-tooltip-tip canvas{top:0;left:0;}#qtip-overlay{position:fixed;left:-10000em;top:-10000em;}#qtip-overlay.blurs{cursor:pointer;}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:black;opacity:.7;filter:alpha(opacity=70);-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";}/*!Light tooltip style */ .ui-tooltip-light .ui-tooltip-titlebar,.ui-tooltip-light .ui-tooltip-content{border-color:#E2E2E2;color:#454545;}.ui-tooltip-light .ui-tooltip-content{background-color:white;}.ui-tooltip-light .ui-tooltip-titlebar{background-color:#f1f1f1;}/*!Dark tooltip style */ .ui-tooltip-dark .ui-tooltip-titlebar,.ui-tooltip-dark .ui-tooltip-content{border-color:#303030;color:#f3f3f3;}.ui-tooltip-dark .ui-tooltip-content{background-color:#505050;}.ui-tooltip-dark .ui-tooltip-titlebar{background-color:#404040;}.ui-tooltip-dark .ui-tooltip-icon{border-color:#444;}.ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}/*!Cream tooltip style */ .ui-tooltip-cream .ui-tooltip-titlebar,.ui-tooltip-cream .ui-tooltip-content{border-color:#F9E98E;color:#A27D35;}.ui-tooltip-cream .ui-tooltip-content{background-color:#FBF7AA;}.ui-tooltip-cream .ui-tooltip-titlebar{background-color:#F0DE7D;}.ui-tooltip-cream .ui-state-default .ui-tooltip-icon{background-position:-82px 0;}/*!Red tooltip style */ .ui-tooltip-red .ui-tooltip-titlebar,.ui-tooltip-red .ui-tooltip-content{border-color:#D95252;color:#912323;}.ui-tooltip-red .ui-tooltip-content{background-color:#F78B83;}.ui-tooltip-red .ui-tooltip-titlebar{background-color:#F06D65;}.ui-tooltip-red .ui-state-default .ui-tooltip-icon{background-position:-102px 0;}.ui-tooltip-red .ui-tooltip-icon{border-color:#D95252;}.ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{border-color:#D95252;}/*!Green tooltip style */ .ui-tooltip-green .ui-tooltip-titlebar,.ui-tooltip-green .ui-tooltip-content{border-color:#90D93F;color:#3F6219;}.ui-tooltip-green .ui-tooltip-content{background-color:#CAED9E;}.ui-tooltip-green .ui-tooltip-titlebar{background-color:#B0DE78;}.ui-tooltip-green .ui-state-default .ui-tooltip-icon{background-position:-42px 0;}/*!Blue tooltip style */ .ui-tooltip-blue .ui-tooltip-titlebar,.ui-tooltip-blue .ui-tooltip-content{border-color:#ADD9ED;color:#5E99BD;}.ui-tooltip-blue .ui-tooltip-content{background-color:#E5F6FE;}.ui-tooltip-blue .ui-tooltip-titlebar{background-color:#D0E9F5;}.ui-tooltip-blue .ui-state-default .ui-tooltip-icon{background-position:-2px 0;}/*!Add shadows to your tooltips in:FF3+,Chrome 2+,Opera 10.6+,IE6+,Safari 2+*/ .ui-tooltip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,0.15);}.ui-tooltip-shadow .ui-tooltip-titlebar,.ui-tooltip-shadow .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3);-ms-filter:"progid:DXImageTransform.Microsoft.Shadow(Color='gray',Direction=135,Strength=3)";_margin-bottom:-3px;.margin-bottom:-3px;}/*!Add rounded corners to your tooltips in:FF3+,Chrome 2+,Opera 10.6+,IE9+,Safari 2+*/ .ui-tooltip-rounded,.ui-tooltip-rounded .ui-tooltip-content,.ui-tooltip-tipsy,.ui-tooltip-tipsy .ui-tooltip-content,.ui-tooltip-youtube,.ui-tooltip-youtube .ui-tooltip-content{-moz-border-radius:4px;-webkit-border-radius:4px;border-radius:4px;}.ui-tooltip-rounded .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-titlebar{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;}.ui-tooltip-rounded .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-tipsy .ui-tooltip-titlebar+.ui-tooltip-content,.ui-tooltip-youtube .ui-tooltip-titlebar+.ui-tooltip-content{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0 0 5px 5px;border-radius:0 0 5px 5px;}/*!Youtube tooltip style */ .ui-tooltip-youtube{-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;}.ui-tooltip-youtube .ui-tooltip-titlebar,.ui-tooltip-youtube .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,0.85);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border-color:#CCC;}.ui-tooltip-youtube .ui-tooltip-icon{border-color:#222;}.ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}.ui-tooltip-jtools{background:#232323;background:rgba(0,0,0,0.7);background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333;}.ui-tooltip-jtools .ui-tooltip-titlebar{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)";}.ui-tooltip-jtools .ui-tooltip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)";}.ui-tooltip-jtools .ui-tooltip-titlebar,.ui-tooltip-jtools .ui-tooltip-content{background:transparent;color:white;border:0 dashed transparent;}.ui-tooltip-jtools .ui-tooltip-icon{border-color:#555;}.ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{border-color:#333;}.ui-tooltip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,0.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,0.4);box-shadow:4px 4px 5px rgba(0,0,0,0.4);}.ui-tooltip-cluetip .ui-tooltip-titlebar{background-color:#87876A;color:white;border:0 dashed transparent;}.ui-tooltip-cluetip .ui-tooltip-content{background-color:#D9D9C2;color:#111;border:0 dashed transparent;}.ui-tooltip-cluetip .ui-tooltip-icon{border-color:#808064;}.ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{border-color:#696952;color:#696952;}.ui-tooltip-tipsy{border:0;}.ui-tooltip-tipsy .ui-tooltip-titlebar,.ui-tooltip-tipsy .ui-tooltip-content{_margin-bottom:0;.margin-bottom:0;background:transparent;background:rgba(0,0,0,.87);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#D9000000,endColorstr=#D9000000)";color:white;border:0 transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:bold;line-height:16px;text-shadow:0 1px black;}.ui-tooltip-tipsy .ui-tooltip-titlebar{padding:6px 35px 0 10;}.ui-tooltip-tipsy .ui-tooltip-content{padding:6px 10;}.ui-tooltip-tipsy .ui-tooltip-icon{border-color:#222;text-shadow:none;}.ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{border-color:#303030;}.ui-tooltip-tipped .ui-tooltip-titlebar,.ui-tooltip-tipped .ui-tooltip-content{border:3px solid #959FA9;filter:none;-ms-filter:none;}.ui-tooltip-tipped .ui-tooltip-titlebar{background:#3A79B8;background-image:-moz-linear-gradient(top,#3A79B8,#2E629D);background-image:-webkit-gradient(linear,left top,left bottom,from(#3A79B8),to(#2E629D));filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)";color:white;font-weight:normal;font-family:serif;border-bottom-width:0;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;}.ui-tooltip-tipped .ui-tooltip-content{background-color:#F9F9F9;color:#454545;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px;}.ui-tooltip-tipped .ui-tooltip-icon{border:2px solid #285589;background:#285589;}.ui-tooltip-tipped .ui-tooltip-icon .ui-icon{background-color:#FBFBFB;color:#555;}.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content,.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{filter:none;-ms-filter:none;}
\ No newline at end of file
diff --git a/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js
index 5c273e3d0..0c8c48ff3 100644
--- a/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js
+++ b/airtime_mvc/public/js/airtime/library/events/library_playlistbuilder.js
@@ -1,9 +1,5 @@
function fnLibraryTableRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
- function test() {
- alert("hi");
- }
-
$(nRow).attr("id", aData["tr_id"]);
$(nRow).find('td')
@@ -12,8 +8,6 @@ function fnLibraryTableRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFul
{id: aData["id"], type: aData["ftype"]},
{xposition: "mouse", yposition: "mouse"});
- //{title:"Menu Item 4 - Js function", action:{type:"fn",callback:function(){ alert('THIS IS THE TEST'); }
-
return nRow;
}
diff --git a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
index a798ab18a..d445fbd00 100644
--- a/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
+++ b/airtime_mvc/public/js/airtime/library/events/library_showbuilder.js
@@ -12,8 +12,6 @@ function fnLibraryTableRowCallback( nRow, aData, iDisplayIndex, iDisplayIndexFul
function fnLibraryTableDrawCallback() {
addLibraryItemEvents();
- //addMetadataQtip();
- //setupGroupActions();
}
function addLibraryItemEvents() {
diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js
index 6b391cf9b..75426a001 100644
--- a/airtime_mvc/public/js/airtime/library/library.js
+++ b/airtime_mvc/public/js/airtime/library/library.js
@@ -198,58 +198,43 @@ function addQtipToSCIcons(){
});
}
-function addMetadataQtip(){
- var tableRow = $('#library_display tbody tr');
- tableRow.each(function(){
- var title = $(this).find('td.library_title').html();
- var info = $(this).attr("id");
- info = info.split("_");
- var id = info[1];
- var type = info[0];
- $(this).qtip({
- content: {
- text: "Loading...",
- title: {
- text: title
- },
- ajax: {
- url: "/Library/get-file-meta-data",
- type: "post",
- data: ({format: "html", id : id, type: type}),
- success: function(data, status){
- this.set('content.text', data);
- }
- }
- },
- position: {
- target: 'event',
- adjust: {
- resize: true,
- method: "flip flip"
- },
- at: "right center",
- my: "left top",
- viewport: $(window)
- },
- style: {
- width: 570,
- classes: "ui-tooltip-dark"
- },
- show: 'mousedown',
- events: {
- show: function(event, api) {
- // Only show the tooltip if it was a right-click
- if(event.originalEvent.button !== 2) {
- event.preventDefault();
- }
- }
- }
- });
- });
-
- tableRow.bind('contextmenu', function(e){
- return false;
- });
+function fnCreatedRow( nRow, aData, iDataIndex ) {
+
+ //add a tool tip to appear when the user clicks on the type icon.
+ $(nRow.children[1]).qtip({
+ content: {
+ text: "Loading...",
+ title: {
+ text: aData.track_title
+ },
+ ajax: {
+ url: "/Library/get-file-meta-data",
+ type: "get",
+ data: ({format: "html", id : aData.id, type: aData.ftype}),
+ success: function(data, status) {
+ this.set('content.text', data);
+ }
+ }
+ },
+ position: {
+ my: 'left center',
+ at: 'right center', // Position the tooltip above the link
+ viewport: $(window), // Keep the tooltip on-screen at all times
+ effect: false // Disable positioning animation
+ },
+ style: {
+ classes: "ui-tooltip-dark"
+ },
+ show: {
+ event: 'click',
+ solo: true // Only show one tooltip at a time
+ },
+ hide: 'mouseout',
+
+ }).click(function(event) {
+ event.preventDefault();
+ event.stopPropagation();
+ });
}
/**
@@ -269,14 +254,6 @@ function getNumEntriesPreference(data) {
return parseInt(data.libraryInit.numEntries, 10);
}
-function groupAdd() {
-
-}
-
-function groupDelete() {
-
-}
-
function createDataTable(data) {
var oTable;
@@ -295,6 +272,8 @@ function createDataTable(data) {
} );
},
"fnRowCallback": fnLibraryTableRowCallback,
+ "fnCreatedRow": fnCreatedRow,
+ "fnCreatedRowCallback": fnCreatedRow,
"fnDrawCallback": fnLibraryTableDrawCallback,
"fnHeaderCallback": function(nHead) {
$(nHead).find("input[type=checkbox]").attr("checked", false);
@@ -309,7 +288,7 @@ function createDataTable(data) {
/* Genre */ {"sTitle": "Genre", "sName": "genre", "mDataProp": "genre", "sClass": "library_genre"},
/* Year */ {"sTitle": "Year", "sName": "year", "mDataProp": "year", "sClass": "library_year"},
/* Length */ {"sTitle": "Length", "sName": "length", "mDataProp": "length", "sClass": "library_length"},
- /* Upload Time */ {"sTitle": "Upload Time", "sName": "utime", "mDataProp": "utime", "sClass": "library_upload_time"},
+ /* Upload Time */ {"sTitle": "Uploaded", "sName": "utime", "mDataProp": "utime", "sClass": "library_upload_time"},
/* Last Modified */ {"sTitle": "Last Modified", "sName": "mtime", "bVisible": false, "mDataProp": "mtime", "sClass": "library_modified_time"}
],
"aaSorting": [[2,'asc']],
diff --git a/airtime_mvc/public/js/datatables/js/jquery.dataTables.js b/airtime_mvc/public/js/datatables/js/jquery.dataTables.js
index a295d1706..35b8d1b57 100644
--- a/airtime_mvc/public/js/datatables/js/jquery.dataTables.js
+++ b/airtime_mvc/public/js/datatables/js/jquery.dataTables.js
@@ -1,18 +1,17 @@
-/*
- * File: jquery.dataTables.js
- * Version: 1.8.2
- * Description: Paginate, search and sort HTML tables
- * Author: Allan Jardine (www.sprymedia.co.uk)
- * Created: 28/3/2008
- * Language: Javascript
- * License: GPL v2 or BSD 3 point style
- * Project: Mtaala
- * Contact: allan.jardine@sprymedia.co.uk
- *
- * Copyright 2008-2011 Allan Jardine, all rights reserved.
+/**
+ * @summary DataTables
+ * @description Paginate, search and sort HTML tables
+ * @version 1.9.0
+ * @file jquery.dataTables.js
+ * @author Allan Jardine (www.sprymedia.co.uk)
+ * @contact www.sprymedia.co.uk/contact
+ *
+ * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved.
*
* This source file is free software, under either the GPL v2 license or a
- * BSD style license, as supplied with this software.
+ * BSD style license, available at:
+ * http://datatables.net/license_gpl2
+ * http://datatables.net/license_bsd
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
@@ -21,2557 +20,89 @@
* For details please refer to: http://www.datatables.net
*/
-/*
- * When considering jsLint, we need to allow eval() as it it is used for reading cookies
- */
/*jslint evil: true, undef: true, browser: true */
-/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageProcess,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnArrayCmp,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn*/
+/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex*/
-(function($, window, document) {
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Section - DataTables variables
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /*
- * Variable: dataTableSettings
- * Purpose: Store the settings for each dataTables instance
- * Scope: jQuery.fn
- */
- $.fn.dataTableSettings = [];
- var _aoSettings = $.fn.dataTableSettings; /* Short reference for fast internal lookup */
-
- /*
- * Variable: dataTableExt
- * Purpose: Container for customisable parts of DataTables
- * Scope: jQuery.fn
- */
- $.fn.dataTableExt = {};
- var _oExt = $.fn.dataTableExt;
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Section - DataTables extensible objects
+(/** @lends */function($, window, document, undefined) {
+ /**
+ * DataTables is a plug-in for the jQuery Javascript library. It is a
+ * highly flexible tool, based upon the foundations of progressive
+ * enhancement, which will add advanced interaction controls to any
+ * HTML table. For a full list of features please refer to
+ * DataTables.net.
+ *
+ * Note that the DataTable object is not a global variable but is
+ * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which
+ * it may be accessed.
+ *
+ * @class
+ * @param {object} [oInit={}] Configuration object for DataTables. Options
+ * are defined by {@link DataTable.defaults}
+ * @requires jQuery 1.3+
*
- * The _oExt object is used to provide an area where user defined plugins can be
- * added to DataTables. The following properties of the object are used:
- * oApi - Plug-in API functions
- * aTypes - Auto-detection of types
- * oSort - Sorting functions used by DataTables (based on the type)
- * oPagination - Pagination functions for different input styles
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /*
- * Variable: sVersion
- * Purpose: Version string for plug-ins to check compatibility
- * Scope: jQuery.fn.dataTableExt
- * Notes: Allowed format is a.b.c.d.e where:
- * a:int, b:int, c:int, d:string(dev|beta), e:int. d and e are optional
+ * @example
+ * // Basic initialisation
+ * $(document).ready( function {
+ * $('#example').dataTable();
+ * } );
+ *
+ * @example
+ * // Initialisation with configuration options - in this case, disable
+ * // pagination and sorting.
+ * $(document).ready( function {
+ * $('#example').dataTable( {
+ * "bPaginate": false,
+ * "bSort": false
+ * } );
+ * } );
*/
- _oExt.sVersion = "1.8.2";
-
- /*
- * Variable: sErrMode
- * Purpose: How should DataTables report an error. Can take the value 'alert' or 'throw'
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.sErrMode = "alert";
-
- /*
- * Variable: iApiIndex
- * Purpose: Index for what 'this' index API functions should use
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.iApiIndex = 0;
-
- /*
- * Variable: oApi
- * Purpose: Container for plugin API functions
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.oApi = { };
-
- /*
- * Variable: aFiltering
- * Purpose: Container for plugin filtering functions
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.afnFiltering = [ ];
-
- /*
- * Variable: aoFeatures
- * Purpose: Container for plugin function functions
- * Scope: jQuery.fn.dataTableExt
- * Notes: Array of objects with the following parameters:
- * fnInit: Function for initialisation of Feature. Takes oSettings and returns node
- * cFeature: Character that will be matched in sDom - case sensitive
- * sFeature: Feature name - just for completeness :-)
- */
- _oExt.aoFeatures = [ ];
-
- /*
- * Variable: ofnSearch
- * Purpose: Container for custom filtering functions
- * Scope: jQuery.fn.dataTableExt
- * Notes: This is an object (the name should match the type) for custom filtering function,
- * which can be used for live DOM checking or formatted text filtering
- */
- _oExt.ofnSearch = { };
-
- /*
- * Variable: afnSortData
- * Purpose: Container for custom sorting data source functions
- * Scope: jQuery.fn.dataTableExt
- * Notes: Array (associative) of functions which is run prior to a column of this
- * 'SortDataType' being sorted upon.
- * Function input parameters:
- * object:oSettings- DataTables settings object
- * int:iColumn - Target column number
- * Return value: Array of data which exactly matched the full data set size for the column to
- * be sorted upon
- */
- _oExt.afnSortData = [ ];
-
- /*
- * Variable: oStdClasses
- * Purpose: Storage for the various classes that DataTables uses
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.oStdClasses = {
- /* Two buttons buttons */
- "sPagePrevEnabled": "paginate_enabled_previous",
- "sPagePrevDisabled": "paginate_disabled_previous",
- "sPageNextEnabled": "paginate_enabled_next",
- "sPageNextDisabled": "paginate_disabled_next",
- "sPageJUINext": "",
- "sPageJUIPrev": "",
-
- /* Full numbers paging buttons */
- "sPageButton": "paginate_button",
- "sPageButtonActive": "paginate_active",
- "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled",
- "sPageFirst": "first",
- "sPagePrevious": "previous",
- "sPageNext": "next",
- "sPageLast": "last",
-
- /* Striping classes */
- "sStripeOdd": "odd",
- "sStripeEven": "even",
-
- /* Empty row */
- "sRowEmpty": "dataTables_empty",
-
- /* Features */
- "sWrapper": "dataTables_wrapper",
- "sFilter": "dataTables_filter",
- "sInfo": "dataTables_info",
- "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
- "sLength": "dataTables_length",
- "sProcessing": "dataTables_processing",
-
- /* Sorting */
- "sSortAsc": "sorting_asc",
- "sSortDesc": "sorting_desc",
- "sSortable": "sorting", /* Sortable in both directions */
- "sSortableAsc": "sorting_asc_disabled",
- "sSortableDesc": "sorting_desc_disabled",
- "sSortableNone": "sorting_disabled",
- "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
- "sSortJUIAsc": "",
- "sSortJUIDesc": "",
- "sSortJUI": "",
- "sSortJUIAscAllowed": "",
- "sSortJUIDescAllowed": "",
- "sSortJUIWrapper": "",
- "sSortIcon": "",
-
- /* Scrolling */
- "sScrollWrapper": "dataTables_scroll",
- "sScrollHead": "dataTables_scrollHead",
- "sScrollHeadInner": "dataTables_scrollHeadInner",
- "sScrollBody": "dataTables_scrollBody",
- "sScrollFoot": "dataTables_scrollFoot",
- "sScrollFootInner": "dataTables_scrollFootInner",
-
- /* Misc */
- "sFooterTH": ""
- };
-
- /*
- * Variable: oJUIClasses
- * Purpose: Storage for the various classes that DataTables uses - jQuery UI suitable
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.oJUIClasses = {
- /* Two buttons buttons */
- "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left",
- "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
- "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right",
- "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",
- "sPageJUINext": "ui-icon ui-icon-circle-arrow-e",
- "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w",
-
- /* Full numbers paging buttons */
- "sPageButton": "fg-button ui-button ui-state-default",
- "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled",
- "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled",
- "sPageFirst": "first ui-corner-tl ui-corner-bl",
- "sPagePrevious": "previous",
- "sPageNext": "next",
- "sPageLast": "last ui-corner-tr ui-corner-br",
-
- /* Striping classes */
- "sStripeOdd": "odd",
- "sStripeEven": "even",
-
- /* Empty row */
- "sRowEmpty": "dataTables_empty",
-
- /* Features */
- "sWrapper": "dataTables_wrapper",
- "sFilter": "dataTables_filter",
- "sInfo": "dataTables_info",
- "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
- "ui-buttonset-multi paging_", /* Note that the type is postfixed */
- "sLength": "dataTables_length",
- "sProcessing": "dataTables_processing",
-
- /* Sorting */
- "sSortAsc": "ui-state-default",
- "sSortDesc": "ui-state-default",
- "sSortable": "ui-state-default",
- "sSortableAsc": "ui-state-default",
- "sSortableDesc": "ui-state-default",
- "sSortableNone": "ui-state-default",
- "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
- "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n",
- "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s",
- "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s",
- "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n",
- "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s",
- "sSortJUIWrapper": "DataTables_sort_wrapper",
- "sSortIcon": "DataTables_sort_icon",
-
- /* Scrolling */
- "sScrollWrapper": "dataTables_scroll",
- "sScrollHead": "dataTables_scrollHead ui-state-default",
- "sScrollHeadInner": "dataTables_scrollHeadInner",
- "sScrollBody": "dataTables_scrollBody",
- "sScrollFoot": "dataTables_scrollFoot ui-state-default",
- "sScrollFootInner": "dataTables_scrollFootInner",
-
- /* Misc */
- "sFooterTH": "ui-state-default"
- };
-
- /*
- * Variable: oPagination
- * Purpose: Container for the various type of pagination that dataTables supports
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt.oPagination = {
- /*
- * Variable: two_button
- * Purpose: Standard two button (forward/back) pagination
- * Scope: jQuery.fn.dataTableExt.oPagination
- */
- "two_button": {
- /*
- * Function: oPagination.two_button.fnInit
- * Purpose: Initialise dom elements required for pagination with forward/back buttons only
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
- * node:nPaging - the DIV which contains this pagination control
- * function:fnCallbackDraw - draw function which must be called on update
- */
- "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
- {
- var nPrevious, nNext, nPreviousInner, nNextInner;
-
- /* Store the next and previous elements in the oSettings object as they can be very
- * usful for automation - particularly testing
- */
- if ( !oSettings.bJUI )
- {
- nPrevious = document.createElement( 'div' );
- nNext = document.createElement( 'div' );
- }
- else
- {
- nPrevious = document.createElement( 'a' );
- nNext = document.createElement( 'a' );
-
- nNextInner = document.createElement('span');
- nNextInner.className = oSettings.oClasses.sPageJUINext;
- nNext.appendChild( nNextInner );
-
- nPreviousInner = document.createElement('span');
- nPreviousInner.className = oSettings.oClasses.sPageJUIPrev;
- nPrevious.appendChild( nPreviousInner );
- }
-
- nPrevious.className = oSettings.oClasses.sPagePrevDisabled;
- nNext.className = oSettings.oClasses.sPageNextDisabled;
-
- nPrevious.title = oSettings.oLanguage.oPaginate.sPrevious;
- nNext.title = oSettings.oLanguage.oPaginate.sNext;
-
- nPaging.appendChild( nPrevious );
- nPaging.appendChild( nNext );
-
- $(nPrevious).bind( 'click.DT', function() {
- if ( oSettings.oApi._fnPageChange( oSettings, "previous" ) )
- {
- /* Only draw when the page has actually changed */
- fnCallbackDraw( oSettings );
- }
- } );
-
- $(nNext).bind( 'click.DT', function() {
- if ( oSettings.oApi._fnPageChange( oSettings, "next" ) )
- {
- fnCallbackDraw( oSettings );
- }
- } );
-
- /* Take the brutal approach to cancelling text selection */
- $(nPrevious).bind( 'selectstart.DT', function () { return false; } );
- $(nNext).bind( 'selectstart.DT', function () { return false; } );
-
- /* ID the first elements only */
- if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.p == "undefined" )
- {
- nPaging.setAttribute( 'id', oSettings.sTableId+'_paginate' );
- nPrevious.setAttribute( 'id', oSettings.sTableId+'_previous' );
- nNext.setAttribute( 'id', oSettings.sTableId+'_next' );
- }
- },
-
- /*
- * Function: oPagination.two_button.fnUpdate
- * Purpose: Update the two button pagination at the end of the draw
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
- * function:fnCallbackDraw - draw function to call on page change
- */
- "fnUpdate": function ( oSettings, fnCallbackDraw )
- {
- if ( !oSettings.aanFeatures.p )
- {
- return;
- }
-
- /* Loop over each instance of the pager */
- var an = oSettings.aanFeatures.p;
- for ( var i=0, iLen=an.length ; i= (iPages - iPageCountHalf))
- {
- iStartButton = iPages - iPageCount + 1;
- iEndButton = iPages;
- }
- else
- {
- iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
- iEndButton = iStartButton + iPageCount - 1;
- }
- }
- }
-
- /* Build the dynamic list */
- for ( i=iStartButton ; i<=iEndButton ; i++ )
- {
- if ( iCurrentPage != i )
- {
- sList += ''+i+'';
- }
- else
- {
- sList += ''+i+'';
- }
- }
-
- /* Loop over each instance of the pager */
- var an = oSettings.aanFeatures.p;
- var anButtons, anStatic, nPaginateList;
- var fnClick = function(e) {
- /* Use the information in the element to jump to the required page */
- var iTarget = (this.innerHTML * 1) - 1;
- oSettings._iDisplayStart = iTarget * oSettings._iDisplayLength;
- fnCallbackDraw( oSettings );
- e.preventDefault();
- };
- var fnFalse = function () { return false; };
-
- for ( i=0, iLen=an.length ; i y) ? 1 : 0));
- },
-
- "string-desc": function ( a, b )
- {
- if ( typeof a != 'string' ) { a = ''; }
- if ( typeof b != 'string' ) { b = ''; }
- var x = a.toLowerCase();
- var y = b.toLowerCase();
- return ((x < y) ? 1 : ((x > y) ? -1 : 0));
- },
-
-
- /*
- * html sorting (ignore html tags)
- */
- "html-asc": function ( a, b )
- {
- var x = a.replace( /<.*?>/g, "" ).toLowerCase();
- var y = b.replace( /<.*?>/g, "" ).toLowerCase();
- return ((x < y) ? -1 : ((x > y) ? 1 : 0));
- },
-
- "html-desc": function ( a, b )
- {
- var x = a.replace( /<.*?>/g, "" ).toLowerCase();
- var y = b.replace( /<.*?>/g, "" ).toLowerCase();
- return ((x < y) ? 1 : ((x > y) ? -1 : 0));
- },
-
-
- /*
- * date sorting
- */
- "date-asc": function ( a, b )
- {
- var x = Date.parse( a );
- var y = Date.parse( b );
-
- if ( isNaN(x) || x==="" )
- {
- x = Date.parse( "01/01/1970 00:00:00" );
- }
- if ( isNaN(y) || y==="" )
- {
- y = Date.parse( "01/01/1970 00:00:00" );
- }
-
- return x - y;
- },
-
- "date-desc": function ( a, b )
- {
- var x = Date.parse( a );
- var y = Date.parse( b );
-
- if ( isNaN(x) || x==="" )
- {
- x = Date.parse( "01/01/1970 00:00:00" );
- }
- if ( isNaN(y) || y==="" )
- {
- y = Date.parse( "01/01/1970 00:00:00" );
- }
-
- return y - x;
- },
-
-
- /*
- * numerical sorting
- */
- "numeric-asc": function ( a, b )
- {
- var x = (a=="-" || a==="") ? 0 : a*1;
- var y = (b=="-" || b==="") ? 0 : b*1;
- return x - y;
- },
-
- "numeric-desc": function ( a, b )
- {
- var x = (a=="-" || a==="") ? 0 : a*1;
- var y = (b=="-" || b==="") ? 0 : b*1;
- return y - x;
- }
- };
-
-
- /*
- * Variable: aTypes
- * Purpose: Container for the various type of type detection that dataTables supports
- * Scope: jQuery.fn.dataTableExt
- * Notes: The functions in this array are expected to parse a string to see if it is a data
- * type that it recognises. If so then the function should return the name of the type (a
- * corresponding sort function should be defined!), if the type is not recognised then the
- * function should return null such that the parser and move on to check the next type.
- * Note that ordering is important in this array - the functions are processed linearly,
- * starting at index 0.
- * Note that the input for these functions is always a string! It cannot be any other data
- * type
- */
- _oExt.aTypes = [
- /*
- * Function: -
- * Purpose: Check to see if a string is numeric
- * Returns: string:'numeric' or null
- * Inputs: mixed:sText - string to check
- */
- function ( sData )
- {
- /* Allow zero length strings as a number */
- if ( typeof sData == 'number' )
- {
- return 'numeric';
- }
- else if ( typeof sData != 'string' )
- {
- return null;
- }
-
- var sValidFirstChars = "0123456789-";
- var sValidChars = "0123456789.";
- var Char;
- var bDecimal = false;
-
- /* Check for a valid first char (no period and allow negatives) */
- Char = sData.charAt(0);
- if (sValidFirstChars.indexOf(Char) == -1)
- {
- return null;
- }
-
- /* Check all the other characters are valid */
- for ( var i=1 ; i') != -1 )
- {
- return 'html';
- }
- return null;
- }
- ];
-
- /*
- * Function: fnVersionCheck
- * Purpose: Check a version string against this version of DataTables. Useful for plug-ins
- * Returns: bool:true -this version of DataTables is greater or equal to the required version
- * false -this version of DataTales is not suitable
- * Inputs: string:sVersion - the version to check against. May be in the following formats:
- * "a", "a.b" or "a.b.c"
- * Notes: This function will only check the first three parts of a version string. It is
- * assumed that beta and dev versions will meet the requirements. This might change in future
- */
- _oExt.fnVersionCheck = function( sVersion )
+ var DataTable = function( oInit )
{
- /* This is cheap, but very effective */
- var fnZPad = function (Zpad, count)
- {
- while(Zpad.length < count) {
- Zpad += '0';
- }
- return Zpad;
- };
- var aThis = _oExt.sVersion.split('.');
- var aThat = sVersion.split('.');
- var sThis = '', sThat = '';
-
- for ( var i=0, iLen=aThat.length ; i= parseInt(sThat, 10);
- };
-
- /*
- * Variable: _oExternConfig
- * Purpose: Store information for DataTables to access globally about other instances
- * Scope: jQuery.fn.dataTableExt
- */
- _oExt._oExternConfig = {
- /* int:iNextUnique - next unique number for an instance */
- "iNextUnique": 0
- };
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Section - DataTables prototype
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- /*
- * Function: dataTable
- * Purpose: DataTables information
- * Returns: -
- * Inputs: object:oInit - initialisation options for the table
- */
- $.fn.dataTable = function( oInit )
- {
- /*
- * Function: classSettings
- * Purpose: Settings container function for all 'class' properties which are required
- * by dataTables
- * Returns: -
- * Inputs: -
- */
- function classSettings ()
- {
- this.fnRecordsTotal = function ()
- {
- if ( this.oFeatures.bServerSide ) {
- return parseInt(this._iRecordsTotal, 10);
- } else {
- return this.aiDisplayMaster.length;
- }
- };
-
- this.fnRecordsDisplay = function ()
- {
- if ( this.oFeatures.bServerSide ) {
- return parseInt(this._iRecordsDisplay, 10);
- } else {
- return this.aiDisplay.length;
- }
- };
-
- this.fnDisplayEnd = function ()
- {
- if ( this.oFeatures.bServerSide ) {
- if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) {
- return this._iDisplayStart+this.aiDisplay.length;
- } else {
- return Math.min( this._iDisplayStart+this._iDisplayLength,
- this._iRecordsDisplay );
- }
- } else {
- return this._iDisplayEnd;
- }
- };
-
- /*
- * Variable: oInstance
- * Purpose: The DataTables object for this table
- * Scope: jQuery.dataTable.classSettings
- */
- this.oInstance = null;
-
- /*
- * Variable: sInstance
- * Purpose: Unique idendifier for each instance of the DataTables object
- * Scope: jQuery.dataTable.classSettings
- */
- this.sInstance = null;
-
- /*
- * Variable: oFeatures
- * Purpose: Indicate the enablement of key dataTable features
- * Scope: jQuery.dataTable.classSettings
- */
- this.oFeatures = {
- "bPaginate": true,
- "bLengthChange": true,
- "bFilter": true,
- "bSort": true,
- "bInfo": true,
- "bAutoWidth": true,
- "bProcessing": false,
- "bSortClasses": true,
- "bStateSave": false,
- "bServerSide": false,
- "bDeferRender": false
- };
-
- /*
- * Variable: oScroll
- * Purpose: Container for scrolling options
- * Scope: jQuery.dataTable.classSettings
- */
- this.oScroll = {
- "sX": "",
- "sXInner": "",
- "sY": "",
- "bCollapse": false,
- "bInfinite": false,
- "iLoadGap": 100,
- "iBarWidth": 0,
- "bAutoCss": true
- };
-
- /*
- * Variable: aanFeatures
- * Purpose: Array referencing the nodes which are used for the features
- * Scope: jQuery.dataTable.classSettings
- * Notes: The parameters of this object match what is allowed by sDom - i.e.
- * 'l' - Length changing
- * 'f' - Filtering input
- * 't' - The table!
- * 'i' - Information
- * 'p' - Pagination
- * 'r' - pRocessing
- */
- this.aanFeatures = [];
-
- /*
- * Variable: oLanguage
- * Purpose: Store the language strings used by dataTables
- * Scope: jQuery.dataTable.classSettings
- * Notes: The words in the format _VAR_ are variables which are dynamically replaced
- * by javascript
- */
- this.oLanguage = {
- "sProcessing": "Processing...",
- "sLengthMenu": "Show _MENU_ entries",
- "sZeroRecords": "No matching records found",
- "sEmptyTable": "No data available in table",
- "sLoadingRecords": "Loading...",
- "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
- "sInfoEmpty": "Showing 0 to 0 of 0 entries",
- "sInfoFiltered": "(filtered from _MAX_ total entries)",
- "sInfoPostFix": "",
- "sInfoThousands": ",",
- "sSearch": "Search:",
- "sUrl": "",
- "oPaginate": {
- "sFirst": "First",
- "sPrevious": "Previous",
- "sNext": "Next",
- "sLast": "Last"
- },
- "fnInfoCallback": null
- };
-
- /*
- * Variable: aoData
- * Purpose: Store data information
- * Scope: jQuery.dataTable.classSettings
- * Notes: This is an array of objects with the following parameters:
- * int: _iId - internal id for tracking
- * array: _aData - internal data - used for sorting / filtering etc
- * node: nTr - display node
- * array node: _anHidden - hidden TD nodes
- * string: _sRowStripe
- */
- this.aoData = [];
-
- /*
- * Variable: aiDisplay
- * Purpose: Array of indexes which are in the current display (after filtering etc)
- * Scope: jQuery.dataTable.classSettings
- */
- this.aiDisplay = [];
-
- /*
- * Variable: aiDisplayMaster
- * Purpose: Array of indexes for display - no filtering
- * Scope: jQuery.dataTable.classSettings
- */
- this.aiDisplayMaster = [];
-
- /*
- * Variable: aoColumns
- * Purpose: Store information about each column that is in use
- * Scope: jQuery.dataTable.classSettings
- */
- this.aoColumns = [];
-
- /*
- * Variable: aoHeader
- * Purpose: Store information about the table's header
- * Scope: jQuery.dataTable.classSettings
- */
- this.aoHeader = [];
-
- /*
- * Variable: aoFooter
- * Purpose: Store information about the table's footer
- * Scope: jQuery.dataTable.classSettings
- */
- this.aoFooter = [];
-
- /*
- * Variable: iNextId
- * Purpose: Store the next unique id to be used for a new row
- * Scope: jQuery.dataTable.classSettings
- */
- this.iNextId = 0;
-
- /*
- * Variable: asDataSearch
- * Purpose: Search data array for regular expression searching
- * Scope: jQuery.dataTable.classSettings
- */
- this.asDataSearch = [];
-
- /*
- * Variable: oPreviousSearch
- * Purpose: Store the previous search incase we want to force a re-search
- * or compare the old search to a new one
- * Scope: jQuery.dataTable.classSettings
- */
- this.oPreviousSearch = {
- "sSearch": "",
- "bRegex": false,
- "bSmart": true
- };
-
- /*
- * Variable: aoPreSearchCols
- * Purpose: Store the previous search for each column
- * Scope: jQuery.dataTable.classSettings
- */
- this.aoPreSearchCols = [];
-
- /*
- * Variable: aaSorting
- * Purpose: Sorting information
- * Scope: jQuery.dataTable.classSettings
- * Notes: Index 0 - column number
- * Index 1 - current sorting direction
- * Index 2 - index of asSorting for this column
- */
- this.aaSorting = [ [0, 'asc', 0] ];
-
- /*
- * Variable: aaSortingFixed
- * Purpose: Sorting information that is always applied
- * Scope: jQuery.dataTable.classSettings
- */
- this.aaSortingFixed = null;
-
- /*
- * Variable: asStripeClasses
- * Purpose: Classes to use for the striping of a table
- * Scope: jQuery.dataTable.classSettings
- */
- this.asStripeClasses = [];
-
- /*
- * Variable: asDestroyStripes
- * Purpose: If restoring a table - we should restore its striping classes as well
- * Scope: jQuery.dataTable.classSettings
- */
- this.asDestroyStripes = [];
-
- /*
- * Variable: sDestroyWidth
- * Purpose: If restoring a table - we should restore its width
- * Scope: jQuery.dataTable.classSettings
- */
- this.sDestroyWidth = 0;
-
- /*
- * Variable: fnRowCallback
- * Purpose: Call this function every time a row is inserted (draw)
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnRowCallback = null;
-
- /*
- * Variable: fnHeaderCallback
- * Purpose: Callback function for the header on each draw
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnHeaderCallback = null;
-
- /*
- * Variable: fnFooterCallback
- * Purpose: Callback function for the footer on each draw
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnFooterCallback = null;
-
- /*
- * Variable: aoDrawCallback
- * Purpose: Array of callback functions for draw callback functions
- * Scope: jQuery.dataTable.classSettings
- * Notes: Each array element is an object with the following parameters:
- * function:fn - function to call
- * string:sName - name callback (feature). useful for arranging array
- */
- this.aoDrawCallback = [];
-
- /*
- * Variable: fnPreDrawCallback
- * Purpose: Callback function for just before the table is redrawn. A return of false
- * will be used to cancel the draw.
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnPreDrawCallback = null;
-
- /*
- * Variable: fnInitComplete
- * Purpose: Callback function for when the table has been initialised
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnInitComplete = null;
-
- /*
- * Variable: sTableId
- * Purpose: Cache the table ID for quick access
- * Scope: jQuery.dataTable.classSettings
- */
- this.sTableId = "";
-
- /*
- * Variable: nTable
- * Purpose: Cache the table node for quick access
- * Scope: jQuery.dataTable.classSettings
- */
- this.nTable = null;
-
- /*
- * Variable: nTHead
- * Purpose: Permanent ref to the thead element
- * Scope: jQuery.dataTable.classSettings
- */
- this.nTHead = null;
-
- /*
- * Variable: nTFoot
- * Purpose: Permanent ref to the tfoot element - if it exists
- * Scope: jQuery.dataTable.classSettings
- */
- this.nTFoot = null;
-
- /*
- * Variable: nTBody
- * Purpose: Permanent ref to the tbody element
- * Scope: jQuery.dataTable.classSettings
- */
- this.nTBody = null;
-
- /*
- * Variable: nTableWrapper
- * Purpose: Cache the wrapper node (contains all DataTables controlled elements)
- * Scope: jQuery.dataTable.classSettings
- */
- this.nTableWrapper = null;
-
- /*
- * Variable: bDeferLoading
- * Purpose: Indicate if when using server-side processing the loading of data
- * should be deferred until the second draw
- * Scope: jQuery.dataTable.classSettings
- */
- this.bDeferLoading = false;
-
- /*
- * Variable: bInitialised
- * Purpose: Indicate if all required information has been read in
- * Scope: jQuery.dataTable.classSettings
- */
- this.bInitialised = false;
-
- /*
- * Variable: aoOpenRows
- * Purpose: Information about open rows
- * Scope: jQuery.dataTable.classSettings
- * Notes: Has the parameters 'nTr' and 'nParent'
- */
- this.aoOpenRows = [];
-
- /*
- * Variable: sDom
- * Purpose: Dictate the positioning that the created elements will take
- * Scope: jQuery.dataTable.classSettings
- * Notes:
- * The following options are allowed:
- * 'l' - Length changing
- * 'f' - Filtering input
- * 't' - The table!
- * 'i' - Information
- * 'p' - Pagination
- * 'r' - pRocessing
- * The following constants are allowed:
- * 'H' - jQueryUI theme "header" classes
- * 'F' - jQueryUI theme "footer" classes
- * The following syntax is expected:
- * '<' and '>' - div elements
- * '<"class" and '>' - div with a class
- * Examples:
- * '<"wrapper"flipt>', 'ip>'
- */
- this.sDom = 'lfrtip';
-
- /*
- * Variable: sPaginationType
- * Purpose: Note which type of sorting should be used
- * Scope: jQuery.dataTable.classSettings
- */
- this.sPaginationType = "two_button";
-
- /*
- * Variable: iCookieDuration
- * Purpose: The cookie duration (for bStateSave) in seconds - default 2 hours
- * Scope: jQuery.dataTable.classSettings
- */
- this.iCookieDuration = 60 * 60 * 2;
-
- /*
- * Variable: sCookiePrefix
- * Purpose: The cookie name prefix
- * Scope: jQuery.dataTable.classSettings
- */
- this.sCookiePrefix = "SpryMedia_DataTables_";
-
- /*
- * Variable: fnCookieCallback
- * Purpose: Callback function for cookie creation
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnCookieCallback = null;
-
- /*
- * Variable: aoStateSave
- * Purpose: Array of callback functions for state saving
- * Scope: jQuery.dataTable.classSettings
- * Notes: Each array element is an object with the following parameters:
- * function:fn - function to call. Takes two parameters, oSettings and the JSON string to
- * save that has been thus far created. Returns a JSON string to be inserted into a
- * json object (i.e. '"param": [ 0, 1, 2]')
- * string:sName - name of callback
- */
- this.aoStateSave = [];
-
- /*
- * Variable: aoStateLoad
- * Purpose: Array of callback functions for state loading
- * Scope: jQuery.dataTable.classSettings
- * Notes: Each array element is an object with the following parameters:
- * function:fn - function to call. Takes two parameters, oSettings and the object stored.
- * May return false to cancel state loading.
- * string:sName - name of callback
- */
- this.aoStateLoad = [];
-
- /*
- * Variable: oLoadedState
- * Purpose: State that was loaded from the cookie. Useful for back reference
- * Scope: jQuery.dataTable.classSettings
- */
- this.oLoadedState = null;
-
- /*
- * Variable: sAjaxSource
- * Purpose: Source url for AJAX data for the table
- * Scope: jQuery.dataTable.classSettings
- */
- this.sAjaxSource = null;
-
- /*
- * Variable: sAjaxDataProp
- * Purpose: Property from a given object from which to read the table data from. This can
- * be an empty string (when not server-side processing), in which case it is
- * assumed an an array is given directly.
- * Scope: jQuery.dataTable.classSettings
- */
- this.sAjaxDataProp = 'aaData';
-
- /*
- * Variable: bAjaxDataGet
- * Purpose: Note if draw should be blocked while getting data
- * Scope: jQuery.dataTable.classSettings
- */
- this.bAjaxDataGet = true;
-
- /*
- * Variable: jqXHR
- * Purpose: The last jQuery XHR object that was used for server-side data gathering.
- * This can be used for working with the XHR information in one of the callbacks
- * Scope: jQuery.dataTable.classSettings
- */
- this.jqXHR = null;
-
- /*
- * Variable: fnServerData
- * Purpose: Function to get the server-side data - can be overruled by the developer
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnServerData = function ( url, data, callback, settings ) {
- settings.jqXHR = $.ajax( {
- "url": url,
- "data": data,
- "success": function (json) {
- $(settings.oInstance).trigger('xhr', settings);
- callback( json );
- },
- "dataType": "json",
- "cache": false,
- "error": function (xhr, error, thrown) {
- if ( error == "parsererror" ) {
- alert( "DataTables warning: JSON data from server could not be parsed. "+
- "This is caused by a JSON formatting error." );
- }
- }
- } );
- };
-
- /*
- * Variable: aoServerParams
- * Purpose: Functions which are called prior to sending an Ajax request so extra parameters
- * can easily be sent to the server
- * Scope: jQuery.dataTable.classSettings
- * Notes: Each array element is an object with the following parameters:
- * function:fn - function to call
- * string:sName - name callback - useful for knowing where it came from (plugin etc)
- */
- this.aoServerParams = [];
-
- /*
- * Variable: fnFormatNumber
- * Purpose: Format numbers for display
- * Scope: jQuery.dataTable.classSettings
- */
- this.fnFormatNumber = function ( iIn )
- {
- if ( iIn < 1000 )
- {
- /* A small optimisation for what is likely to be the vast majority of use cases */
- return iIn;
- }
- else
- {
- var s=(iIn+""), a=s.split(""), out="", iLen=s.length;
-
- for ( var i=0 ; i= oSettings.aiDisplay.length )
- {
- oSettings._iDisplayStart -= oSettings._iDisplayLength;
- if ( oSettings._iDisplayStart < 0 )
- {
- oSettings._iDisplayStart = 0;
- }
- }
-
- if ( typeof bRedraw == 'undefined' || bRedraw )
- {
- _fnCalculateEnd( oSettings );
- _fnDraw( oSettings );
- }
-
- return oData;
- };
-
- /*
- * Function: fnClearTable
- * Purpose: Quickly and simply clear a table
- * Returns: -
- * Inputs: bool:bRedraw - redraw the table or not - default true
- * Notes: Thanks to Yekimov Denis for contributing the basis for this function!
- */
- this.fnClearTable = function( bRedraw )
- {
- /* Find settings from table node */
- var oSettings = _fnSettingsFromNode( this[_oExt.iApiIndex] );
- _fnClearTable( oSettings );
-
- if ( typeof bRedraw == 'undefined' || bRedraw )
- {
- _fnDraw( oSettings );
- }
- };
-
- /*
- * Function: fnOpen
- * Purpose: Open a display row (append a row after the row in question)
- * Returns: node:nNewRow - the row opened
- * Inputs: node:nTr - the table row to 'open'
- * string|node|jQuery:mHtml - the HTML to put into the row
- * string:sClass - class to give the new TD cell
- */
- this.fnOpen = function( nTr, mHtml, sClass )
- {
- /* Find settings from table node */
- var oSettings = _fnSettingsFromNode( this[_oExt.iApiIndex] );
-
- /* the old open one if there is one */
- this.fnClose( nTr );
-
- var nNewRow = document.createElement("tr");
- var nNewCell = document.createElement("td");
- nNewRow.appendChild( nNewCell );
- nNewCell.className = sClass;
- nNewCell.colSpan = _fnVisbleColumns( oSettings );
-
- if( typeof mHtml.jquery != 'undefined' || typeof mHtml == "object" )
- {
- nNewCell.appendChild( mHtml );
- }
- else
- {
- nNewCell.innerHTML = mHtml;
- }
-
- /* If the nTr isn't on the page at the moment - then we don't insert at the moment */
- var nTrs = $('tr', oSettings.nTBody);
- if ( $.inArray(nTr, nTrs) != -1 )
- {
- $(nNewRow).insertAfter(nTr);
- }
-
- oSettings.aoOpenRows.push( {
- "nTr": nNewRow,
- "nParent": nTr
- } );
-
- return nNewRow;
- };
-
- /*
- * Function: fnClose
- * Purpose: Close a display row
- * Returns: int: 0 (success) or 1 (failed)
- * Inputs: node:nTr - the table row to 'close'
- */
- this.fnClose = function( nTr )
- {
- /* Find settings from table node */
- var oSettings = _fnSettingsFromNode( this[_oExt.iApiIndex] );
-
- for ( var i=0 ; i= _fnVisbleColumns( oSettings ));
-
- /* Which coloumn should we be inserting before? */
- if ( !bAppend )
- {
- for ( i=iCol ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove();
-
- /* When scrolling we had to break the table up - restore it */
- if ( oSettings.nTable != oSettings.nTHead.parentNode )
- {
- $(oSettings.nTable).children('thead').remove();
- oSettings.nTable.appendChild( oSettings.nTHead );
- }
-
- if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode )
- {
- $(oSettings.nTable).children('tfoot').remove();
- oSettings.nTable.appendChild( oSettings.nTFoot );
- }
-
- /* Remove the DataTables generated nodes, events and classes */
- oSettings.nTable.parentNode.removeChild( oSettings.nTable );
- $(oSettings.nTableWrapper).remove();
-
- oSettings.aaSorting = [];
- oSettings.aaSortingFixed = [];
- _fnSortingClasses( oSettings );
-
- $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') );
-
- if ( !oSettings.bJUI )
- {
- $('th', oSettings.nTHead).removeClass( [ _oExt.oStdClasses.sSortable,
- _oExt.oStdClasses.sSortableAsc,
- _oExt.oStdClasses.sSortableDesc,
- _oExt.oStdClasses.sSortableNone ].join(' ')
- );
- }
- else
- {
- $('th', oSettings.nTHead).removeClass( [ _oExt.oStdClasses.sSortable,
- _oExt.oJUIClasses.sSortableAsc,
- _oExt.oJUIClasses.sSortableDesc,
- _oExt.oJUIClasses.sSortableNone ].join(' ')
- );
- $('th span.'+_oExt.oJUIClasses.sSortIcon, oSettings.nTHead).remove();
-
- $('th', oSettings.nTHead).each( function () {
- var jqWrapper = $('div.'+_oExt.oJUIClasses.sSortJUIWrapper, this);
- var kids = jqWrapper.contents();
- $(this).append( kids );
- jqWrapper.remove();
- } );
- }
-
- /* Add the TR elements back into the table in their original order */
- if ( oSettings.nTableReinsertBefore )
- {
- nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore );
- }
- else
- {
- nOrig.appendChild( oSettings.nTable );
- }
-
- for ( i=0, iLen=oSettings.aoData.length ; i=0 if successful (index of new aoData entry), -1 if failed
- * Inputs: object:oSettings - dataTables settings object
- * array:aData - data array to be added
- * Notes: There are two basic methods for DataTables to get data to display - a JS array
- * (which is dealt with by this function), and the DOM, which has it's own optimised
- * function (_fnGatherData). Be careful to make the same changes here as there and vice-versa
+
+ /**
+ * Adjust the table column widths for new data. Note: you would probably want to
+ * do a redraw after calling this function!
+ * @param {object} oSettings dataTables settings object
+ * @memberof DataTable#oApi
+ */
+ function _fnAdjustColumnSizing ( oSettings )
+ {
+ /* Not interested in doing column width calculation if autowidth is disabled */
+ if ( oSettings.oFeatures.bAutoWidth === false )
+ {
+ return false;
+ }
+
+ _fnCalculateColumnWidths( oSettings );
+ for ( var i=0 , iLen=oSettings.aoColumns.length ; i=0 ; i-- )
+ {
+ /* Each definition can target multiple columns, as it is an array */
+ var aTargets = aoColDefs[i].aTargets;
+ if ( !$.isArray( aTargets ) )
+ {
+ _fnLog( oSettings, 1, 'aTargets must be an array of targets, not a '+(typeof aTargets) );
+ }
+
+ for ( j=0, jLen=aTargets.length ; j= 0 )
+ {
+ /* Add columns that we don't yet know about */
+ while( oSettings.aoColumns.length <= aTargets[j] )
+ {
+ _fnAddColumn( oSettings );
+ }
+
+ /* Integer, basic index */
+ fn( aTargets[j], aoColDefs[i] );
+ }
+ else if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )
+ {
+ /* Negative integer, right to left column counting */
+ fn( oSettings.aoColumns.length+aTargets[j], aoColDefs[i] );
+ }
+ else if ( typeof aTargets[j] === 'string' )
+ {
+ /* Class name matching on TH element */
+ for ( k=0, kLen=oSettings.aoColumns.length ; k=0 if successful (index of new aoData entry), -1 if failed
+ * @memberof DataTable#oApi
*/
function _fnAddData ( oSettings, aDataSupplied )
{
@@ -2674,30 +445,21 @@
/* Create the object for storing information about this new row */
var iRow = oSettings.aoData.length;
- var oData = {
- "nTr": null,
- "_iId": oSettings.iNextId++,
- "_aData": aDataIn,
- "_anHidden": [],
- "_sRowStripe": ""
- };
+ var oData = $.extend( true, {}, DataTable.models.oRow, {
+ "_aData": aDataIn
+ } );
oSettings.aoData.push( oData );
-
+
/* Create the cells */
var nTd, sThisType;
for ( var i=0, iLen=oSettings.aoColumns.length ; i iTarget )
+ {
+ a[i]--;
+ }
+ }
+
+ if ( iTargetIndex != -1 )
+ {
+ a.splice( iTargetIndex, 1 );
+ }
+ }
+
+
+ /**
+ * Call the developer defined fnRender function for a given cell (row/column) with
+ * the required parameters and return the result.
+ * @param {object} oSettings dataTables settings object
+ * @param {int} iRow aoData index for the row
+ * @param {int} iCol aoColumns index for the column
+ * @returns {*} Return of the developer's fnRender function
+ * @memberof DataTable#oApi
+ */
+ function _fnRender( oSettings, iRow, iCol )
+ {
+ var oCol = oSettings.aoColumns[iCol];
+
+ return oCol.fnRender( {
+ "iDataRow": iRow,
+ "iDataColumn": iCol,
+ "oSettings": oSettings,
+ "aData": oSettings.aoData[iRow]._aData,
+ "mDataProp": oCol.mDataProp
+ }, _fnGetCellData(oSettings, iRow, iCol, 'display') );
+ }
+
+
+ /**
+ * Create a new TR element (and it's TD children) for a row
+ * @param {object} oSettings dataTables settings object
+ * @param {int} iRow Row to consider
+ * @memberof DataTable#oApi
+ */
+ function _fnCreateTr ( oSettings, iRow )
+ {
+ var oData = oSettings.aoData[iRow];
+ var nTd;
+
+ if ( oData.nTr === null )
+ {
+ oData.nTr = document.createElement('tr');
+
+ /* Use a private property on the node to allow reserve mapping from the node
+ * to the aoData array for fast look up
+ */
+ oData.nTr._DT_RowIndex = iRow;
+
+ /* Special parameters can be given by the data source to be used on the row */
+ if ( oData._aData.DT_RowId )
+ {
+ oData.nTr.id = oData._aData.DT_RowId;
+ }
+
+ if ( oData._aData.DT_RowClass )
+ {
+ $(oData.nTr).addClass( oData._aData.DT_RowClass );
+ }
+
+ /* Process each column */
+ for ( var i=0, iLen=oSettings.aoColumns.length ; i=0 ; j-- )
{
@@ -3127,45 +1195,47 @@
aoLocal[i].splice( j, 1 );
}
}
-
+
/* Prep the applied array - it needs an element for each row */
aApplied.push( [] );
}
-
+
for ( i=0, iLen=aoLocal.length ; i=0 ; i-- )
+ while( (n = oSettings.nTBody.firstChild) )
{
- nTrs[i].parentNode.removeChild( nTrs[i] );
+ oSettings.nTBody.removeChild( n );
}
}
@@ -3387,11 +1439,7 @@
}
/* Call all required callback functions for the end of a draw */
- for ( i=oSettings.aoDrawCallback.length-1 ; i>=0 ; i-- )
- {
- oSettings.aoDrawCallback[i].fn.call( oSettings.oInstance, oSettings );
- }
- $(oSettings.oInstance).trigger('draw', oSettings);
+ _fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );
/* Draw is complete, sorting and filtering must be as well */
oSettings.bSorted = false;
@@ -3401,18 +1449,18 @@
if ( oSettings.oFeatures.bServerSide )
{
_fnProcessingDisplay( oSettings, false );
- if ( typeof oSettings._bInitComplete == 'undefined' )
+ if ( !oSettings._bInitComplete )
{
_fnInitComplete( oSettings );
}
}
}
- /*
- * Function: _fnReDraw
- * Purpose: Redraw the table - taking account of the various features which are enabled
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
+
+ /**
+ * Redraw the table - taking account of the various features which are enabled
+ * @param {object} oSettings dataTables settings object
+ * @memberof DataTable#oApi
*/
function _fnReDraw( oSettings )
{
@@ -3433,197 +1481,11 @@
}
}
- /*
- * Function: _fnAjaxUpdate
- * Purpose: Update the table using an Ajax call
- * Returns: bool: block the table drawing or not
- * Inputs: object:oSettings - dataTables settings object
- */
- function _fnAjaxUpdate( oSettings )
- {
- if ( oSettings.bAjaxDataGet )
- {
- oSettings.iDraw++;
- _fnProcessingDisplay( oSettings, true );
- var iColumns = oSettings.aoColumns.length;
- var aoData = _fnAjaxParameters( oSettings );
- _fnServerParams( oSettings, aoData );
-
- oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aoData,
- function(json) {
- _fnAjaxUpdateDraw( oSettings, json );
- }, oSettings );
- return false;
- }
- else
- {
- return true;
- }
- }
- /*
- * Function: _fnAjaxParameters
- * Purpose: Build up the parameters in an object needed for a server-side processing request
- * Returns: bool: block the table drawing or not
- * Inputs: object:oSettings - dataTables settings object
- */
- function _fnAjaxParameters( oSettings )
- {
- var iColumns = oSettings.aoColumns.length;
- var aoData = [], mDataProp;
- var i;
-
- aoData.push( { "name": "sEcho", "value": oSettings.iDraw } );
- aoData.push( { "name": "iColumns", "value": iColumns } );
- aoData.push( { "name": "sColumns", "value": _fnColumnOrdering(oSettings) } );
- aoData.push( { "name": "iDisplayStart", "value": oSettings._iDisplayStart } );
- aoData.push( { "name": "iDisplayLength", "value": oSettings.oFeatures.bPaginate !== false ?
- oSettings._iDisplayLength : -1 } );
-
- for ( i=0 ; i')[0];
oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable );
/*
* All DataTables are wrapped in a div
*/
- oSettings.nTableWrapper = document.createElement( 'div' );
- oSettings.nTableWrapper.className = oSettings.oClasses.sWrapper;
- if ( oSettings.sTableId !== '' )
- {
- oSettings.nTableWrapper.setAttribute( 'id', oSettings.sTableId+'_wrapper' );
- }
-
+ oSettings.nTableWrapper = $('')[0];
oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;
-
+
/* Track where we want to insert the option */
var nInsertNode = oSettings.nTableWrapper;
@@ -3660,7 +1516,7 @@
if ( cOption == '<' )
{
/* New container div */
- nNewNode = document.createElement( 'div' );
+ nNewNode = $('')[0];
/* Check to see if we should append an id and/or a class name to the container */
cNext = aDom[i+1];
@@ -3690,12 +1546,12 @@
if ( sAttr.indexOf('.') != -1 )
{
var aSplit = sAttr.split('.');
- nNewNode.setAttribute('id', aSplit[0].substr(1, aSplit[0].length-1) );
+ nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);
nNewNode.className = aSplit[1];
}
else if ( sAttr.charAt(0) == "#" )
{
- nNewNode.setAttribute('id', sAttr.substr(1, sAttr.length-1) );
+ nNewNode.id = sAttr.substr(1, sAttr.length-1);
}
else
{
@@ -3749,10 +1605,10 @@
nTmp = _fnFeatureHtmlPaginate( oSettings );
iPushFeature = 1;
}
- else if ( _oExt.aoFeatures.length !== 0 )
+ else if ( DataTable.ext.aoFeatures.length !== 0 )
{
/* Plug-in features */
- var aoFeatures = _oExt.aoFeatures;
+ var aoFeatures = DataTable.ext.aoFeatures;
for ( var k=0, kLen=aoFeatures.length ; k') :
+ sSearchStr==="" ? '' : sSearchStr+' ';
+
+ var nFilter = document.createElement( 'div' );
+ nFilter.className = oSettings.oClasses.sFilter;
+ nFilter.innerHTML = '';
+ if ( !oSettings.aanFeatures.f )
+ {
+ nFilter.id = oSettings.sTableId+'_filter';
+ }
+
+ var jqFilter = $("input", nFilter);
+ jqFilter.val( oPreviousSearch.sSearch.replace('"','"') );
+ jqFilter.bind( 'keyup.DT', function(e) {
+ /* Update all other filter input elements for the new display */
+ var n = oSettings.aanFeatures.f;
+ for ( var i=0, iLen=n.length ; i=0 ; i-- )
+ {
+ var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ),
+ oSettings.aoColumns[iColumn].sType );
+ if ( ! rpSearch.test( sData ) )
+ {
+ oSettings.aiDisplay.splice( i, 1 );
+ iIndexCorrector++;
+ }
+ }
+ }
+
+
+ /**
+ * Filter the data table based on user input and draw the table
+ * @param {object} oSettings dataTables settings object
+ * @param {string} sInput string to filter on
+ * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0)
+ * @param {bool} bRegex treat as a regular expression or not
+ * @param {bool} bSmart perform smart filtering or not
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
+ * @memberof DataTable#oApi
+ */
+ function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive )
+ {
+ var i;
+ var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive );
+ var oPrevSearch = oSettings.oPreviousSearch;
+
+ /* Check if we are forcing or not - optional parameter */
+ if ( !iForce )
+ {
+ iForce = 0;
+ }
+
+ /* Need to take account of custom filtering functions - always filter */
+ if ( DataTable.ext.afnFiltering.length !== 0 )
+ {
+ iForce = 1;
+ }
+
+ /*
+ * If the input is blank - we want the full data set
+ */
+ if ( sInput.length <= 0 )
+ {
+ oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
+ }
+ else
+ {
+ /*
+ * We are starting a new search or the new search string is smaller
+ * then the old one (i.e. delete). Search from the master array
+ */
+ if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length ||
+ oPrevSearch.sSearch.length > sInput.length || iForce == 1 ||
+ sInput.indexOf(oPrevSearch.sSearch) !== 0 )
+ {
+ /* Nuke the old display array - we are going to rebuild it */
+ oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
+
+ /* Force a rebuild of the search array */
+ _fnBuildSearchArray( oSettings, 1 );
+
+ /* Search through all records to populate the search array
+ * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1
+ * mapping
+ */
+ for ( i=0 ; i tag - remove it */
+ sSearch = sSearch.replace(/\n/g," ").replace(/\r/g,"");
+ }
+
+ return sSearch;
+ }
+
+ /**
+ * Build a regular expression object suitable for searching a table
+ * @param {string} sSearch string to search for
+ * @param {bool} bRegex treat as a regular expression or not
+ * @param {bool} bSmart perform smart filtering or not
+ * @param {bool} bCaseInsensitive Do case insenstive matching or not
+ * @returns {RegExp} constructed object
+ * @memberof DataTable#oApi
+ */
+ function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive )
+ {
+ var asSearch, sRegExpString;
+
+ if ( bSmart )
+ {
+ /* Generate the regular expression to use. Something along the lines of:
+ * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$
+ */
+ asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' );
+ sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$';
+ return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" );
+ }
+ else
+ {
+ sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch );
+ return new RegExp( sSearch, bCaseInsensitive ? "i" : "" );
+ }
+ }
+
+
+ /**
+ * Convert raw data into something that the user can search on
+ * @param {string} sData data to be modified
+ * @param {string} sType data type
+ * @returns {string} search string
+ * @memberof DataTable#oApi
+ */
+ function _fnDataToSearch ( sData, sType )
+ {
+ if ( typeof DataTable.ext.ofnSearch[sType] === "function" )
+ {
+ return DataTable.ext.ofnSearch[sType]( sData );
+ }
+ else if ( sType == "html" )
+ {
+ return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" );
+ }
+ else if ( typeof sData === "string" )
+ {
+ return sData.replace(/[\r\n]/g," ");
+ }
+ else if ( sData === null )
+ {
+ return '';
+ }
+ return sData;
+ }
+
+
+ /**
+ * scape a string stuch that it can be used in a regular expression
+ * @param {string} sVal string to escape
+ * @returns {string} escaped string
+ * @memberof DataTable#oApi
+ */
+ function _fnEscapeRegex ( sVal )
+ {
+ var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^' ];
+ var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' );
+ return sVal.replace(reReplace, '\\$1');
+ }
+
+
+
+ /**
+ * Generate the node required for the info display
+ * @param {object} oSettings dataTables settings object
+ * @returns {node} Information element
+ * @memberof DataTable#oApi
+ */
+ function _fnFeatureHtmlInfo ( oSettings )
+ {
+ var nInfo = document.createElement( 'div' );
+ nInfo.className = oSettings.oClasses.sInfo;
+
+ /* Actions that are to be taken once only for this feature */
+ if ( !oSettings.aanFeatures.i )
+ {
+ /* Add draw callback */
+ oSettings.aoDrawCallback.push( {
+ "fn": _fnUpdateInfo,
+ "sName": "information"
+ } );
+
+ /* Add id */
+ nInfo.id = oSettings.sTableId+'_info';
+ }
+ oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' );
+
+ return nInfo;
+ }
+
+
+ /**
+ * Update the information elements in the display
+ * @param {object} oSettings dataTables settings object
+ * @memberof DataTable#oApi
+ */
+ function _fnUpdateInfo ( oSettings )
+ {
+ /* Show information about the table */
+ if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 )
+ {
+ return;
+ }
+
+ var
+ iStart = oSettings._iDisplayStart+1, iEnd = oSettings.fnDisplayEnd(),
+ iMax = oSettings.fnRecordsTotal(), iTotal = oSettings.fnRecordsDisplay(),
+ sStart = oSettings.fnFormatNumber( iStart ), sEnd = oSettings.fnFormatNumber( iEnd ),
+ sMax = oSettings.fnFormatNumber( iMax ), sTotal = oSettings.fnFormatNumber( iTotal ),
+ sOut;
+
+ /* When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
+ * internally
+ */
+ if ( oSettings.oScroll.bInfinite )
+ {
+ sStart = oSettings.fnFormatNumber( 1 );
+ }
+
+ if ( oSettings.fnRecordsDisplay() === 0 &&
+ oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() )
+ {
+ /* Empty record set */
+ sOut = oSettings.oLanguage.sInfoEmpty+ oSettings.oLanguage.sInfoPostFix;
+ }
+ else if ( oSettings.fnRecordsDisplay() === 0 )
+ {
+ /* Rmpty record set after filtering */
+ sOut = oSettings.oLanguage.sInfoEmpty +' '+
+ oSettings.oLanguage.sInfoFiltered.replace('_MAX_', sMax)+
+ oSettings.oLanguage.sInfoPostFix;
+ }
+ else if ( oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() )
+ {
+ /* Normal record set */
+ sOut = oSettings.oLanguage.sInfo.
+ replace('_START_', sStart).
+ replace('_END_', sEnd).
+ replace('_TOTAL_', sTotal)+
+ oSettings.oLanguage.sInfoPostFix;
+ }
+ else
+ {
+ /* Record set after filtering */
+ sOut = oSettings.oLanguage.sInfo.
+ replace('_START_', sStart).
+ replace('_END_', sEnd).
+ replace('_TOTAL_', sTotal) +' '+
+ oSettings.oLanguage.sInfoFiltered.replace('_MAX_',
+ oSettings.fnFormatNumber(oSettings.fnRecordsTotal()))+
+ oSettings.oLanguage.sInfoPostFix;
+ }
+
+ if ( oSettings.oLanguage.fnInfoCallback !== null )
+ {
+ sOut = oSettings.oLanguage.fnInfoCallback.call( oSettings.oInstance,
+ oSettings, iStart, iEnd, iMax, iTotal, sOut );
+ }
+
+ var n = oSettings.aanFeatures.i;
+ for ( var i=0, iLen=n.length ; i';
+ var i, iLen;
+ var aLengthMenu = oSettings.aLengthMenu;
+
+ if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' &&
+ typeof aLengthMenu[1] === 'object' )
+ {
+ for ( i=0, iLen=aLengthMenu[0].length ; i'+aLengthMenu[1][i]+'';
+ }
+ }
+ else
+ {
+ for ( i=0, iLen=aLengthMenu.length ; i'+aLengthMenu[i]+'';
+ }
+ }
+ sStdMenu += '';
+
+ var nLength = document.createElement( 'div' );
+ if ( !oSettings.aanFeatures.l )
+ {
+ nLength.id = oSettings.sTableId+'_length';
+ }
+ nLength.className = oSettings.oClasses.sLength;
+ nLength.innerHTML = '';
+
+ /*
+ * Set the length to the current display length - thanks to Andrea Pavlovic for this fix,
+ * and Stefan Skopnik for fixing the fix!
+ */
+ $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true);
+
+ $('select', nLength).bind( 'change.DT', function(e) {
+ var iVal = $(this).val();
+
+ /* Update all other length options for the new display */
+ var n = oSettings.aanFeatures.l;
+ for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length ||
+ oSettings._iDisplayLength == -1 )
+ {
+ oSettings._iDisplayEnd = oSettings.aiDisplay.length;
+ }
+ else
+ {
+ oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength;
+ }
+ }
+ }
+
+
+
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Section - Feature: Filtering
+ * Note that most of the paging logic is done in
+ * DataTable.ext.oPagination
*/
- /*
- * Function: _fnFeatureHtmlTable
- * Purpose: Add any control elements for the table - specifically scrolling
- * Returns: node: - Node to add to the DOM
- * Inputs: object:oSettings - dataTables settings object
+ /**
+ * Generate the node required for default pagination
+ * @param {object} oSettings dataTables settings object
+ * @returns {node} Pagination feature node
+ * @memberof DataTable#oApi
+ */
+ function _fnFeatureHtmlPaginate ( oSettings )
+ {
+ if ( oSettings.oScroll.bInfinite )
+ {
+ return null;
+ }
+
+ var nPaginate = document.createElement( 'div' );
+ nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType;
+
+ DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate,
+ function( oSettings ) {
+ _fnCalculateEnd( oSettings );
+ _fnDraw( oSettings );
+ }
+ );
+
+ /* Add a draw callback for the pagination on first instance, to update the paging display */
+ if ( !oSettings.aanFeatures.p )
+ {
+ oSettings.aoDrawCallback.push( {
+ "fn": function( oSettings ) {
+ DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) {
+ _fnCalculateEnd( oSettings );
+ _fnDraw( oSettings );
+ } );
+ },
+ "sName": "pagination"
+ } );
+ }
+ return nPaginate;
+ }
+
+
+ /**
+ * Alter the display settings to change the page
+ * @param {object} oSettings dataTables settings object
+ * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last"
+ * or page number to jump to (integer)
+ * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1
+ * @memberof DataTable#oApi
+ */
+ function _fnPageChange ( oSettings, mAction )
+ {
+ var iOldStart = oSettings._iDisplayStart;
+
+ if ( typeof mAction === "number" )
+ {
+ oSettings._iDisplayStart = mAction * oSettings._iDisplayLength;
+ if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() )
+ {
+ oSettings._iDisplayStart = 0;
+ }
+ }
+ else if ( mAction == "first" )
+ {
+ oSettings._iDisplayStart = 0;
+ }
+ else if ( mAction == "previous" )
+ {
+ oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ?
+ oSettings._iDisplayStart - oSettings._iDisplayLength :
+ 0;
+
+ /* Correct for underrun */
+ if ( oSettings._iDisplayStart < 0 )
+ {
+ oSettings._iDisplayStart = 0;
+ }
+ }
+ else if ( mAction == "next" )
+ {
+ if ( oSettings._iDisplayLength >= 0 )
+ {
+ /* Make sure we are not over running the display array */
+ if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() )
+ {
+ oSettings._iDisplayStart += oSettings._iDisplayLength;
+ }
+ }
+ else
+ {
+ oSettings._iDisplayStart = 0;
+ }
+ }
+ else if ( mAction == "last" )
+ {
+ if ( oSettings._iDisplayLength >= 0 )
+ {
+ var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1;
+ oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength;
+ }
+ else
+ {
+ oSettings._iDisplayStart = 0;
+ }
+ }
+ else
+ {
+ _fnLog( oSettings, 0, "Unknown paging action: "+mAction );
+ }
+ $(oSettings.oInstance).trigger('page', oSettings);
+
+ return iOldStart != oSettings._iDisplayStart;
+ }
+
+
+
+ /**
+ * Generate the node required for the processing node
+ * @param {object} oSettings dataTables settings object
+ * @returns {node} Processing element
+ * @memberof DataTable#oApi
+ */
+ function _fnFeatureHtmlProcessing ( oSettings )
+ {
+ var nProcessing = document.createElement( 'div' );
+
+ if ( !oSettings.aanFeatures.r )
+ {
+ nProcessing.id = oSettings.sTableId+'_processing';
+ }
+ nProcessing.innerHTML = oSettings.oLanguage.sProcessing;
+ nProcessing.className = oSettings.oClasses.sProcessing;
+ oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable );
+
+ return nProcessing;
+ }
+
+
+ /**
+ * Display or hide the processing indicator
+ * @param {object} oSettings dataTables settings object
+ * @param {bool} bShow Show the processing indicator (true) or not (false)
+ * @memberof DataTable#oApi
+ */
+ function _fnProcessingDisplay ( oSettings, bShow )
+ {
+ if ( oSettings.oFeatures.bProcessing )
+ {
+ var an = oSettings.aanFeatures.r;
+ for ( var i=0, iLen=an.length ; i
@@ -3950,16 +3029,17 @@
return nScroller;
}
- /*
- * Function: _fnScrollDraw
- * Purpose: Update the various tables for resizing
- * Returns: node: - Node to add to the DOM
- * Inputs: object:o - dataTables settings object
- * Notes: It's a bit of a pig this function, but basically the idea to:
+
+ /**
+ * Update the various tables for resizing. It's a bit of a pig this function, but
+ * basically the idea to:
* 1. Re-create the table inside the scrolling div
* 2. Take live measurements from the DOM
* 3. Apply the measurements
* 4. Clean up
+ * @param {object} o dataTables settings object
+ * @returns {node} Node to add to the DOM
+ * @memberof DataTable#oApi
*/
function _fnScrollDraw ( o )
{
@@ -3984,10 +3064,11 @@
o.nTable.removeChild( nTheadSize[0] );
}
+ var nTfootSize;
if ( o.nTFoot !== null )
{
/* Remove the old minimised footer element in the cloned header */
- var nTfootSize = o.nTable.getElementsByTagName('tfoot');
+ nTfootSize = o.nTable.getElementsByTagName('tfoot');
if ( nTfootSize.length > 0 )
{
o.nTable.removeChild( nTfootSize[0] );
@@ -4043,8 +3124,8 @@
* the scrollbar - which is shouldn't. When there is a scrollbar we need to take this
* into account.
*/
- if ( ie67 && (nScrollBody.scrollHeight >
- nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") )
+ if ( ie67 && ($('tbody', nScrollBody).height() > nScrollBody.offsetHeight ||
+ $(nScrollBody).css('overflow-y') == "scroll") )
{
o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth()-o.oScroll.iBarWidth );
}
@@ -4195,7 +3276,6 @@
/*
* 4. Clean up
*/
-
if ( o.oScroll.sY === "" )
{
/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting
@@ -4223,1315 +3303,59 @@
/* Finally set the width's of the header and footer tables */
var iOuterWidth = $(o.nTable).outerWidth();
nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth );
- nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth+o.oScroll.iBarWidth );
+ nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth );
if ( o.nTFoot !== null )
{
- nScrollFootInner.style.width = _fnStringToCss( o.nTable.offsetWidth+o.oScroll.iBarWidth );
+ nScrollFootInner.style.width = _fnStringToCss( o.nTable.offsetWidth );
nScrollFootTable.style.width = _fnStringToCss( o.nTable.offsetWidth );
}
- /* If sorting or filtering has occured, jump the scrolling back to the top */
+ /* If sorting or filtering has occurred, jump the scrolling back to the top */
if ( o.bSorted || o.bFiltered )
{
nScrollBody.scrollTop = 0;
}
}
- /*
- * Function: _fnAdjustColumnSizing
- * Purpose: Adjust the table column widths for new data
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
- * Notes: You would probably want to do a redraw after calling this function!
+
+ /**
+ * Apply a given function to the display child nodes of an element array (typically
+ * TD children of TR rows
+ * @param {function} fn Method to apply to the objects
+ * @param array {nodes} an1 List of elements to look through for display children
+ * @param array {nodes} an2 Another list (identical structure to the first) - optional
+ * @memberof DataTable#oApi
*/
- function _fnAdjustColumnSizing ( oSettings )
+ function _fnApplyToChildren( fn, an1, an2 )
{
- /* Not interested in doing column width calculation if autowidth is disabled */
- if ( oSettings.oFeatures.bAutoWidth === false )
+ for ( var i=0, iLen=an1.length ; i') :
- sSearchStr==="" ? '' : sSearchStr+' ';
-
- var nFilter = document.createElement( 'div' );
- nFilter.className = oSettings.oClasses.sFilter;
- nFilter.innerHTML = '';
- if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.f == "undefined" )
- {
- nFilter.setAttribute( 'id', oSettings.sTableId+'_filter' );
- }
-
- var jqFilter = $("input", nFilter);
- jqFilter.val( oSettings.oPreviousSearch.sSearch.replace('"','"') );
- jqFilter.bind( 'keyup.DT', function(e) {
- /* Update all other filter input elements for the new display */
- var n = oSettings.aanFeatures.f;
- for ( var i=0, iLen=n.length ; i=0 ; i-- )
- {
- var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ),
- oSettings.aoColumns[iColumn].sType );
- if ( ! rpSearch.test( sData ) )
- {
- oSettings.aiDisplay.splice( i, 1 );
- iIndexCorrector++;
- }
- }
- }
-
- /*
- * Function: _fnFilter
- * Purpose: Filter the data table based on user input and draw the table
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
- * string:sInput - string to filter on
- * int:iForce - optional - force a research of the master array (1) or not (undefined or 0)
- * bool:bRegex - treat as a regular expression or not
- * bool:bSmart - perform smart filtering or not
- */
- function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart )
- {
- var i;
- var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart );
-
- /* Check if we are forcing or not - optional parameter */
- if ( typeof iForce == 'undefined' || iForce === null )
- {
- iForce = 0;
- }
-
- /* Need to take account of custom filtering functions - always filter */
- if ( _oExt.afnFiltering.length !== 0 )
- {
- iForce = 1;
- }
-
- /*
- * If the input is blank - we want the full data set
- */
- if ( sInput.length <= 0 )
- {
- oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
- oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
- }
- else
- {
- /*
- * We are starting a new search or the new search string is smaller
- * then the old one (i.e. delete). Search from the master array
- */
- if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length ||
- oSettings.oPreviousSearch.sSearch.length > sInput.length || iForce == 1 ||
- sInput.indexOf(oSettings.oPreviousSearch.sSearch) !== 0 )
- {
- /* Nuke the old display array - we are going to rebuild it */
- oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length);
-
- /* Force a rebuild of the search array */
- _fnBuildSearchArray( oSettings, 1 );
-
- /* Search through all records to populate the search array
- * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1
- * mapping
- */
- for ( i=0 ; i tag - remove it */
- sSearch = sSearch.replace(/\n/g," ").replace(/\r/g,"");
- }
-
- return sSearch;
- }
-
- /*
- * Function: _fnFilterCreateSearch
- * Purpose: Build a regular expression object suitable for searching a table
- * Returns: RegExp: - constructed object
- * Inputs: string:sSearch - string to search for
- * bool:bRegex - treat as a regular expression or not
- * bool:bSmart - perform smart filtering or not
- */
- function _fnFilterCreateSearch( sSearch, bRegex, bSmart )
- {
- var asSearch, sRegExpString;
-
- if ( bSmart )
- {
- /* Generate the regular expression to use. Something along the lines of:
- * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$
- */
- asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' );
- sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$';
- return new RegExp( sRegExpString, "i" );
- }
- else
- {
- sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch );
- return new RegExp( sSearch, "i" );
- }
- }
-
- /*
- * Function: _fnDataToSearch
- * Purpose: Convert raw data into something that the user can search on
- * Returns: string: - search string
- * Inputs: string:sData - data to be modified
- * string:sType - data type
- */
- function _fnDataToSearch ( sData, sType )
- {
- if ( typeof _oExt.ofnSearch[sType] == "function" )
- {
- return _oExt.ofnSearch[sType]( sData );
- }
- else if ( sType == "html" )
- {
- return sData.replace(/\n/g," ").replace( /<.*?>/g, "" );
- }
- else if ( typeof sData == "string" )
- {
- return sData.replace(/\n/g," ");
- }
- else if ( sData === null )
- {
- return '';
- }
- return sData;
- }
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Section - Feature: Sorting
- */
-
- /*
- * Function: _fnSort
- * Purpose: Change the order of the table
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
- * bool:bApplyClasses - optional - should we apply classes or not
- * Notes: We always sort the master array and then apply a filter again
- * if it is needed. This probably isn't optimal - but atm I can't think
- * of any other way which is (each has disadvantages). we want to sort aiDisplayMaster -
- * but according to aoData[]._aData
- */
- function _fnSort ( oSettings, bApplyClasses )
- {
- var
- iDataSort, iDataType,
- i, iLen, j, jLen,
- aaSort = [],
- aiOrig = [],
- oSort = _oExt.oSort,
- aoData = oSettings.aoData,
- aoColumns = oSettings.aoColumns;
-
- /* No sorting required if server-side or no sorting array */
- if ( !oSettings.oFeatures.bServerSide &&
- (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) )
- {
- if ( oSettings.aaSortingFixed !== null )
- {
- aaSort = oSettings.aaSortingFixed.concat( oSettings.aaSorting );
- }
- else
- {
- aaSort = oSettings.aaSorting.slice();
- }
-
- /* If there is a sorting data type, and a fuction belonging to it, then we need to
- * get the data from the developer's function and apply it for this column
- */
- for ( i=0 ; i= iColumns )
- {
- for ( i=0 ; i=0 ?
- oSettings._iDisplayStart - oSettings._iDisplayLength :
- 0;
-
- /* Correct for underrun */
- if ( oSettings._iDisplayStart < 0 )
- {
- oSettings._iDisplayStart = 0;
- }
- }
- else if ( sAction == "next" )
- {
- if ( oSettings._iDisplayLength >= 0 )
- {
- /* Make sure we are not over running the display array */
- if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() )
- {
- oSettings._iDisplayStart += oSettings._iDisplayLength;
- }
- }
- else
- {
- oSettings._iDisplayStart = 0;
- }
- }
- else if ( sAction == "last" )
- {
- if ( oSettings._iDisplayLength >= 0 )
- {
- var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1;
- oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength;
- }
- else
- {
- oSettings._iDisplayStart = 0;
- }
- }
- else
- {
- _fnLog( oSettings, 0, "Unknown paging action: "+sAction );
- }
- $(oSettings.oInstance).trigger('page', oSettings);
-
- return iOldStart != oSettings._iDisplayStart;
- }
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Section - Feature: HTML info
- */
-
- /*
- * Function: _fnFeatureHtmlInfo
- * Purpose: Generate the node required for the info display
- * Returns: node
- * Inputs: object:oSettings - dataTables settings object
- */
- function _fnFeatureHtmlInfo ( oSettings )
- {
- var nInfo = document.createElement( 'div' );
- nInfo.className = oSettings.oClasses.sInfo;
-
- /* Actions that are to be taken once only for this feature */
- if ( typeof oSettings.aanFeatures.i == "undefined" )
- {
- /* Add draw callback */
- oSettings.aoDrawCallback.push( {
- "fn": _fnUpdateInfo,
- "sName": "information"
- } );
-
- /* Add id */
- if ( oSettings.sTableId !== '' )
- {
- nInfo.setAttribute( 'id', oSettings.sTableId+'_info' );
- }
- }
-
- return nInfo;
- }
-
- /*
- * Function: _fnUpdateInfo
- * Purpose: Update the information elements in the display
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
- */
- function _fnUpdateInfo ( oSettings )
- {
- /* Show information about the table */
- if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 )
- {
- return;
- }
-
- var
- iStart = oSettings._iDisplayStart+1, iEnd = oSettings.fnDisplayEnd(),
- iMax = oSettings.fnRecordsTotal(), iTotal = oSettings.fnRecordsDisplay(),
- sStart = oSettings.fnFormatNumber( iStart ), sEnd = oSettings.fnFormatNumber( iEnd ),
- sMax = oSettings.fnFormatNumber( iMax ), sTotal = oSettings.fnFormatNumber( iTotal ),
- sOut;
-
- /* When infinite scrolling, we are always starting at 1. _iDisplayStart is used only
- * internally
- */
- if ( oSettings.oScroll.bInfinite )
- {
- sStart = oSettings.fnFormatNumber( 1 );
- }
-
- if ( oSettings.fnRecordsDisplay() === 0 &&
- oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() )
- {
- /* Empty record set */
- sOut = oSettings.oLanguage.sInfoEmpty+ oSettings.oLanguage.sInfoPostFix;
- }
- else if ( oSettings.fnRecordsDisplay() === 0 )
- {
- /* Rmpty record set after filtering */
- sOut = oSettings.oLanguage.sInfoEmpty +' '+
- oSettings.oLanguage.sInfoFiltered.replace('_MAX_', sMax)+
- oSettings.oLanguage.sInfoPostFix;
- }
- else if ( oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() )
- {
- /* Normal record set */
- sOut = oSettings.oLanguage.sInfo.
- replace('_START_', sStart).
- replace('_END_', sEnd).
- replace('_TOTAL_', sTotal)+
- oSettings.oLanguage.sInfoPostFix;
- }
- else
- {
- /* Record set after filtering */
- sOut = oSettings.oLanguage.sInfo.
- replace('_START_', sStart).
- replace('_END_', sEnd).
- replace('_TOTAL_', sTotal) +' '+
- oSettings.oLanguage.sInfoFiltered.replace('_MAX_',
- oSettings.fnFormatNumber(oSettings.fnRecordsTotal()))+
- oSettings.oLanguage.sInfoPostFix;
- }
-
- if ( oSettings.oLanguage.fnInfoCallback !== null )
- {
- sOut = oSettings.oLanguage.fnInfoCallback( oSettings, iStart, iEnd, iMax, iTotal, sOut );
- }
-
- var n = oSettings.aanFeatures.i;
- for ( var i=0, iLen=n.length ; i';
- var i, iLen;
-
- if ( oSettings.aLengthMenu.length == 2 && typeof oSettings.aLengthMenu[0] == 'object' &&
- typeof oSettings.aLengthMenu[1] == 'object' )
- {
- for ( i=0, iLen=oSettings.aLengthMenu[0].length ; i'+
- oSettings.aLengthMenu[1][i]+'';
- }
- }
- else
- {
- for ( i=0, iLen=oSettings.aLengthMenu.length ; i'+
- oSettings.aLengthMenu[i]+'';
- }
- }
- sStdMenu += '';
-
- var nLength = document.createElement( 'div' );
- if ( oSettings.sTableId !== '' && typeof oSettings.aanFeatures.l == "undefined" )
- {
- nLength.setAttribute( 'id', oSettings.sTableId+'_length' );
- }
- nLength.className = oSettings.oClasses.sLength;
- nLength.innerHTML = '';
-
- /*
- * Set the length to the current display length - thanks to Andrea Pavlovic for this fix,
- * and Stefan Skopnik for fixing the fix!
- */
- $('select option[value="'+oSettings._iDisplayLength+'"]',nLength).attr("selected",true);
-
- $('select', nLength).bind( 'change.DT', function(e) {
- var iVal = $(this).val();
-
- /* Update all other length options for the new display */
- var n = oSettings.aanFeatures.l;
- for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length ||
- oSettings._iDisplayLength == -1 )
- {
- oSettings._iDisplayEnd = oSettings.aiDisplay.length;
- }
- else
- {
- oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength;
- }
- }
- }
-
- /*
- * Function: _fnConvertToWidth
- * Purpose: Convert a CSS unit width to pixels (e.g. 2em)
- * Returns: int:iWidth - width in pixels
- * Inputs: string:sWidth - width to be converted
- * node:nParent - parent to get the with for (required for
- * relative widths) - optional
+ /**
+ * Convert a CSS unit width to pixels (e.g. 2em)
+ * @param {string} sWidth width to be converted
+ * @param {node} nParent parent to get the with for (required for relative widths) - optional
+ * @returns {int} iWidth width in pixels
+ * @memberof DataTable#oApi
*/
function _fnConvertToWidth ( sWidth, nParent )
{
@@ -5540,7 +3364,7 @@
return 0;
}
- if ( typeof nParent == "undefined" )
+ if ( !nParent )
{
nParent = document.getElementsByTagName('body')[0];
}
@@ -5556,11 +3380,11 @@
return ( iWidth );
}
- /*
- * Function: _fnCalculateColumnWidths
- * Purpose: Calculate the width of columns for the table
- * Returns: -
- * Inputs: object:oSettings - dataTables settings object
+
+ /**
+ * Calculate the width of columns for the table
+ * @param {object} oSettings dataTables settings object
+ * @memberof DataTable#oApi
*/
function _fnCalculateColumnWidths ( oSettings )
{
@@ -5571,6 +3395,7 @@
var iColums = oSettings.aoColumns.length;
var i, iIndex, iCorrector, iWidth;
var oHeaders = $('th', oSettings.nTHead);
+ var widthAttr = oSettings.nTable.getAttribute('width');
/* Convert any user input sizes into pixel sizes */
for ( i=0 ; itd', nCalcTmp);
}
-
+
/* Apply custom sizing to the cloned header */
var nThs = _fnGetUniqueThs( oSettings, nTheadClone );
iCorrector = 0;
@@ -5662,7 +3487,7 @@
iCorrector++;
}
}
-
+
/* Find the biggest td for each column and put it into the table */
for ( i=0 ; i iTarget )
- {
- a[i]--;
- }
- }
-
- if ( iTargetIndex != -1 )
- {
- a.splice( iTargetIndex, 1 );
- }
- }
-
- /*
- * Function: _fnReOrderIndex
- * Purpose: Figure out how to reorder a display list
- * Returns: array int:aiReturn - index list for reordering
- * Inputs: object:oSettings - dataTables settings object
- */
- function _fnReOrderIndex ( oSettings, sColumns )
- {
- var aColumns = sColumns.split(',');
- var aiReturn = [];
-
- for ( var i=0, iLen=oSettings.aoColumns.length ; i 4096 ) /* Magic 10 for padding */
- {
- var aCookies =document.cookie.split(';');
- for ( var i=0, iLen=aCookies.length ; i 0 && aaSort[0][0] == i )
+ {
+ nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" );
+
+ var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ?
+ aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0];
+ nTh.setAttribute('aria-label', aoColumns[i].sTitle+
+ (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
+ }
+ else
+ {
+ nTh.setAttribute('aria-label', aoColumns[i].sTitle+
+ (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) );
+ }
+ }
+ else
+ {
+ nTh.setAttribute('aria-label', aoColumns[i].sTitle);
+ }
+ }
+
+ /* Tell the draw function that we have sorted the data */
+ oSettings.bSorted = true;
+ $(oSettings.oInstance).trigger('sort', oSettings);
+
+ /* Copy the master data into the draw array and re-draw */
+ if ( oSettings.oFeatures.bFilter )
+ {
+ /* _fnFilter() will redraw the table for us */
+ _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 );
+ }
+ else
+ {
+ oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
+ oSettings._iDisplayStart = 0; /* reset display back to page 0 */
+ _fnCalculateEnd( oSettings );
+ _fnDraw( oSettings );
+ }
+ }
+
+
+ /**
+ * Attach a sort handler (click) to a node
+ * @param {object} oSettings dataTables settings object
+ * @param {node} nNode node to attach the handler to
+ * @param {int} iDataIndex column sorting index
+ * @param {function} [fnCallback] callback function
+ * @memberof DataTable#oApi
+ */
+ function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback )
+ {
+ _fnBindAction( nNode, {}, function (e) {
+ /* If the column is not sortable - don't to anything */
+ if ( oSettings.aoColumns[iDataIndex].bSortable === false )
+ {
+ return;
+ }
+
+ /*
+ * This is a little bit odd I admit... I declare a temporary function inside the scope of
+ * _fnBuildHead and the click handler in order that the code presented here can be used
+ * twice - once for when bProcessing is enabled, and another time for when it is
+ * disabled, as we need to perform slightly different actions.
+ * Basically the issue here is that the Javascript engine in modern browsers don't
+ * appear to allow the rendering engine to update the display while it is still excuting
+ * it's thread (well - it does but only after long intervals). This means that the
+ * 'processing' display doesn't appear for a table sort. To break the js thread up a bit
+ * I force an execution break by using setTimeout - but this breaks the expected
+ * thread continuation for the end-developer's point of view (their code would execute
+ * too early), so we on;y do it when we absolutely have to.
+ */
+ var fnInnerSorting = function () {
+ var iColumn, iNextSort;
+
+ /* If the shift key is pressed then we are multipe column sorting */
+ if ( e.shiftKey )
+ {
+ /* Are we already doing some kind of sort on this column? */
+ var bFound = false;
+ for ( var i=0 ; i= iColumns )
+ {
+ for ( i=0 ; i 4096 ) /* Magic 10 for padding */
+ {
+ var aCookies =document.cookie.split(';');
+ for ( var i=0, iLen=aCookies.length ; i=0 ; i-- )
{
- /* Give an empty string for rendering / sorting etc */
- return function (data) {
- return null;
- };
+ aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) );
}
- else if ( typeof mSource == 'function' )
+
+ if ( sTrigger !== null )
{
- return function (data) {
- return mSource( data );
- };
+ $(oSettings.oInstance).trigger(sTrigger, aArgs);
}
- else if ( typeof mSource == 'string' && mSource.indexOf('.') != -1 )
+
+ return aRet;
+ }
+
+
+ /**
+ * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other
+ * library, then we use that as it is fast, safe and accurate. If the function isn't
+ * available then we need to built it ourselves - the insperation for this function comes
+ * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is
+ * not perfect and absolutely should not be used as a replacement to json2.js - but it does
+ * do what we need, without requiring a dependency for DataTables.
+ * @param {object} o JSON object to be converted
+ * @returns {string} JSON string
+ * @memberof DataTable#oApi
+ */
+ var _fnJsonString = (window.JSON) ? JSON.stringify : function( o )
+ {
+ /* Not an object or array */
+ var sType = typeof o;
+ if (sType !== "object" || o === null)
{
- /* If there is a . in the source string then the data source is in a nested object
- * we provide two 'quick' functions for the look up to speed up the most common
- * operation, and a generalised one for when it is needed
- */
- var a = mSource.split('.');
- if ( a.length == 2 )
+ // simple data type
+ if (sType === "string")
{
- return function (data) {
- return data[ a[0] ][ a[1] ];
- };
+ o = '"'+o+'"';
}
- else if ( a.length == 3 )
+ return o+"";
+ }
+
+ /* If object or array, need to recurse over it */
+ var
+ sProp, mValue,
+ json = [],
+ bArr = $.isArray(o);
+
+ for (sProp in o)
+ {
+ mValue = o[sProp];
+ sType = typeof mValue;
+
+ if (sType === "string")
{
- return function (data) {
- return data[ a[0] ][ a[1] ][ a[2] ];
- };
+ mValue = '"'+mValue+'"';
}
- else
+ else if (sType === "object" && mValue !== null)
{
- return function (data) {
- for ( var i=0, iLen=a.length ; i
+ *
1D array of data - add a single row with the data provided
+ *
2D array of arrays - add multiple rows in a single call
+ *
object - data object when using mDataProp
+ *
array of objects - multiple data objects when using mDataProp
+ *
+ * @param {bool} [bRedraw=true] redraw the table or not
+ * @returns {array} An array of integers, representing the list of indexes in
+ * aoData ({@link DataTable.models.oSettings}) that have been added to
+ * the table.
+ * @dtopt API
+ *
+ * @example
+ * // Global var for counter
+ * var giCount = 2;
+ *
+ * $(document).ready(function() {
+ * $('#example').dataTable();
+ * } );
+ *
+ * function fnClickAddRow() {
+ * $('#example').dataTable().fnAddData( [
+ * giCount+".1",
+ * giCount+".2",
+ * giCount+".3",
+ * giCount+".4" ]
+ * );
+ *
+ * giCount++;
+ * }
+ */
+ this.fnAddData = function( mData, bRedraw )
+ {
+ if ( mData.length === 0 )
{
- return function (data, val) {
- return mSource( data, val );
- };
+ return [];
}
- else if ( typeof mSource == 'string' && mSource.indexOf('.') != -1 )
+
+ var aiReturn = [];
+ var iTest;
+
+ /* Find settings from table node */
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
+
+ /* Check if we want to add multiple rows or not */
+ if ( typeof mData[0] === "object" && mData[0] !== null )
{
- /* Like the get, we need to get data from a nested object. Again two fast lookup
- * functions are provided, and a generalised one.
- */
- var a = mSource.split('.');
- if ( a.length == 2 )
+ for ( var i=0 ; i= oSettings.aiDisplay.length )
+ {
+ oSettings._iDisplayStart -= oSettings._iDisplayLength;
+ if ( oSettings._iDisplayStart < 0 )
+ {
+ oSettings._iDisplayStart = 0;
+ }
+ }
+
+ if ( bRedraw === undefined || bRedraw )
+ {
+ _fnCalculateEnd( oSettings );
+ _fnDraw( oSettings );
+ }
+
+ return oData;
+ };
+
+
+ /**
+ * Restore the table to it's original state in the DOM by removing all of DataTables
+ * enhancements, alterations to the DOM structure of the table and event listeners.
+ * @param {boolean} [bRemove=false] Completely remove the table from the DOM
+ * @dtopt API
+ *
+ * @example
+ * $(document).ready(function() {
+ * // This example is fairly pointless in reality, but shows how fnDestroy can be used
+ * var oTable = $('#example').dataTable();
+ * oTable.fnDestroy();
+ * } );
+ */
+ this.fnDestroy = function ( bRemove )
+ {
+ var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] );
+ var nOrig = oSettings.nTableWrapper.parentNode;
+ var nBody = oSettings.nTBody;
+ var i, iLen;
+
+ bRemove = (bRemove===undefined) ? false : true;
+
+ /* Flag to note that the table is currently being destroyed - no action should be taken */
+ oSettings.bDestroying = true;
+
+ /* Restore hidden columns */
+ for ( i=0, iLen=oSettings.aoDestroyCallback.length ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove();
+
+ /* When scrolling we had to break the table up - restore it */
+ if ( oSettings.nTable != oSettings.nTHead.parentNode )
+ {
+ $(oSettings.nTable).children('thead').remove();
+ oSettings.nTable.appendChild( oSettings.nTHead );
+ }
+
+ if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode )
+ {
+ $(oSettings.nTable).children('tfoot').remove();
+ oSettings.nTable.appendChild( oSettings.nTFoot );
+ }
+
+ /* Remove the DataTables generated nodes, events and classes */
+ oSettings.nTable.parentNode.removeChild( oSettings.nTable );
+ $(oSettings.nTableWrapper).remove();
+
+ oSettings.aaSorting = [];
+ oSettings.aaSortingFixed = [];
+ _fnSortingClasses( oSettings );
+
+ $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') );
+
+ $('th, td', oSettings.nTHead).removeClass( [
+ oSettings.oClasses.sSortable,
+ oSettings.oClasses.sSortableAsc,
+ oSettings.oClasses.sSortableDesc,
+ oSettings.oClasses.sSortableNone ].join(' ')
+ );
+ if ( oSettings.bJUI )
+ {
+ $('th span.'+oSettings.oClasses.sSortIcon
+ + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove();
+
+ $('th, td', oSettings.nTHead).each( function () {
+ var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this);
+ var kids = jqWrapper.contents();
+ $(this).append( kids );
+ jqWrapper.remove();
+ } );
+ }
+
+ /* Add the TR elements back into the table in their original order */
+ if ( !bRemove && oSettings.nTableReinsertBefore )
+ {
+ nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore );
+ }
+ else if ( !bRemove )
+ {
+ nOrig.appendChild( oSettings.nTable );
+ }
+
+ for ( i=0, iLen=oSettings.aoData.length ; i= _fnVisbleColumns( oSettings ));
+
+ /* Which coloumn should we be inserting before? */
+ if ( !bAppend )
+ {
+ for ( i=iCol ; i=0 ; i-- )
- {
- /* Each column def can target multiple columns, as it is an array */
- var aTargets = oInit.aoColumnDefs[i].aTargets;
- if ( !$.isArray( aTargets ) )
- {
- _fnLog( oSettings, 1, 'aTargets must be an array of targets, not a '+(typeof aTargets) );
- }
- for ( j=0, jLen=aTargets.length ; j= 0 )
- {
- /* 0+ integer, left to right column counting. We add columns which are unknown
- * automatically. Is this the right behaviour for this? We should at least
- * log it in future. We cannot do this for the negative or class targets, only here.
- */
- while( oSettings.aoColumns.length <= aTargets[j] )
- {
- _fnAddColumn( oSettings );
- }
- _fnColumnOptions( oSettings, aTargets[j], oInit.aoColumnDefs[i] );
- }
- else if ( typeof aTargets[j] == 'number' && aTargets[j] < 0 )
- {
- /* Negative integer, right to left column counting */
- _fnColumnOptions( oSettings, oSettings.aoColumns.length+aTargets[j],
- oInit.aoColumnDefs[i] );
- }
- else if ( typeof aTargets[j] == 'string' )
- {
- /* Class name matching on TH element */
- for ( k=0, kLen=oSettings.aoColumns.length ; k 0 )
@@ -7435,6 +6531,5082 @@
{
_fnInitialise( oSettings );
}
- });
+ } );
};
-})(jQuery, window, document);
+
+ /**
+ * Version string for plug-ins to check compatibility. Allowed format is
+ * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
+ * e are optional
+ * @member
+ * @type string
+ * @default Version number
+ */
+ DataTable.version = "1.9.0";
+
+ /**
+ * Private data store, containing all of the settings objects that are created for the
+ * tables on a given page.
+ *
+ * Note that the DataTable.settings object is aliased to jQuery.fn.dataTableExt
+ * through which it may be accessed and manipulated, or jQuery.fn.dataTable.settings.
+ * @member
+ * @type array
+ * @default []
+ * @private
+ */
+ DataTable.settings = [];
+
+ /**
+ * Object models container, for the various models that DataTables has available
+ * to it. These models define the objects that are used to hold the active state
+ * and configuration of the table.
+ * @namespace
+ */
+ DataTable.models = {};
+
+
+ /**
+ * DataTables extension options and plug-ins. This namespace acts as a collection "area"
+ * for plug-ins that can be used to extend the default DataTables behaviour - indeed many
+ * of the build in methods use this method to provide their own capabilities (sorting methods
+ * for example).
+ *
+ * Note that this namespace is aliased to jQuery.fn.dataTableExt so it can be readily accessed
+ * and modified by plug-ins.
+ * @namespace
+ */
+ DataTable.models.ext = {
+ /**
+ * Plug-in filtering functions - this method of filtering is complimentary to the default
+ * type based filtering, and a lot more comprehensive as it allows you complete control
+ * over the filtering logic. Each element in this array is a function (parameters
+ * described below) that is called for every row in the table, and your logic decides if
+ * it should be included in the filtered data set or not.
+ *
+ *
+ * Function input parameters:
+ *
+ *
{object} DataTables settings object: see {@link DataTable.models.oSettings}.
+ *
{array|object} Data for the row to be processed (same as the original format
+ * that was passed in as the data source, or an array from a DOM data source
+ *
{int} Row index in aoData ({@link DataTable.models.oSettings.aoData}), which can
+ * be useful to retrieve the TR element if you need DOM interaction.
+ *
+ *
+ *
+ * Function return:
+ *
+ *
{boolean} Include the row in the filtered result set (true) or not (false)
+ *
+ *
+ *
+ * @type array
+ * @default []
+ *
+ * @example
+ * // The following example shows custom filtering being applied to the fourth column (i.e.
+ * // the aData[3] index) based on two input values from the end-user, matching the data in
+ * // a certain range.
+ * $.fn.dataTableExt.afnFiltering.push(
+ * function( oSettings, aData, iDataIndex ) {
+ * var iMin = document.getElementById('min').value * 1;
+ * var iMax = document.getElementById('max').value * 1;
+ * var iVersion = aData[3] == "-" ? 0 : aData[3]*1;
+ * if ( iMin == "" && iMax == "" ) {
+ * return true;
+ * }
+ * else if ( iMin == "" && iVersion < iMax ) {
+ * return true;
+ * }
+ * else if ( iMin < iVersion && "" == iMax ) {
+ * return true;
+ * }
+ * else if ( iMin < iVersion && iVersion < iMax ) {
+ * return true;
+ * }
+ * return false;
+ * }
+ * );
+ */
+ "afnFiltering": [],
+
+
+ /**
+ * Plug-in sorting functions - this method of sorting is complimentary to the default type
+ * based sorting that DataTables does automatically, allowing much greater control over the
+ * the data that is being used to sort a column. This is useful if you want to do sorting
+ * based on live data (for example the contents of an 'input' element) rather than just the
+ * static string that DataTables knows of. The way these plug-ins work is that you create
+ * an array of the values you wish to be sorted for the column in question and then return
+ * that array. Which pre-sorting function is run here depends on the sSortDataType parameter
+ * that is used for the column (if any). This is the corollary of ofnSearch for sort
+ * data.
+ *
+ *
+ * Function input parameters:
+ *
+ *
{object} DataTables settings object: see {@link DataTable.models.oSettings}.
+ *
{int} Target column index
+ *
+ *
+ *
+ * Function return:
+ *
+ *
{array} Data for the column to be sorted upon
+ *
+ *
+ *
+ *
+ * Note that as of v1.9, it is typically preferable to use mDataProp to prepare data for
+ * the different uses that DataTables can put the data to. Specifically mDataProp when
+ * used as a function will give you a 'type' (sorting, filtering etc) that you can use to
+ * prepare the data as required for the different types. As such, this method is deprecated.
+ * @type array
+ * @default []
+ * @deprecated
+ *
+ * @example
+ * // Updating the cached sorting information with user entered values in HTML input elements
+ * jQuery.fn.dataTableExt.afnSortData['dom-text'] = function ( oSettings, iColumn )
+ * {
+ * var aData = [];
+ * $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () {
+ * aData.push( this.value );
+ * } );
+ * return aData;
+ * }
+ */
+ "afnSortData": [],
+
+
+ /**
+ * Feature plug-ins - This is an array of objects which describe the feature plug-ins that are
+ * available to DataTables. These feature plug-ins are accessible through the sDom initialisation
+ * option. As such, each feature plug-in must describe a function that is used to initialise
+ * itself (fnInit), a character so the feature can be enabled by sDom (cFeature) and the name
+ * of the feature (sFeature). Thus the objects attached to this method must provide:
+ *
+ *
{function} fnInit Initialisation of the plug-in
+ *
+ *
+ * Function input parameters:
+ *
+ *
{object} DataTables settings object: see {@link DataTable.models.oSettings}.
+ *
+ *
+ *
+ * Function return:
+ *
+ *
{node|null} The element which contains your feature. Note that the return
+ * may also be void if your plug-in does not require to inject any DOM elements
+ * into DataTables control (sDom) - for example this might be useful when
+ * developing a plug-in which allows table control via keyboard entry.
+ *
+ *
+ *
+ *
+ *
{character} cFeature Character that will be matched in sDom - case sensitive
+ *
{string} sFeature Feature name
+ *
+ * @type array
+ * @default []
+ *
+ * @example
+ * // How TableTools initialises itself.
+ * $.fn.dataTableExt.aoFeatures.push( {
+ * "fnInit": function( oSettings ) {
+ * return new TableTools( { "oDTSettings": oSettings } );
+ * },
+ * "cFeature": "T",
+ * "sFeature": "TableTools"
+ * } );
+ */
+ "aoFeatures": [],
+
+
+ /**
+ * Type detection plug-in functions - DataTables utilises types to define how sorting and
+ * filtering behave, and types can be either be defined by the developer (sType for the
+ * column) or they can be automatically detected by the methods in this array. The functions
+ * defined in the array are quite simple, taking a single parameter (the data to analyse)
+ * and returning the type if it is a known type, or null otherwise.
+ *
+ *
+ * Function input parameters:
+ *
+ *
{*} Data from the column cell to be analysed
+ *
+ *
+ *
+ * Function return:
+ *
+ *
{string|null} Data type detected, or null if unknown (and thus pass it
+ * on to the other type detection functions.
+ *
+ *
+ *
+ * @type array
+ * @default []
+ *
+ * @example
+ * // Currency type detection plug-in:
+ * jQuery.fn.dataTableExt.aTypes.push(
+ * function ( sData ) {
+ * var sValidChars = "0123456789.-";
+ * var Char;
+ *
+ * // Check the numeric part
+ * for ( i=1 ; i= parseInt(sThat, 10);
+ },
+
+
+ /**
+ * Index for what 'this' index API functions should use
+ * @type int
+ * @default 0
+ */
+ "iApiIndex": 0,
+
+
+ /**
+ * Pre-processing of filtering data plug-ins - When you assign the sType for a column
+ * (or have it automatically detected for you by DataTables or a type detection plug-in),
+ * you will typically be using this for custom sorting, but it can also be used to provide
+ * custom filtering by allowing you to pre-processing the data and returning the data in
+ * the format that should be filtered upon. This is done by adding functions this object
+ * with a parameter name which matches the sType for that target column. This is the
+ * corollary of afnSortData for filtering data.
+ *
+ *
+ * Function input parameters:
+ *
+ *
{*} Data from the column cell to be prepared for filtering
+ *
+ *
+ *
+ * Function return:
+ *
+ *
{string|null} Formatted string that will be used for the filtering.
+ *
+ *
+ *
+ *
+ * Note that as of v1.9, it is typically preferable to use mDataProp to prepare data for
+ * the different uses that DataTables can put the data to. Specifically mDataProp when
+ * used as a function will give you a 'type' (sorting, filtering etc) that you can use to
+ * prepare the data as required for the different types. As such, this method is deprecated.
+ * @type object
+ * @default {}
+ * @deprecated
+ *
+ * @example
+ * $.fn.dataTableExt.ofnSearch['title-numeric'] = function ( sData ) {
+ * return sData.replace(/\n/g," ").replace( /<.*?>/g, "" );
+ * }
+ */
+ "ofnSearch": {},
+
+
+ /**
+ * Container for all private functions in DataTables so they can be exposed externally
+ * @type object
+ * @default {}
+ */
+ "oApi": {},
+
+
+ /**
+ * Storage for the various classes that DataTables uses
+ * @type object
+ * @default {}
+ */
+ "oStdClasses": {},
+
+
+ /**
+ * Storage for the various classes that DataTables uses - jQuery UI suitable
+ * @type object
+ * @default {}
+ */
+ "oJUIClasses": {},
+
+
+ /**
+ * Pagination plug-in methods - The style and controls of the pagination can significantly
+ * impact on how the end user interacts with the data in your table, and DataTables allows
+ * the addition of pagination controls by extending this object, which can then be enabled
+ * through the sPaginationType initialisation parameter. Each pagination type that
+ * is added is an object (the property name of which is what sPaginationType refers
+ * to) that has two properties, both methods that are used by DataTables to update the
+ * control's state.
+ *
+ *
+ * fnInit - Initialisation of the paging controls. Called only during initialisation
+ * of the table. It is expected that this function will add the required DOM elements
+ * to the page for the paging controls to work. The element pointer
+ * 'oSettings.aanFeatures.p' array is provided by DataTables to contain the paging
+ * controls (note that this is a 2D array to allow for multiple instances of each
+ * DataTables DOM element). It is suggested that you add the controls to this element
+ * as children
+ *
+ *
+ * Function input parameters:
+ *
+ *
{object} DataTables settings object: see {@link DataTable.models.oSettings}.
+ *
{node} Container into which the pagination controls must be inserted
+ *
{function} Draw callback function - whenever the controls cause a page
+ * change, this method must be called to redraw the table.
+ *
+ *
+ *
+ * Function return:
+ *
+ *
No return required
+ *
+ *
+ *
+ *
+ *
+ * fnInit - This function is called whenever the paging status of the table changes and is
+ * typically used to update classes and/or text of the paging controls to reflex the new
+ * status.
+ *
+ *
+ * Function input parameters:
+ *
+ *
{object} DataTables settings object: see {@link DataTable.models.oSettings}.
+ *
{function} Draw callback function - in case you need to redraw the table again
+ * or attach new event listeners
{int} Sorting match: <0 if first parameter should be sorted lower than
+ * the second parameter, ===0 if the two parameters are equal and >0 if
+ * the first parameter should be sorted height than the second parameter.
+ *
+ *
+ *
+ * @type object
+ * @default {}
+ *
+ * @example
+ * // Case-sensitive string sorting, with no pre-formatting method
+ * $.extend( $.fn.dataTableExt.oSort, {
+ * "string-case-asc": function(x,y) {
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+ * },
+ * "string-case-desc": function(x,y) {
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
+ * }
+ * } );
+ *
+ * @example
+ * // Case-insensitive string sorting, with pre-formatting
+ * $.extend( $.fn.dataTableExt.oSort, {
+ * "string-pre": function(x) {
+ * return x.toLowerCase();
+ * },
+ * "string-asc": function(x,y) {
+ * return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+ * },
+ * "string-desc": function(x,y) {
+ * return ((x < y) ? 1 : ((x > y) ? -1 : 0));
+ * }
+ * } );
+ */
+ "oSort": {},
+
+
+ /**
+ * Version string for plug-ins to check compatibility. Allowed format is
+ * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and
+ * e are optional
+ * @type string
+ * @default Version number
+ */
+ "sVersion": DataTable.version,
+
+
+ /**
+ * How should DataTables report an error. Can take the value 'alert' or 'throw'
+ * @type string
+ * @default alert
+ */
+ "sErrMode": "alert",
+
+
+ /**
+ * Store information for DataTables to access globally about other instances
+ * @namespace
+ * @private
+ */
+ "_oExternConfig": {
+ /* int:iNextUnique - next unique number for an instance */
+ "iNextUnique": 0
+ }
+ };
+
+
+
+
+ /**
+ * Template object for the way in which DataTables holds information about
+ * search information for the global filter and individual column filters.
+ * @namespace
+ */
+ DataTable.models.oSearch = {
+ /**
+ * Flag to indicate if the filtering should be case insensitive or not
+ * @type boolean
+ * @default true
+ */
+ "bCaseInsensitive": true,
+
+ /**
+ * Applied search term
+ * @type string
+ * @default Empty string
+ */
+ "sSearch": "",
+
+ /**
+ * Flag to indicate if the search term should be interpreted as a
+ * regular expression (true) or not (false) and therefore and special
+ * regex characters escaped.
+ * @type boolean
+ * @default false
+ */
+ "bRegex": false,
+
+ /**
+ * Flag to indicate if DataTables is to use its smart filtering or not.
+ * @type boolean
+ * @default true
+ */
+ "bSmart": true
+ };
+
+
+
+
+ /**
+ * Template object for the way in which DataTables holds information about
+ * each individual row. This is the object format used for the settings
+ * aoData array.
+ * @namespace
+ */
+ DataTable.models.oRow = {
+ /**
+ * TR element for the row
+ * @type node
+ * @default null
+ */
+ "nTr": null,
+
+ /**
+ * Data object from the original data source for the row. This is either
+ * an array if using the traditional form of DataTables, or an object if
+ * using mDataProp options. The exact type will depend on the passed in
+ * data from the data source, or will be an array if using DOM a data
+ * source.
+ * @type array|object
+ * @default []
+ */
+ "_aData": [],
+
+ /**
+ * Sorting data cache - this array is ostensibly the same length as the
+ * number of columns (although each index is generated only as it is
+ * needed), and holds the data that is used for sorting each column in the
+ * row. We do this cache generation at the start of the sort in order that
+ * the formatting of the sort data need be done only once for each cell
+ * per sort. This array should not be read from or written to by anything
+ * other than the master sorting methods.
+ * @type array
+ * @default []
+ * @private
+ */
+ "_aSortData": [],
+
+ /**
+ * Array of TD elements that are cached for hidden rows, so they can be
+ * reinserted into the table if a column is made visible again (or to act
+ * as a store if a column is made hidden). Only hidden columns have a
+ * reference in the array. For non-hidden columns the value is either
+ * undefined or null.
+ * @type array nodes
+ * @default []
+ * @private
+ */
+ "_anHidden": [],
+
+ /**
+ * Cache of the class name that DataTables has applied to the row, so we
+ * can quickly look at this variable rather than needing to do a DOM check
+ * on className for the nTr property.
+ * @type string
+ * @default Empty string
+ * @private
+ */
+ "_sRowStripe": ""
+ };
+
+
+
+ /**
+ * Template object for the column information object in DataTables. This object
+ * is held in the settings aoColumns array and contains all the information that
+ * DataTables needs about each individual column.
+ *
+ * Note that this object is related to {@link DataTable.defaults.columns}
+ * but this one is the internal data store for DataTables's cache of columns.
+ * It should NOT be manipulated outside of DataTables. Any configuration should
+ * be done through the initialisation options.
+ * @namespace
+ */
+ DataTable.models.oColumn = {
+ /**
+ * A list of the columns that sorting should occur on when this column
+ * is sorted. That this property is an array allows multi-column sorting
+ * to be defined for a column (for example first name / last name columns
+ * would benefit from this). The values are integers pointing to the
+ * columns to be sorted on (typically it will be a single integer pointing
+ * at itself, but that doesn't need to be the case).
+ * @type array
+ */
+ "aDataSort": null,
+
+ /**
+ * Define the sorting directions that are applied to the column, in sequence
+ * as the column is repeatedly sorted upon - i.e. the first value is used
+ * as the sorting direction when the column if first sorted (clicked on).
+ * Sort it again (click again) and it will move on to the next index.
+ * Repeat until loop.
+ * @type array
+ */
+ "asSorting": null,
+
+ /**
+ * Flag to indicate if the column is searchable, and thus should be included
+ * in the filtering or not.
+ * @type boolean
+ */
+ "bSearchable": null,
+
+ /**
+ * Flag to indicate if the column is sortable or not.
+ * @type boolean
+ */
+ "bSortable": null,
+
+ /**
+ * When using fnRender, you have two options for what to do with the data,
+ * and this property serves as the switch. Firstly, you can have the sorting
+ * and filtering use the rendered value (true - default), or you can have
+ * the sorting and filtering us the original value (false).
+ *
+ * *NOTE* It is it is advisable now to use mDataProp as a function and make
+ * use of the 'type' that it gives, allowing (potentially) different data to
+ * be used for sorting, filtering, display and type detection.
+ * @type boolean
+ * @deprecated
+ */
+ "bUseRendered": null,
+
+ /**
+ * Flag to indicate if the column is currently visible in the table or not
+ * @type boolean
+ */
+ "bVisible": null,
+
+ /**
+ * Flag to indicate to the type detection method if the automatic type
+ * detection should be used, or if a column type (sType) has been specified
+ * @type boolean
+ * @default true
+ * @private
+ */
+ "_bAutoType": true,
+
+ /**
+ * Developer definable function that is called whenever a cell is created (Ajax source,
+ * etc) or processed for input (DOM source). This can be used as a compliment to fnRender
+ * allowing you to modify the DOM element (add background colour for example) when the
+ * element is available (since it is not when fnRender is called).
+ * @type function
+ * @param {element} nTd The TD node that has been created
+ * @param {*} sData The Data for the cell
+ * @param {array|object} oData The data for the whole row
+ * @param {int} iRow The row index for the aoData data store
+ * @default null
+ */
+ "fnCreatedCell": null,
+
+ /**
+ * Function to get data from a cell in a column. You should never
+ * access data directly through _aData internally in DataTables - always use
+ * the method attached to this property. It allows mDataProp to function as
+ * required. This function is automatically assigned by the column
+ * initialisation method
+ * @type function
+ * @param {array|object} oData The data array/object for the array
+ * (i.e. aoData[]._aData)
+ * @param {string} sSpecific The specific data type you want to get -
+ * 'display', 'type' 'filter' 'sort'
+ * @returns {*} The data for the cell from the given row's data
+ * @default null
+ */
+ "fnGetData": null,
+
+ /**
+ * Custom display function that will be called for the display of each cell
+ * in this column.
+ * @type function
+ * @param {object} o Object with the following parameters:
+ * @param {int} o.iDataRow The row in aoData
+ * @param {int} o.iDataColumn The column in question
+ * @param {array o.aData The data for the row in question
+ * @param {object} o.oSettings The settings object for this DataTables instance
+ * @returns {string} The string you which to use in the display
+ * @default null
+ */
+ "fnRender": null,
+
+ /**
+ * Function to set data for a cell in the column. You should never
+ * set the data directly to _aData internally in DataTables - always use
+ * this method. It allows mDataProp to function as required. This function
+ * is automatically assigned by the column initialisation method
+ * @type function
+ * @param {array|object} oData The data array/object for the array
+ * (i.e. aoData[]._aData)
+ * @param {*} sValue Value to set
+ * @default null
+ */
+ "fnSetData": null,
+
+ /**
+ * Property to read the value for the cells in the column from the data
+ * source array / object. If null, then the default content is used, if a
+ * function is given then the return from the function is used.
+ * @type function|int|string|null
+ * @default null
+ */
+ "mDataProp": null,
+
+ /**
+ * Unique header TH/TD element for this column - this is what the sorting
+ * listener is attached to (if sorting is enabled.)
+ * @type node
+ * @default null
+ */
+ "nTh": null,
+
+ /**
+ * Unique footer TH/TD element for this column (if there is one). Not used
+ * in DataTables as such, but can be used for plug-ins to reference the
+ * footer for each column.
+ * @type node
+ * @default null
+ */
+ "nTf": null,
+
+ /**
+ * The class to apply to all TD elements in the table's TBODY for the column
+ * @type string
+ * @default null
+ */
+ "sClass": null,
+
+ /**
+ * When DataTables calculates the column widths to assign to each column,
+ * it finds the longest string in each column and then constructs a
+ * temporary table and reads the widths from that. The problem with this
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
+ * string - thus the calculation can go wrong (doing it properly and putting
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
+ * a "work around" we provide this option. It will append its value to the
+ * text that is found to be the longest string for the column - i.e. padding.
+ * @type string
+ */
+ "sContentPadding": null,
+
+ /**
+ * Allows a default value to be given for a column's data, and will be used
+ * whenever a null data source is encountered (this can be because mDataProp
+ * is set to null, or because the data source itself is null).
+ * @type string
+ * @default null
+ */
+ "sDefaultContent": null,
+
+ /**
+ * Name for the column, allowing reference to the column by name as well as
+ * by index (needs a lookup to work by name).
+ * @type string
+ */
+ "sName": null,
+
+ /**
+ * Custom sorting data type - defines which of the available plug-ins in
+ * afnSortData the custom sorting will use - if any is defined.
+ * @type string
+ * @default std
+ */
+ "sSortDataType": 'std',
+
+ /**
+ * Class to be applied to the header element when sorting on this column
+ * @type string
+ * @default null
+ */
+ "sSortingClass": null,
+
+ /**
+ * Class to be applied to the header element when sorting on this column -
+ * when jQuery UI theming is used.
+ * @type string
+ * @default null
+ */
+ "sSortingClassJUI": null,
+
+ /**
+ * Title of the column - what is seen in the TH element (nTh).
+ * @type string
+ */
+ "sTitle": null,
+
+ /**
+ * Column sorting and filtering type
+ * @type string
+ * @default null
+ */
+ "sType": null,
+
+ /**
+ * Width of the column
+ * @type string
+ * @default null
+ */
+ "sWidth": null,
+
+ /**
+ * Width of the column when it was first "encountered"
+ * @type string
+ * @default null
+ */
+ "sWidthOrig": null
+ };
+
+
+
+ /**
+ * Initialisation options that can be given to DataTables at initialisation
+ * time.
+ * @namespace
+ */
+ DataTable.defaults = {
+ /**
+ * An array of data to use for the table, passed in at initialisation which
+ * will be used in preference to any data which is already in the DOM. This is
+ * particularly useful for constructing tables purely in Javascript, for
+ * example with a custom Ajax call.
+ * @type array
+ * @default null
+ * @dtopt Option
+ *
+ * @example
+ * // Using a 2D array data source
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "aaData": [
+ * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],
+ * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],
+ * ],
+ * "aoColumns": [
+ * { "sTitle": "Engine" },
+ * { "sTitle": "Browser" },
+ * { "sTitle": "Platform" },
+ * { "sTitle": "Version" },
+ * { "sTitle": "Grade" }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using an array of objects as a data source (mDataProp)
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "aaData": [
+ * {
+ * "engine": "Trident",
+ * "browser": "Internet Explorer 4.0",
+ * "platform": "Win 95+",
+ * "version": 4,
+ * "grade": "X"
+ * },
+ * {
+ * "engine": "Trident",
+ * "browser": "Internet Explorer 5.0",
+ * "platform": "Win 95+",
+ * "version": 5,
+ * "grade": "C"
+ * }
+ * ],
+ * "aoColumns": [
+ * { "sTitle": "Engine", "mDataProp": "engine" },
+ * { "sTitle": "Browser", "mDataProp": "browser" },
+ * { "sTitle": "Platform", "mDataProp": "platform" },
+ * { "sTitle": "Version", "mDataProp": "version" },
+ * { "sTitle": "Grade", "mDataProp": "grade" }
+ * ]
+ * } );
+ * } );
+ */
+ "aaData": null,
+
+
+ /**
+ * If sorting is enabled, then DataTables will perform a first pass sort on
+ * initialisation. You can define which column(s) the sort is performed upon,
+ * and the sorting direction, with this variable. The aaSorting array should
+ * contain an array for each column to be sorted initially containing the
+ * column's index and a direction string ('asc' or 'desc').
+ * @type array
+ * @default [[0,'asc']]
+ * @dtopt Option
+ *
+ * @example
+ * // Sort by 3rd column first, and then 4th column
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "aaSorting": [[2,'asc'], [3,'desc']]
+ * } );
+ * } );
+ *
+ * // No initial sorting
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "aaSorting": []
+ * } );
+ * } );
+ */
+ "aaSorting": [[0,'asc']],
+
+
+ /**
+ * This parameter is basically identical to the aaSorting parameter, but
+ * cannot be overridden by user interaction with the table. What this means
+ * is that you could have a column (visible or hidden) which the sorting will
+ * always be forced on first - any sorting after that (from the user) will
+ * then be performed as required. This can be useful for grouping rows
+ * together.
+ * @type array
+ * @default null
+ * @dtopt Option
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "aaSortingFixed": [[0,'asc']]
+ * } );
+ * } )
+ */
+ "aaSortingFixed": null,
+
+
+ /**
+ * This parameter allows you to readily specify the entries in the length drop
+ * down menu that DataTables shows when pagination is enabled. It can be
+ * either a 1D array of options which will be used for both the displayed
+ * option and the value, or a 2D array which will use the array in the first
+ * position as the value, and the array in the second position as the
+ * displayed options (useful for language strings such as 'All').
+ * @type array
+ * @default [ 10, 25, 50, 100 ]
+ * @dtopt Option
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]]
+ * } );
+ * } );
+ *
+ * @example
+ * // Setting the default display length as well as length menu
+ * // This is likely to be wanted if you remove the '10' option which
+ * // is the iDisplayLength default.
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "iDisplayLength": 25,
+ * "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]]
+ * } );
+ * } );
+ */
+ "aLengthMenu": [ 10, 25, 50, 100 ],
+
+
+ /**
+ * The aoColumns option in the initialisation parameter allows you to define
+ * details about the way individual columns behave. For a full list of
+ * column options that can be set, please see
+ * {@link DataTable.defaults.columns}. Note that if you use aoColumns to
+ * define your columns, you must have an entry in the array for every single
+ * column that you have in your table (these can be null if you don't which
+ * to specify any options).
+ * @member
+ */
+ "aoColumns": null,
+
+ /**
+ * Very similar to aoColumns, aoColumnDefs allows you to target a specific
+ * column, multiple columns, or all columns, using the aTargets property of
+ * each object in the array. This allows great flexibility when creating
+ * tables, as the aoColumnDefs arrays can be of any length, targeting the
+ * columns you specifically want. aoColumnDefs may use any of the column
+ * options available: {@link DataTable.defaults.columns}, but it _must_
+ * have aTargets defined in each object in the array. Values in the aTargets
+ * array may be:
+ *
+ *
a string - class name will be matched on the TH for the column
+ *
0 or a positive integer - column index counting from the left
+ *
a negative integer - column index counting from the right
+ *
the string "_all" - all columns (i.e. assign a default)
+ *
+ * @member
+ */
+ "aoColumnDefs": null,
+
+
+ /**
+ * Basically the same as oSearch, this parameter defines the individual column
+ * filtering state at initialisation time. The array must be of the same size
+ * as the number of columns, and each element be an object with the parameters
+ * "sSearch" and "bEscapeRegex" (the latter is optional). 'null' is also
+ * accepted and the default will be used.
+ * @type array
+ * @default []
+ * @dtopt Option
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "aoSearchCols": [
+ * null,
+ * { "sSearch": "My filter" },
+ * null,
+ * { "sSearch": "^[0-9]", "bEscapeRegex": false }
+ * ]
+ * } );
+ * } )
+ */
+ "aoSearchCols": [],
+
+
+ /**
+ * An array of CSS classes that should be applied to displayed rows. This
+ * array may be of any length, and DataTables will apply each class
+ * sequentially, looping when required.
+ * @type array
+ * @default [ 'odd', 'even' ]
+ * @dtopt Option
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "asStripeClasses": [ 'strip1', 'strip2', 'strip3' ]
+ * } );
+ * } )
+ */
+ "asStripeClasses": [ 'odd', 'even' ],
+
+
+ /**
+ * Enable or disable automatic column width calculation. This can be disabled
+ * as an optimisation (it takes some time to calculate the widths) if the
+ * tables widths are passed in using aoColumns.
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bAutoWidth": false
+ * } );
+ * } );
+ */
+ "bAutoWidth": true,
+
+
+ /**
+ * Deferred rendering can provide DataTables with a huge speed boost when you
+ * are using an Ajax or JS data source for the table. This option, when set to
+ * true, will cause DataTables to defer the creation of the table elements for
+ * each row until they are needed for a draw - saving a significant amount of
+ * time.
+ * @type boolean
+ * @default false
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready(function() {
+ * var oTable = $('#example').dataTable( {
+ * "sAjaxSource": "sources/arrays.txt",
+ * "bDeferRender": true
+ * } );
+ * } );
+ */
+ "bDeferRender": false,
+
+
+ /**
+ * Replace a DataTable which matches the given selector and replace it with
+ * one which has the properties of the new initialisation object passed. If no
+ * table matches the selector, then the new DataTable will be constructed as
+ * per normal.
+ * @type boolean
+ * @default false
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sScrollY": "200px",
+ * "bPaginate": false
+ * } );
+ *
+ * // Some time later....
+ * $('#example').dataTable( {
+ * "bFilter": false,
+ * "bDestroy": true
+ * } );
+ * } );
+ */
+ "bDestroy": false,
+
+
+ /**
+ * Enable or disable filtering of data. Filtering in DataTables is "smart" in
+ * that it allows the end user to input multiple words (space separated) and
+ * will match a row containing those words, even if not in the order that was
+ * specified (this allow matching across multiple columns). Note that if you
+ * wish to use filtering in DataTables this must remain 'true' - to remove the
+ * default filtering input box and retain filtering abilities, please use
+ * @ref{sDom}.
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bFilter": false
+ * } );
+ * } );
+ */
+ "bFilter": true,
+
+
+ /**
+ * Enable or disable the table information display. This shows information
+ * about the data that is currently visible on the page, including information
+ * about filtered data if that action is being performed.
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bInfo": false
+ * } );
+ * } );
+ */
+ "bInfo": true,
+
+
+ /**
+ * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some
+ * slightly different and additional mark-up from what DataTables has
+ * traditionally used).
+ * @type boolean
+ * @default false
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "bJQueryUI": true
+ * } );
+ * } );
+ */
+ "bJQueryUI": false,
+
+
+ /**
+ * Allows the end user to select the size of a formatted page from a select
+ * menu (sizes are 10, 25, 50 and 100). Requires pagination (bPaginate).
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bLengthChange": false
+ * } );
+ * } );
+ */
+ "bLengthChange": true,
+
+
+ /**
+ * Enable or disable pagination.
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bPaginate": false
+ * } );
+ * } );
+ */
+ "bPaginate": true,
+
+
+ /**
+ * Enable or disable the display of a 'processing' indicator when the table is
+ * being processed (e.g. a sort). This is particularly useful for tables with
+ * large amounts of data where it can take a noticeable amount of time to sort
+ * the entries.
+ * @type boolean
+ * @default false
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bProcessing": true
+ * } );
+ * } );
+ */
+ "bProcessing": false,
+
+
+ /**
+ * Retrieve the DataTables object for the given selector. Note that if the
+ * table has already been initialised, this parameter will cause DataTables
+ * to simply return the object that has already been set up - it will not take
+ * account of any changes you might have made to the initialisation object
+ * passed to DataTables (setting this parameter to true is an acknowledgement
+ * that you understand this). bDestroy can be used to reinitialise a table if
+ * you need.
+ * @type boolean
+ * @default false
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * initTable();
+ * tableActions();
+ * } );
+ *
+ * function initTable ()
+ * {
+ * return $('#example').dataTable( {
+ * "sScrollY": "200px",
+ * "bPaginate": false,
+ * "bRetrieve": true
+ * } );
+ * }
+ *
+ * function tableActions ()
+ * {
+ * var oTable = initTable();
+ * // perform API operations with oTable
+ * }
+ */
+ "bRetrieve": false,
+
+
+ /**
+ * Indicate if DataTables should be allowed to set the padding / margin
+ * etc for the scrolling header elements or not. Typically you will want
+ * this.
+ * @type boolean
+ * @default true
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bScrollAutoCss": false,
+ * "sScrollY": "200px"
+ * } );
+ * } );
+ */
+ "bScrollAutoCss": true,
+
+
+ /**
+ * When vertical (y) scrolling is enabled, DataTables will force the height of
+ * the table's viewport to the given height at all times (useful for layout).
+ * However, this can look odd when filtering data down to a small data set,
+ * and the footer is left "floating" further down. This parameter (when
+ * enabled) will cause DataTables to collapse the table's viewport down when
+ * the result set will fit within the given Y height.
+ * @type boolean
+ * @default false
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sScrollY": "200",
+ * "bScrollCollapse": true
+ * } );
+ * } );
+ */
+ "bScrollCollapse": false,
+
+
+ /**
+ * Enable infinite scrolling for DataTables (to be used in combination with
+ * sScrollY). Infinite scrolling means that DataTables will continually load
+ * data as a user scrolls through a table, which is very useful for large
+ * dataset. This cannot be used with pagination, which is automatically
+ * disabled. Note - the Scroller extra for DataTables is recommended in
+ * in preference to this option.
+ * @type boolean
+ * @default false
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bScrollInfinite": true,
+ * "bScrollCollapse": true,
+ * "sScrollY": "200px"
+ * } );
+ * } );
+ */
+ "bScrollInfinite": false,
+
+
+ /**
+ * Configure DataTables to use server-side processing. Note that the
+ * sAjaxSource parameter must also be given in order to give DataTables a
+ * source to obtain the required data for each draw.
+ * @type boolean
+ * @default false
+ * @dtopt Features
+ * @dtopt Server-side
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bServerSide": true,
+ * "sAjaxSource": "xhr.php"
+ * } );
+ * } );
+ */
+ "bServerSide": false,
+
+
+ /**
+ * Enable or disable sorting of columns. Sorting of individual columns can be
+ * disabled by the "bSortable" option for each column.
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bSort": false
+ * } );
+ * } );
+ */
+ "bSort": true,
+
+
+ /**
+ * Allows control over whether DataTables should use the top (true) unique
+ * cell that is found for a single column, or the bottom (false - default).
+ * This is useful when using complex headers.
+ * @type boolean
+ * @default false
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bSortCellsTop": true
+ * } );
+ * } );
+ */
+ "bSortCellsTop": false,
+
+
+ /**
+ * Enable or disable the addition of the classes 'sorting_1', 'sorting_2' and
+ * 'sorting_3' to the columns which are currently being sorted on. This is
+ * presented as a feature switch as it can increase processing time (while
+ * classes are removed and added) so for large data sets you might want to
+ * turn this off.
+ * @type boolean
+ * @default true
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bSortClasses": false
+ * } );
+ * } );
+ */
+ "bSortClasses": true,
+
+
+ /**
+ * Enable or disable state saving. When enabled a cookie will be used to save
+ * table display information such as pagination information, display length,
+ * filtering and sorting. As such when the end user reloads the page the
+ * display display will match what thy had previously set up.
+ * @type boolean
+ * @default false
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "bStateSave": true
+ * } );
+ * } );
+ */
+ "bStateSave": false,
+
+
+ /**
+ * Customise the cookie and / or the parameters being stored when using
+ * DataTables with state saving enabled. This function is called whenever
+ * the cookie is modified, and it expects a fully formed cookie string to be
+ * returned. Note that the data object passed in is a Javascript object which
+ * must be converted to a string (JSON.stringify for example).
+ * @type function
+ * @param {string} sName Name of the cookie defined by DataTables
+ * @param {object} oData Data to be stored in the cookie
+ * @param {string} sExpires Cookie expires string
+ * @param {string} sPath Path of the cookie to set
+ * @returns {string} Cookie formatted string (which should be encoded by
+ * using encodeURIComponent())
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready( function () {
+ * $('#example').dataTable( {
+ * "fnCookieCallback": function (sName, oData, sExpires, sPath) {
+ * // Customise oData or sName or whatever else here
+ * return sName + "="+JSON.stringify(oData)+"; expires=" + sExpires +"; path=" + sPath;
+ * }
+ * } );
+ * } );
+ */
+ "fnCookieCallback": null,
+
+
+ /**
+ * This function is called when a TR element is created (and all TD child
+ * elements have been inserted), or registered if using a DOM source, allowing
+ * manipulation of the TR element (adding classes etc).
+ * @type function
+ * @param {node} nRow "TR" element for the current row
+ * @param {array} aData Raw data array for this row
+ * @param {int} iDataIndex The index of this row in aoData
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "fnCreatedRow": function( nRow, aData, iDataIndex ) {
+ * // Bold the grade for all 'A' grade browsers
+ * if ( aData[4] == "A" )
+ * {
+ * $('td:eq(4)', nRow).html( 'A' );
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "fnCreatedRow": null,
+
+
+ /**
+ * This function is called on every 'draw' event, and allows you to
+ * dynamically modify any aspect you want about the created DOM.
+ * @type function
+ * @param {object} oSettings DataTables settings object
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "fnDrawCallback": function() {
+ * alert( 'DataTables has redrawn the table' );
+ * }
+ * } );
+ * } );
+ */
+ "fnDrawCallback": null,
+
+
+ /**
+ * Identical to fnHeaderCallback() but for the table footer this function
+ * allows you to modify the table footer on every 'draw' even.
+ * @type function
+ * @param {node} nFoot "TR" element for the footer
+ * @param {array} aData Full table data (as derived from the original HTML)
+ * @param {int} iStart Index for the current display starting point in the
+ * display array
+ * @param {int} iEnd Index for the current display ending point in the
+ * display array
+ * @param {array int} aiDisplay Index array to translate the visual position
+ * to the full data array
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) {
+ * nFoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+iStart;
+ * }
+ * } );
+ * } )
+ */
+ "fnFooterCallback": null,
+
+
+ /**
+ * When rendering large numbers in the information element for the table
+ * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers
+ * to have a comma separator for the 'thousands' units (e.g. 1 million is
+ * rendered as "1,000,000") to help readability for the end user. This
+ * function will override the default method DataTables uses.
+ * @type function
+ * @member
+ * @param {int} iIn number to be formatted
+ * @returns {string} formatted string for DataTables to show the number
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "fnFormatNumber": function ( iIn ) {
+ * if ( iIn < 1000 ) {
+ * return iIn;
+ * } else {
+ * var
+ * s=(iIn+""),
+ * a=s.split(""), out="",
+ * iLen=s.length;
+ *
+ * for ( var i=0 ; i<iLen ; i++ ) {
+ * if ( i%3 === 0 && i !== 0 ) {
+ * out = "'"+out;
+ * }
+ * out = a[iLen-i-1]+out;
+ * }
+ * }
+ * return out;
+ * };
+ * } );
+ * } );
+ */
+ "fnFormatNumber": function ( iIn ) {
+ if ( iIn < 1000 )
+ {
+ // A small optimisation for what is likely to be the majority of use cases
+ return iIn;
+ }
+
+ var s=(iIn+""), a=s.split(""), out="", iLen=s.length;
+
+ for ( var i=0 ; iA' );
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "fnRowCallback": null,
+
+
+ /**
+ * This parameter allows you to override the default function which obtains
+ * the data from the server ($.getJSON) so something more suitable for your
+ * application. For example you could use POST data, or pull information from
+ * a Gears or AIR database.
+ * @type function
+ * @member
+ * @param {string} sSource HTTP source to obtain the data from (sAjaxSource)
+ * @param {array} aoData A key/value pair object containing the data to send
+ * to the server
+ * @param {function} fnCallback to be called on completion of the data get
+ * process that will draw the data on the page.
+ * @param {object} oSettings DataTables settings object
+ * @dtopt Callbacks
+ * @dtopt Server-side
+ *
+ * @example
+ * // POST data to server
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bProcessing": true,
+ * "bServerSide": true,
+ * "sAjaxSource": "xhr.php",
+ * "fnServerData": function ( sSource, aoData, fnCallback ) {
+ * $.ajax( {
+ * "dataType": 'json',
+ * "type": "POST",
+ * "url": sSource,
+ * "data": aoData,
+ * "success": fnCallback
+ * } );
+ * }
+ * } );
+ * } );
+ */
+ "fnServerData": function ( sUrl, aoData, fnCallback, oSettings ) {
+ oSettings.jqXHR = $.ajax( {
+ "url": sUrl,
+ "data": aoData,
+ "success": function (json) {
+ $(oSettings.oInstance).trigger('xhr', oSettings);
+ fnCallback( json );
+ },
+ "dataType": "json",
+ "cache": false,
+ "type": oSettings.sServerMethod,
+ "error": function (xhr, error, thrown) {
+ if ( error == "parsererror" ) {
+ alert( "DataTables warning: JSON data from server could not be parsed. "+
+ "This is caused by a JSON formatting error." );
+ }
+ }
+ } );
+ },
+
+
+ /**
+ * It is often useful to send extra data to the server when making an Ajax
+ * request - for example custom filtering information, and this callback
+ * function makes it trivial to send extra information to the server. The
+ * passed in parameter is the data set that has been constructed by
+ * DataTables, and you can add to this or modify it as you require.
+ * @type function
+ * @param {array} aoData Data array (array of objects which are name/value
+ * pairs) that has been constructed by DataTables and will be sent to the
+ * server. In the case of Ajax sourced data with server-side processing
+ * this will be an empty array, for server-side processing there will be a
+ * significant number of parameters!
+ * @returns {undefined} Ensure that you modify the aoData array passed in,
+ * as this is passed by reference.
+ * @dtopt Callbacks
+ * @dtopt Server-side
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bProcessing": true,
+ * "bServerSide": true,
+ * "sAjaxSource": "scripts/server_processing.php",
+ * "fnServerParams": function ( aoData ) {
+ * aoData.push( { "name": "more_data", "value": "my_value" } );
+ * }
+ * } );
+ * } );
+ */
+ "fnServerParams": null,
+
+
+ /**
+ * Load the table state. With this function you can define from where, and how, the
+ * state of a table is loaded. By default DataTables will load from its state saving
+ * cookie, but you might wish to use local storage (HTML5) or a server-side database.
+ * @type function
+ * @member
+ * @param {object} oSettings DataTables settings object
+ * @return {object} The DataTables state object to be loaded
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bStateSave": true,
+ * "fnStateSave": function (oSettings, oData) {
+ * var o;
+ *
+ * // Send an Ajax request to the server to get the data. Note that
+ * // this is a synchronous request.
+ * $.ajax( {
+ * "url": "/state_load",
+ * "async": false,
+ * "dataType": "json",
+ * "success": function (json) {
+ * o = json;
+ * }
+ * } );
+ *
+ * return o;
+ * }
+ * } );
+ * } );
+ */
+ "fnStateLoad": function ( oSettings ) {
+ var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance );
+ var oData;
+
+ try {
+ oData = (typeof $.parseJSON === 'function') ?
+ $.parseJSON(sData) : eval( '('+sData+')' );
+ } catch (e) {
+ oData = null;
+ }
+
+ return oData;
+ },
+
+
+ /**
+ * Callback which allows modification of the saved state prior to loading that state.
+ * This callback is called when the table is loading state from the stored data, but
+ * prior to the settings object being modified by the saved state. Note that for
+ * plug-in authors, you should use the 'stateLoadParams' event to load parameters for
+ * a plug-in.
+ * @type function
+ * @param {object} oSettings DataTables settings object
+ * @param {object} oData The state object that is to be loaded
+ * @dtopt Callbacks
+ *
+ * @example
+ * // Remove a saved filter, so filtering is never loaded
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bStateSave": true,
+ * "fnStateLoadParams": function (oSettings, oData) {
+ * oData.oFilter.sSearch = "";
+ * } );
+ * } );
+ *
+ * @example
+ * // Disallow state loading by returning false
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bStateSave": true,
+ * "fnStateLoadParams": function (oSettings, oData) {
+ * return false;
+ * } );
+ * } );
+ */
+ "fnStateLoadParams": null,
+
+
+ /**
+ * Callback that is called when the state has been loaded from the state saving method
+ * and the DataTables settings object has been modified as a result of the loaded state.
+ * @type function
+ * @param {object} oSettings DataTables settings object
+ * @param {object} oData The state object that was loaded
+ * @dtopt Callbacks
+ *
+ * @example
+ * // Show an alert with the filtering value that was saved
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bStateSave": true,
+ * "fnStateLoaded": function (oSettings, oData) {
+ * alert( 'Saved filter was: '+oData.oFilter.sSearch );
+ * } );
+ * } );
+ */
+ "fnStateLoaded": null,
+
+
+ /**
+ * Save the table state. This function allows you to define where and how the state
+ * information for the table is stored - by default it will use a cookie, but you
+ * might want to use local storage (HTML5) or a server-side database.
+ * @type function
+ * @member
+ * @param {object} oSettings DataTables settings object
+ * @param {object} oData The state object to be saved
+ * @dtopt Callbacks
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bStateSave": true,
+ * "fnStateSave": function (oSettings, oData) {
+ * // Send an Ajax request to the server with the state object
+ * $.ajax( {
+ * "url": "/state_save",
+ * "data": oData,
+ * "dataType": "json",
+ * "method": "POST"
+ * "success": function () {}
+ * } );
+ * }
+ * } );
+ * } );
+ */
+ "fnStateSave": function ( oSettings, oData ) {
+ this.oApi._fnCreateCookie(
+ oSettings.sCookiePrefix+oSettings.sInstance,
+ this.oApi._fnJsonString(oData),
+ oSettings.iCookieDuration,
+ oSettings.sCookiePrefix,
+ oSettings.fnCookieCallback
+ );
+ },
+
+
+ /**
+ * Callback which allows modification of the state to be saved. Called when the table
+ * has changed state a new state save is required. This method allows modification of
+ * the state saving object prior to actually doing the save, including addition or
+ * other state properties or modification. Note that for plug-in authors, you should
+ * use the 'stateSaveParams' event to save parameters for a plug-in.
+ * @type function
+ * @param {object} oSettings DataTables settings object
+ * @param {object} oData The state object to be saved
+ * @dtopt Callbacks
+ *
+ * @example
+ * // Remove a saved filter, so filtering is never saved
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bStateSave": true,
+ * "fnStateLoadParams": function (oSettings, oData) {
+ * oData.oFilter.sSearch = "";
+ * } );
+ * } );
+ */
+ "fnStateSaveParams": null,
+
+
+ /**
+ * Duration of the cookie which is used for storing session information. This
+ * value is given in seconds.
+ * @type int
+ * @default 7200 (2 hours)
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "iCookieDuration": 60*60*24 // 1 day
+ * } );
+ * } )
+ */
+ "iCookieDuration": 7200,
+
+
+ /**
+ * When enabled DataTables will not make a request to the server for the first
+ * page draw - rather it will use the data already on the page (no sorting etc
+ * will be applied to it), thus saving on an XHR at load time. iDeferLoading
+ * is used to indicate that deferred loading is required, but it is also used
+ * to tell DataTables how many records there are in the full table (allowing
+ * the information element and pagination to be displayed correctly).
+ * @type int
+ * @default null
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bServerSide": true,
+ * "sAjaxSource": "scripts/server_processing.php",
+ * "iDeferLoading": 57
+ * } );
+ * } );
+ */
+ "iDeferLoading": null,
+
+
+ /**
+ * Number of rows to display on a single page when using pagination. If
+ * feature enabled (bLengthChange) then the end user will be able to override
+ * this to a custom setting using a pop-up menu.
+ * @type int
+ * @default 10
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "iDisplayLength": 50
+ * } );
+ * } )
+ */
+ "iDisplayLength": 10,
+
+
+ /**
+ * Define the starting point for data display when using DataTables with
+ * pagination. Note that this parameter is the number of records, rather than
+ * the page number, so if you have 10 records per page and want to start on
+ * the third page, it should be "20".
+ * @type int
+ * @default 0
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "iDisplayStart": 20
+ * } );
+ * } )
+ */
+ "iDisplayStart": 0,
+
+
+ /**
+ * The scroll gap is the amount of scrolling that is left to go before
+ * DataTables will load the next 'page' of data automatically. You typically
+ * want a gap which is big enough that the scrolling will be smooth for the
+ * user, while not so large that it will load more data than need.
+ * @type int
+ * @default 100
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bScrollInfinite": true,
+ * "bScrollCollapse": true,
+ * "sScrollY": "200px",
+ * "iScrollLoadGap": 50
+ * } );
+ * } );
+ */
+ "iScrollLoadGap": 100,
+
+
+ /**
+ * By default DataTables allows keyboard navigation of the table (sorting, paging,
+ * and filtering) by adding a tabindex attribute to the required elements. This
+ * allows you to tab through the controls and press the enter key to activate them.
+ * The tabindex is default 0, meaning that the tab follows the flow of the document.
+ * You can overrule this using this parameter if you wish. Use a value of -1 to
+ * disable built-in keyboard navigation.
+ * @type int
+ * @default 0
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "iTabIndex": 1
+ * } );
+ * } );
+ */
+ "iTabIndex": 0,
+
+
+ /**
+ * All strings that DataTables uses in the user interface that it creates
+ * are defined in this object, allowing you to modified them individually or
+ * completely replace them all as required.
+ * @namespace
+ */
+ "oLanguage": {
+ /**
+ * Strings that are used for WAI-ARIA labels and controls only (these are not
+ * actually visible on the page, but will be read by screenreaders, and thus
+ * must be internationalised as well).
+ * @namespace
+ */
+ "oAria": {
+ /**
+ * ARIA label that is added to the table headers when the column may be
+ * sorted ascending by activing the column (click or return when focused).
+ * Note that the column header is prefixed to this string.
+ * @type string
+ * @default : activate to sort column ascending
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "oAria": {
+ * "sSortAscending": " - click/return to sort ascending"
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "sSortAscending": ": activate to sort column ascending",
+
+ /**
+ * ARIA label that is added to the table headers when the column may be
+ * sorted descending by activing the column (click or return when focused).
+ * Note that the column header is prefixed to this string.
+ * @type string
+ * @default : activate to sort column ascending
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "oAria": {
+ * "sSortDescending": " - click/return to sort descending"
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "sSortDescending": ": activate to sort column descending"
+ },
+
+ /**
+ * Pagination string used by DataTables for the two built-in pagination
+ * control types ("two_button" and "full_numbers")
+ * @namespace
+ */
+ "oPaginate": {
+ /**
+ * Text to use when using the 'full_numbers' type of pagination for the
+ * button to take the user to the first page.
+ * @type string
+ * @default First
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "oPaginate": {
+ * "sFirst": "First page"
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "sFirst": "First",
+
+
+ /**
+ * Text to use when using the 'full_numbers' type of pagination for the
+ * button to take the user to the last page.
+ * @type string
+ * @default Last
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "oPaginate": {
+ * "sLast": "Last page"
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "sLast": "Last",
+
+
+ /**
+ * Text to use when using the 'full_numbers' type of pagination for the
+ * button to take the user to the next page.
+ * @type string
+ * @default Next
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "oPaginate": {
+ * "sNext": "Next page"
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "sNext": "Next",
+
+
+ /**
+ * Text to use when using the 'full_numbers' type of pagination for the
+ * button to take the user to the previous page.
+ * @type string
+ * @default Previous
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "oPaginate": {
+ * "sPrevious": "Previous page"
+ * }
+ * }
+ * } );
+ * } );
+ */
+ "sPrevious": "Previous"
+ },
+
+ /**
+ * This string is shown in preference to sZeroRecords when the table is
+ * empty of data (regardless of filtering). Note that this is an optional
+ * parameter - if it is not given, the value of sZeroRecords will be used
+ * instead (either the default or given value).
+ * @type string
+ * @default No data available in table
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sEmptyTable": "No data available in table"
+ * }
+ * } );
+ * } );
+ */
+ "sEmptyTable": "No data available in table",
+
+
+ /**
+ * This string gives information to the end user about the information that
+ * is current on display on the page. The _START_, _END_ and _TOTAL_
+ * variables are all dynamically replaced as the table display updates, and
+ * can be freely moved or removed as the language requirements change.
+ * @type string
+ * @default Showing _START_ to _END_ of _TOTAL_ entries
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sInfo": "Got a total of _TOTAL_ entries to show (_START_ to _END_)"
+ * }
+ * } );
+ * } );
+ */
+ "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
+
+
+ /**
+ * Display information string for when the table is empty. Typically the
+ * format of this string should match sInfo.
+ * @type string
+ * @default Showing 0 to 0 of 0 entries
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sInfoEmpty": "No entries to show"
+ * }
+ * } );
+ * } );
+ */
+ "sInfoEmpty": "Showing 0 to 0 of 0 entries",
+
+
+ /**
+ * When a user filters the information in a table, this string is appended
+ * to the information (sInfo) to give an idea of how strong the filtering
+ * is. The variable _MAX_ is dynamically updated.
+ * @type string
+ * @default (filtered from _MAX_ total entries)
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sInfoFiltered": " - filtering from _MAX_ records"
+ * }
+ * } );
+ * } );
+ */
+ "sInfoFiltered": "(filtered from _MAX_ total entries)",
+
+
+ /**
+ * If can be useful to append extra information to the info string at times,
+ * and this variable does exactly that. This information will be appended to
+ * the sInfo (sInfoEmpty and sInfoFiltered in whatever combination they are
+ * being used) at all times.
+ * @type string
+ * @default Empty string
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sInfoPostFix": "All records shown are derived from real information."
+ * }
+ * } );
+ * } );
+ */
+ "sInfoPostFix": "",
+
+
+ /**
+ * DataTables has a build in number formatter (fnFormatNumber) which is used
+ * to format large numbers that are used in the table information. By
+ * default a comma is used, but this can be trivially changed to any
+ * character you wish with this parameter.
+ * @type string
+ * @default ,
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sInfoThousands": "'"
+ * }
+ * } );
+ * } );
+ */
+ "sInfoThousands": ",",
+
+
+ /**
+ * Detail the action that will be taken when the drop down menu for the
+ * pagination length option is changed. The '_MENU_' variable is replaced
+ * with a default select list of 10, 25, 50 and 100, and can be replaced
+ * with a custom select box if required.
+ * @type string
+ * @default Show _MENU_ entries
+ * @dtopt Language
+ *
+ * @example
+ * // Language change only
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sLengthMenu": "Display _MENU_ records"
+ * }
+ * } );
+ * } );
+ *
+ * @example
+ * // Language and options change
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sLengthMenu": 'Display records'
+ * }
+ * } );
+ * } );
+ */
+ "sLengthMenu": "Show _MENU_ entries",
+
+
+ /**
+ * When using Ajax sourced data and during the first draw when DataTables is
+ * gathering the data, this message is shown in an empty row in the table to
+ * indicate to the end user the the data is being loaded. Note that this
+ * parameter is not used when loading data by server-side processing, just
+ * Ajax sourced data with client-side processing.
+ * @type string
+ * @default Loading...
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sLoadingRecords": "Please wait - loading..."
+ * }
+ * } );
+ * } );
+ */
+ "sLoadingRecords": "Loading...",
+
+
+ /**
+ * Text which is displayed when the table is processing a user action
+ * (usually a sort command or similar).
+ * @type string
+ * @default Processing...
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sProcessing": "DataTables is currently busy"
+ * }
+ * } );
+ * } );
+ */
+ "sProcessing": "Processing...",
+
+
+ /**
+ * Details the actions that will be taken when the user types into the
+ * filtering input text box. The variable "_INPUT_", if used in the string,
+ * is replaced with the HTML text box for the filtering input allowing
+ * control over where it appears in the string. If "_INPUT_" is not given
+ * then the input box is appended to the string automatically.
+ * @type string
+ * @default Search:
+ * @dtopt Language
+ *
+ * @example
+ * // Input text box will be appended at the end automatically
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sSearch": "Filter records:"
+ * }
+ * } );
+ * } );
+ *
+ * @example
+ * // Specify where the filter should appear
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sSearch": "Apply filter _INPUT_ to table"
+ * }
+ * } );
+ * } );
+ */
+ "sSearch": "Search:",
+
+
+ /**
+ * All of the language information can be stored in a file on the
+ * server-side, which DataTables will look up if this parameter is passed.
+ * It must store the URL of the language file, which is in a JSON format,
+ * and the object has the same properties as the oLanguage object in the
+ * initialiser object (i.e. the above parameters). Please refer to one of
+ * the example language files to see how this works in action.
+ * @type string
+ * @default Empty string - i.e. disabled
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sUrl": "http://www.sprymedia.co.uk/dataTables/lang.txt"
+ * }
+ * } );
+ * } );
+ */
+ "sUrl": "",
+
+
+ /**
+ * Text shown inside the table records when the is no information to be
+ * displayed after filtering. sEmptyTable is shown when there is simply no
+ * information in the table at all (regardless of filtering).
+ * @type string
+ * @default No matching records found
+ * @dtopt Language
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "oLanguage": {
+ * "sZeroRecords": "No records to display"
+ * }
+ * } );
+ * } );
+ */
+ "sZeroRecords": "No matching records found"
+ },
+
+
+ /**
+ * This parameter allows you to have define the global filtering state at
+ * initialisation time. As an object the "sSearch" parameter must be
+ * defined, but all other parameters are optional. When "bRegex" is true,
+ * the search string will be treated as a regular expression, when false
+ * (default) it will be treated as a straight string. When "bSmart"
+ * DataTables will use it's smart filtering methods (to word match at
+ * any point in the data), when false this will not be done.
+ * @namespace
+ * @extends DataTable.models.oSearch
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "oSearch": {"sSearch": "Initial search"}
+ * } );
+ * } )
+ */
+ "oSearch": $.extend( {}, DataTable.models.oSearch ),
+
+
+ /**
+ * By default DataTables will look for the property 'aaData' when obtaining
+ * data from an Ajax source or for server-side processing - this parameter
+ * allows that property to be changed. You can use Javascript dotted object
+ * notation to get a data source for multiple levels of nesting.
+ * @type string
+ * @default aaData
+ * @dtopt Options
+ * @dtopt Server-side
+ *
+ * @example
+ * // Get data from { "data": [...] }
+ * $(document).ready(function() {
+ * var oTable = $('#example').dataTable( {
+ * "sAjaxSource": "sources/data.txt",
+ * "sAjaxDataProp": "data"
+ * } );
+ * } );
+ *
+ * @example
+ * // Get data from { "data": { "inner": [...] } }
+ * $(document).ready(function() {
+ * var oTable = $('#example').dataTable( {
+ * "sAjaxSource": "sources/data.txt",
+ * "sAjaxDataProp": "data.inner"
+ * } );
+ * } );
+ */
+ "sAjaxDataProp": "aaData",
+
+
+ /**
+ * You can instruct DataTables to load data from an external source using this
+ * parameter (use aData if you want to pass data in you already have). Simply
+ * provide a url a JSON object can be obtained from. This object must include
+ * the parameter 'aaData' which is the data source for the table.
+ * @type string
+ * @default null
+ * @dtopt Options
+ * @dtopt Server-side
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "sAjaxSource": "http://www.sprymedia.co.uk/dataTables/json.php"
+ * } );
+ * } )
+ */
+ "sAjaxSource": null,
+
+
+ /**
+ * This parameter can be used to override the default prefix that DataTables
+ * assigns to a cookie when state saving is enabled.
+ * @type string
+ * @default SpryMedia_DataTables_
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sCookiePrefix": "my_datatable_",
+ * } );
+ * } );
+ */
+ "sCookiePrefix": "SpryMedia_DataTables_",
+
+
+ /**
+ * This initialisation variable allows you to specify exactly where in the
+ * DOM you want DataTables to inject the various controls it adds to the page
+ * (for example you might want the pagination controls at the top of the
+ * table). DIV elements (with or without a custom class) can also be added to
+ * aid styling. The follow syntax is used:
+ *
+ *
+ * @type string
+ * @default lfrtip (when bJQueryUI is false)or
+ * <"H"lfr>t<"F"ip> (when bJQueryUI is true)
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sDom": '<"top"i>rt<"bottom"flp><"clear"&lgt;'
+ * } );
+ * } );
+ */
+ "sDom": "lfrtip",
+
+
+ /**
+ * DataTables features two different built-in pagination interaction methods
+ * ('two_button' or 'full_numbers') which present different page controls to
+ * the end user. Further methods can be added using the API (see below).
+ * @type string
+ * @default two_button
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready( function() {
+ * $('#example').dataTable( {
+ * "sPaginationType": "full_numbers"
+ * } );
+ * } )
+ */
+ "sPaginationType": "two_button",
+
+
+ /**
+ * Enable horizontal scrolling. When a table is too wide to fit into a certain
+ * layout, or you have a large number of columns in the table, you can enable
+ * x-scrolling to show the table in a viewport, which can be scrolled. This
+ * property can by any CSS unit, or a number (in which case it will be treated
+ * as a pixel measurement).
+ * @type string
+ * @default blank string - i.e. disabled
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sScrollX": "100%",
+ * "bScrollCollapse": true
+ * } );
+ * } );
+ */
+ "sScrollX": "",
+
+
+ /**
+ * This property can be used to force a DataTable to use more width than it
+ * might otherwise do when x-scrolling is enabled. For example if you have a
+ * table which requires to be well spaced, this parameter is useful for
+ * "over-sizing" the table, and thus forcing scrolling. This property can by
+ * any CSS unit, or a number (in which case it will be treated as a pixel
+ * measurement).
+ * @type string
+ * @default blank string - i.e. disabled
+ * @dtopt Options
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sScrollX": "100%",
+ * "sScrollXInner": "110%"
+ * } );
+ * } );
+ */
+ "sScrollXInner": "",
+
+
+ /**
+ * Enable vertical scrolling. Vertical scrolling will constrain the DataTable
+ * to the given height, an enable scrolling for any data which overflows the
+ * current viewport. This can be used as an alternative to paging to display
+ * a lot of data in a small area (although paging and scrolling can both be
+ * enabled at the same time). This property can by any CSS unit, or a number
+ * (in which case it will be treated as a pixel measurement).
+ * @type string
+ * @default blank string - i.e. disabled
+ * @dtopt Features
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "sScrollY": "200px",
+ * "bPaginate": false
+ * } );
+ * } );
+ */
+ "sScrollY": "",
+
+
+ /**
+ * Set the HTTP method that is used to make the Ajax call for server-side
+ * processing or Ajax sourced data.
+ * @type string
+ * @default GET
+ * @dtopt Options
+ * @dtopt Server-side
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "bServerSide": true,
+ * "sAjaxSource": "scripts/post.php",
+ * "sServerMethod": "POST"
+ * } );
+ * } );
+ */
+ "sServerMethod": "GET"
+ };
+
+
+
+ /**
+ * Column options that can be given to DataTables at initialisation time.
+ * @namespace
+ */
+ DataTable.defaults.columns = {
+ /**
+ * Allows a column's sorting to take multiple columns into account when
+ * doing a sort. For example first name / last name columns make sense to
+ * do a multi-column sort over the two columns.
+ * @type array
+ * @default null Takes the value of the column index automatically
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "aDataSort": [ 0, 1 ], "aTargets": [ 0 ] },
+ * { "aDataSort": [ 1, 0 ], "aTargets": [ 1 ] },
+ * { "aDataSort": [ 2, 3, 4 ], "aTargets": [ 2 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "aDataSort": [ 0, 1 ] },
+ * { "aDataSort": [ 1, 0 ] },
+ * { "aDataSort": [ 2, 3, 4 ] },
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "aDataSort": null,
+
+
+ /**
+ * You can control the default sorting direction, and even alter the behaviour
+ * of the sort handler (i.e. only allow ascending sorting etc) using this
+ * parameter.
+ * @type array
+ * @default [ 'asc', 'desc' ]
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "asSorting": [ "asc" ], "aTargets": [ 1 ] },
+ * { "asSorting": [ "desc", "asc", "asc" ], "aTargets": [ 2 ] },
+ * { "asSorting": [ "desc" ], "aTargets": [ 3 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * null,
+ * { "asSorting": [ "asc" ] },
+ * { "asSorting": [ "desc", "asc", "asc" ] },
+ * { "asSorting": [ "desc" ] },
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "asSorting": [ 'asc', 'desc' ],
+
+
+ /**
+ * Enable or disable filtering on the data in this column.
+ * @type boolean
+ * @default true
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "bSearchable": false, "aTargets": [ 0 ] }
+ * ] } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "bSearchable": false },
+ * null,
+ * null,
+ * null,
+ * null
+ * ] } );
+ * } );
+ */
+ "bSearchable": true,
+
+
+ /**
+ * Enable or disable sorting on this column.
+ * @type boolean
+ * @default true
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "bSortable": false, "aTargets": [ 0 ] }
+ * ] } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "bSortable": false },
+ * null,
+ * null,
+ * null,
+ * null
+ * ] } );
+ * } );
+ */
+ "bSortable": true,
+
+
+ /**
+ * When using fnRender() for a column, you may wish to use the original data
+ * (before rendering) for sorting and filtering (the default is to used the
+ * rendered data that the user can see). This may be useful for dates etc.
+ *
+ * *NOTE* It is it is advisable now to use mDataProp as a function and make
+ * use of the 'type' that it gives, allowing (potentially) different data to
+ * be used for sorting, filtering, display and type detection.
+ * @type boolean
+ * @default true
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * {
+ * "fnRender": function ( oObj ) {
+ * return oObj.aData[0] +' '+ oObj.aData[3];
+ * },
+ * "bUseRendered": false,
+ * "aTargets": [ 0 ]
+ * }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * {
+ * "fnRender": function ( oObj ) {
+ * return oObj.aData[0] +' '+ oObj.aData[3];
+ * },
+ * "bUseRendered": false
+ * },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "bUseRendered": true,
+
+
+ /**
+ * Enable or disable the display of this column.
+ * @type boolean
+ * @default true
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "bVisible": false, "aTargets": [ 0 ] }
+ * ] } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "bVisible": false },
+ * null,
+ * null,
+ * null,
+ * null
+ * ] } );
+ * } );
+ */
+ "bVisible": true,
+
+
+ /**
+ * Developer definable function that is called whenever a cell is created (Ajax source,
+ * etc) or processed for input (DOM source). This can be used as a compliment to fnRender
+ * allowing you to modify the DOM element (add background colour for example) when the
+ * element is available (since it is not when fnRender is called).
+ * @type function
+ * @param {element} nTd The TD node that has been created
+ * @param {*} sData The Data for the cell
+ * @param {array|object} oData The data for the whole row
+ * @param {int} iRow The row index for the aoData data store
+ * @param {int} iCol The column index for aoColumns
+ * @dtopt Columns
+ *
+ * @example
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [ {
+ * "aTargets": [3],
+ * "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) {
+ * if ( sData == "1.7" ) {
+ * $(nTd).css('color', 'blue')
+ * }
+ * }
+ * } ]
+ * });
+ * } );
+ */
+ "fnCreatedCell": null,
+
+
+ /**
+ * Custom display function that will be called for the display of each cell in
+ * this column.
+ * @type function
+ * @param {object} o Object with the following parameters:
+ * @param {int} o.iDataRow The row in aoData
+ * @param {int} o.iDataColumn The column in question
+ * @param {array} o.aData The data for the row in question
+ * @param {object} o.oSettings The settings object for this DataTables instance
+ * @param {object} o.mDataProp The data property used for this column
+ * @param {*} val The current cell value
+ * @returns {string} The string you which to use in the display
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * {
+ * "fnRender": function ( o, val ) {
+ * return o.aData[0] +' '+ o.aData[3];
+ * },
+ * "aTargets": [ 0 ]
+ * }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "fnRender": function ( o, val ) {
+ * return o.aData[0] +' '+ o.aData[3];
+ * } },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "fnRender": null,
+
+
+ /**
+ * The column index (starting from 0!) that you wish a sort to be performed
+ * upon when this column is selected for sorting. This can be used for sorting
+ * on hidden columns for example.
+ * @type int
+ * @default -1 Use automatically calculated column index
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "iDataSort": 1, "aTargets": [ 0 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "iDataSort": 1 },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "iDataSort": -1,
+
+
+ /**
+ * This property can be used to read data from any JSON data source property,
+ * including deeply nested objects / properties. mDataProp can be given in a
+ * number of different ways which effect its behaviour:
+ *
+ *
integer - treated as an array index for the data source. This is the
+ * default that DataTables uses (incrementally increased for each column).
+ *
string - read an object property from the data source. Note that you can
+ * use Javascript dotted notation to read deep properties/arrays from the
+ * data source.
+ *
null - the sDafaultContent option will use used for the cell (empty
+ * string by default. This can be useful on generated columns such as
+ * edit / delete action columns.
+ *
function - the function given will be executed whenever DataTables
+ * needs to set or get the data for a cell in the column. The function
+ * takes three parameters:
+ *
+ *
{array|object} The data source for the row
+ *
{string} The type call data requested - this will be 'set' when
+ * setting data or 'filter', 'display', 'type' or 'sort' when gathering
+ * data.
+ *
{*} Data to set when the second parameter is 'set'.
+ *
+ * The return value from the function is not required when 'set' is the type
+ * of call, but otherwise the return is what will be used for the data
+ * requested.
+ *
+ * @type string|int|function|null
+ * @default null Use automatically calculated column index
+ * @dtopt Columns
+ *
+ * @example
+ * // Read table data from objects
+ * $(document).ready(function() {
+ * var oTable = $('#example').dataTable( {
+ * "sAjaxSource": "sources/deep.txt",
+ * "aoColumns": [
+ * { "mDataProp": "engine" },
+ * { "mDataProp": "browser" },
+ * { "mDataProp": "platform.inner" },
+ * { "mDataProp": "platform.details.0" },
+ * { "mDataProp": "platform.details.1" }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using mDataProp as a function to provide different information for
+ * // sorting, filtering and display. In this case, currency (price)
+ * $(document).ready(function() {
+ * var oTable = $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * {
+ * "aTargets": [ 0 ],
+ * "mDataProp": function ( source, type, val ) {
+ * if (type === 'set') {
+ * source.price = val;
+ * // Store the computed dislay and filter values for efficiency
+ * source.price_display = val=="" ? "" : "$"+numberFormat(val);
+ * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val;
+ * return;
+ * }
+ * else if (type === 'display') {
+ * return source.price_display;
+ * }
+ * else if (type === 'filter') {
+ * return source.price_filter;
+ * }
+ * // 'sort' and 'type' both just use the integer
+ * return source.price;
+ * }
+ * ]
+ * } );
+ * } );
+ */
+ "mDataProp": null,
+
+
+ /**
+ * Class to give to each cell in this column.
+ * @type string
+ * @default Empty string
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "sClass": "my_class", "aTargets": [ 0 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "sClass": "my_class" },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "sClass": "",
+
+ /**
+ * When DataTables calculates the column widths to assign to each column,
+ * it finds the longest string in each column and then constructs a
+ * temporary table and reads the widths from that. The problem with this
+ * is that "mmm" is much wider then "iiii", but the latter is a longer
+ * string - thus the calculation can go wrong (doing it properly and putting
+ * it into an DOM object and measuring that is horribly(!) slow). Thus as
+ * a "work around" we provide this option. It will append its value to the
+ * text that is found to be the longest string for the column - i.e. padding.
+ * Generally you shouldn't need this, and it is not documented on the
+ * general DataTables.net documentation
+ * @type string
+ * @default Empty string
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * null,
+ * null,
+ * null,
+ * {
+ * "sContentPadding": "mmm"
+ * }
+ * ]
+ * } );
+ * } );
+ */
+ "sContentPadding": "",
+
+
+ /**
+ * Allows a default value to be given for a column's data, and will be used
+ * whenever a null data source is encountered (this can be because mDataProp
+ * is set to null, or because the data source itself is null).
+ * @type string
+ * @default null
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * {
+ * "mDataProp": null,
+ * "sDefaultContent": "Edit",
+ * "aTargets": [ -1 ]
+ * }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * null,
+ * null,
+ * null,
+ * {
+ * "mDataProp": null,
+ * "sDefaultContent": "Edit"
+ * }
+ * ]
+ * } );
+ * } );
+ */
+ "sDefaultContent": null,
+
+
+ /**
+ * This parameter is only used in DataTables' server-side processing. It can
+ * be exceptionally useful to know what columns are being displayed on the
+ * client side, and to map these to database fields. When defined, the names
+ * also allow DataTables to reorder information from the server if it comes
+ * back in an unexpected order (i.e. if you switch your columns around on the
+ * client-side, your server-side code does not also need updating).
+ * @type string
+ * @default Empty string
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "sName": "engine", "aTargets": [ 0 ] },
+ * { "sName": "browser", "aTargets": [ 1 ] },
+ * { "sName": "platform", "aTargets": [ 2 ] },
+ * { "sName": "version", "aTargets": [ 3 ] },
+ * { "sName": "grade", "aTargets": [ 4 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "sName": "engine" },
+ * { "sName": "browser" },
+ * { "sName": "platform" },
+ * { "sName": "version" },
+ * { "sName": "grade" }
+ * ]
+ * } );
+ * } );
+ */
+ "sName": "",
+
+
+ /**
+ * Defines a data source type for the sorting which can be used to read
+ * realtime information from the table (updating the internally cached
+ * version) prior to sorting. This allows sorting to occur on user editable
+ * elements such as form inputs.
+ * @type string
+ * @default std
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "sSortDataType": "dom-text", "aTargets": [ 2, 3 ] },
+ * { "sType": "numeric", "aTargets": [ 3 ] },
+ * { "sSortDataType": "dom-select", "aTargets": [ 4 ] },
+ * { "sSortDataType": "dom-checkbox", "aTargets": [ 5 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * null,
+ * null,
+ * { "sSortDataType": "dom-text" },
+ * { "sSortDataType": "dom-text", "sType": "numeric" },
+ * { "sSortDataType": "dom-select" },
+ * { "sSortDataType": "dom-checkbox" }
+ * ]
+ * } );
+ * } );
+ */
+ "sSortDataType": "std",
+
+
+ /**
+ * The title of this column.
+ * @type string
+ * @default null Derived from the 'TH' value for this column in the
+ * original HTML table.
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "sTitle": "My column title", "aTargets": [ 0 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "sTitle": "My column title" },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "sTitle": null,
+
+
+ /**
+ * The type allows you to specify how the data for this column will be sorted.
+ * Four types (string, numeric, date and html (which will strip HTML tags
+ * before sorting)) are currently available. Note that only date formats
+ * understood by Javascript's Date() object will be accepted as type date. For
+ * example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 'numeric',
+ * 'date' or 'html' (by default). Further types can be adding through
+ * plug-ins.
+ * @type string
+ * @default null Auto-detected from raw data
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "sType": "html", "aTargets": [ 0 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "sType": "html" },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "sType": null,
+
+
+ /**
+ * Defining the width of the column, this parameter may take any CSS value
+ * (3em, 20px etc). DataTables applys 'smart' widths to columns which have not
+ * been given a specific width through this interface ensuring that the table
+ * remains readable.
+ * @type string
+ * @default null Automatic
+ * @dtopt Columns
+ *
+ * @example
+ * // Using aoColumnDefs
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumnDefs": [
+ * { "sWidth": "20%", "aTargets": [ 0 ] }
+ * ]
+ * } );
+ * } );
+ *
+ * @example
+ * // Using aoColumns
+ * $(document).ready(function() {
+ * $('#example').dataTable( {
+ * "aoColumns": [
+ * { "sWidth": "20%" },
+ * null,
+ * null,
+ * null,
+ * null
+ * ]
+ * } );
+ * } );
+ */
+ "sWidth": null
+ };
+
+
+
+ /**
+ * DataTables settings object - this holds all the information needed for a
+ * given table, including configuration, data and current application of the
+ * table options. DataTables does not have a single instance for each DataTable
+ * with the settings attached to that instance, but rather instances of the
+ * DataTable "class" are created on-the-fly as needed (typically by a
+ * $().dataTable() call) and the settings object is then applied to that
+ * instance.
+ *
+ * Note that this object is related to {@link DataTable.defaults} but this
+ * one is the internal data store for DataTables's cache of columns. It should
+ * NOT be manipulated outside of DataTables. Any configuration should be done
+ * through the initialisation options.
+ * @namespace
+ * @todo Really should attach the settings object to individual instances so we
+ * don't need to create new instances on each $().dataTable() call (if the
+ * table already exists). It would also save passing oSettings around and
+ * into every single function. However, this is a very significant
+ * architecture change for DataTables and will almost certainly break
+ * backwards compatibility with older installations. This is something that
+ * will be done in 2.0.
+ */
+ DataTable.models.oSettings = {
+ /**
+ * Primary features of DataTables and their enablement state.
+ * @namespace
+ */
+ "oFeatures": {
+
+ /**
+ * Flag to say if DataTables should automatically try to calculate the
+ * optimum table and columns widths (true) or not (false).
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bAutoWidth": null,
+
+ /**
+ * Delay the creation of TR and TD elements until they are actually
+ * needed by a driven page draw. This can give a significant speed
+ * increase for Ajax source and Javascript source data, but makes no
+ * difference at all fro DOM and server-side processing tables.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bDeferRender": null,
+
+ /**
+ * Enable filtering on the table or not. Note that if this is disabled
+ * then there is no filtering at all on the table, including fnFilter.
+ * To just remove the filtering input use sDom and remove the 'f' option.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bFilter": null,
+
+ /**
+ * Table information element (the 'Showing x of y records' div) enable
+ * flag.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bInfo": null,
+
+ /**
+ * Present a user control allowing the end user to change the page size
+ * when pagination is enabled.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bLengthChange": null,
+
+ /**
+ * Pagination enabled or not. Note that if this is disabled then length
+ * changing must also be disabled.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bPaginate": null,
+
+ /**
+ * Processing indicator enable flag whenever DataTables is enacting a
+ * user request - typically an Ajax request for server-side processing.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bProcessing": null,
+
+ /**
+ * Server-side processing enabled flag - when enabled DataTables will
+ * get all data from the server for every draw - there is no filtering,
+ * sorting or paging done on the client-side.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bServerSide": null,
+
+ /**
+ * Sorting enablement flag.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bSort": null,
+
+ /**
+ * Apply a class to the columns which are being sorted to provide a
+ * visual highlight or not. This can slow things down when enabled since
+ * there is a lot of DOM interaction.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bSortClasses": null,
+
+ /**
+ * State saving enablement flag.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bStateSave": null
+ },
+
+
+ /**
+ * Scrolling settings for a table.
+ * @namespace
+ */
+ "oScroll": {
+ /**
+ * Indicate if DataTables should be allowed to set the padding / margin
+ * etc for the scrolling header elements or not. Typically you will want
+ * this.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bAutoCss": null,
+
+ /**
+ * When the table is shorter in height than sScrollY, collapse the
+ * table container down to the height of the table (when true).
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bCollapse": null,
+
+ /**
+ * Infinite scrolling enablement flag. Now deprecated in favour of
+ * using the Scroller plug-in.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bInfinite": null,
+
+ /**
+ * Width of the scrollbar for the web-browser's platform. Calculated
+ * during table initialisation.
+ * @type int
+ * @default 0
+ */
+ "iBarWidth": 0,
+
+ /**
+ * Space (in pixels) between the bottom of the scrolling container and
+ * the bottom of the scrolling viewport before the next page is loaded
+ * when using infinite scrolling.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type int
+ */
+ "iLoadGap": null,
+
+ /**
+ * Viewport width for horizontal scrolling. Horizontal scrolling is
+ * disabled if an empty string.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ */
+ "sX": null,
+
+ /**
+ * Width to expand the table to when using x-scrolling. Typically you
+ * should not need to use this.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ * @deprecated
+ */
+ "sXInner": null,
+
+ /**
+ * Viewport height for vertical scrolling. Vertical scrolling is disabled
+ * if an empty string.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ */
+ "sY": null
+ },
+
+ /**
+ * Language information for the table.
+ * @namespace
+ * @extends DataTable.defaults.oLanguage
+ */
+ "oLanguage": {
+ /**
+ * Information callback function. See
+ * {@link DataTable.defaults.fnInfoCallback}
+ * @type function
+ * @default
+ */
+ "fnInfoCallback": null
+ },
+
+ /**
+ * Array referencing the nodes which are used for the features. The
+ * parameters of this object match what is allowed by sDom - i.e.
+ *
+ *
'l' - Length changing
+ *
'f' - Filtering input
+ *
't' - The table!
+ *
'i' - Information
+ *
'p' - Pagination
+ *
'r' - pRocessing
+ *
+ * @type array
+ * @default []
+ */
+ "aanFeatures": [],
+
+ /**
+ * Store data information - see {@link DataTable.models.oRow} for detailed
+ * information.
+ * @type array
+ * @default []
+ */
+ "aoData": [],
+
+ /**
+ * Array of indexes which are in the current display (after filtering etc)
+ * @type array
+ * @default []
+ */
+ "aiDisplay": [],
+
+ /**
+ * Array of indexes for display - no filtering
+ * @type array
+ * @default []
+ */
+ "aiDisplayMaster": [],
+
+ /**
+ * Store information about each column that is in use
+ * @type array
+ * @default []
+ */
+ "aoColumns": [],
+
+ /**
+ * Store information about the table's header
+ * @type array
+ * @default []
+ */
+ "aoHeader": [],
+
+ /**
+ * Store information about the table's footer
+ * @type array
+ * @default []
+ */
+ "aoFooter": [],
+
+ /**
+ * Search data array for regular expression searching
+ * @type array
+ * @default []
+ */
+ "asDataSearch": [],
+
+ /**
+ * Store the applied global search information in case we want to force a
+ * research or compare the old search to a new one.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @namespace
+ * @extends DataTable.models.oSearch
+ */
+ "oPreviousSearch": {},
+
+ /**
+ * Store the applied search for each column - see
+ * {@link DataTable.models.oSearch} for the format that is used for the
+ * filtering information for each column.
+ * @type array
+ * @default []
+ */
+ "aoPreSearchCols": [],
+
+ /**
+ * Sorting that is applied to the table. Note that the inner arrays are
+ * used in the following manner:
+ *
+ *
Index 0 - column number
+ *
Index 1 - current sorting direction
+ *
Index 2 - index of asSorting for this column
+ *
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type array
+ * @todo These inner arrays should really be objects
+ */
+ "aaSorting": null,
+
+ /**
+ * Sorting that is always applied to the table (i.e. prefixed in front of
+ * aaSorting).
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type array|null
+ * @default null
+ */
+ "aaSortingFixed": null,
+
+ /**
+ * Classes to use for the striping of a table.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type array
+ * @default []
+ */
+ "asStripeClasses": null,
+
+ /**
+ * If restoring a table - we should restore its striping classes as well
+ * @type array
+ * @default []
+ */
+ "asDestroyStripes": [],
+
+ /**
+ * If restoring a table - we should restore its width
+ * @type int
+ * @default 0
+ */
+ "sDestroyWidth": 0,
+
+ /**
+ * Callback functions array for every time a row is inserted (i.e. on a draw).
+ * @type array
+ * @default []
+ */
+ "aoRowCallback": [],
+
+ /**
+ * Callback functions for the header on each draw.
+ * @type array
+ * @default []
+ */
+ "aoHeaderCallback": [],
+
+ /**
+ * Callback function for the footer on each draw.
+ * @type array
+ * @default []
+ */
+ "aoFooterCallback": [],
+
+ /**
+ * Array of callback functions for draw callback functions
+ * @type array
+ * @default []
+ */
+ "aoDrawCallback": [],
+
+ /**
+ * Array of callback functions for row created function
+ * @type array
+ * @default []
+ */
+ "aoRowCreatedCallback": [],
+
+ /**
+ * Callback functions for just before the table is redrawn. A return of
+ * false will be used to cancel the draw.
+ * @type array
+ * @default []
+ */
+ "aoPreDrawCallback": [],
+
+ /**
+ * Callback functions for when the table has been initialised.
+ * @type array
+ * @default []
+ */
+ "aoInitComplete": [],
+
+
+ /**
+ * Callbacks for modifying the settings to be stored for state saving, prior to
+ * saving state.
+ * @type array
+ * @default []
+ */
+ "aoStateSaveParams": [],
+
+ /**
+ * Callbacks for modifying the settings that have been stored for state saving
+ * prior to using the stored values to restore the state.
+ * @type array
+ * @default []
+ */
+ "aoStateLoadParams": [],
+
+ /**
+ * Callbacks for operating on the settings object once the saved state has been
+ * loaded
+ * @type array
+ * @default []
+ */
+ "aoStateLoaded": [],
+
+ /**
+ * Cache the table ID for quick access
+ * @type string
+ * @default Empty string
+ */
+ "sTableId": "",
+
+ /**
+ * The TABLE node for the main table
+ * @type node
+ * @default null
+ */
+ "nTable": null,
+
+ /**
+ * Permanent ref to the thead element
+ * @type node
+ * @default null
+ */
+ "nTHead": null,
+
+ /**
+ * Permanent ref to the tfoot element - if it exists
+ * @type node
+ * @default null
+ */
+ "nTFoot": null,
+
+ /**
+ * Permanent ref to the tbody element
+ * @type node
+ * @default null
+ */
+ "nTBody": null,
+
+ /**
+ * Cache the wrapper node (contains all DataTables controlled elements)
+ * @type node
+ * @default null
+ */
+ "nTableWrapper": null,
+
+ /**
+ * Indicate if when using server-side processing the loading of data
+ * should be deferred until the second draw.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ * @default false
+ */
+ "bDeferLoading": false,
+
+ /**
+ * Indicate if all required information has been read in
+ * @type boolean
+ * @default false
+ */
+ "bInitialised": false,
+
+ /**
+ * Information about open rows. Each object in the array has the parameters
+ * 'nTr' and 'nParent'
+ * @type array
+ * @default []
+ */
+ "aoOpenRows": [],
+
+ /**
+ * Dictate the positioning of DataTables' control elements - see
+ * {@link DataTable.model.oInit.sDom}.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ * @default null
+ */
+ "sDom": null,
+
+ /**
+ * Which type of pagination should be used.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ * @default two_button
+ */
+ "sPaginationType": "two_button",
+
+ /**
+ * The cookie duration (for bStateSave) in seconds.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type int
+ * @default 0
+ */
+ "iCookieDuration": 0,
+
+ /**
+ * The cookie name prefix.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ * @default Empty string
+ */
+ "sCookiePrefix": "",
+
+ /**
+ * Callback function for cookie creation.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type function
+ * @default null
+ */
+ "fnCookieCallback": null,
+
+ /**
+ * Array of callback functions for state saving. Each array element is an
+ * object with the following parameters:
+ *
+ *
function:fn - function to call. Takes two parameters, oSettings
+ * and the JSON string to save that has been thus far created. Returns
+ * a JSON string to be inserted into a json object
+ * (i.e. '"param": [ 0, 1, 2]')
+ *
string:sName - name of callback
+ *
+ * @type array
+ * @default []
+ */
+ "aoStateSave": [],
+
+ /**
+ * Array of callback functions for state loading. Each array element is an
+ * object with the following parameters:
+ *
+ *
function:fn - function to call. Takes two parameters, oSettings
+ * and the object stored. May return false to cancel state loading
+ *
string:sName - name of callback
+ *
+ * @type array
+ * @default []
+ */
+ "aoStateLoad": [],
+
+ /**
+ * State that was loaded from the cookie. Useful for back reference
+ * @type object
+ * @default null
+ */
+ "oLoadedState": null,
+
+ /**
+ * Source url for AJAX data for the table.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ * @default null
+ */
+ "sAjaxSource": null,
+
+ /**
+ * Property from a given object from which to read the table data from. This
+ * can be an empty string (when not server-side processing), in which case
+ * it is assumed an an array is given directly.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ */
+ "sAjaxDataProp": null,
+
+ /**
+ * Note if draw should be blocked while getting data
+ * @type boolean
+ * @default true
+ */
+ "bAjaxDataGet": true,
+
+ /**
+ * The last jQuery XHR object that was used for server-side data gathering.
+ * This can be used for working with the XHR information in one of the
+ * callbacks
+ * @type object
+ * @default null
+ */
+ "jqXHR": null,
+
+ /**
+ * Function to get the server-side data.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type function
+ */
+ "fnServerData": null,
+
+ /**
+ * Functions which are called prior to sending an Ajax request so extra
+ * parameters can easily be sent to the server
+ * @type array
+ * @default []
+ */
+ "aoServerParams": [],
+
+ /**
+ * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if
+ * required).
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type string
+ */
+ "sServerMethod": null,
+
+ /**
+ * Format numbers for display.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type function
+ */
+ "fnFormatNumber": null,
+
+ /**
+ * List of options that can be used for the user selectable length menu.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type array
+ * @default []
+ */
+ "aLengthMenu": null,
+
+ /**
+ * Counter for the draws that the table does. Also used as a tracker for
+ * server-side processing
+ * @type int
+ * @default 0
+ */
+ "iDraw": 0,
+
+ /**
+ * Indicate if a redraw is being done - useful for Ajax
+ * @type boolean
+ * @default false
+ */
+ "bDrawing": false,
+
+ /**
+ * Draw index (iDraw) of the last error when parsing the returned data
+ * @type int
+ * @default -1
+ */
+ "iDrawError": -1,
+
+ /**
+ * Paging display length
+ * @type int
+ * @default 10
+ */
+ "_iDisplayLength": 10,
+
+ /**
+ * Paging start point - aiDisplay index
+ * @type int
+ * @default 0
+ */
+ "_iDisplayStart": 0,
+
+ /**
+ * Paging end point - aiDisplay index. Use fnDisplayEnd rather than
+ * this property to get the end point
+ * @type int
+ * @default 10
+ * @private
+ */
+ "_iDisplayEnd": 10,
+
+ /**
+ * Server-side processing - number of records in the result set
+ * (i.e. before filtering), Use fnRecordsTotal rather than
+ * this property to get the value of the number of records, regardless of
+ * the server-side processing setting.
+ * @type int
+ * @default 0
+ * @private
+ */
+ "_iRecordsTotal": 0,
+
+ /**
+ * Server-side processing - number of records in the current display set
+ * (i.e. after filtering). Use fnRecordsDisplay rather than
+ * this property to get the value of the number of records, regardless of
+ * the server-side processing setting.
+ * @type boolean
+ * @default 0
+ * @private
+ */
+ "_iRecordsDisplay": 0,
+
+ /**
+ * Flag to indicate if jQuery UI marking and classes should be used.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bJUI": null,
+
+ /**
+ * The classes to use for the table
+ * @type object
+ * @default {}
+ */
+ "oClasses": {},
+
+ /**
+ * Flag attached to the settings object so you can check in the draw
+ * callback if filtering has been done in the draw. Deprecated in favour of
+ * events.
+ * @type boolean
+ * @default false
+ * @deprecated
+ */
+ "bFiltered": false,
+
+ /**
+ * Flag attached to the settings object so you can check in the draw
+ * callback if sorting has been done in the draw. Deprecated in favour of
+ * events.
+ * @type boolean
+ * @default false
+ * @deprecated
+ */
+ "bSorted": false,
+
+ /**
+ * Indicate that if multiple rows are in the header and there is more than
+ * one unique cell per column, if the top one (true) or bottom one (false)
+ * should be used for sorting / title by DataTables.
+ * Note that this parameter will be set by the initialisation routine. To
+ * set a default use {@link DataTable.defaults}.
+ * @type boolean
+ */
+ "bSortCellsTop": null,
+
+ /**
+ * Initialisation object that is used for the table
+ * @type object
+ * @default null
+ */
+ "oInit": null,
+
+ /**
+ * Destroy callback functions - for plug-ins to attach themselves to the
+ * destroy so they can clean up markup and events.
+ * @type array
+ * @default []
+ */
+ "aoDestroyCallback": [],
+
+
+ /**
+ * Get the number of records in the current record set, before filtering
+ * @type function
+ */
+ "fnRecordsTotal": function ()
+ {
+ if ( this.oFeatures.bServerSide ) {
+ return parseInt(this._iRecordsTotal, 10);
+ } else {
+ return this.aiDisplayMaster.length;
+ }
+ },
+
+ /**
+ * Get the number of records in the current record set, after filtering
+ * @type function
+ */
+ "fnRecordsDisplay": function ()
+ {
+ if ( this.oFeatures.bServerSide ) {
+ return parseInt(this._iRecordsDisplay, 10);
+ } else {
+ return this.aiDisplay.length;
+ }
+ },
+
+ /**
+ * Set the display end point - aiDisplay index
+ * @type function
+ * @todo Should do away with _iDisplayEnd and calculate it on-the-fly here
+ */
+ "fnDisplayEnd": function ()
+ {
+ if ( this.oFeatures.bServerSide ) {
+ if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) {
+ return this._iDisplayStart+this.aiDisplay.length;
+ } else {
+ return Math.min( this._iDisplayStart+this._iDisplayLength,
+ this._iRecordsDisplay );
+ }
+ } else {
+ return this._iDisplayEnd;
+ }
+ },
+
+ /**
+ * The DataTables object for this table
+ * @type object
+ * @default null
+ */
+ "oInstance": null,
+
+ /**
+ * Unique identifier for each instance of the DataTables object. If there
+ * is an ID on the table node, then it takes that value, otherwise an
+ * incrementing internal counter is used.
+ * @type string
+ * @default null
+ */
+ "sInstance": null,
+
+ /**
+ * tabindex attribute value that is added to DataTables control elements, allowing
+ * keyboard navigation of the table and its controls.
+ */
+ "iTabIndex": 0
+ };
+
+ /**
+ * Extension object for DataTables that is used to provide all extension options.
+ *
+ * Note that the DataTable.ext object is available through
+ * jQuery.fn.dataTable.ext where it may be accessed and manipulated. It is
+ * also aliased to jQuery.fn.dataTableExt for historic reasons.
+ * @namespace
+ * @extends DataTable.models.ext
+ */
+ DataTable.ext = $.extend( true, {}, DataTable.models.ext );
+
+ $.extend( DataTable.ext.oStdClasses, {
+ "sTable": "dataTable",
+
+ /* Two buttons buttons */
+ "sPagePrevEnabled": "paginate_enabled_previous",
+ "sPagePrevDisabled": "paginate_disabled_previous",
+ "sPageNextEnabled": "paginate_enabled_next",
+ "sPageNextDisabled": "paginate_disabled_next",
+ "sPageJUINext": "",
+ "sPageJUIPrev": "",
+
+ /* Full numbers paging buttons */
+ "sPageButton": "paginate_button",
+ "sPageButtonActive": "paginate_active",
+ "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled",
+ "sPageFirst": "first",
+ "sPagePrevious": "previous",
+ "sPageNext": "next",
+ "sPageLast": "last",
+
+ /* Striping classes */
+ "sStripeOdd": "odd",
+ "sStripeEven": "even",
+
+ /* Empty row */
+ "sRowEmpty": "dataTables_empty",
+
+ /* Features */
+ "sWrapper": "dataTables_wrapper",
+ "sFilter": "dataTables_filter",
+ "sInfo": "dataTables_info",
+ "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */
+ "sLength": "dataTables_length",
+ "sProcessing": "dataTables_processing",
+
+ /* Sorting */
+ "sSortAsc": "sorting_asc",
+ "sSortDesc": "sorting_desc",
+ "sSortable": "sorting", /* Sortable in both directions */
+ "sSortableAsc": "sorting_asc_disabled",
+ "sSortableDesc": "sorting_desc_disabled",
+ "sSortableNone": "sorting_disabled",
+ "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */
+ "sSortJUIAsc": "",
+ "sSortJUIDesc": "",
+ "sSortJUI": "",
+ "sSortJUIAscAllowed": "",
+ "sSortJUIDescAllowed": "",
+ "sSortJUIWrapper": "",
+ "sSortIcon": "",
+
+ /* Scrolling */
+ "sScrollWrapper": "dataTables_scroll",
+ "sScrollHead": "dataTables_scrollHead",
+ "sScrollHeadInner": "dataTables_scrollHeadInner",
+ "sScrollBody": "dataTables_scrollBody",
+ "sScrollFoot": "dataTables_scrollFoot",
+ "sScrollFootInner": "dataTables_scrollFootInner",
+
+ /* Misc */
+ "sFooterTH": ""
+ } );
+
+
+ $.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, {
+ /* Two buttons buttons */
+ "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left",
+ "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",
+ "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right",
+ "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",
+ "sPageJUINext": "ui-icon ui-icon-circle-arrow-e",
+ "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w",
+
+ /* Full numbers paging buttons */
+ "sPageButton": "fg-button ui-button ui-state-default",
+ "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled",
+ "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled",
+ "sPageFirst": "first ui-corner-tl ui-corner-bl",
+ "sPageLast": "last ui-corner-tr ui-corner-br",
+
+ /* Features */
+ "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+
+ "ui-buttonset-multi paging_", /* Note that the type is postfixed */
+
+ /* Sorting */
+ "sSortAsc": "ui-state-default",
+ "sSortDesc": "ui-state-default",
+ "sSortable": "ui-state-default",
+ "sSortableAsc": "ui-state-default",
+ "sSortableDesc": "ui-state-default",
+ "sSortableNone": "ui-state-default",
+ "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n",
+ "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s",
+ "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s",
+ "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n",
+ "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s",
+ "sSortJUIWrapper": "DataTables_sort_wrapper",
+ "sSortIcon": "DataTables_sort_icon",
+
+ /* Scrolling */
+ "sScrollHead": "dataTables_scrollHead ui-state-default",
+ "sScrollFoot": "dataTables_scrollFoot ui-state-default",
+
+ /* Misc */
+ "sFooterTH": "ui-state-default"
+ } );
+
+
+ /*
+ * Variable: oPagination
+ * Purpose:
+ * Scope: jQuery.fn.dataTableExt
+ */
+ $.extend( DataTable.ext.oPagination, {
+ /*
+ * Variable: two_button
+ * Purpose: Standard two button (forward/back) pagination
+ * Scope: jQuery.fn.dataTableExt.oPagination
+ */
+ "two_button": {
+ /*
+ * Function: oPagination.two_button.fnInit
+ * Purpose: Initialise dom elements required for pagination with forward/back buttons only
+ * Returns: -
+ * Inputs: object:oSettings - dataTables settings object
+ * node:nPaging - the DIV which contains this pagination control
+ * function:fnCallbackDraw - draw function which must be called on update
+ */
+ "fnInit": function ( oSettings, nPaging, fnCallbackDraw )
+ {
+ var oLang = oSettings.oLanguage.oPaginate;
+ var oClasses = oSettings.oClasses;
+ var fnClickHandler = function ( e ) {
+ if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) )
+ {
+ fnCallbackDraw( oSettings );
+ }
+ };
+
+ var sAppend = (!oSettings.bJUI) ?
+ ''+oLang.sPrevious+''+
+ ''+oLang.sNext+''
+ :
+ ''+
+ '';
+ $(nPaging).append( sAppend );
+
+ var els = $('a', nPaging);
+ var nPrevious = els[0],
+ nNext = els[1];
+
+ oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler );
+ oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
+
+ /* ID the first elements only */
+ if ( !oSettings.aanFeatures.p )
+ {
+ nPaging.id = oSettings.sTableId+'_paginate';
+ nPrevious.id = oSettings.sTableId+'_previous';
+ nNext.id = oSettings.sTableId+'_next';
+
+ nPrevious.setAttribute('aria-controls', oSettings.sTableId);
+ nNext.setAttribute('aria-controls', oSettings.sTableId);
+ }
+ },
+
+ /*
+ * Function: oPagination.two_button.fnUpdate
+ * Purpose: Update the two button pagination at the end of the draw
+ * Returns: -
+ * Inputs: object:oSettings - dataTables settings object
+ * function:fnCallbackDraw - draw function to call on page change
+ */
+ "fnUpdate": function ( oSettings, fnCallbackDraw )
+ {
+ if ( !oSettings.aanFeatures.p )
+ {
+ return;
+ }
+
+ var oClasses = oSettings.oClasses;
+ var an = oSettings.aanFeatures.p;
+
+ /* Loop over each instance of the pager */
+ for ( var i=0, iLen=an.length ; i'+oLang.sFirst+''+
+ ''+oLang.sPrevious+''+
+ ''+
+ ''+oLang.sNext+''+
+ ''+oLang.sLast+''
+ );
+ var els = $('a', nPaging);
+ var nFirst = els[0],
+ nPrev = els[1],
+ nNext = els[2],
+ nLast = els[3];
+
+ oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler );
+ oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler );
+ oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler );
+ oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler );
+
+ /* ID the first elements only */
+ if ( !oSettings.aanFeatures.p )
+ {
+ nPaging.id = oSettings.sTableId+'_paginate';
+ nFirst.id =oSettings.sTableId+'_first';
+ nPrev.id =oSettings.sTableId+'_previous';
+ nNext.id =oSettings.sTableId+'_next';
+ nLast.id =oSettings.sTableId+'_last';
+ }
+ },
+
+ /*
+ * Function: oPagination.full_numbers.fnUpdate
+ * Purpose: Update the list of page buttons shows
+ * Returns: -
+ * Inputs: object:oSettings - dataTables settings object
+ * function:fnCallbackDraw - draw function to call on page change
+ */
+ "fnUpdate": function ( oSettings, fnCallbackDraw )
+ {
+ if ( !oSettings.aanFeatures.p )
+ {
+ return;
+ }
+
+ var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages;
+ var iPageCountHalf = Math.floor(iPageCount / 2);
+ var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength);
+ var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
+ var sList = "";
+ var iStartButton, iEndButton, i, iLen;
+ var oClasses = oSettings.oClasses;
+ var anButtons, anStatic, nPaginateList;
+ var an = oSettings.aanFeatures.p;
+ var fnBind = function (j) {
+ oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) {
+ /* Use the information in the element to jump to the required page */
+ oSettings.oApi._fnPageChange( oSettings, e.data.page );
+ fnCallbackDraw( oSettings );
+ e.preventDefault();
+ } );
+ };
+
+ /* Pages calculation */
+ if (iPages < iPageCount)
+ {
+ iStartButton = 1;
+ iEndButton = iPages;
+ }
+ else if (iCurrentPage <= iPageCountHalf)
+ {
+ iStartButton = 1;
+ iEndButton = iPageCount;
+ }
+ else if (iCurrentPage >= (iPages - iPageCountHalf))
+ {
+ iStartButton = iPages - iPageCount + 1;
+ iEndButton = iPages;
+ }
+ else
+ {
+ iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1;
+ iEndButton = iStartButton + iPageCount - 1;
+ }
+
+ /* Build the dynamic list */
+ for ( i=iStartButton ; i<=iEndButton ; i++ )
+ {
+ sList += (iCurrentPage !== i) ?
+ ''+oSettings.fnFormatNumber(i)+'' :
+ ''+oSettings.fnFormatNumber(i)+'';
+ }
+
+ /* Loop over each instance of the pager */
+ for ( i=0, iLen=an.length ; i y) ? 1 : 0));
+ },
+
+ "string-desc": function ( x, y )
+ {
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
+ },
+
+
+ /*
+ * html sorting (ignore html tags)
+ */
+ "html-pre": function ( a )
+ {
+ return a.replace( /<.*?>/g, "" ).toLowerCase();
+ },
+
+ "html-asc": function ( x, y )
+ {
+ return ((x < y) ? -1 : ((x > y) ? 1 : 0));
+ },
+
+ "html-desc": function ( x, y )
+ {
+ return ((x < y) ? 1 : ((x > y) ? -1 : 0));
+ },
+
+
+ /*
+ * date sorting
+ */
+ "date-pre": function ( a )
+ {
+ var x = Date.parse( a );
+
+ if ( isNaN(x) || x==="" )
+ {
+ x = Date.parse( "01/01/1970 00:00:00" );
+ }
+ return x;
+ },
+
+ "date-asc": function ( x, y )
+ {
+ return x - y;
+ },
+
+ "date-desc": function ( x, y )
+ {
+ return y - x;
+ },
+
+
+ /*
+ * numerical sorting
+ */
+ "numeric-pre": function ( a )
+ {
+ return (a=="-" || a==="") ? 0 : a*1;
+ },
+
+ "numeric-asc": function ( x, y )
+ {
+ return x - y;
+ },
+
+ "numeric-desc": function ( x, y )
+ {
+ return y - x;
+ }
+ } );
+
+
+ $.extend( DataTable.ext.aTypes, [
+ /*
+ * Function: -
+ * Purpose: Check to see if a string is numeric
+ * Returns: string:'numeric' or null
+ * Inputs: mixed:sText - string to check
+ */
+ function ( sData )
+ {
+ /* Allow zero length strings as a number */
+ if ( typeof sData === 'number' )
+ {
+ return 'numeric';
+ }
+ else if ( typeof sData !== 'string' )
+ {
+ return null;
+ }
+
+ var sValidFirstChars = "0123456789-";
+ var sValidChars = "0123456789.";
+ var Char;
+ var bDecimal = false;
+
+ /* Check for a valid first char (no period and allow negatives) */
+ Char = sData.charAt(0);
+ if (sValidFirstChars.indexOf(Char) == -1)
+ {
+ return null;
+ }
+
+ /* Check all the other characters are valid */
+ for ( var i=1 ; i') != -1 )
+ {
+ return 'html';
+ }
+ return null;
+ }
+ ] );
+
+
+ // jQuery aliases
+ $.fn.DataTable = DataTable;
+ $.fn.dataTable = DataTable;
+ $.fn.dataTableSettings = DataTable.settings;
+ $.fn.dataTableExt = DataTable.ext;
+
+
+ // Information about events fired by DataTables - for documentation.
+ /**
+ * Draw event, fired whenever the table is redrawn on the page, at the same point as
+ * fnDrawCallback. This may be useful for binding events or performing calculations when
+ * the table is altered at all.
+ * @name DataTable#draw
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
+ */
+
+ /**
+ * Filter event, fired when the filtering applied to the table (using the build in global
+ * global filter, or column filters) is altered.
+ * @name DataTable#filter
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
+ */
+
+ /**
+ * Page change event, fired when the paging of the table is altered.
+ * @name DataTable#page
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
+ */
+
+ /**
+ * Sort event, fired when the sorting applied to the table is altered.
+ * @name DataTable#sort
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
+ */
+
+ /**
+ * DataTables initialisation complete event, fired when the table is fully drawn,
+ * including Ajax data loaded, if Ajax data is required.
+ * @name DataTable#init
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} oSettings DataTables settings object
+ * @param {object} json The JSON object request from the server - only
+ * present if client-side Ajax sourced data is used
+ */
+
+ /**
+ * State save event, fired when the table has changed state a new state save is required.
+ * This method allows modification of the state saving object prior to actually doing the
+ * save, including addition or other state properties (for plug-ins) or modification
+ * of a DataTables core property.
+ * @name DataTable#stateSaveParams
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} oSettings DataTables settings object
+ * @param {object} json The state information to be saved
+ */
+
+ /**
+ * State load event, fired when the table is loading state from the stored data, but
+ * prior to the settings object being modified by the saved state - allowing modification
+ * of the saved state is required or loading of state for a plug-in.
+ * @name DataTable#stateLoadParams
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} oSettings DataTables settings object
+ * @param {object} json The saved state information
+ */
+
+ /**
+ * State loaded event, fired when state has been loaded from stored data and the settings
+ * object has been modified by the loaded data.
+ * @name DataTable#stateLoaded
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} oSettings DataTables settings object
+ * @param {object} json The saved state information
+ */
+
+ /**
+ * Processing event, fired when DataTables is doing some kind of processing (be it,
+ * sort, filter or anything else). Can be used to indicate to the end user that
+ * there is something happening, or that something has finished.
+ * @name DataTable#processing
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} oSettings DataTables settings object
+ * @param {boolean} bShow Flag for if DataTables is doing processing or not
+ */
+
+ /**
+ * Ajax (XHR) event, fired whenever an Ajax request is completed from a request to
+ * made to the server for new data (note that this trigger is called in fnServerData,
+ * if you override fnServerData and which to use this event, you need to trigger it in
+ * you success function).
+ * @name DataTable#xhr
+ * @event
+ * @param {event} e jQuery event object
+ * @param {object} o DataTables settings object {@link DataTable.models.oSettings}
+ */
+}(jQuery, window, document, undefined));
diff --git a/airtime_mvc/public/js/datatables/js/jquery.dataTables.min.js b/airtime_mvc/public/js/datatables/js/jquery.dataTables.min.js
index 4280c6d63..bbbddb5b0 100644
--- a/airtime_mvc/public/js/datatables/js/jquery.dataTables.min.js
+++ b/airtime_mvc/public/js/datatables/js/jquery.dataTables.min.js
@@ -1,151 +1,153 @@
/*
* File: jquery.dataTables.min.js
- * Version: 1.8.2
+ * Version: 1.9.0
* Author: Allan Jardine (www.sprymedia.co.uk)
* Info: www.datatables.net
*
- * Copyright 2008-2011 Allan Jardine, all rights reserved.
+ * Copyright 2008-2012 Allan Jardine, all rights reserved.
*
* This source file is free software, under either the GPL v2 license or a
- * BSD style license, as supplied with this software.
+ * BSD style license, available at:
+ * http://datatables.net/license_gpl2
+ * http://datatables.net/license_bsd
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
*/
-(function(i,za,p){i.fn.dataTableSettings=[];var D=i.fn.dataTableSettings;i.fn.dataTableExt={};var n=i.fn.dataTableExt;n.sVersion="1.8.2";n.sErrMode="alert";n.iApiIndex=0;n.oApi={};n.afnFiltering=[];n.aoFeatures=[];n.ofnSearch={};n.afnSortData=[];n.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",
-sPageButtonStaticDisabled:"paginate_button paginate_button_disabled",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",
-sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""};n.oJUIClasses={sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",
-sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",
-sPageFirst:"first ui-corner-tl ui-corner-bl",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",
-sSortableAsc:"ui-state-default",sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollWrapper:"dataTables_scroll",
-sScrollHead:"dataTables_scrollHead ui-state-default",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot ui-state-default",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"ui-state-default"};n.oPagination={two_button:{fnInit:function(g,l,s){var t,w,y;if(g.bJUI){t=p.createElement("a");w=p.createElement("a");y=p.createElement("span");y.className=g.oClasses.sPageJUINext;w.appendChild(y);y=p.createElement("span");y.className=g.oClasses.sPageJUIPrev;
-t.appendChild(y)}else{t=p.createElement("div");w=p.createElement("div")}t.className=g.oClasses.sPagePrevDisabled;w.className=g.oClasses.sPageNextDisabled;t.title=g.oLanguage.oPaginate.sPrevious;w.title=g.oLanguage.oPaginate.sNext;l.appendChild(t);l.appendChild(w);i(t).bind("click.DT",function(){g.oApi._fnPageChange(g,"previous")&&s(g)});i(w).bind("click.DT",function(){g.oApi._fnPageChange(g,"next")&&s(g)});i(t).bind("selectstart.DT",function(){return false});i(w).bind("selectstart.DT",function(){return false});
-if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){l.setAttribute("id",g.sTableId+"_paginate");t.setAttribute("id",g.sTableId+"_previous");w.setAttribute("id",g.sTableId+"_next")}},fnUpdate:function(g){if(g.aanFeatures.p)for(var l=g.aanFeatures.p,s=0,t=l.length;s=w-t){t=w-s+1;x=w}else{t=y-Math.ceil(s/2)+1;x=t+s-1}for(s=t;s<=x;s++)F+=y!=s?''+s+"":''+s+"";x=g.aanFeatures.p;var z,$=function(M){g._iDisplayStart=(this.innerHTML*1-1)*g._iDisplayLength;l(g);M.preventDefault()},X=function(){return false};s=0;for(t=x.length;sl?1:0},"string-desc":function(g,l){if(typeof g!="string")g="";if(typeof l!="string")l="";g=g.toLowerCase();l=l.toLowerCase();return gl?-1:0},"html-asc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return g<
-l?-1:g>l?1:0},"html-desc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return gl?-1:0},"date-asc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return g-l},"date-desc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return l-
-g},"numeric-asc":function(g,l){return(g=="-"||g===""?0:g*1)-(l=="-"||l===""?0:l*1)},"numeric-desc":function(g,l){return(l=="-"||l===""?0:l*1)-(g=="-"||g===""?0:g*1)}};n.aTypes=[function(g){if(typeof g=="number")return"numeric";else if(typeof g!="string")return null;var l,s=false;l=g.charAt(0);if("0123456789-".indexOf(l)==-1)return null;for(var t=1;t")!=-1)return"html";return null}];n.fnVersionCheck=function(g){var l=function(x,v){for(;x.length=parseInt(w,10)};n._oExternConfig={iNextUnique:0};i.fn.dataTable=function(g){function l(){this.fnRecordsTotal=
-function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||this._iDisplayLength==-1?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance=
-this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false,bDeferRender:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0,bAutoCss:true};this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sEmptyTable:"No data available in table",
-sLoadingRecords:"Loading...",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sInfoThousands:",",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.aoHeader=[];this.aoFooter=[];this.iNextId=0;this.asDataSearch=[];this.oPreviousSearch={sSearch:"",
-bRegex:false,bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripeClasses=[];this.asDestroyStripes=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=this.fnPreDrawCallback=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=this.bDeferLoading=false;this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType=
-"two_button";this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.sAjaxDataProp="aaData";this.bAjaxDataGet=true;this.jqXHR=null;this.fnServerData=function(a,b,c,d){d.jqXHR=i.ajax({url:a,data:b,success:function(f){i(d.oInstance).trigger("xhr",d);c(f)},dataType:"json",cache:false,error:function(f,e){e=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})};
-this.aoServerParams=[];this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b=a+"";a=b.split("");var c="";b=b.length;for(var d=0;d=0;e--)!a.aoColumns[e].bVisible&&!c&&h[d].splice(e,1);j.push([])}d=0;for(f=h.length;d=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;E(a)}if(a.bDeferLoading){a.bDeferLoading=false;a.iDraw++}else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!Ca(a))return}else a.iDraw++;if(a.aiDisplay.length!==0){var h=a._iDisplayStart,j=a._iDisplayEnd;if(a.oFeatures.bServerSide){h=0;j=a.aoData.length}for(h=
-h;h=0;b--)c[b].parentNode.removeChild(c[b])}b=0;for(c=d.length;b=0;b--)a.aoDrawCallback[b].fn.call(a.oInstance,a);i(a.oInstance).trigger("draw",a);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(a.oFeatures.bServerSide){K(a,false);typeof a._bInitComplete=="undefined"&&w(a)}}}function da(a){if(a.oFeatures.bSort)R(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)N(a,
-a.oPreviousSearch);else{E(a);C(a)}}function Ca(a){if(a.bAjaxDataGet){a.iDraw++;K(a,true);var b=Da(a);ha(a,b);a.fnServerData.call(a.oInstance,a.sAjaxSource,b,function(c){Ea(a,c)},a);return false}else return true}function Da(a){var b=a.aoColumns.length,c=[],d,f;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:ka(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength:
--1});for(f=0;f")c=c.parentNode;else if(h=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){f=Ga(a);e=1}else if(h=="f"&&a.oFeatures.bFilter){f=Ha(a);e=1}else if(h=="r"&&a.oFeatures.bProcessing){f=Ia(a);e=1}else if(h=="t"){f=Ja(a);e=1}else if(h=="i"&&a.oFeatures.bInfo){f=Ka(a);e=1}else if(h=="p"&&a.oFeatures.bPaginate){f=La(a);e=1}else if(n.aoFeatures.length!==0){j=n.aoFeatures;u=0;for(k=j.length;ui(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()0&&a.nTable.removeChild(h[0]);if(a.nTFoot!==null){k=a.nTable.getElementsByTagName("tfoot");k.length>0&&a.nTable.removeChild(k[0])}h=a.nTHead.cloneNode(true);a.nTable.insertBefore(h,a.nTable.childNodes[0]);if(a.nTFoot!==null){k=a.nTFoot.cloneNode(true);
-a.nTable.insertBefore(k,a.nTable.childNodes[1])}if(a.oScroll.sX===""){d.style.width="100%";b.parentNode.style.width="100%"}var U=S(a,h);f=0;for(e=U.length;fd.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=q(i(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!==
-"")a.nTable.style.width=q(a.oScroll.sXInner);else if(f==i(d).width()&&i(d).height()f-a.oScroll.iBarWidth)a.nTable.style.width=q(f)}else a.nTable.style.width=q(f);f=i(a.nTable).outerWidth();e=a.nTHead.getElementsByTagName("tr");h=h.getElementsByTagName("tr");P(function(I,na){m=I.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;r=i(I).width();na.style.width=
-q(r);H.push(r)},h,e);i(h).height(0);if(a.nTFoot!==null){j=k.getElementsByTagName("tr");k=a.nTFoot.getElementsByTagName("tr");P(function(I,na){m=I.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;r=i(I).width();na.style.width=q(r);H.push(r)},j,k);i(j).height(0)}P(function(I){I.innerHTML="";I.style.width=q(H.shift())},h);a.nTFoot!==null&&P(function(I){I.innerHTML="";I.style.width=q(H.shift())},j);if(i(a.nTable).outerWidth()d.offsetHeight||
-i(d).css("overflow-y")=="scroll"?f+a.oScroll.iBarWidth:f;if(B&&(d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=q(j-a.oScroll.iBarWidth);d.style.width=q(j);b.parentNode.style.width=q(j);if(a.nTFoot!==null)L.parentNode.style.width=q(j);if(a.oScroll.sX==="")J(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width.");else a.oScroll.sXInner!==""&&J(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else{d.style.width=
-q("100%");b.parentNode.style.width=q("100%");if(a.nTFoot!==null)L.parentNode.style.width=q("100%")}if(a.oScroll.sY==="")if(B)d.style.height=q(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=q(a.oScroll.sY);B=a.oScroll.sX!==""&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight'):b===""?'':b+' ';var c=p.createElement("div");
-c.className=a.oClasses.sFilter;c.innerHTML="";a.sTableId!==""&&typeof a.aanFeatures.f=="undefined"&&c.setAttribute("id",a.sTableId+"_filter");b=i("input",c);b.val(a.oPreviousSearch.sSearch.replace('"',"""));b.bind("keyup.DT",function(){for(var d=a.aanFeatures.f,f=0,e=d.length;f=0;d--){f=qa(G(a,a.aiDisplay[d],c,"filter"),a.aoColumns[c].sType);if(!b.test(f)){a.aiDisplay.splice(d,1);e++}}}}function Oa(a,b,c,d,f){var e=pa(b,d,f);if(typeof c=="undefined"||c===null)c=0;if(n.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||
-a.oPreviousSearch.sSearch.length>b.length||c==1||b.indexOf(a.oPreviousSearch.sSearch)!==0){a.aiDisplay.splice(0,a.aiDisplay.length);oa(a,1);for(c=0;c/g,"");else if(typeof a=="string")return a.replace(/\n/g," ");else if(a===null)return"";return a}function R(a,b){var c,d,f,e,h=[],j=[],k=n.oSort;d=a.aoData;var m=a.aoColumns;if(!a.oFeatures.bServerSide&&
-(a.aaSorting.length!==0||a.aaSortingFixed!==null)){h=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c=h)for(b=0;b=0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength=0){b=parseInt((a.fnRecordsDisplay()-
-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else J(a,0,"Unknown paging action: "+b);i(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}function Ka(a){var b=p.createElement("div");b.className=a.oClasses.sInfo;if(typeof a.aanFeatures.i=="undefined"){a.aoDrawCallback.push({fn:Ra,sName:"information"});a.sTableId!==""&&b.setAttribute("id",a.sTableId+"_info")}return b}function Ra(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a._iDisplayStart+
-1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),e=a.fnFormatNumber(b),h=a.fnFormatNumber(c),j=a.fnFormatNumber(d),k=a.fnFormatNumber(f);if(a.oScroll.bInfinite)e=a.fnFormatNumber(1);e=a.fnRecordsDisplay()===0&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()===0?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",j)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",
-e).replace("_END_",h).replace("_TOTAL_",k)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",e).replace("_END_",h).replace("_TOTAL_",k)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;if(a.oLanguage.fnInfoCallback!==null)e=a.oLanguage.fnInfoCallback(a,b,c,d,f,e);a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d;if(a.aLengthMenu.length==2&&typeof a.aLengthMenu[0]=="object"&&typeof a.aLengthMenu[1]=="object"){c=0;for(d=a.aLengthMenu[0].length;c'+a.aLengthMenu[1][c]+""}else{c=0;for(d=a.aLengthMenu.length;c'+a.aLengthMenu[c]+""}b+="";var f=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.l=="undefined"&&f.setAttribute("id",a.sTableId+"_length");
-f.className=a.oClasses.sLength;f.innerHTML="";i('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",true);i("select",f).bind("change.DT",function(){var e=i(this).val(),h=a.aanFeatures.l;c=0;for(d=h.length;ca.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Sa(a,b){if(!a||a===null||a==="")return 0;if(typeof b=="undefined")b=p.getElementsByTagName("body")[0];var c=p.createElement("div");c.style.width=q(a);b.appendChild(c);a=c.offsetWidth;b.removeChild(c);return a}function ga(a){var b=0,c,d=0,f=a.aoColumns.length,e,h=i("th",
-a.nTHead);for(e=0;etd",b);h=S(a,e);for(e=d=0;e0)a.aoColumns[e].sWidth=q(c);d++}a.nTable.style.width=q(i(b).outerWidth());b.parentNode.removeChild(b)}}function Ua(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){i(b).width();b.style.width=q(i(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!==
-"")b.style.width=q(i(b).outerWidth())}function Ta(a,b){var c=Va(a,b);if(c<0)return null;if(a.aoData[c].nTr===null){var d=p.createElement("td");d.innerHTML=G(a,c,b,"");return d}return Q(a,c)[b]}function Va(a,b){for(var c=-1,d=-1,f=0;f/g,"");if(e.length>c){c=e.length;d=f}}return d}function q(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b=a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+
-"px"}function Za(a,b){if(a.length!=b.length)return 1;for(var c=0;cb&&a[d]--;c!=-1&&a.splice(c,1)}function Fa(a,b){b=b.split(",");for(var c=[],d=0,f=a.aoColumns.length;d4096){a=p.cookie.split(";");for(var j=0,k=a.length;j=d.aiDisplay.length){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(typeof c=="undefined"||c){E(d);C(d)}return f};this.fnClearTable=function(a){var b=A(this[n.iApiIndex]);la(b);if(typeof a=="undefined"||a)C(b)};this.fnOpen=function(a,b,c){var d=A(this[n.iApiIndex]);this.fnClose(a);var f=p.createElement("tr"),e=p.createElement("td");f.appendChild(e);e.className=c;
-e.colSpan=Z(d);if(typeof b.jquery!="undefined"||typeof b=="object")e.appendChild(b);else e.innerHTML=b;b=i("tr",d.nTBody);i.inArray(a,b)!=-1&&i(f).insertAfter(a);d.aoOpenRows.push({nTr:f,nParent:a});return f};this.fnClose=function(a){for(var b=A(this[n.iApiIndex]),c=0;c=Z(d);if(!j)for(f=a;ftr>td."+a.oClasses.sRowEmpty,a.nTable).parent().remove();
-if(a.nTable!=a.nTHead.parentNode){i(a.nTable).children("thead").remove();a.nTable.appendChild(a.nTHead)}if(a.nTFoot&&a.nTable!=a.nTFoot.parentNode){i(a.nTable).children("tfoot").remove();a.nTable.appendChild(a.nTFoot)}a.nTable.parentNode.removeChild(a.nTable);i(a.nTableWrapper).remove();a.aaSorting=[];a.aaSortingFixed=[];V(a);i(ba(a)).removeClass(a.asStripeClasses.join(" "));if(a.bJUI){i("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oJUIClasses.sSortableAsc,n.oJUIClasses.sSortableDesc,n.oJUIClasses.sSortableNone].join(" "));
-i("th span."+n.oJUIClasses.sSortIcon,a.nTHead).remove();i("th",a.nTHead).each(function(){var e=i("div."+n.oJUIClasses.sSortJUIWrapper,this),h=e.contents();i(this).append(h);e.remove()})}else i("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oStdClasses.sSortableAsc,n.oStdClasses.sSortableDesc,n.oStdClasses.sSortableNone].join(" "));a.nTableReinsertBefore?b.insertBefore(a.nTable,a.nTableReinsertBefore):b.appendChild(a.nTable);d=0;for(f=a.aoData.length;dt<"F"ip>'}if(e.oScroll.sX!==""||e.oScroll.sY!==
-"")e.oScroll.iBarWidth=Ya();if(typeof g.iDisplayStart!="undefined"&&typeof e.iInitDisplayStart=="undefined"){e.iInitDisplayStart=g.iDisplayStart;e._iDisplayStart=g.iDisplayStart}if(typeof g.bStateSave!="undefined"){e.oFeatures.bStateSave=g.bStateSave;Xa(e,g);e.aoDrawCallback.push({fn:va,sName:"state_save"})}if(typeof g.iDeferLoading!="undefined"){e.bDeferLoading=true;e._iRecordsTotal=g.iDeferLoading;e._iRecordsDisplay=g.iDeferLoading}if(typeof g.aaData!="undefined")j=true;if(typeof g!="undefined"&&
-typeof g.aoData!="undefined")g.aoColumns=g.aoData;if(typeof g.oLanguage!="undefined")if(typeof g.oLanguage.sUrl!="undefined"&&g.oLanguage.sUrl!==""){e.oLanguage.sUrl=g.oLanguage.sUrl;i.getJSON(e.oLanguage.sUrl,null,function(u){y(e,u,true)});h=true}else y(e,g.oLanguage,false)}else g={};if(typeof g.asStripClasses=="undefined"&&typeof g.asStripeClasses=="undefined"){e.asStripeClasses.push(e.oClasses.sStripeOdd);e.asStripeClasses.push(e.oClasses.sStripeEven)}c=false;d=i(this).children("tbody").children("tr");
-a=0;for(b=e.asStripeClasses.length;a=0;a--){var m=
-g.aoColumnDefs[a].aTargets;i.isArray(m)||J(e,1,"aTargets must be an array of targets, not a "+typeof m);c=0;for(d=m.length;c=0){for(;e.aoColumns.length<=m[c];)F(e);x(e,m[c],g.aoColumnDefs[a])}else if(typeof m[c]=="number"&&m[c]<0)x(e,e.aoColumns.length+m[c],g.aoColumnDefs[a]);else if(typeof m[c]=="string"){b=0;for(f=e.aoColumns.length;b=e.aoColumns.length)e.aaSorting[a][0]=0;k=e.aoColumns[e.aaSorting[a][0]];if(typeof e.aaSorting[a][2]=="undefined")e.aaSorting[a][2]=0;if(typeof g.aaSorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k.asSorting[0];c=0;for(d=k.asSorting.length;c0){e.nTFoot=a[0];Y(e.aoFooter,e.nTFoot)}if(j)for(a=0;am[h])d(a.aoColumns.length+m[h],b[f]);else if("string"===typeof m[h])for(e=0,q=a.aoColumns.length;eb&&a[d]--; -1!=c&&a.splice(c,
+1)}function R(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mDataProp},w(a,b,c,"display"))}function ca(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=k.createElement("tr");c.nTr._DT_RowIndex=b;if(c._aData.DT_RowId)c.nTr.id=c._aData.DT_RowId;c._aData.DT_RowClass&&i(c.nTr).addClass(c._aData.DT_RowClass);for(var f=0,h=a.aoColumns.length;f=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,z(a);if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!va(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var g=a._iDisplayStart;c=a._iDisplayEnd;if(a.oFeatures.bServerSide)g=0,c=a.aoData.length;for(;g")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=i('')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),f,h,g,e,q,m,o,l=0;l")[0];q=d[l+1];if("'"==q||'"'==q){m="";for(o=2;d[l+o]!=q;)m+=d[l+o],
+o++;"H"==m?m="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix":"F"==m&&(m="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix");-1!=m.indexOf(".")?(q=m.split("."),e.id=q[0].substr(1,q[0].length-1),e.className=q[1]):"#"==m.charAt(0)?e.id=m.substr(1,m.length-1):e.className=m;l+=o}c.appendChild(e);c=e}else if(">"==g)c=c.parentNode;else if("l"==g&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)f=xa(a),h=1;else if("f"==g&&a.oFeatures.bFilter)f=
+ya(a),h=1;else if("r"==g&&a.oFeatures.bProcessing)f=za(a),h=1;else if("t"==g)f=Aa(a),h=1;else if("i"==g&&a.oFeatures.bInfo)f=Ba(a),h=1;else if("p"==g&&a.oFeatures.bPaginate)f=Ca(a),h=1;else if(0!==j.ext.aoFeatures.length){e=j.ext.aoFeatures;o=0;for(q=e.length;o'):""===c?'':c+' ',d=k.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="";if(!a.aanFeatures.f)d.id=a.sTableId+"_filter";c=i("input",
+d);c.val(b.sSearch.replace('"',"""));c.bind("keyup.DT",function(){for(var c=a.aanFeatures.f,d=0,g=c.length;d=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length||
+f.sSearch.length>b.length||1==c||0!==b.indexOf(f.sSearch)){a.aiDisplay.splice(0,a.aiDisplay.length);ia(a,1);for(b=0;b/g,""):"string"===typeof a?a.replace(/[\r\n]/g," "):null===a?"":a}function ma(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^)","g"),"\\$1")}function Ba(a){var b=k.createElement("div");b.className=a.oClasses.sInfo;if(!a.aanFeatures.i)a.aoDrawCallback.push({fn:Ia,sName:"information"}),b.id=a.sTableId+"_info";a.nTable.setAttribute("aria-describedby",
+a.sTableId+"_info");return b}function Ia(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var b=a._iDisplayStart+1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),h=a.fnFormatNumber(b),g=a.fnFormatNumber(c),e=a.fnFormatNumber(d),q=a.fnFormatNumber(f);a.oScroll.bInfinite&&(h=a.fnFormatNumber(1));h=0===a.fnRecordsDisplay()&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:0===a.fnRecordsDisplay()?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",
+e)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",h).replace("_END_",g).replace("_TOTAL_",q)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",h).replace("_END_",g).replace("_TOTAL_",q)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;null!==a.oLanguage.fnInfoCallback&&(h=a.oLanguage.fnInfoCallback.call(a.oInstance,a,b,c,d,f,h));a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d,f=a.aLengthMenu;if(2==f.length&&"object"===typeof f[0]&&"object"===typeof f[1])for(c=0,d=f[0].length;c'+f[1][c]+"";else for(c=0,d=f.length;c'+f[c]+"";b+="";f=k.createElement("div");if(!a.aanFeatures.l)f.id=a.sTableId+"_length";f.className=a.oClasses.sLength;f.innerHTML="";
+i('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",!0);i("select",f).bind("change.DT",function(){var b=i(this).val(),f=a.aanFeatures.l;for(c=0,d=f.length;ca._iDisplayStart))a._iDisplayStart=0;if(-1==a._iDisplayLength)a._iDisplayStart=0;y(a)});i("select",f).attr("aria-controls",a.sTableId);return f}
+function z(a){a._iDisplayEnd=!1===a.oFeatures.bPaginate?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Ca(a){if(a.oScroll.bInfinite)return null;var b=k.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;j.ext.oPagination[a.sPaginationType].fnInit(a,b,function(a){z(a);y(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){j.ext.oPagination[a.sPaginationType].fnUpdate(a,
+function(a){z(a);y(a)})},sName:"pagination"});return b}function oa(a,b){var c=a._iDisplayStart;if("number"===typeof b){if(a._iDisplayStart=b*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay())a._iDisplayStart=0}else if("first"==b)a._iDisplayStart=0;else if("previous"==b){if(a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart)a._iDisplayStart=0}else if("next"==b)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLengthi(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()=i.browser.version;g=a.nTable.getElementsByTagName("thead");0d.offsetHeight||"scroll"==i(d).css("overflow-y")))a.nTable.style.width=
+p(i(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(""!==a.oScroll.sXInner)a.nTable.style.width=p(a.oScroll.sXInner);else if(f==i(d).width()&&i(d).height()f-a.oScroll.iBarWidth)a.nTable.style.width=p(f)}else a.nTable.style.width=p(f);f=i(a.nTable).outerWidth();h=a.nTHead.getElementsByTagName("tr");g=g.getElementsByTagName("tr");N(function(a,b){m=a.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth=
+"0";m.borderBottomWidth="0";m.height=0;l=i(a).width();b.style.width=p(l);r.push(l)},g,h);i(g).height(0);null!==a.nTFoot&&(e=j.getElementsByTagName("tr"),j=a.nTFoot.getElementsByTagName("tr"),N(function(a,b){m=a.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;l=i(a).width();b.style.width=p(l);r.push(l)},e,j),i(e).height(0));N(function(a){a.innerHTML="";a.style.width=p(r.shift())},g);null!==a.nTFoot&&N(function(a){a.innerHTML="";a.style.width=p(r.shift())},
+e);if(i(a.nTable).outerWidth()d.offsetHeight||"scroll"==i(d).css("overflow-y")?f+a.oScroll.iBarWidth:f;if(k&&(d.scrollHeight>d.offsetHeight||"scroll"==i(d).css("overflow-y")))a.nTable.style.width=p(e-a.oScroll.iBarWidth);d.style.width=p(e);b.parentNode.style.width=p(e);if(null!==a.nTFoot)n.parentNode.style.width=p(e);""===a.oScroll.sX?F(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."):
+""!==a.oScroll.sXInner&&F(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else if(d.style.width=p("100%"),b.parentNode.style.width=p("100%"),null!==a.nTFoot)n.parentNode.style.width=p("100%");if(""===a.oScroll.sY&&k)d.style.height=p(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(""!==a.oScroll.sY&&a.oScroll.bCollapse&&(d.style.height=p(a.oScroll.sY),k=""!==a.oScroll.sX&&a.nTable.offsetWidth>
+d.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeighttd",b));g=O(a,
+h);for(h=d=0;hc)return null;if(null===a.aoData[c].nTr){var d=k.createElement("td");d.innerHTML=w(a,c,b,"");return d}return L(a,c)[b]}function Na(a,b){for(var c=-1,d=-1,f=0;f/g,"");if(h.length>c)c=h.length,d=f}return d}function p(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1);return 48>b||57=g)for(b=0;be&&e++}}}function pa(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b,c;b=a.oScroll.bInfinite;var d={iCreate:(new Date).getTime(),iStart:b?0:a._iDisplayStart,
+iEnd:b?a._iDisplayLength:a._iDisplayEnd,iLength:a._iDisplayLength,aaSorting:i.extend(!0,[],a.aaSorting),oSearch:i.extend(!0,{},a.oPreviousSearch),aoSearchCols:i.extend(!0,[],a.aoPreSearchCols),abVisCols:[]};for(b=0,c=a.aoColumns.length;b=d.aiDisplay.length&&(d._iDisplayStart-=d._iDisplayLength,0>d._iDisplayStart))d._iDisplayStart=0;if(c===l||c)z(d),y(d);return e};this.fnDestroy=function(a){var b=u(this[j.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,f,e,a=a===l?!1:!0;b.bDestroying=!0;for(f=0,e=b.aoDestroyCallback.length;ftr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();b.nTable!=b.nTHead.parentNode&&(i(b.nTable).children("thead").remove(),b.nTable.appendChild(b.nTHead));b.nTFoot&&b.nTable!=b.nTFoot.parentNode&&(i(b.nTable).children("tfoot").remove(),b.nTable.appendChild(b.nTFoot));b.nTable.parentNode.removeChild(b.nTable);i(b.nTableWrapper).remove();b.aaSorting=
+[];b.aaSortingFixed=[];Q(b);i(S(b)).removeClass(b.asStripeClasses.join(" "));i("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc,b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));b.bJUI&&(i("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove(),i("th, td",b.nTHead).each(function(){var a=i("div."+b.oClasses.sSortJUIWrapper,this),c=a.contents();i(this).append(c);a.remove()}));!a&&b.nTableReinsertBefore?c.insertBefore(b.nTable,b.nTableReinsertBefore):
+a||c.appendChild(b.nTable);for(f=0,e=b.aoData.length;f=v(d);if(!m)for(f=a;ft<"F"ip>'}else i.extend(g.oClasses,j.ext.oStdClasses);i(this).addClass(g.oClasses.sTable);if(""!==g.oScroll.sX||""!==g.oScroll.sY)g.oScroll.iBarWidth=Oa();if(g.iInitDisplayStart===l)g.iInitDisplayStart=e.iDisplayStart,g._iDisplayStart=e.iDisplayStart;if(e.bStateSave)g.oFeatures.bStateSave=!0,Qa(g,e),A(g,"aoDrawCallback",pa,"state_save");if(null!==e.iDeferLoading)g.bDeferLoading=!0,g._iRecordsTotal=e.iDeferLoading,
+g._iRecordsDisplay=e.iDeferLoading;null!==e.aaData&&(h=!0);""!==e.oLanguage.sUrl?(g.oLanguage.sUrl=e.oLanguage.sUrl,i.getJSON(g.oLanguage.sUrl,null,function(a){na(a);i.extend(!0,g.oLanguage,e.oLanguage,a);$(g)}),f=!0):i.extend(!0,g.oLanguage,e.oLanguage);c=!1;d=i(this).children("tbody").children("tr");for(a=0,b=g.asStripeClasses.length;a=g.aoColumns.length&&(g.aaSorting[a][0]=0);var r=g.aoColumns[g.aaSorting[a][0]];g.aaSorting[a][2]===l&&(g.aaSorting[a][2]=0);e.aaSorting===l&&g.saved_aaSorting===l&&(g.aaSorting[a][1]=r.asSorting[0]);for(c=0,d=r.asSorting.length;c<
+d;c++)if(g.aaSorting[a][1]==r.asSorting[c]){g.aaSorting[a][2]=c;break}}Q(g);a=i(this).children("thead");0===a.length&&(a=[k.createElement("thead")],this.appendChild(a[0]));g.nTHead=a[0];a=i(this).children("tbody");0===a.length&&(a=[k.createElement("tbody")],this.appendChild(a[0]));g.nTBody=a[0];g.nTBody.setAttribute("role","alert");g.nTBody.setAttribute("aria-live","polite");g.nTBody.setAttribute("aria-relevant","all");a=i(this).children("tfoot");if(0=parseInt(k,10)},iApiIndex:0,ofnSearch:{},oApi:{},
+oStdClasses:{},oJUIClasses:{},oPagination:{},oSort:{},sVersion:j.version,sErrMode:"alert",_oExternConfig:{iNextUnique:0}};j.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};j.models.oRow={nTr:null,_aData:[],_aSortData:[],_anHidden:[],_sRowStripe:""};j.models.oColumn={aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bUseRendered:null,bVisible:null,_bAutoType:!0,fnCreatedCell:null,fnGetData:null,fnRender:null,fnSetData:null,mDataProp:null,nTh:null,nTf:null,sClass:null,
+sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};j.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:["odd","even"],bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollAutoCss:!0,bScrollCollapse:!1,
+bScrollInfinite:!1,bServerSide:!1,bSort:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCookieCallback:null,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(e){if(1E3>e)return e;for(var i=e+"",e=i.split(""),j="",i=i.length,l=0;l'+k.sPrevious+''+k.sNext+"":'';i(j).append(k);var t=i("a",j),k=t[0],t=t[1];e.oApi._fnBindAction(k,{action:"previous"},s);e.oApi._fnBindAction(t,{action:"next"},s);if(!e.aanFeatures.p)j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_previous",t.id=e.sTableId+"_next",k.setAttribute("aria-controls",e.sTableId),t.setAttribute("aria-controls",e.sTableId)},fnUpdate:function(e){if(e.aanFeatures.p)for(var i=e.oClasses,j=e.aanFeatures.p,l=0,
+k=j.length;l'+k.sFirst+
+''+k.sPrevious+''+k.sNext+''+k.sLast+"");var v=i("a",j),k=v[0],s=v[1],B=v[2],v=v[3];e.oApi._fnBindAction(k,{action:"first"},t);e.oApi._fnBindAction(s,{action:"previous"},t);e.oApi._fnBindAction(B,{action:"next"},t);e.oApi._fnBindAction(v,{action:"last"},
+t);if(!e.aanFeatures.p)j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_first",s.id=e.sTableId+"_previous",B.id=e.sTableId+"_next",v.id=e.sTableId+"_last"},fnUpdate:function(e,l){if(e.aanFeatures.p){var k=j.ext.oPagination.iFullNumbersShowPages,r=Math.floor(k/2),s=Math.ceil(e.fnRecordsDisplay()/e._iDisplayLength),t=Math.ceil(e._iDisplayStart/e._iDisplayLength)+1,v="",B,D=e.oClasses,x,I=e.aanFeatures.p,G=function(i){e.oApi._fnBindAction(this,{page:i+B-1},function(i){e.oApi._fnPageChange(e,i.data.page);
+l(e);i.preventDefault()})};s=s-r?(B=s-k+1,r=s):(B=t-Math.ceil(k/2)+1,r=B+k-1);for(k=B;k<=r;k++)v+=t!==k?''+e.fnFormatNumber(k)+"":''+e.fnFormatNumber(k)+"";for(k=0,r=I.length;ki?1:0},"string-desc":function(e,i){return ei?-1:0},"html-pre":function(e){return e.replace(/<.*?>/g,"").toLowerCase()},
+"html-asc":function(e,i){return ei?1:0},"html-desc":function(e,i){return ei?-1:0},"date-pre":function(e){e=Date.parse(e);if(isNaN(e)||""===e)e=Date.parse("01/01/1970 00:00:00");return e},"date-asc":function(e,i){return e-i},"date-desc":function(e,i){return i-e},"numeric-pre":function(e){return"-"==e||""===e?0:1*e},"numeric-asc":function(e,i){return e-i},"numeric-desc":function(e,i){return i-e}});i.extend(j.ext.aTypes,[function(e){if("number"===typeof e)return"numeric";if("string"!==
+typeof e)return null;var i,j=!1;i=e.charAt(0);if(-1=="0123456789-".indexOf(i))return null;for(var k=1;k")?"html":null}]);i.fn.DataTable=j;i.fn.dataTable=j;i.fn.dataTableSettings=j.settings;i.fn.dataTableExt=
+j.ext})(jQuery,window,document,void 0);
diff --git a/airtime_mvc/public/js/datatables/unit_testing/controller.js b/airtime_mvc/public/js/datatables/unit_testing/controller.js
deleted file mode 100644
index 590b756ab..000000000
--- a/airtime_mvc/public/js/datatables/unit_testing/controller.js
+++ /dev/null
@@ -1,94 +0,0 @@
-var giTotalTestCount = 0;
-var giActiveModule = 0;
-var giModuleTests;
-var giStartTime;
-var giTest;
-var gbStop = false;
-var gtoTest;
-
-function fnTestStart ( sTestInfo )
-{
- gaoTest[ giActiveModule ].iTests++;
- document.getElementById('test_info').innerHTML +=
- (giActiveModule+1)+'.'+(giModuleTests+1)+'. '+sTestInfo+'... ';
- document.getElementById('test_number').innerHTML = giTotalTestCount+1;
- giModuleTests++;
- giTotalTestCount++;
-
- /* Set a timer to catch stalled script */
- gtoTest = setTimeout( function () {
- fnMessage( 'WARNING - test script stalled. Likely a JS error' );
- gbStop = true;
- }, 3000 );
-}
-
-function fnTestResult ( bResult )
-{
- clearTimeout( gtoTest );
- if ( bResult )
- {
- fnMessage( 'Passed' );
- }
- else
- {
- fnMessage( 'FAILED' );
- gbStop = true;
- fnEnd( false );
- }
-}
-
-function fnUnitStart( iTest )
-{
- if ( !gbStop )
- {
- giModuleTests = 0;
- window.parent.test_arena.location.href =
- (iTest==0?"":"../")+'templates/'+gaoTest[iTest].sTemplate+'.php?scripts='+gaoTest[iTest].sTest;
- giTest = iTest;
- }
-}
-
-function fnStartMessage( sMessage )
-{
- fnMessage( ' '+gaoTest[giTest].sGroup+' - '+sMessage+'' );
-}
-
-function fnMessage( sMessage )
-{
- var nInfo = document.getElementById('test_info');
- nInfo.innerHTML += sMessage+' ';
- nInfo.scrollTop = nInfo.scrollHeight;
-}
-
-function fnUnitComplete()
-{
- if ( giActiveModule < gaoTest.length - 1 )
- {
- fnUnitStart( ++giActiveModule );
- }
- else
- {
- fnEnd( true );
- }
-}
-
-function fnEnd( bSuccess )
-{
- var iEndTime = new Date().getTime();
- var sTime = ' This test run took '+parseInt((iEndTime-giStartTime)/1000, 10)+
- ' second(s) to complete.';
-
- if ( bSuccess )
- {
- $('#test_running').html( 'Tests complete. '+giTotalTestCount+' tests were run.'+sTime );
- }
- else
- {
- $('#test_running').html( 'Unit tests failed at test '+giTotalTestCount+'.'+sTime );
- }
-}
-
-$(document).ready( function () {
- giStartTime = new Date().getTime();
- fnUnitStart( giActiveModule );
-} );
\ No newline at end of file
diff --git a/airtime_mvc/public/js/datatables/unit_testing/controller.php b/airtime_mvc/public/js/datatables/unit_testing/controller.php
deleted file mode 100644
index 2dfe671a3..000000000
--- a/airtime_mvc/public/js/datatables/unit_testing/controller.php
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
- DataTables unit test controller
-
-
-
-
-
-
-
-
-
DataTables unit testing
-
Running test:
-
- Test information:
-
-
-
\ No newline at end of file
diff --git a/airtime_mvc/public/js/datatables/unit_testing/index.html b/airtime_mvc/public/js/datatables/unit_testing/index.html
deleted file mode 100644
index caab383ba..000000000
--- a/airtime_mvc/public/js/datatables/unit_testing/index.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/airtime_mvc/public/js/datatables/unit_testing/performance/draw.html b/airtime_mvc/public/js/datatables/unit_testing/performance/draw.html
deleted file mode 100644
index 32af1a91b..000000000
--- a/airtime_mvc/public/js/datatables/unit_testing/performance/draw.html
+++ /dev/null
@@ -1,482 +0,0 @@
-
-
-
-
-
-
- DataTables example
-
-
-
-
-
-
-
-
- DataTables performance test - draw
-
-
-
-
-
-
-
-
Rendering engine
-
Browser
-
Platform(s)
-
Engine version
-
CSS grade
-
-
-
-
-
Trident
-
Internet
- Explorer 4.0
-
Win 95+
-
4
-
X
-
-
-
Trident
-
Internet
- Explorer 5.0
-
Win 95+
-
5
-
C
-
-
-
Trident
-
Internet
- Explorer 5.5
-
Win 95+
-
5.5
-
A
-
-
-
Trident
-
Internet
- Explorer 6
-
Win 98+
-
6
-
A
-
-
-
Trident
-
Internet Explorer 7
-
Win XP SP2+
-
7
-
A
-
-
-
Trident
-
AOL browser (AOL desktop)
-
Win XP
-
6
-
A
-
-
-
Gecko
-
Firefox 1.0
-
Win 98+ / OSX.2+
-
1.7
-
A
-
-
-
Gecko
-
Firefox 1.5
-
Win 98+ / OSX.2+
-
1.8
-
A
-
-
-
Gecko
-
Firefox 2.0
-
Win 98+ / OSX.2+
-
1.8
-
A
-
-
-
Gecko
-
Firefox 3.0
-
Win 2k+ / OSX.3+
-
1.9
-
A
-
-
-
Gecko
-
Camino 1.0
-
OSX.2+
-
1.8
-
A
-
-
-
Gecko
-
Camino 1.5
-
OSX.3+
-
1.8
-
A
-
-
-
Gecko
-
Netscape 7.2
-
Win 95+ / Mac OS 8.6-9.2
-
1.7
-
A
-
-
-
Gecko
-
Netscape Browser 8
-
Win 98SE+
-
1.7
-
A
-
-
-
Gecko
-
Netscape Navigator 9
-
Win 98+ / OSX.2+
-
1.8
-
A
-
-
-
Gecko
-
Mozilla 1.0
-
Win 95+ / OSX.1+
-
1
-
A
-
-
-
Gecko
-
Mozilla 1.1
-
Win 95+ / OSX.1+
-
1.1
-
A
-
-
-
Gecko
-
Mozilla 1.2
-
Win 95+ / OSX.1+
-
1.2
-
A
-
-
-
Gecko
-
Mozilla 1.3
-
Win 95+ / OSX.1+
-
1.3
-
A
-
-
-
Gecko
-
Mozilla 1.4
-
Win 95+ / OSX.1+
-
1.4
-
A
-
-
-
Gecko
-
Mozilla 1.5
-
Win 95+ / OSX.1+
-
1.5
-
A
-
-
-
Gecko
-
Mozilla 1.6
-
Win 95+ / OSX.1+
-
1.6
-
A
-
-
-
Gecko
-
Mozilla 1.7
-
Win 98+ / OSX.1+
-
1.7
-
A
-
-
-
Gecko
-
Mozilla 1.8
-
Win 98+ / OSX.1+
-
1.8
-
A
-
-
-
Gecko
-
Seamonkey 1.1
-
Win 98+ / OSX.2+
-
1.8
-
A
-
-
-
Gecko
-
Epiphany 2.20
-
Gnome
-
1.8
-
A
-
-
-
Webkit
-
Safari 1.2
-
OSX.3
-
125.5
-
A
-
-
-
Webkit
-
Safari 1.3
-
OSX.3
-
312.8
-
A
-
-
-
Webkit
-
Safari 2.0
-
OSX.4+
-
419.3
-
A
-
-
-
Webkit
-
Safari 3.0
-
OSX.4+
-
522.1
-
A
-
-
-
Webkit
-
OmniWeb 5.5
-
OSX.4+
-
420
-
A
-
-
-
Webkit
-
iPod Touch / iPhone
-
iPod
-
420.1
-
A
-
-
-
Webkit
-
S60
-
S60
-
413
-
A
-
-
-
Presto
-
Opera 7.0
-
Win 95+ / OSX.1+
-
-
-
A
-
-
-
Presto
-
Opera 7.5
-
Win 95+ / OSX.2+
-
-
-
A
-
-
-
Presto
-
Opera 8.0
-
Win 95+ / OSX.2+
-
-
-
A
-
-
-
Presto
-
Opera 8.5
-
Win 95+ / OSX.2+
-
-
-
A
-
-
-
Presto
-
Opera 9.0
-
Win 95+ / OSX.3+
-
-
-
A
-
-
-
Presto
-
Opera 9.2
-
Win 88+ / OSX.3+
-
-
-
A
-
-
-
Presto
-
Opera 9.5
-
Win 88+ / OSX.3+
-
-
-
A
-
-
-
Presto
-
Opera for Wii
-
Wii
-
-
-
A
-
-
-
Presto
-
Nokia N800
-
N800
-
-
-
A
-
-
-
Presto
-
Nintendo DS browser
-
Nintendo DS
-
8.5
-
C/A1
-
-
-
KHTML
-
Konqureror 3.1
-
KDE 3.1
-
3.1
-
C
-
-
-
KHTML
-
Konqureror 3.3
-
KDE 3.3
-
3.3
-
A
-
-
-
KHTML
-
Konqureror 3.5
-
KDE 3.5
-
3.5
-
A
-
-
-
Tasman
-
Internet Explorer 4.5
-
Mac OS 8-9
-
-
-
X
-
-
-
Tasman
-
Internet Explorer 5.1
-
Mac OS 7.6-9
-
1
-
C
-
-
-
Tasman
-
Internet Explorer 5.2
-
Mac OS 8-X
-
1
-
C
-
-
-
Misc
-
NetFront 3.1
-
Embedded devices
-
-
-
C
-
-
-
Misc
-
NetFront 3.4
-
Embedded devices
-
-
-
A
-
-
-
Misc
-
Dillo 0.8
-
Embedded devices
-
-
-
X
-
-
-
Misc
-
Links
-
Text only
-
-
-
X
-
-
-
Misc
-
Lynx
-
Text only
-
-
-
X
-
-
-
Misc
-
IE Mobile
-
Windows Mobile 6
-
-
-
C
-
-
-
Misc
-
PSP browser
-
PSP
-
-
-
C
-
-
-
Other browsers
-
All others
-
-
-
-
-
U
-
-
-
-
-
Rendering engine
-
Browser
-
Platform(s)
-
Engine version
-
CSS grade
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/airtime_mvc/public/js/datatables/unit_testing/performance/large.php b/airtime_mvc/public/js/datatables/unit_testing/performance/large.php
deleted file mode 100644
index 6dbb72447..000000000
--- a/airtime_mvc/public/js/datatables/unit_testing/performance/large.php
+++ /dev/null
@@ -1,107 +0,0 @@
-
-
-
-
-
-
- DataTables example
-
-
-
-
-
-
-