├── LICENSE ├── README.md ├── css ├── dataTables.alphabetSearch.bootstrap.css └── dataTables.alphabetSearch.css ├── js ├── dataTables.alphabetSearch.js └── dataTables.alphabetSearch.min.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | Modified work: 2 | Copyright (c) Gyrocode 3 | https://www.gyrocode.com 4 | 5 | Original work: 6 | Copyright (c) SpryMedia Limited 7 | http://datatables.net 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in 17 | all copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jQuery DataTables AlphabetSearch 2 | ===================================== 3 | 4 | AlphabetSearch is a feature plug-in for the jQuery DataTables library 5 | that provides A-Z alphabetical search feature. 6 | 7 | More information and examples is available at 8 | [gyrocode.com/projects/jquery-datatables-alphabetsearch](https://www.gyrocode.com/projects/jquery-datatables-alphabetsearch/). 9 | 10 | 11 | How to use 12 | ---------- 13 | 14 | ```` 15 | $('#example').DataTable({ 16 | dom: 'Alfrtip', 17 | alphabetSearch: { 18 | column: 0 19 | } 20 | }); 21 | ```` 22 | 23 | 24 | Copyright 25 | --------- 26 | 27 | * SpryMedia Limited, [datatables.net](http://datatables.net) 28 | * Gyrocode, [gyrocode.com](https://www.gyrocode.com) 29 | 30 | 31 | License 32 | ------- 33 | 34 | MIT License, [opensource.org/licenses/MIT](http://www.opensource.org/licenses/MIT) 35 | -------------------------------------------------------------------------------- /css/dataTables.alphabetSearch.bootstrap.css: -------------------------------------------------------------------------------- 1 | div.alphabet { 2 | clear:both; 3 | position:relative; 4 | margin:0.5em 0; 5 | } 6 | 7 | @media screen and (max-width:767px){ 8 | div.alphabet { 9 | text-align:center; 10 | } 11 | } 12 | 13 | div.alphabet ul.pagination { 14 | margin:0; 15 | } 16 | 17 | div.alphabet ul.pagination > li { 18 | display:inline-block; 19 | } 20 | 21 | div.alphabet a span { 22 | opacity:1; 23 | } 24 | 25 | div.alphabet a.empty span { 26 | opacity:0.3; 27 | } 28 | 29 | div.alphabet a.empty.active span { 30 | opacity:1; 31 | } 32 | 33 | div.alphabet .alphabet-info-display { 34 | vertical-align:top; 35 | margin-right:0.5em; 36 | } 37 | 38 | div.alphabet div.alphabet-info { 39 | position:absolute; 40 | background-color:#111; 41 | border-radius:3px; 42 | color:#FFF; 43 | margin-top:0.2em; 44 | padding:0.2em 0.4em; 45 | text-align:center; 46 | opacity:0; 47 | transition:opacity .4s ease-in-out; 48 | z-index:9999; 49 | } 50 | 51 | tr.alphabet-group, tr.alphabet-group:hover { 52 | background-color:rgba(0,0,0,0.15) !important; 53 | } -------------------------------------------------------------------------------- /css/dataTables.alphabetSearch.css: -------------------------------------------------------------------------------- 1 | div.alphabet { 2 | clear:both; 3 | position:relative; 4 | margin:0.5em 0; 5 | } 6 | 7 | @media screen and (max-width:640px){ 8 | div.alphabet { 9 | text-align:center; 10 | } 11 | } 12 | 13 | div.alphabet ul { 14 | display:inline-block; 15 | margin:0; 16 | padding:0; 17 | list-style:none; 18 | } 19 | 20 | div.alphabet li { 21 | display:inline-block; 22 | } 23 | 24 | div.alphabet a { 25 | display:inline-block; 26 | cursor:pointer; 27 | text-align:center; 28 | text-decoration:none; 29 | box-sizing:content-box; 30 | padding:0.2em 0.1em; 31 | min-width:1.3em; 32 | color:#333 !important; 33 | border:1px solid transparent; 34 | border-radius:2px; 35 | } 36 | 37 | div.alphabet a:hover { 38 | color:#FFF !important; 39 | border:1px solid #111; 40 | background-color:#585858; 41 | background:linear-gradient(to bottom, #585858 0%, #111 100%); 42 | } 43 | 44 | div.alphabet a:active { 45 | outline:none; 46 | background-color:#2b2b2b; 47 | background:linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%); 48 | box-shadow:inset 0 0 3px #111; 49 | } 50 | 51 | div.alphabet a.empty { 52 | color:#888 !important; 53 | } 54 | 55 | div.alphabet a.active, 56 | div.alphabet a.active.empty { 57 | color:#333 !important; 58 | border:1px solid #979797; 59 | background-color:#FFF; 60 | background:linear-gradient(to bottom, #fff 0%, #dcdcdc 100%) 61 | } 62 | 63 | div.alphabet .alphabet-info-display { 64 | margin-right:0.5em; 65 | } 66 | 67 | div.alphabet div.alphabet-info { 68 | position:absolute; 69 | border:1px solid #111; 70 | background-color:#585858; 71 | background:linear-gradient(to bottom, #585858 0%, #111 100%); 72 | border-radius:2px; 73 | color:#FFF; 74 | margin-top:0.2em; 75 | padding:0.2em 0.4em; 76 | text-align:center; 77 | opacity:0; 78 | z-index:9999; 79 | } 80 | 81 | tr.alphabet-group, tr.alphabet-group:hover { 82 | background-color:rgba(0,0,0,0.15) !important; 83 | } 84 | -------------------------------------------------------------------------------- /js/dataTables.alphabetSearch.js: -------------------------------------------------------------------------------- 1 | /*! AlphabetSearch for DataTables v1.2.7 2 | * 2014 SpryMedia Ltd - datatables.net/license 3 | * Gyrocode LLC - 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.2.7 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 LLC (www.gyrocode.com) 16 | * @contact www.gyrocode.com/contacts 17 | * @copyright Copyright (c) Gyrocode LLC 18 | * 19 | * License MIT - http://datatables.net/license/mit 20 | * 21 | * For more detailed information please see: 22 | * https://www.gyrocode.com/projects/jquery-datatables-alphabetsearch/ 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 () { 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 table has alphabet search feature enabled 53 | if ( ! context.hasOwnProperty('alphabetSearch') ) { 54 | return true; 55 | } 56 | 57 | // Ensure that there is a search applied to this table before running it 58 | if ( ! context.alphabetSearch.letterSearch ) { 59 | return true; 60 | } 61 | 62 | var letter = searchData[context.alphabetSearch.column] 63 | .toString() 64 | .replace(/<.*?>/g, '') 65 | .charAt(0).toUpperCase(); 66 | 67 | 68 | if(context.alphabetSearch.letterSearch !== '#'){ 69 | if ( letter === context.alphabetSearch.letterSearch ) { 70 | return true; 71 | } 72 | } else { 73 | if(/\d/.test(letter)){ 74 | return true; 75 | } 76 | } 77 | 78 | return false; 79 | } ); 80 | 81 | 82 | // Order plug-in 83 | // 84 | // NOTE: If sorting by alphabetized column there would be two calls to this method. 85 | $.fn.dataTable.ext.order['alphabetSearch'] = function ( context, col ) 86 | { 87 | var orderColumn = this.api().order()[0][0]; 88 | var orderMethod = this.api().order()[0][1]; 89 | 90 | // If sorting by column other than the one being alphabetized 91 | if(orderColumn !== context.alphabetSearch.column){ 92 | context.alphabetSearch.pass = 0; 93 | } 94 | 95 | var data = this.api().column( col, { order: 'index' } ).data().map( function (value, index) { 96 | var text = value.toString().replace(/<.*?>/g, ''); 97 | var letter = text.charAt(0).toUpperCase(); 98 | 99 | // If sorting by alphabetized column 100 | if(orderColumn === context.alphabetSearch.column) { 101 | 102 | // If this is a first pass 103 | if(context.alphabetSearch.pass === 0){ 104 | // Ignore 105 | return ''; 106 | 107 | // Otherwise, if this is a second pass 108 | } else { 109 | // When sorting in ascending order 110 | if (orderMethod === 'asc'){ 111 | // Return actual content 112 | return text; 113 | 114 | // Otherwise, when sorting in descending order 115 | } else { 116 | var textReversed = ''; 117 | 118 | // If letter search is applied to the table 119 | if(context.alphabetSearch.letterSearch) { 120 | // Reverse (take characters from the oposite side of the character table) all characters. 121 | // 122 | // NOTE: Allows to sort alphabetized column in descending order 123 | // by returning reversed text 124 | // to compensate fixed ascending order applied during initialization. 125 | // 126 | // TODO: Better solution would be to find a way to manipulate first element 127 | // of the context.aaSortingFixed array before each sort. 128 | 129 | for(var i = 0; i < text.length; i++){ 130 | textReversed += String.fromCharCode(65535 - text.charCodeAt(i)); 131 | } 132 | 133 | // Otherwise, if letter search is not applied to the table 134 | } else { 135 | // Reverse (take characters from the oposite side of the character table) first character. 136 | // 137 | // NOTE: Allows to sort group of rows by first letter in descending order 138 | // but preserve ascending order within each group. 139 | 140 | for(var i = 0; i < text.length; i++){ 141 | textReversed += (i) ? text.charAt(i) : String.fromCharCode(65535 - text.charCodeAt(i)); 142 | } 143 | } 144 | 145 | return textReversed; 146 | } 147 | } 148 | 149 | // Otherwise, if sorting by column other than the one being alphabetized, 150 | } else { 151 | // Return first letter only 152 | return letter; 153 | } 154 | } ); 155 | 156 | // If sorting by alphabetized column 157 | if(orderColumn === context.alphabetSearch.column){ 158 | // If pass is not defined, set it to 0 159 | if(!context.alphabetSearch.pass){ context.alphabetSearch.pass = 0; } 160 | // Increment pass counter and reset it to 0 if it's a second pass 161 | context.alphabetSearch.pass = (context.alphabetSearch.pass + 1) % 2; 162 | } 163 | 164 | return data; 165 | }; 166 | 167 | 168 | // Private support methods 169 | function bin ( data ) { 170 | var letter, bins = {}; 171 | 172 | for ( var i=0, ien=data.length ; i/g, '') 176 | .charAt(0).toUpperCase(); 177 | 178 | if(/\d/.test(letter)){ letter = '#'; } 179 | 180 | if ( bins[letter] ) { 181 | bins[letter]++; 182 | } 183 | else { 184 | bins[letter] = 1; 185 | } 186 | } 187 | 188 | return bins; 189 | } 190 | 191 | function draw ( table, alphabet, context ) 192 | { 193 | alphabet.empty(); 194 | 195 | if(context.oLanguage.alphabetSearch.infoDisplay !== ''){ 196 | $('') 197 | .html(context.oLanguage.alphabetSearch.infoDisplay) 198 | .appendTo( alphabet ); 199 | } 200 | 201 | var columnData = table.column(context.alphabetSearch.column, { search: 'applied' } ).data(); 202 | var bins = bin( columnData ); 203 | 204 | var alphabetList = $('