diff --git a/features/alphabetSearch/dataTables.alphabetSearch.css b/features/alphabetSearch/dataTables.alphabetSearch.css
index 3258e1e..5837e33 100644
--- a/features/alphabetSearch/dataTables.alphabetSearch.css
+++ b/features/alphabetSearch/dataTables.alphabetSearch.css
@@ -10,7 +10,7 @@ div.alphabet span {
color: #3174c7;
cursor: pointer;
text-align: center;
- width: 3.5%
+ width: 3.5%;
}
div.alphabet span:hover {
@@ -25,7 +25,7 @@ div.alphabet span.empty {
color: red;
}
-div.alphabetInfo {
+div.alphabet_info {
display: block;
position: absolute;
background-color: #111;
@@ -37,3 +37,7 @@ div.alphabetInfo {
text-align: center;
z-index: 1;
}
+
+tr.alphabet_group, tr.alphabet_group:hover {
+ background-color: rgba(0,0,0,0.15) !important;
+}
diff --git a/features/alphabetSearch/dataTables.alphabetSearch.js b/features/alphabetSearch/dataTables.alphabetSearch.js
index a43eabc..ed948a6 100644
--- a/features/alphabetSearch/dataTables.alphabetSearch.js
+++ b/features/alphabetSearch/dataTables.alphabetSearch.js
@@ -1,4 +1,4 @@
-/*! AlphabetSearch for DataTables v1.0.0
+/*! AlphabetSearch for DataTables v1.1.0
* 2014 SpryMedia Ltd - datatables.net/license
*/
@@ -6,16 +6,17 @@
* @summary AlphabetSearch
* @description Show an set of alphabet buttons alongside a table providing
* search input options
- * @version 1.0.0
+ * @version 1.1.1
* @file dataTables.alphabetSearch.js
* @author SpryMedia Ltd (www.sprymedia.co.uk)
* @contact www.sprymedia.co.uk/contact
* @copyright Copyright 2014 SpryMedia Ltd.
- *
+ *
* License MIT - http://datatables.net/license/mit
*
* For more detailed information please see:
* http://datatables.net/blog/2014-09-22
+ * http://www.gyrocode.com/articles/jquery-datatables-alphabetical-search
*/
(function(){
@@ -23,7 +24,7 @@
// Search function
$.fn.dataTable.Api.register( 'alphabetSearch()', function ( searchTerm ) {
this.iterator( 'table', function ( context ) {
- context.alphabetSearch = searchTerm;
+ context.alphabetSearch.letter = searchTerm;
} );
return this;
@@ -34,7 +35,8 @@ $.fn.dataTable.Api.register( 'alphabetSearch.recalc()', function ( searchTerm )
this.iterator( 'table', function ( context ) {
draw(
new $.fn.dataTable.Api( context ),
- $('div.alphabet', this.table().container())
+ $('div.alphabet', this.table().container()),
+ context
);
} );
@@ -45,18 +47,81 @@ $.fn.dataTable.Api.register( 'alphabetSearch.recalc()', function ( searchTerm )
// Search plug-in
$.fn.dataTable.ext.search.push( function ( context, searchData ) {
// Ensure that there is a search applied to this table before running it
- if ( ! context.alphabetSearch ) {
+ if ( ! context.alphabetSearch.letterSearch ) {
return true;
}
- if ( searchData[0].charAt(0) === context.alphabetSearch ) {
- return true;
+ var letter = searchData[context.alphabetSearch.column]
+ .toString()
+ .replace(/<.*?>/g, '')
+ .charAt(0).toUpperCase();
+
+
+ if(context.alphabetSearch.letterSearch !== '#'){
+ if ( letter === context.alphabetSearch.letterSearch ) {
+ return true;
+ }
+ } else {
+ if(/\d/.test(letter)){
+ return true;
+ }
}
return false;
} );
+// Order plug-in
+//
+// NOTES: If sorting by alphabetized column
+// there would be two calls to this method
+$.fn.dataTable.ext.order['alphabetSearch'] = function ( context, col )
+{
+ var order_col = this.api().order()[0][0];
+ var order_method = this.api().order()[0][1];
+
+ // If sorting by column other than the one being alphabetized
+ if(order_col !== context.alphabetSearch.column){
+ context.alphabetSearch.pass = 0;
+ }
+
+ var data = this.api().column( col, { order: 'index' } ).data().map( function (value, index) {
+ // If sorting by alphabetized column
+ return (order_col === context.alphabetSearch.column)
+ ? (
+ // If first pass
+ ( !context.alphabetSearch.pass )
+ // Ignore
+ ?
+ ''
+ // Otherwise, if it's a second pass
+ :
+ (
+ // If method is ascending sort
+ ( order_method === 'asc' )
+ // Return first letter
+ ? value.charAt(0)
+ : String.fromCharCode(65535 - value.charCodeAt(0))
+ )
+ )
+ // Otherwise, if sorting by column other than the one being alphabetized,
+ // return first letter
+ : value.charAt(0);
+
+ } );
+
+ // If sorting by alphabetized column
+ if(order_col === context.alphabetSearch.column){
+ // If pass is not defined, set it to 0
+ if(!context.alphabetSearchPass){ context.alphabetSearch.pass = 0; }
+ // Increment pass counter and reset it to 0 if it's a second pass
+ context.alphabetSearch.pass = (context.alphabetSearch.pass + 1) % 2;
+ }
+
+ return data;
+};
+
+
// Private support methods
function bin ( data ) {
var letter, bins = {};
@@ -67,6 +132,8 @@ function bin ( data ) {
.replace(/<.*?>/g, '')
.charAt(0).toUpperCase();
+ if(/\d/.test(letter)){ letter = '#'; }
+
if ( bins[letter] ) {
bins[letter]++;
}
@@ -78,33 +145,67 @@ function bin ( data ) {
return bins;
}
-function draw ( table, alphabet )
+function draw ( table, alphabet, context )
{
alphabet.empty();
- alphabet.append( 'Search: ' );
+ alphabet.append( context.oLanguage.alphabetSearch.infoDisplay + ': ' );
- var columnData = table.column(0).data();
+ var columnData = table.column(context.alphabetSearch.column, { search: 'applied' } ).data();
var bins = bin( columnData );
- $('')
+ $('')
.data( 'letter', '' )
.data( 'match-count', columnData.length )
- .html( 'None' )
+ .html( context.oLanguage.alphabetSearch.infoAll )
.appendTo( alphabet );
- for ( var i=0 ; i<26 ; i++ ) {
- var letter = String.fromCharCode( 65 + i );
+ for ( var i=0 ; i')
.data( 'letter', letter )
.data( 'match-count', bins[letter] || 0 )
- .addClass( ! bins[letter] ? 'empty' : '' )
- .html( letter )
+ .addClass(
+ (! bins[letter] ? 'empty' : '')
+ + ((context.alphabetSearch.letter === letter) ? ' active' : '')
+ )
+ .html(
+ (letter === '#') ? '0-9' : letter
+ )
.appendTo( alphabet );
}
- $('
')
+ $('')
.appendTo( alphabet );
+
+
+ // Perform second rendering
+ // needed to filter search results by letter
+ // NOTE: Future optimization is needed to avoid rendering twice
+ // when no search is performed
+
+ // If letter is selected
+ if(context.alphabetSearch.letter){
+ // Apply filtering by letter
+ context.alphabetSearch.letterSearch = context.alphabetSearch.letter;
+
+ // Redraw table
+ table.draw();
+
+ // Remove filtering by letter
+ context.alphabetSearch.letterSearch = '';
+ }
+
+ // Handle search event here only once
+ // when alphabet panel has been drawn
+ // because we are performing two-step rendering
+ // that could trigger search hanlder when not needed
+ table.one('search', function (e, context) {
+ var api = new $.fn.dataTable.Api( context );
+
+ // Redraw alphabet panel
+ api.alphabetSearch.recalc();
+ });
}
@@ -112,7 +213,76 @@ $.fn.dataTable.AlphabetSearch = function ( context ) {
var table = new $.fn.dataTable.Api( context );
var alphabet = $('');
- draw( table, alphabet );
+ // Language
+ context.oLanguage.alphabetSearch =
+ $.extend(
+ {
+ 'alphabet': '#ABCDEFGHIJKLMNOPQRSTUVXYZ',
+ 'infoDisplay': 'Display',
+ 'infoAll': 'All'
+ },
+ ((context.oLanguage.alphabetSearch)
+ ? context.oLanguage.alphabetSearch
+ : {}
+ )
+ );
+ // Convert alphabet to uppercase
+ context.oLanguage.alphabetSearch.alphabet.toUpperCase();
+
+ context.alphabetSearch =
+ $.extend(
+ {
+ column: 0
+ },
+ $.isPlainObject(context.oInit.alphabetSearch) ? context.oInit.alphabetSearch : {},
+ {
+ letter: '',
+ letterSearch: '',
+ pass: 0
+ }
+ );
+
+ // Set required "orderDataType" ("sSortDataType") for a column
+ if(context.alphabetSearch.column >= 0 && context.alphabetSearch.column < context.aoColumns.length){
+ context.aoColumns[context.alphabetSearch.column].sSortDataType = 'alphabetSearch';
+ }
+
+ // Add column containing names to a list of columns
+ // where ordering will be always applied to the table
+ if( context.hasOwnProperty('aaSortingFixed')
+ && typeof context.aaSortingFixed === 'object' )
+ {
+ if( $.isArray(context.aaSortingFixed) ){
+ if( context.aaSortingFixed.length && !$.isArray( context.aaSortingFixed[0] ) ) {
+ // 1D array
+ context.aaSortingFixed = [[context.alphabetSearch.column, 'asc'], context.aaSortingFixed];
+
+ } else {
+ // 2D array
+ context.aaSortingFixed.unshift([context.alphabetSearch.column, 'asc']);
+ }
+ } else {
+ if( !context.aaSortingFixed.hasOwnProperty('pre') ){
+ context.aaSortingFixed.pre = [];
+ }
+
+ if( context.aaSortingFixed.pre.length && !$.isArray( context.aaSortingFixed.pre[0] ) ) {
+ // 1D array
+ context.aaSortingFixed.pre = [[context.alphabetSearch.column, 'asc'], context.aaSortingFixed.pre];
+
+ } else {
+ // 2D array
+ context.aaSortingFixed.pre.unshift([context.alphabetSearch.column, 'asc']);
+ }
+ }
+
+ } else {
+ context.aaSortingFixed = [context.alphabetSearch.column, 'asc'];
+ }
+
+
+ draw( table, alphabet, context );
+
// Trigger a search
alphabet.on( 'click', 'span', function () {
@@ -128,7 +298,7 @@ $.fn.dataTable.AlphabetSearch = function ( context ) {
alphabet
.on( 'mouseenter', 'span', function () {
alphabet
- .find('div.alphabetInfo')
+ .find('div.alphabet_info')
.css( {
opacity: 1,
left: $(this).position().left,
@@ -138,10 +308,41 @@ $.fn.dataTable.AlphabetSearch = function ( context ) {
} )
.on( 'mouseleave', 'span', function () {
alphabet
- .find('div.alphabetInfo')
+ .find('div.alphabet_info')
.css('opacity', 0);
} );
+ table.on('draw', function (e, context) {
+ var api = new $.fn.dataTable.Api( context );
+
+ // Total number of column nodes
+ var col_total = api.columns().nodes().length;
+
+ var rows = api.rows({ page: 'current' }).nodes();
+ var group_last = null;
+
+ api.column(context.alphabetSearch.column, { page: 'current' }).data().each(function (name, index){
+ var group = name.charAt(0).toUpperCase();
+
+ if (group_last !== group) {
+ $(rows).eq(index).before(
+ '' + group + ' |
'
+ );
+
+ group_last = group;
+ }
+ });
+
+ // If there are no rows found and letter is selected
+ if(!rows.length && context.alphabetSearch){
+ var letter = (context.alphabetSearch.letter === '#') ? '0-9' : context.alphabetSearch.letter;
+
+ $(api.table().body()).prepend(
+ '' + letter + ' |
'
+ );
+ }
+ });
+
// API method to get the alphabet container node
this.node = function () {
return alphabet;
@@ -162,4 +363,3 @@ $.fn.dataTable.ext.feature.push( {
}());
-
diff --git a/features/alphabetSearch/dataTables.alphabetSearch.min.js b/features/alphabetSearch/dataTables.alphabetSearch.min.js
index 033b500..efd2482 100644
--- a/features/alphabetSearch/dataTables.alphabetSearch.min.js
+++ b/features/alphabetSearch/dataTables.alphabetSearch.min.js
@@ -1,8 +1,4 @@
-/*!
- AlphabetSearch for DataTables v1.0.0
- 2014 SpryMedia Ltd - datatables.net/license
-*/
-(function(){function f(b,c){c.empty();c.append("Search: ");for(var a=b.column(0).data(),d,e={},g=0,f=a.length;g/g,"").charAt(0).toUpperCase(),e[d]?e[d]++:e[d]=1;$('').data("letter","").data("match-count",a.length).html("None").appendTo(c);for(a=0;26>a;a++)d=String.fromCharCode(65+a),$("").data("letter",d).data("match-count",e[d]||0).addClass(!e[d]?"empty":"").html(d).appendTo(c);$('').appendTo(c)}
-$.fn.dataTable.Api.register("alphabetSearch()",function(b){this.iterator("table",function(c){c.alphabetSearch=b});return this});$.fn.dataTable.Api.register("alphabetSearch.recalc()",function(){this.iterator("table",function(b){f(new $.fn.dataTable.Api(b),$("div.alphabet",this.table().container()))});return this});$.fn.dataTable.ext.search.push(function(b,c){return!b.alphabetSearch||c[0].charAt(0)===b.alphabetSearch?!0:!1});$.fn.dataTable.AlphabetSearch=function(b){var c=new $.fn.dataTable.Api(b),
-a=$('');f(c,a);a.on("click","span",function(){a.find(".active").removeClass("active");$(this).addClass("active");c.alphabetSearch($(this).data("letter")).draw()});a.on("mouseenter","span",function(){a.find("div.alphabetInfo").css({opacity:1,left:$(this).position().left,width:$(this).width()}).html($(this).data("match-count"))}).on("mouseleave","span",function(){a.find("div.alphabetInfo").css("opacity",0)});this.node=function(){return a}};$.fn.DataTable.AlphabetSearch=$.fn.dataTable.AlphabetSearch;
-$.fn.dataTable.ext.feature.push({fnInit:function(b){return(new $.fn.dataTable.AlphabetSearch(b)).node()},cFeature:"A"})})();
+/*! AlphabetSearch for DataTables v1.1.0
+ * 2014 SpryMedia Ltd - datatables.net/license
+ */
+(function(){$.fn.dataTable.Api.register("alphabetSearch()",function(searchTerm){this.iterator("table",function(context){context.alphabetSearch.letter=searchTerm;});return this;});$.fn.dataTable.Api.register("alphabetSearch.recalc()",function(searchTerm){this.iterator("table",function(context){draw(new $.fn.dataTable.Api(context),$("div.alphabet",this.table().container()),context);});return this;});$.fn.dataTable.ext.search.push(function(context,searchData){if(!context.alphabetSearch.letterSearch){return true;}var letter=searchData[context.alphabetSearch.column].toString().replace(/<.*?>/g,"").charAt(0).toUpperCase();if(context.alphabetSearch.letterSearch!=="#"){if(letter===context.alphabetSearch.letterSearch){return true;}}else{if(/\d/.test(letter)){return true;}}return false;});$.fn.dataTable.ext.order["alphabetSearch"]=function(context,col){var order_col=this.api().order()[0][0];var order_method=this.api().order()[0][1];if(order_col!==context.alphabetSearch.column){context.alphabetSearch.pass=0;}var data=this.api().column(col,{order:"index"}).data().map(function(value,index){return(order_col===context.alphabetSearch.column)?((!context.alphabetSearch.pass)?"":((order_method==="asc")?value.charAt(0):String.fromCharCode(65535-value.charCodeAt(0)))):value.charAt(0);});if(order_col===context.alphabetSearch.column){if(!context.alphabetSearchPass){context.alphabetSearch.pass=0;}context.alphabetSearch.pass=(context.alphabetSearch.pass+1)%2;}return data;};function bin(data){var letter,bins={};for(var i=0,ien=data.length;i/g,"").charAt(0).toUpperCase();if(/\d/.test(letter)){letter="#";}if(bins[letter]){bins[letter]++;}else{bins[letter]=1;}}return bins;}function draw(table,alphabet,context){alphabet.empty();alphabet.append(context.oLanguage.alphabetSearch.infoDisplay+": ");var columnData=table.column(context.alphabetSearch.column,{search:"applied"}).data();var bins=bin(columnData);$('').data("letter","").data("match-count",columnData.length).html(context.oLanguage.alphabetSearch.infoAll).appendTo(alphabet);for(var i=0;i").data("letter",letter).data("match-count",bins[letter]||0).addClass((!bins[letter]?"empty":"")+((context.alphabetSearch.letter===letter)?" active":"")).html((letter==="#")?"0-9":letter).appendTo(alphabet);}$('').appendTo(alphabet);if(context.alphabetSearch.letter){context.alphabetSearch.letterSearch=context.alphabetSearch.letter;table.draw();context.alphabetSearch.letterSearch="";}table.one("search",function(e,context){var api=new $.fn.dataTable.Api(context);api.alphabetSearch.recalc();});}$.fn.dataTable.AlphabetSearch=function(context){var table=new $.fn.dataTable.Api(context);var alphabet=$('');context.oLanguage.alphabetSearch=$.extend({"alphabet":"#ABCDEFGHIJKLMNOPQRSTUVXYZ","infoDisplay":"Display","infoAll":"All"},((context.oLanguage.alphabetSearch)?context.oLanguage.alphabetSearch:{}));context.oLanguage.alphabetSearch.alphabet.toUpperCase();context.alphabetSearch=$.extend({column:0},$.isPlainObject(context.oInit.alphabetSearch)?context.oInit.alphabetSearch:{},{letter:"",letterSearch:"",pass:0});if(context.alphabetSearch.column>=0&&context.alphabetSearch.column'+group+" | ");group_last=group;}});if(!rows.length&&context.alphabetSearch){var letter=(context.alphabetSearch.letter==="#")?"0-9":context.alphabetSearch.letter;$(api.table().body()).prepend(''+letter+" |
");}});this.node=function(){return alphabet;};};$.fn.DataTable.AlphabetSearch=$.fn.dataTable.AlphabetSearch;$.fn.dataTable.ext.feature.push({fnInit:function(settings){var search=new $.fn.dataTable.AlphabetSearch(settings);return search.node();},cFeature:"A"});}());
\ No newline at end of file