jquery-datatables 1.10.12 → 1.10.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/app/assets/javascripts/datatables/dataTables.bootstrap.js +2 -2
  4. data/app/assets/javascripts/datatables/dataTables.bootstrap4.js +5 -5
  5. data/app/assets/javascripts/datatables/dataTables.foundation.js +1 -1
  6. data/app/assets/javascripts/datatables/dataTables.material.js +1 -1
  7. data/app/assets/javascripts/datatables/dataTables.semanticui.js +1 -1
  8. data/app/assets/javascripts/datatables/extensions/AutoFill/dataTables.autoFill.js +63 -31
  9. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.colVis.js +2 -3
  10. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.flash.js +145 -55
  11. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.html5.js +224 -206
  12. data/app/assets/javascripts/datatables/extensions/Buttons/buttons.print.js +14 -8
  13. data/app/assets/javascripts/datatables/extensions/Buttons/dataTables.buttons.js +54 -24
  14. data/app/assets/javascripts/datatables/extensions/KeyTable/dataTables.keyTable.js +137 -68
  15. data/app/assets/javascripts/datatables/extensions/Responsive/dataTables.responsive.js +30 -7
  16. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap.js +6 -2
  17. data/app/assets/javascripts/datatables/extensions/Responsive/responsive.bootstrap4.js +6 -2
  18. data/app/assets/javascripts/datatables/extensions/RowReorder/dataTables.rowReorder.js +64 -6
  19. data/app/assets/javascripts/datatables/extensions/Select/dataTables.select.js +40 -15
  20. data/app/assets/javascripts/datatables/jquery.dataTables.js +246 -217
  21. data/app/assets/javascripts/datatables/plugins/api/average.js +32 -0
  22. data/app/assets/javascripts/datatables/plugins/api/sum.js +51 -0
  23. data/app/assets/javascripts/datatables/plugins/pagination/input.js +224 -0
  24. data/app/assets/javascripts/datatables/plugins/search/alphabetSearch.js +368 -0
  25. data/app/assets/javascripts/datatables/plugins/sorting/file-size.js +43 -0
  26. data/app/assets/javascripts/datatables/plugins/sorting/ip-address.js +103 -0
  27. data/app/assets/stylesheets/datatables/dataTables.bootstrap.css +0 -1
  28. data/app/assets/stylesheets/datatables/dataTables.semanticui.css +0 -1
  29. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap.css +4 -4
  30. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.bootstrap4.css +4 -4
  31. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.dataTables.css +4 -4
  32. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.foundation.css +4 -4
  33. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.jqueryui.css +4 -4
  34. data/app/assets/stylesheets/datatables/extensions/Responsive/responsive.semanticui.css +4 -4
  35. data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap.css +9 -4
  36. data/app/assets/stylesheets/datatables/extensions/Select/select.bootstrap4.css +9 -4
  37. data/app/assets/stylesheets/datatables/extensions/Select/select.dataTables.css +9 -4
  38. data/app/assets/stylesheets/datatables/extensions/Select/select.foundation.css +9 -4
  39. data/app/assets/stylesheets/datatables/extensions/Select/select.jqueryui.css +9 -4
  40. data/app/assets/stylesheets/datatables/extensions/Select/select.semanticui.css +9 -4
  41. data/app/assets/stylesheets/datatables/plugins/search/alphabetSearch.css +43 -0
  42. data/lib/jquery-datatables/version.rb +1 -1
  43. metadata +10 -3
@@ -0,0 +1,32 @@
1
+ /**
2
+ * It can sometimes be useful to get the average of data in an API result set,
3
+ * be it from a column, or a collection of cells. This method provides exactly
4
+ * that ability.
5
+ *
6
+ * @name average()
7
+ * @summary Average the values in a data set.
8
+ * @author [Allan Jardine](http://sprymedia.co.uk)
9
+ * @requires DataTables 1.10+
10
+ *
11
+ * @returns {Number} Calculated average
12
+ *
13
+ * @example
14
+ * // Average a column
15
+ * var table = $('#example').DataTable();
16
+ * table.column( 3 ).data().average();
17
+ *
18
+ * @example
19
+ * // Average two cells
20
+ * var table = $('#example').DataTable();
21
+ * table.cells( 0, [3,4] ).data().average();
22
+ */
23
+
24
+ jQuery.fn.dataTable.Api.register( 'average()', function () {
25
+ var data = this.flatten();
26
+ var sum = data.reduce( function ( a, b ) {
27
+ return (a*1) + (b*1); // cast values in-case they are strings
28
+ }, 0 );
29
+
30
+ return sum / data.length;
31
+ } );
32
+
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Fairly simply, this plug-in will take the data from an API result set
3
+ * and sum it, returning the summed value. The data can come from any data
4
+ * source, including column data, cells or rows.
5
+ *
6
+ * Note that it will attempt to 'deformat' any string based data that is passed
7
+ * into it - i.e. it will strip any non-numeric characters in order to make a
8
+ * best effort attempt to sum all data types. This can be useful when working
9
+ * with formatting numbers such as currency. However the trade-off is that no
10
+ * error is thrown if non-numeric data is passed in. You should be aware of this
11
+ * in case unexpected values are returned - likely the input data is not what is
12
+ * expected.
13
+ *
14
+ * @name sum()
15
+ * @summary Sum the values in a data set.
16
+ * @author [Allan Jardine](http://sprymedia.co.uk)
17
+ * @requires DataTables 1.10+
18
+ *
19
+ * @returns {Number} Summed value
20
+ *
21
+ * @example
22
+ * // Simply get the sum of a column
23
+ * var table = $('#example').DataTable();
24
+ * table.column( 3 ).data().sum();
25
+ *
26
+ * @example
27
+ * // Insert the sum of a column into the columns footer, for the visible
28
+ * // data on each draw
29
+ * $('#example').DataTable( {
30
+ * drawCallback: function () {
31
+ * var api = this.api();
32
+ * $( api.table().footer() ).html(
33
+ * api.column( 4, {page:'current'} ).data().sum()
34
+ * );
35
+ * }
36
+ * } );
37
+ */
38
+
39
+ jQuery.fn.dataTable.Api.register( 'sum()', function ( ) {
40
+ return this.flatten().reduce( function ( a, b ) {
41
+ if ( typeof a === 'string' ) {
42
+ a = a.replace(/[^\d.-]/g, '') * 1;
43
+ }
44
+ if ( typeof b === 'string' ) {
45
+ b = b.replace(/[^\d.-]/g, '') * 1;
46
+ }
47
+
48
+ return a + b;
49
+ }, 0 );
50
+ } );
51
+
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Sometimes for quick navigation, it can be useful to allow an end user to
3
+ * enter which page they wish to jump to manually. This paging control uses a
4
+ * text input box to accept new paging numbers (arrow keys are also allowed
5
+ * for), and four standard navigation buttons are also presented to the end
6
+ * user.
7
+ *
8
+ * @name Navigation with text input
9
+ * @summary Shows an input element into which the user can type a page number
10
+ * @author [Allan Jardine](http://sprymedia.co.uk)
11
+ * @author [Gordey Doronin](http://github.com/GDoronin)
12
+ *
13
+ * @example
14
+ * $(document).ready(function() {
15
+ * $('#example').dataTable( {
16
+ * "pagingType": "input"
17
+ * } );
18
+ * } );
19
+ */
20
+
21
+ (function ($) {
22
+ function calcDisableClasses(oSettings) {
23
+ var start = oSettings._iDisplayStart;
24
+ var length = oSettings._iDisplayLength;
25
+ var visibleRecords = oSettings.fnRecordsDisplay();
26
+ var all = length === -1;
27
+
28
+ // Gordey Doronin: Re-used this code from main jQuery.dataTables source code. To be consistent.
29
+ var page = all ? 0 : Math.ceil(start / length);
30
+ var pages = all ? 1 : Math.ceil(visibleRecords / length);
31
+
32
+ var disableFirstPrevClass = (page > 0 ? '' : oSettings.oClasses.sPageButtonDisabled);
33
+ var disableNextLastClass = (page < pages - 1 ? '' : oSettings.oClasses.sPageButtonDisabled);
34
+
35
+ return {
36
+ 'first': disableFirstPrevClass,
37
+ 'previous': disableFirstPrevClass,
38
+ 'next': disableNextLastClass,
39
+ 'last': disableNextLastClass
40
+ };
41
+ }
42
+
43
+ function calcCurrentPage(oSettings) {
44
+ return Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
45
+ }
46
+
47
+ function calcPages(oSettings) {
48
+ return Math.ceil(oSettings.fnRecordsDisplay() / oSettings._iDisplayLength);
49
+ }
50
+
51
+ var firstClassName = 'first';
52
+ var previousClassName = 'previous';
53
+ var nextClassName = 'next';
54
+ var lastClassName = 'last';
55
+
56
+ var paginateClassName = 'paginate';
57
+ var paginateOfClassName = 'paginate_of';
58
+ var paginatePageClassName = 'paginate_page';
59
+ var paginateInputClassName = 'paginate_input';
60
+
61
+ $.fn.dataTableExt.oPagination.input = {
62
+ 'fnInit': function (oSettings, nPaging, fnCallbackDraw) {
63
+ var nFirst = document.createElement('span');
64
+ var nPrevious = document.createElement('span');
65
+ var nNext = document.createElement('span');
66
+ var nLast = document.createElement('span');
67
+ var nInput = document.createElement('input');
68
+ var nPage = document.createElement('span');
69
+ var nOf = document.createElement('span');
70
+
71
+ var language = oSettings.oLanguage.oPaginate;
72
+ var classes = oSettings.oClasses;
73
+
74
+ nFirst.innerHTML = language.sFirst;
75
+ nPrevious.innerHTML = language.sPrevious;
76
+ nNext.innerHTML = language.sNext;
77
+ nLast.innerHTML = language.sLast;
78
+
79
+ nFirst.className = firstClassName + ' ' + classes.sPageButton;
80
+ nPrevious.className = previousClassName + ' ' + classes.sPageButton;
81
+ nNext.className = nextClassName + ' ' + classes.sPageButton;
82
+ nLast.className = lastClassName + ' ' + classes.sPageButton;
83
+
84
+ nOf.className = paginateOfClassName;
85
+ nPage.className = paginatePageClassName;
86
+ nInput.className = paginateInputClassName;
87
+
88
+ if (oSettings.sTableId !== '') {
89
+ nPaging.setAttribute('id', oSettings.sTableId + '_' + paginateClassName);
90
+ nFirst.setAttribute('id', oSettings.sTableId + '_' + firstClassName);
91
+ nPrevious.setAttribute('id', oSettings.sTableId + '_' + previousClassName);
92
+ nNext.setAttribute('id', oSettings.sTableId + '_' + nextClassName);
93
+ nLast.setAttribute('id', oSettings.sTableId + '_' + lastClassName);
94
+ }
95
+
96
+ nInput.type = 'text';
97
+ nPage.innerHTML = 'Page ';
98
+
99
+ nPaging.appendChild(nFirst);
100
+ nPaging.appendChild(nPrevious);
101
+ nPaging.appendChild(nPage);
102
+ nPaging.appendChild(nInput);
103
+ nPaging.appendChild(nOf);
104
+ nPaging.appendChild(nNext);
105
+ nPaging.appendChild(nLast);
106
+
107
+ $(nFirst).click(function() {
108
+ var iCurrentPage = calcCurrentPage(oSettings);
109
+ if (iCurrentPage !== 1) {
110
+ oSettings.oApi._fnPageChange(oSettings, 'first');
111
+ fnCallbackDraw(oSettings);
112
+ }
113
+ });
114
+
115
+ $(nPrevious).click(function() {
116
+ var iCurrentPage = calcCurrentPage(oSettings);
117
+ if (iCurrentPage !== 1) {
118
+ oSettings.oApi._fnPageChange(oSettings, 'previous');
119
+ fnCallbackDraw(oSettings);
120
+ }
121
+ });
122
+
123
+ $(nNext).click(function() {
124
+ var iCurrentPage = calcCurrentPage(oSettings);
125
+ if (iCurrentPage !== calcPages(oSettings)) {
126
+ oSettings.oApi._fnPageChange(oSettings, 'next');
127
+ fnCallbackDraw(oSettings);
128
+ }
129
+ });
130
+
131
+ $(nLast).click(function() {
132
+ var iCurrentPage = calcCurrentPage(oSettings);
133
+ if (iCurrentPage !== calcPages(oSettings)) {
134
+ oSettings.oApi._fnPageChange(oSettings, 'last');
135
+ fnCallbackDraw(oSettings);
136
+ }
137
+ });
138
+
139
+ $(nInput).keyup(function (e) {
140
+ // 38 = up arrow, 39 = right arrow
141
+ if (e.which === 38 || e.which === 39) {
142
+ this.value++;
143
+ }
144
+ // 37 = left arrow, 40 = down arrow
145
+ else if ((e.which === 37 || e.which === 40) && this.value > 1) {
146
+ this.value--;
147
+ }
148
+
149
+ if (this.value === '' || this.value.match(/[^0-9]/)) {
150
+ /* Nothing entered or non-numeric character */
151
+ this.value = this.value.replace(/[^\d]/g, ''); // don't even allow anything but digits
152
+ return;
153
+ }
154
+
155
+ var iNewStart = oSettings._iDisplayLength * (this.value - 1);
156
+ if (iNewStart < 0) {
157
+ iNewStart = 0;
158
+ }
159
+ if (iNewStart >= oSettings.fnRecordsDisplay()) {
160
+ iNewStart = (Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength) - 1) * oSettings._iDisplayLength;
161
+ }
162
+
163
+ oSettings._iDisplayStart = iNewStart;
164
+ fnCallbackDraw(oSettings);
165
+ });
166
+
167
+ // Take the brutal approach to cancelling text selection.
168
+ $('span', nPaging).bind('mousedown', function () { return false; });
169
+ $('span', nPaging).bind('selectstart', function() { return false; });
170
+
171
+ // If we can't page anyway, might as well not show it.
172
+ var iPages = calcPages(oSettings);
173
+ if (iPages <= 1) {
174
+ $(nPaging).hide();
175
+ }
176
+ },
177
+
178
+ 'fnUpdate': function (oSettings) {
179
+ if (!oSettings.aanFeatures.p) {
180
+ return;
181
+ }
182
+
183
+ var iPages = calcPages(oSettings);
184
+ var iCurrentPage = calcCurrentPage(oSettings);
185
+
186
+ var an = oSettings.aanFeatures.p;
187
+ if (iPages <= 1) // hide paging when we can't page
188
+ {
189
+ $(an).hide();
190
+ return;
191
+ }
192
+
193
+ var disableClasses = calcDisableClasses(oSettings);
194
+
195
+ $(an).show();
196
+
197
+ // Enable/Disable `first` button.
198
+ $(an).children('.' + firstClassName)
199
+ .removeClass(oSettings.oClasses.sPageButtonDisabled)
200
+ .addClass(disableClasses[firstClassName]);
201
+
202
+ // Enable/Disable `prev` button.
203
+ $(an).children('.' + previousClassName)
204
+ .removeClass(oSettings.oClasses.sPageButtonDisabled)
205
+ .addClass(disableClasses[previousClassName]);
206
+
207
+ // Enable/Disable `next` button.
208
+ $(an).children('.' + nextClassName)
209
+ .removeClass(oSettings.oClasses.sPageButtonDisabled)
210
+ .addClass(disableClasses[nextClassName]);
211
+
212
+ // Enable/Disable `last` button.
213
+ $(an).children('.' + lastClassName)
214
+ .removeClass(oSettings.oClasses.sPageButtonDisabled)
215
+ .addClass(disableClasses[lastClassName]);
216
+
217
+ // Paginate of N pages text
218
+ $(an).children('.' + paginateOfClassName).html(' of ' + iPages);
219
+
220
+ // Current page numer input value
221
+ $(an).children('.' + paginateInputClassName).val(iCurrentPage);
222
+ }
223
+ };
224
+ })(jQuery);
@@ -0,0 +1,368 @@
1
+ /*! AlphabetSearch for DataTables v1.1.2
2
+ * 2014 SpryMedia Ltd - datatables.net/license
3
+ * Gyrocode - MIT License
4
+ */
5
+
6
+ /**
7
+ * @summary AlphabetSearch
8
+ * @description Show an set of alphabet buttons alongside a table providing
9
+ * search input options
10
+ * @version 1.1.1
11
+ * @file dataTables.alphabetSearch.js
12
+ * @author SpryMedia Ltd (www.sprymedia.co.uk)
13
+ * @contact www.sprymedia.co.uk/contact
14
+ * @copyright Copyright 2014 SpryMedia Ltd.
15
+ * @author Gyrocode (www.gyrocode.com)
16
+ * @contact www.gyrocode.com/contacts
17
+ * @copyright Copyright (c) Gyrocode
18
+ *
19
+ * License MIT - http://datatables.net/license/mit
20
+ *
21
+ * For more detailed information please see:
22
+ * http://www.gyrocode.com/articles/jquery-datatables-alphabetical-search
23
+ */
24
+ (function(){
25
+
26
+
27
+ // Search function
28
+ $.fn.dataTable.Api.register( 'alphabetSearch()', function ( searchTerm ) {
29
+ this.iterator( 'table', function ( context ) {
30
+ context.alphabetSearch.letter = searchTerm;
31
+ } );
32
+
33
+ return this;
34
+ } );
35
+
36
+ // Recalculate the alphabet display for updated data
37
+ $.fn.dataTable.Api.register( 'alphabetSearch.recalc()', function ( searchTerm ) {
38
+ this.iterator( 'table', function ( context ) {
39
+ draw(
40
+ new $.fn.dataTable.Api( context ),
41
+ $('div.alphabet', this.table().container()),
42
+ context
43
+ );
44
+ } );
45
+
46
+ return this;
47
+ } );
48
+
49
+
50
+ // Search plug-in
51
+ $.fn.dataTable.ext.search.push( function ( context, searchData ) {
52
+ // Ensure that there is a search applied to this table before running it
53
+ if ( ! context.alphabetSearch.letterSearch ) {
54
+ return true;
55
+ }
56
+
57
+ var letter = searchData[context.alphabetSearch.column]
58
+ .toString()
59
+ .replace(/<.*?>/g, '')
60
+ .charAt(0).toUpperCase();
61
+
62
+
63
+ if(context.alphabetSearch.letterSearch !== '#'){
64
+ if ( letter === context.alphabetSearch.letterSearch ) {
65
+ return true;
66
+ }
67
+ } else {
68
+ if(/\d/.test(letter)){
69
+ return true;
70
+ }
71
+ }
72
+
73
+ return false;
74
+ } );
75
+
76
+
77
+ // Order plug-in
78
+ //
79
+ // NOTES: If sorting by alphabetized column
80
+ // there would be two calls to this method
81
+ $.fn.dataTable.ext.order['alphabetSearch'] = function ( context, col )
82
+ {
83
+ var order_col = this.api().order()[0][0];
84
+ var order_method = this.api().order()[0][1];
85
+
86
+ // If sorting by column other than the one being alphabetized
87
+ if(order_col !== context.alphabetSearch.column){
88
+ context.alphabetSearch.pass = 0;
89
+ }
90
+
91
+ var data = this.api().column( col, { order: 'index' } ).data().map( function (value, index) {
92
+ // If sorting by alphabetized column
93
+ return (order_col === context.alphabetSearch.column)
94
+ ? (
95
+ // If first pass
96
+ ( !context.alphabetSearch.pass )
97
+ // Ignore
98
+ ?
99
+ ''
100
+ // Otherwise, if it's a second pass
101
+ :
102
+ (
103
+ // If method is ascending sort
104
+ ( order_method === 'asc' )
105
+ // Return first letter
106
+ ? value.charAt(0)
107
+ : String.fromCharCode(65535 - value.charCodeAt(0))
108
+ )
109
+ )
110
+ // Otherwise, if sorting by column other than the one being alphabetized,
111
+ // return first letter
112
+ : value.charAt(0);
113
+
114
+ } );
115
+
116
+ // If sorting by alphabetized column
117
+ if(order_col === context.alphabetSearch.column){
118
+ // If pass is not defined, set it to 0
119
+ if(!context.alphabetSearchPass){ context.alphabetSearch.pass = 0; }
120
+ // Increment pass counter and reset it to 0 if it's a second pass
121
+ context.alphabetSearch.pass = (context.alphabetSearch.pass + 1) % 2;
122
+ }
123
+
124
+ return data;
125
+ };
126
+
127
+
128
+ // Private support methods
129
+ function bin ( data ) {
130
+ var letter, bins = {};
131
+
132
+ for ( var i=0, ien=data.length ; i<ien ; i++ ) {
133
+ letter = data[i]
134
+ .toString()
135
+ .replace(/<.*?>/g, '')
136
+ .charAt(0).toUpperCase();
137
+
138
+ if(/\d/.test(letter)){ letter = '#'; }
139
+
140
+ if ( bins[letter] ) {
141
+ bins[letter]++;
142
+ }
143
+ else {
144
+ bins[letter] = 1;
145
+ }
146
+ }
147
+
148
+ return bins;
149
+ }
150
+
151
+ function draw ( table, alphabet, context )
152
+ {
153
+ alphabet.empty();
154
+ alphabet.append( context.oLanguage.alphabetSearch.infoDisplay + ': ' );
155
+
156
+ var columnData = table.column(context.alphabetSearch.column, { search: 'applied' } ).data();
157
+ var bins = bin( columnData );
158
+
159
+ $('<span class="alphabet-clear' + ((!context.alphabetSearch.letter) ? ' active' : '') + '"/>')
160
+ .data( 'letter', '' )
161
+ .data( 'match-count', columnData.length )
162
+ .html( context.oLanguage.alphabetSearch.infoAll )
163
+ .appendTo( alphabet );
164
+
165
+ for ( var i=0 ; i<context.oLanguage.alphabetSearch.alphabet.length ; i++ ) {
166
+ var letter = context.oLanguage.alphabetSearch.alphabet[i];
167
+
168
+ $('<span/>')
169
+ .data( 'letter', letter )
170
+ .data( 'match-count', bins[letter] || 0 )
171
+ .addClass(
172
+ (! bins[letter] ? 'empty' : '')
173
+ + ((context.alphabetSearch.letter === letter) ? ' active' : '')
174
+ )
175
+ .html(
176
+ (letter === '#') ? '0-9' : letter
177
+ )
178
+ .appendTo( alphabet );
179
+ }
180
+
181
+ $('<div class="alphabet_info"></div>')
182
+ .appendTo( alphabet );
183
+
184
+
185
+ // Perform second rendering
186
+ // needed to filter search results by letter
187
+ // NOTE: Future optimization is needed to avoid rendering twice
188
+ // when no search is performed
189
+
190
+ // If letter is selected
191
+ if(context.alphabetSearch.letter){
192
+ // Apply filtering by letter
193
+ context.alphabetSearch.letterSearch = context.alphabetSearch.letter;
194
+
195
+ // Redraw table
196
+ table.draw();
197
+
198
+ // Remove filtering by letter
199
+ context.alphabetSearch.letterSearch = '';
200
+ }
201
+
202
+ // Handle search event here only once
203
+ // when alphabet panel has been drawn
204
+ // because we are performing two-step rendering
205
+ // that could trigger search hanlder when not needed
206
+ table.one('search', function (e, context) {
207
+ var api = new $.fn.dataTable.Api( context );
208
+
209
+ // Redraw alphabet panel
210
+ api.alphabetSearch.recalc();
211
+ });
212
+ }
213
+
214
+
215
+ $.fn.dataTable.AlphabetSearch = function ( context ) {
216
+ var table = new $.fn.dataTable.Api( context );
217
+ var alphabet = $('<div class="alphabet"/>');
218
+
219
+ // Language
220
+ context.oLanguage.alphabetSearch =
221
+ $.extend(
222
+ {
223
+ 'alphabet': '#ABCDEFGHIJKLMNOPQRSTUVWXYZ',
224
+ 'infoDisplay': 'Display',
225
+ 'infoAll': 'All'
226
+ },
227
+ ((context.oLanguage.alphabetSearch)
228
+ ? context.oLanguage.alphabetSearch
229
+ : {}
230
+ )
231
+ );
232
+ // Convert alphabet to uppercase
233
+ context.oLanguage.alphabetSearch.alphabet.toUpperCase();
234
+
235
+ context.alphabetSearch =
236
+ $.extend(
237
+ {
238
+ column: 0
239
+ },
240
+ $.isPlainObject(context.oInit.alphabetSearch) ? context.oInit.alphabetSearch : {},
241
+ {
242
+ letter: '',
243
+ letterSearch: '',
244
+ pass: 0
245
+ }
246
+ );
247
+
248
+ // Set required "orderDataType" ("sSortDataType") for a column
249
+ if(context.alphabetSearch.column >= 0 && context.alphabetSearch.column < context.aoColumns.length){
250
+ context.aoColumns[context.alphabetSearch.column].sSortDataType = 'alphabetSearch';
251
+ }
252
+
253
+ // Add column containing names to a list of columns
254
+ // where ordering will be always applied to the table
255
+ if( context.hasOwnProperty('aaSortingFixed')
256
+ && typeof context.aaSortingFixed === 'object' )
257
+ {
258
+ if( $.isArray(context.aaSortingFixed) ){
259
+ if( context.aaSortingFixed.length && !$.isArray( context.aaSortingFixed[0] ) ) {
260
+ // 1D array
261
+ context.aaSortingFixed = [[context.alphabetSearch.column, 'asc'], context.aaSortingFixed];
262
+
263
+ } else {
264
+ // 2D array
265
+ context.aaSortingFixed.unshift([context.alphabetSearch.column, 'asc']);
266
+ }
267
+ } else {
268
+ if( !context.aaSortingFixed.hasOwnProperty('pre') ){
269
+ context.aaSortingFixed.pre = [];
270
+ }
271
+
272
+ if( context.aaSortingFixed.pre.length && !$.isArray( context.aaSortingFixed.pre[0] ) ) {
273
+ // 1D array
274
+ context.aaSortingFixed.pre = [[context.alphabetSearch.column, 'asc'], context.aaSortingFixed.pre];
275
+
276
+ } else {
277
+ // 2D array
278
+ context.aaSortingFixed.pre.unshift([context.alphabetSearch.column, 'asc']);
279
+ }
280
+ }
281
+
282
+ } else {
283
+ context.aaSortingFixed = [context.alphabetSearch.column, 'asc'];
284
+ }
285
+
286
+
287
+ draw( table, alphabet, context );
288
+
289
+
290
+ // Trigger a search
291
+ alphabet.on( 'click', 'span', function () {
292
+ alphabet.find( '.active' ).removeClass( 'active' );
293
+ $(this).addClass( 'active' );
294
+
295
+ table
296
+ .alphabetSearch( $(this).data('letter') )
297
+ .draw();
298
+ } );
299
+
300
+ // Mouse events to show helper information
301
+ alphabet
302
+ .on( 'mouseenter', 'span', function () {
303
+ alphabet
304
+ .find('div.alphabet_info')
305
+ .css( {
306
+ opacity: 1,
307
+ left: $(this).position().left,
308
+ width: $(this).width()
309
+ } )
310
+ .html( $(this).data('match-count') );
311
+ } )
312
+ .on( 'mouseleave', 'span', function () {
313
+ alphabet
314
+ .find('div.alphabet_info')
315
+ .css('opacity', 0);
316
+ } );
317
+
318
+ table.on('draw', function (e, context) {
319
+ var api = new $.fn.dataTable.Api( context );
320
+
321
+ // Total number of column nodes
322
+ var col_total = api.columns().nodes().length;
323
+
324
+ var rows = api.rows({ page: 'current' }).nodes();
325
+ var group_last = null;
326
+
327
+ api.column(context.alphabetSearch.column, { page: 'current' }).data().each(function (name, index){
328
+ var group = name.charAt(0).toUpperCase();
329
+
330
+ if (group_last !== group) {
331
+ $(rows).eq(index).before(
332
+ '<tr class="alphabet_group"><td colspan="' + col_total + '">' + group + '</td></tr>'
333
+ );
334
+
335
+ group_last = group;
336
+ }
337
+ });
338
+
339
+ // If there are no rows found and letter is selected
340
+ if(!rows.length && context.alphabetSearch){
341
+ var letter = (context.alphabetSearch.letter === '#') ? '0-9' : context.alphabetSearch.letter;
342
+
343
+ $(api.table().body()).prepend(
344
+ '<tr class="alphabet_group"><td colspan="' + col_total + '">' + letter + '</td></tr>'
345
+ );
346
+ }
347
+ });
348
+
349
+ // API method to get the alphabet container node
350
+ this.node = function () {
351
+ return alphabet;
352
+ };
353
+ };
354
+
355
+ $.fn.DataTable.AlphabetSearch = $.fn.dataTable.AlphabetSearch;
356
+
357
+
358
+ // Register a search plug-in
359
+ $.fn.dataTable.ext.feature.push( {
360
+ fnInit: function ( settings ) {
361
+ var search = new $.fn.dataTable.AlphabetSearch( settings );
362
+ return search.node();
363
+ },
364
+ cFeature: 'A'
365
+ } );
366
+
367
+
368
+ }());