├── images ├── blank.png ├── arrows.gif ├── up_arrow.png ├── down_arrow.png ├── up_arrow3.png └── down_arrow3.png ├── css └── demostyle.css ├── README.md ├── demo.html └── dynamic_table.js /images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidDurman/DynamicTable/HEAD/images/blank.png -------------------------------------------------------------------------------- /images/arrows.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidDurman/DynamicTable/HEAD/images/arrows.gif -------------------------------------------------------------------------------- /images/up_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidDurman/DynamicTable/HEAD/images/up_arrow.png -------------------------------------------------------------------------------- /images/down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidDurman/DynamicTable/HEAD/images/down_arrow.png -------------------------------------------------------------------------------- /images/up_arrow3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidDurman/DynamicTable/HEAD/images/up_arrow3.png -------------------------------------------------------------------------------- /images/down_arrow3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DavidDurman/DynamicTable/HEAD/images/down_arrow3.png -------------------------------------------------------------------------------- /css/demostyle.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Table 1 3 | */ 4 | 5 | #t1 .dynamic-table-toolbar { 6 | height: 30px; 7 | } 8 | 9 | #t1 .dynamic-table-filter { 10 | height: 15px; 11 | font-size: 9px; 12 | border: 1px solid black; 13 | display: block; 14 | float: left; 15 | } 16 | 17 | /** 18 | * tools can be styled individualy 19 | * every tool has class name tool-1, tool-2, ..., tool-n 20 | */ 21 | #t1 .dynamic-table-toolbar .tool-1 .dynamic-table-filter { 22 | width: 50px; 23 | } 24 | #t1 .dynamic-table-toolbar .tool-2 .dynamic-table-filter { 25 | width: 350px; 26 | } 27 | #t1 .dynamic-table-toolbar .tool-3 .dynamic-table-filter { 28 | width: 200px; 29 | } 30 | #t1 .dynamic-table-toolbar .tool-4 .dynamic-table-filter { 31 | width: 120px; 32 | } 33 | 34 | 35 | #t1 .dynamic-table-downarrow { 36 | height: 15px; 37 | width: 15px; 38 | background-image: url(../images/down_arrow.png); 39 | cursor: pointer; 40 | } 41 | #t1 .dynamic-table-uparrow { 42 | height: 15px; 43 | width: 15px; 44 | background-image: url(../images/up_arrow.png); 45 | cursor: pointer; 46 | } 47 | 48 | #t1 .dynamic-table-pagerbar { 49 | background-color: #F2F5F7; 50 | } 51 | 52 | #t1 .dynamic-table-pagerbar .dynamic-table-page-selector { 53 | display : block; 54 | color: orange; 55 | text-decoration: none; 56 | float: left; 57 | width: 20px; 58 | margin-right: 2px; 59 | } 60 | 61 | #t1 .dynamic-table-pagerbar .dynamic-table-page-selector:hover { 62 | font-weight: bolder; 63 | text-decoration: underline; 64 | } 65 | 66 | #t1 .dynamic-table-pagerbar .dynamic-table-page-selected { 67 | display : block; 68 | color: red; 69 | text-decoration: none; 70 | float: left; 71 | width: 20px; 72 | margin-right: 2px; 73 | } 74 | 75 | /** 76 | * Table 2 77 | */ 78 | #t2 .dynamic-table-filter { 79 | border: 2px solid gray; 80 | } 81 | 82 | #t2 .dynamic-table-downarrow { 83 | height: 18px; 84 | width: 20px; 85 | background-image: url(../images/down_arrow3.png); 86 | cursor: pointer; 87 | } 88 | #t2 .dynamic-table-uparrow { 89 | height: 18px; 90 | width: 20px; 91 | background-image: url(../images/up_arrow3.png); 92 | cursor: pointer; 93 | } 94 | 95 | 96 | #t2 .dynamic-table-pagerbar { 97 | background-color: #F2F5F7; 98 | border: 1px dotted black; 99 | } 100 | 101 | #t2 .dynamic-table-pagerbar .dynamic-table-page-selector { 102 | display : block; 103 | color: orange; 104 | text-decoration: none; 105 | float: left; 106 | width: 20px; 107 | margin-right: 2px; 108 | } 109 | 110 | #t2 .dynamic-table-pagerbar .dynamic-table-page-selector:hover { 111 | font-weight: bolder; 112 | text-decoration: underline; 113 | } 114 | 115 | #t2 .dynamic-table-pagerbar .dynamic-table-page-selected { 116 | display : block; 117 | color: red; 118 | text-decoration: none; 119 | float: left; 120 | width: 20px; 121 | margin-right: 2px; 122 | } 123 | 124 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DynamicTable 2 | ============ 3 | 4 | Make your HTML table dynamic with paging, filters and sorting. 5 | 6 | Dedicated to [Walter Zorn](http://www.walterzorn.de/en/). 7 | 8 | 9 | DEMO 10 | ---- 11 | 12 | Demo is available here: [http://www.daviddurman.com/dynamic-table-javascript-library.html](http://www.daviddurman.com/dynamic-table-javascript-library.html). 13 | 14 | USAGE 15 | ----- 16 | 17 | // Pass HTML table element string ID 18 | new DynamicTable('myTableId') 19 | 20 | // or pass HTML table element directly. 21 | new DynamicTable(document.getElementById('myTableId')) 22 | 23 | // or directly in HTML - no need to be worry about duplicate instantiation for the same table element, 24 | // DynamicTable takes care of it. 25 | ...
26 | 27 | // First column alphanumerically sorted, second column sorted by numbers. 28 | new DynamicTable('myTableId', { 29 | colTypes: ['alpha', 'number'] 30 | }) 31 | 32 | // Custom sort function. 33 | // Predefined sort functions are: 34 | 35 | // - 'alpha': alphanumeric using current locale 36 | // - 'number': by numbers 37 | // - 'czdate': czech date format (dd.mm.yyyy) 38 | // - 'date': english date format (yyyy-mm-dd) 39 | 40 | new DynamicTable('myTableId', { 41 | colTypes: ['myLastChar'], 42 | customTypes: { 43 | myLastChar: function(a, b) { 44 | return a.charCodeAt(a.length - 1) - b.charCodeAt(b.length - 1) 45 | } 46 | } 47 | }) 48 | 49 | // Custom filter function - case-agnostic instead of the default case-sensitive. 50 | // Filter function must return -1 when not found, something else otherwise. 51 | new DynamicTable('myTableId', { 52 | filterFunction: function(a, b) { 53 | return a.search(b); 54 | } 55 | }) 56 | 57 | // Paging. 58 | new DynamicTable('myTableId', { 59 | pager: { 60 | rowsCount: 10, 61 | currentPage: 3 62 | } 63 | }) 64 | 65 | // Visual effects. 66 | new DynamicTable('myTableId', { 67 | fadeDestroy: { 68 | opacity: 90, // % 69 | sensitivity: -1, 70 | duration: 10 // 1 second 71 | }, 72 | fadeCreate: { 73 | opacity: 10, // % of the opacity when the effect starts 74 | sensitivity: .5, 75 | duration: 30 // 3 seconds 76 | } 77 | }) 78 | 79 | // Destroying DynamicTable 80 | DynamicTable.destroy('myTableId') 81 | DynamicTable.destroy(document.getElementById('myTableId')) 82 | 83 | // Hide/show toolbar 84 | DynamicTable.hide('myTableId') 85 | DynamicTable.hide(document.getElementById('myTableId')) 86 | DynamicTable.show('myTableId') 87 | DynamicTable.show(document.getElementById('myTableId')) 88 | 89 | 90 | CSS Classes used in the stylesheet 91 | ---------------------------------- 92 | 93 | .dynamic-table-toolbar (TR element) 94 | .dynamic-table-filter (INPUT element) 95 | .tool-1, .tool-2, ...., tool-n (TH element) 96 | .dynamic-table-downarrow (IMG element) 97 | .dynamic-table-uparrow (IMG element) 98 | .dynamic-table-pagerbar (TD element) 99 | .dynamic-table-page-selector (A element) 100 | .dynamic-table-page-selected (A element) 101 | 102 | Example style for third filter in order: 103 | 104 | #myTableId .dynamic-table-toolbar .tool-3 .dynamic-table-filter { 105 | width: 50px; 106 | } 107 | 108 | 109 | Browser compatibility 110 | --------------------- 111 | 112 | - Mozilla/5.0 Gecko/20080311 Iceweasel/2.0.0.13+ 113 | - IE6+ 114 | - Opera/9.27+ 115 | - Google Chrome 116 | 117 | 118 | LICENSE 119 | ------- 120 | 121 | MIT license. 122 | 123 | 124 | 125 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/DavidDurman/dynamictable/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 126 | 127 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DynamicTable - JavaScript library that turns your HTML tables into dynamic interactive tables. 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Table 1

16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 |
AFNAfghanistan Afghanis75.39663894500.0132631907
ALLAlbania Leke149.71749104910.0066792463
ALLAlbania Leke120.15850003940.0083223409
DZDAlgeria Dinars99.26545443150.0100739981
DZDAlgeria Dinars237.34370154580.0042132991
ARSArgentina Pesos4.96342934110.2014736045
AUDAustralia Dollars7.12248602170.1404004159
AUDAustralia Dollars1.67903960910.5955785644
BSDBahamas Dollars1.56619524190.6384900000
BHDBahrain Dinars0.59037729641.6938320732
BDTBangladesh Taka107.44099359430.0093074344
BBDBarbados Dollars3.10889756320.3216574299
BMDBermuda Dollars1.56619524190.6384900000
BRLBrazil Reais2.61003305670.3831369099
BGNBulgaria Leva1.92485396830.5195199306
XOFCFA BCEAO Francs 655.95700000000.0015244902
XAFCFA BEAC Francs655.95700000000.0015244902
CADCanada Dollars1.58765236730.6298608062
CLPChile Pesos711.05263982210.0014063656
CNYChina Yuan Renminbi10.97981174330.0910762428
COPColombia Pesos2758.85291551750.0003624695
XPFComptoirs Français du Pacifique Francs119.33174224340.0083800000
CRCCosta Rica Colones769.31510314550.0012998575
HRKCroatia Kuna7.26213409760.1377005694
CZKCzech Republic Koruny123.61133298880.0080898731
CZKCzech Republic Koruny25.27839120420.0395594796
DKKDenmark Kroner7.47952199720.1336983834
DOPDominican Republic Pesos52.83716268070.0189260730
DOPDominican Republic Pesos61.97799182450.0161347596
XCDEast Caribbean Dollars4.15041739100.2409396226
EGPEgypt Pounds8.39660762110.1190957164
EEKEstonia Krooni15.64664000000.0639114851
EUREuro4.17800000000.2393489708
EUREuro1.00000000001.0000000000
FJDFiji Dollars2.34460365550.4265113200
FJDFiji Dollars2.85807185610.3498862346
XAUGold Ounces0.0017694084565.1606477424
HKDHong Kong Dollars12.20301022730.0819469935
HUFHungary Forint247.91304754250.0040336723
XDRIMF Special Drawing Rights0.95400000001.0482180294
ISKIceland Kronur115.06993061760.0086903676
ISKIceland Kronur460.97014205390.0021693379
INRIndia Rupees210.19522623690.0047574820
INRIndia Rupees62.72611943800.0159423221
IDRIndonesia Rupiahs14424.97141693680.0000693242
IRRIran Rials43966.41450923270.0000227446
IRRIran Rials14037.80795313940.0000712362
IQDIraq Dinars1880.21738789960.0005318534
ILSIsrael New Shekels5.45819041800.1832109039
JMDJamaica Dollars113.15760622720.0088372318
JPYJapan Yen163.51084590200.0061158023
JPYJapan Yen424.96468849940.0023531367
JODJordan Dinars1.11043242650.9005500705
KESKenya Shillings97.41734404610.0102651125
KESKenya Shillings302.96793998340.0033006793
KWDKuwait Dinars0.41621638552.4025964252
KWDKuwait Dinars1.58120604860.6324286458
LBPLebanon Pounds2366.52101050920.0004225612
MYRMalaysia Ringgits4.93265360460.2027306355
MURMauritius Rupees40.21206283580.0248681597
MXNMexico Pesos23.69189775880.0422085225
MXNMexico Pesos16.38443828410.0610335236
MADMorocco Dirhams11.48026583480.0871059969
NZDNew Zealand Dollars2.00230230700.4994250851
NOKNorway Kroner20.20583689640.0494906499
NOKNorway Kroner8.02455794140.1246174565
OMROman Rials0.60290685841.6586309910
OMROman Rials1.36558403420.7322874133
PKRPakistan Rupees100.69069215780.0099314046
XPDPalladium Ounces0.0035474411281.8933350005
PENPeru Nuevos Soles4.34376419360.2302150751
PHPPhilippines Pesos65.49828521670.0152675753
XPTPlatinum Ounces0.00080030421249.5249300061
PLNPoland Zlotych3.43928644140.2907579863
QARQatar Riyals5.70093063960.1754099573
QARQatar Riyals3.91653934940.2553274487
RONRomania New Lei3.64469294740.2743715354
RUBRussia Rubles68.66871525000.0145626723
RUBRussia Rubles36.99823019940.0270283199
SARSaudi Arabia Riyals5.87448536390.1702276775
XAGSilver Ounces0.35951535642.7815223528
XAGSilver Ounces0.093114570410.7394578043
SGDSingapore Dollars2.13268956440.4688914958
SKKSlovakia Koruny32.39988096920.0308643109
SKKSlovakia Koruny32.17308180240.0310818841
ZARSouth Africa Rand11.97826118840.0834845713
KRWSouth Korea Won1557.08781656720.0006422245
KRWSouth Korea Won736.50253723630.0013577686
LKRSri Lanka Rupees168.67922766480.0059284123
SDGSudan Pounds3.10082381870.3224949428
SDGSudan Pounds3.16410593740.3160450439
SEKSweden Kronor9.37446162040.1066727926
CHFSwitzerland Francs5.67877139810.1760944278
CHFSwitzerland Francs1.62296981940.6161544029
TWDTaiwan New Dollars47.51366505350.0210465768
THBThailand Baht49.40739718820.0202398842
TTDTrinidad and Tobago Dollars9.80438220670.1019952077
TNDTunisia Dinars1.20565803690.8294225803
TNDTunisia Dinars1.82399097870.5482483256
TRYTurkey New Lira2.01068145150.4973438230
AEDUnited Arab Emirates Dirhams5.75185202590.1738570456
GBPUnited Kingdom Pounds0.78980876761.2661292721
USDUnited States Dollars1.56619524190.6384900000
VEFVenezuela Bolivares Fuertes14.38057729960.0695382375
VEFVenezuela Bolivares Fuertes3.36309104290.2973455037
VNDVietnam Dong25228.27290237910.0000396381
ZMKZambia Kwacha5411.20456076050.0001848017
133 | 134 |
135 | 136 | 137 | 157 | 158 | 159 | 160 |

Table 2

161 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 |
appleStrawberry452001-03-13Item 0
Bananaorange76981789-07-14Item 1
orangeBanana45461949-07-04Item 2
Strawberryapple9871975-08-19Item 3
Pearblueberry987432001-01-01Item 4
blueberryPear42001-04-18Item 5
214 | 215 | 216 | 228 | 229 | 230 | 231 | -------------------------------------------------------------------------------- /dynamic_table.js: -------------------------------------------------------------------------------- 1 | // Dynamic table 2 | // ============= 3 | 4 | // Copyright (c) 2008-2012 David Durman 5 | 6 | (function(window, undefined) { 7 | 8 | 9 | // THIS AND ONLY THIS MUST BE SET !!! 10 | var blank_image_src = "images/blank.png"; 11 | 12 | // all DynamicTable's in document 13 | var dTables = []; 14 | 15 | /** 16 | * Dynamic table object 17 | * 18 | * @param obj can be id attribute of a table element or 19 | * a table element itself 20 | * @param options custom options 21 | */ 22 | function DynamicTable(obj, options){ 23 | this.table = (typeof obj == "string") ? document.getElementById(obj) : obj; 24 | // prevent of creating more than one DynamicTables on same element 25 | for (var i = 0, dtl = dTables.length; i < dtl; i++) 26 | if (dTables[i].table == this.table) 27 | return; 28 | dTables.push(this); 29 | 30 | this.sortColumn = null; 31 | this.desc = null; 32 | this.toolbar = null; 33 | 34 | this.maxRowCount = 10; // maximal number of displayed rows 35 | this.currentPage = 1; // default current page 36 | this.rmRows = []; 37 | 38 | 39 | // toolbar onclick handler wrapper 40 | // allows to use "this" 41 | var oThis = this; 42 | this._toolbarClick = function(evt){ oThis.toolbarClick(evt); } 43 | this._filterRows = function(evt){ oThis.filterRows(evt); } 44 | this._pagerClick = function(evt){ oThis.pagerClick(evt); }; 45 | 46 | // table rows 47 | this.rows = []; 48 | for (var i = 0, brl = this.table.tBodies[0].rows.length; i < brl; i++) 49 | this.rows.push(this.table.tBodies[0].rows[i]); 50 | 51 | // table columns (without toolbar buttons!) 52 | this.cols = this.table.rows[0].cells; 53 | 54 | // option parsing 55 | this.opt = {}; 56 | this.opt.colTypes = []; 57 | 58 | if (options != undefined){ 59 | if (options.filterFunction != undefined){ 60 | this.filterFunction = options.filterFunction; 61 | } 62 | 63 | if (options.pager != undefined){ 64 | this.opt.pager = true; 65 | if (options.pager.rowsCount != undefined) 66 | this.maxRowCount = options.pager.rowsCount; 67 | if (options.pager.currentPage != undefined) 68 | this.currentPage = options.pager.currentPage; 69 | } 70 | if (options.colTypes != undefined) 71 | this.opt.colTypes = options.colTypes; 72 | if (options.customTypes != undefined) 73 | for (var ct in options.customTypes) 74 | this.sortFunctions[ct] = options.customTypes[ct]; 75 | this.opt.fadeDestroy = options.fadeDestroy; 76 | this.opt.fadeCreate = options.fadeCreate; 77 | } 78 | 79 | // fill the rest of colTypes with default type 80 | for (var i = this.opt.colTypes.length, cl = this.cols.length; i < cl; i++) 81 | this.opt.colTypes.push("alpha"); 82 | 83 | // toolbar 84 | this.toolbar = document.createElement("tr"); 85 | this.toolbar.className = "dynamic-table-toolbar"; 86 | 87 | this.filters = []; 88 | 89 | // fill the toolbar 90 | for (var i = 0; i < this.cols.length; i++){ 91 | var colTools = document.createElement("th"); 92 | colTools.className = "tool-" + (i + 1); 93 | 94 | if (this.opt.colTypes[i] != "none"){ 95 | // input filter 96 | var filter = document.createElement("input"); 97 | filter.type = "text"; 98 | filter.style.float = "left"; 99 | filter.className = "dynamic-table-filter"; 100 | DynamicTableEvent.observe(filter, "keypress", this._filterRows); 101 | this.filters.push(filter); 102 | 103 | // button for sorting 104 | var toolBtn = document.createElement("img"); 105 | toolBtn.src = blank_image_src; 106 | toolBtn.className = "dynamic-table-downarrow"; 107 | DynamicTableEvent.observe(toolBtn, "click", this._toolbarClick); 108 | 109 | colTools.appendChild(filter); 110 | colTools.appendChild(toolBtn); 111 | 112 | } else // no filter on this column 113 | this.filters.push("none"); 114 | 115 | this.toolbar.appendChild(colTools); 116 | } 117 | 118 | // insert to table header at first place (using effects by options) 119 | if (this.opt.fadeCreate){ 120 | var tb = this.toolbar; 121 | tb.style.visibility = "hidden"; 122 | 123 | if (this.table.tHead) 124 | this.table.tHead.insertBefore(tb, this.table.tHead.rows[0]); 125 | else { 126 | var thead = document.createElement("thead"); 127 | this.table.tBodies[0].parentNode.insertBefore(thead, this.table.tBodies[0]); 128 | thead.appendChild(tb); 129 | } 130 | // this.table.rows[0].parentNode.insertBefore(tb, this.table.rows[0]); 131 | var sensitivity = (this.opt.fadeCreate.sensitivity) ? this.opt.fadeCreate.sensitivity : 1; 132 | var opacity = (this.opt.fadeCreate.opacity) ? this.opt.fadeCreate.opacity : 10; 133 | var duration = (this.opt.fadeCreate.duration) ? this.opt.fadeCreate.duration : 20; 134 | DynamicTable.setOpacity(tb.style, opacity); 135 | tb.style.visibility = "visible"; 136 | DynamicTable.fadeObject(tb.style, opacity, sensitivity, duration); 137 | } else { 138 | if (this.table.tHead) 139 | this.table.tHead.insertBefore(this.toolbar, this.table.tHead.rows[0]); 140 | else { 141 | var thead = document.createElement("thead"); 142 | this.table.tBodies[0].parentNode.insertBefore(thead, this.table.tBodies[0]); 143 | thead.appendChild(this.toolbar); 144 | } 145 | // this.table.rows[0].parentNode.insertBefore(this.toolbar, this.table.rows[0]); 146 | } 147 | 148 | // insert pager navigation as next row in Footage or create new Footage 149 | if (options && options.pager){ 150 | var t_foot = null; 151 | if (this.table.tFoot) 152 | t_foot = this.table.tFoot; 153 | else 154 | t_foot = this.table.createTFoot(); 155 | this.pagerBar = document.createElement("tr"); 156 | var pbTD = document.createElement("td"); 157 | pbTD.className = "dynamic-table-pagerbar"; 158 | // pbTD.colspan = "" + this.cols.length; // is not working 159 | pbTD.setAttribute("colspan", this.cols.length); 160 | var a = null; 161 | for (var i = 0, rl = Math.ceil(this.rows.length / this.maxRowCount); i < rl; ++i){ 162 | a = document.createElement("a"); 163 | a.className = "dynamic-table-page-selector"; 164 | a.appendChild(document.createTextNode(i + 1)); 165 | a.href = "#dt_page_" + (i + 1); 166 | DynamicTableEvent.observe(a, "click", this._pagerClick); 167 | pbTD.appendChild(a); 168 | } 169 | 170 | //!//TODO: element to change number of rows for pager dynamically 171 | // var td = document.createElement("input"); 172 | // td.id = "numberOfRows"; 173 | // td.value = "10"; 174 | // pbTD.appendChild(td); 175 | 176 | this.pagerBar.appendChild(pbTD); 177 | t_foot.appendChild(this.pagerBar); 178 | 179 | this.pager(this.currentPage); 180 | } 181 | } 182 | 183 | DynamicTable.prototype.tableMouseOut = function(evt){ 184 | DynamicTableEvent.preventBubbling(evt); 185 | var el = evt.target || evt.srcElement; 186 | if (el.tagName != "TABLE") 187 | return; 188 | DynamicTable.destroy(this); 189 | } 190 | 191 | /** 192 | * Browser recognizer 193 | */ 194 | DynamicTable.Browser = { 195 | msie: !!(window.attachEvent && !window.opera), 196 | opera: !!window.opera, 197 | gecko: navigator.userAgent.indexOf("Gecko") > -1 && navigator.userAgent.indexOf("KHTML") == -1, 198 | webkit: navigator.userAgent.indexOf("AppleWebKit/") > -1, 199 | mobilesafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) 200 | }; 201 | 202 | /** 203 | * @return column index of an element el 204 | */ 205 | DynamicTable.prototype.getColumnIndex = function(el){ 206 | while (el.tagName != "TH") 207 | el = el.parentNode; 208 | 209 | // column number 210 | var col = null; 211 | if (!DynamicTable.Browser.msie) 212 | col = el.cellIndex; 213 | else { 214 | var tds = el.parentNode.childNodes; 215 | for (col = 0, l = tds.length; tds[col] != el && col < l; col++) 216 | ; 217 | } 218 | return col; 219 | } 220 | 221 | /** 222 | * Tool button onclick event handler 223 | */ 224 | DynamicTable.prototype.toolbarClick = function(evt){ 225 | var el = evt.target || evt.srcElement; 226 | this.sort(this.getColumnIndex(el)); 227 | } 228 | 229 | 230 | /** 231 | * Pager button onclick event handler 232 | */ 233 | DynamicTable.prototype.pagerClick = function(evt){ 234 | var el = evt.target || evt.srcElement; 235 | this.currentPage = parseInt(el.href.substring(el.href.lastIndexOf("dt_page_") + "dt_page_".length)); 236 | this.pager(this.currentPage); 237 | } 238 | 239 | /** 240 | * @return 241 | */ 242 | DynamicTable.prototype.pager = function(page){ 243 | if (!this.opt.pager) 244 | return; 245 | 246 | this.currentPage = page; 247 | var rn = this.rows.length; 248 | var cp = this.currentPage; 249 | var mr = this.maxRowCount; 250 | 251 | // this.pagerBar.style.display = "none"; 252 | 253 | var rows = this.table.tBodies[0].rows; 254 | 255 | // show all rows 256 | for (var i = 0, trl = rows.length; i < trl; i++) 257 | rows[i].style.display = ""; 258 | 259 | var from = cp * mr - mr; 260 | var to = ((from + mr) > this.rows.length) ? this.rows.length : from + mr; 261 | 262 | // alert("from: " + from + " to: " + to); 263 | // alert(this.rows.length); 264 | 265 | // hide rows in other pages 266 | for (var i = 0, rl = rows.length; i < rl; i++){ 267 | if (i < from || i >= to){ 268 | rows[i].style.display = "none"; 269 | } 270 | } 271 | 272 | // hide unnecessary page indexes 273 | var showed_rows_count = this.rows.length - this.rmRows.length; 274 | var p_count = Math.ceil(this.rows.length / this.maxRowCount); // pages count 275 | var p_cur_count = Math.ceil(showed_rows_count / this.maxRowCount); // current pages count 276 | 277 | for (var i = 0; i < p_count; i++){ 278 | this.pagerBar.childNodes[0].childNodes[i].style.visibility = "visible"; 279 | this.pagerBar.childNodes[0].childNodes[i].className = "dynamic-table-page-selector"; // set old class to all selectors 280 | if (i >= p_cur_count || p_cur_count == 1) 281 | this.pagerBar.childNodes[0].childNodes[i].style.visibility = "hidden"; 282 | } 283 | 284 | // "selected" class for selected selector 285 | this.pagerBar.childNodes[0].childNodes[this.currentPage - 1].className = "dynamic-table-page-selected"; 286 | } 287 | 288 | /** 289 | * Filter rows by substring 290 | */ 291 | DynamicTable.prototype.filterRows = function(evt){ 292 | if (evt.keyCode == 13){ 293 | var tTable = this.table; 294 | 295 | // for (var i = 0; i < this.filters.length; i++){ 296 | // alert(this.filters[i].value.toLowerCase()); 297 | // } 298 | 299 | var input = evt.target || evt.srcElement; 300 | var col = this.getColumnIndex(input); 301 | var tRows = this.rows; 302 | 303 | var newRows = []; 304 | this.rmRows = []; // initialize rmRows 305 | 306 | for (var i = 0, trl = tRows.length; i < trl; i++){ 307 | tRows[i].style.display = ""; 308 | 309 | var bPush = true; 310 | for (var j = 0, fl = this.filters.length; j < fl; j++){ 311 | if (this.filters[j] == "none") 312 | continue; 313 | var text = this.rowCells(tRows[i])[j].innerHTML; 314 | if (this.filterFunction(text, this.filters[j].value) == -1) 315 | bPush = false; 316 | } 317 | if (bPush) 318 | newRows.push(tRows[i]); 319 | else 320 | this.rmRows.push(tRows[i]); 321 | } 322 | 323 | // append not filtered rows to tree 324 | for (var i = 0, nrl = newRows.length; i < nrl; i++){ 325 | tTable.tBodies[0].appendChild(newRows[i]); 326 | } 327 | 328 | // delete filtered rows from the tree 329 | this.removeRows(this.rmRows); 330 | this.pager(1); // goto first page 331 | 332 | }//end (evt.keyCode == 13) 333 | } 334 | 335 | /** 336 | * Get row TD cells using childNodes instead of cells (because of IE) 337 | * //!//NOTE: IE looses cells collection on disconnected DOM tree 338 | * (tRows[i].cells[j]) 339 | */ 340 | DynamicTable.prototype.rowCells = function(row){ 341 | var cells = []; 342 | for (var i = 0, rl = row.childNodes.length; i < rl; i++) 343 | if (row.childNodes[i].tagName == 'TD' || 344 | row.childNodes[i].tagName == 'TH') 345 | cells.push(row.childNodes[i]); 346 | return cells; 347 | } 348 | 349 | 350 | /** 351 | * Sort 352 | * @param col column number 353 | */ 354 | DynamicTable.prototype.sort = function(col){ 355 | this.desc = (this.sortColumn != col) ? false : !this.desc; 356 | this.sortColumn = col; 357 | this.orderRows(this.sortFunctions[this.opt.colTypes[col]]); 358 | // update sort arrows 359 | this.toolbar.cells[this.sortColumn].lastChild.className = "dynamic-table-" + ((this.desc) ? "downarrow" : "uparrow"); 360 | } 361 | 362 | /** 363 | * Order rows by sort function 364 | * NOTE: DOM manipulation is faster on disconnected DOM tree (in Mozilla) 365 | */ 366 | DynamicTable.prototype.orderRows = function(sortFnc){ 367 | 368 | // apply sort function 369 | var _sortColumn = this.sortColumn; 370 | var _this = this; 371 | var _sortFnc = function(a, b){ 372 | var x = _this.rowCells(a)[_sortColumn]; 373 | var y = _this.rowCells(b)[_sortColumn]; 374 | return sortFnc(x.innerHTML, y.innerHTML); 375 | } 376 | 377 | var _rows = this.rows; 378 | _rows.sort(_sortFnc); 379 | 380 | if (this.desc) 381 | _rows.reverse(); 382 | 383 | for (var i = 0, len = _rows.length; i < len; ++i){ 384 | this.table.tBodies[0].appendChild(_rows[i]); 385 | _rows[i].display = ""; 386 | } 387 | 388 | this.removeRows(this.rmRows); 389 | this.pager(1); // goto first page 390 | } 391 | 392 | /** 393 | * Remove rows 394 | */ 395 | DynamicTable.prototype.removeRows = function(rows){ 396 | var rmRows = rows; 397 | for (var i = 0, rowsl = rmRows.length; i < rowsl; i++) 398 | if (rmRows[i].parentNode) 399 | rmRows[i].parentNode.removeChild(rmRows[i]); 400 | } 401 | 402 | /** 403 | * Removes toolbar from the table (using effects from options) 404 | */ 405 | DynamicTable.prototype._destroy = function(){ 406 | if (this.toolbar){ 407 | var tb = this.toolbar; 408 | if (this.opt.fadeDestroy){ 409 | var sensitivity = (this.opt.fadeDestroy.sensitivity) ? this.opt.fadeDestroy.sensitivity : -1; 410 | var opacity = (this.opt.fadeDestroy.opacity) ? this.opt.fadeDestroy.opacity : 99; 411 | var duration = (this.opt.fadeDestroy.duration) ? this.opt.fadeDestroy.duration : 20; 412 | DynamicTable.fadeObject(tb.style, opacity, sensitivity, duration); 413 | setTimeout(function(){tb.parentNode.removeChild(tb)}, duration * 100); 414 | } else 415 | tb.parentNode.removeChild(tb); 416 | } 417 | } 418 | 419 | /** 420 | * Destroys DynamicTable object using table element or table id 421 | */ 422 | DynamicTable.destroy = function(tbl){ 423 | var oTbl = (typeof tbl == "string") ? document.getElementById(tbl) : tbl; 424 | for (var i = 0, dtl = dTables.length; i < dtl; i++){ 425 | if (dTables[i].table == oTbl){ 426 | dTables[i]._destroy(); 427 | var tmp1 = dTables.slice(0, i - 1); 428 | var tmp2 = dTables.slice(i + 1, dTables.length); 429 | dTables = tmp1.concat(tmp2); 430 | return; 431 | } 432 | } 433 | } 434 | 435 | 436 | /** 437 | * Hides DynamicTable object toolbar using table element or table id 438 | */ 439 | DynamicTable.hide = function(tbl){ 440 | var oTbl = (typeof tbl == "string") ? document.getElementById(tbl) : tbl; 441 | for (var i = 0, dtl = dTables.length; i < dtl; i++){ 442 | if (dTables[i].table == oTbl){ 443 | dTables[i]._hide(); 444 | } 445 | } 446 | } 447 | 448 | /** 449 | * Hides toolbar of the table (using effects from options) 450 | */ 451 | DynamicTable.prototype._hide = function(){ 452 | if (this.toolbar){ 453 | var tb = this.toolbar; 454 | if (this.opt.fadeDestroy){ 455 | var sensitivity = (this.opt.fadeDestroy.sensitivity) ? this.opt.fadeDestroy.sensitivity : -1; 456 | var opacity = (this.opt.fadeDestroy.opacity) ? this.opt.fadeDestroy.opacity : 99; 457 | var duration = (this.opt.fadeDestroy.duration) ? this.opt.fadeDestroy.duration : 20; 458 | DynamicTable.fadeObject(tb.style, opacity, sensitivity, duration); 459 | setTimeout(function(){tb.style.display="none"}, duration * 100); 460 | } else 461 | tb.style.display = "none"; 462 | } 463 | } 464 | 465 | /** 466 | * Shows DynamicTable object toolbar using table element or table id 467 | */ 468 | DynamicTable.show = function(tbl){ 469 | var oTbl = (typeof tbl == "string") ? document.getElementById(tbl) : tbl; 470 | for (var i = 0, dtl = dTables.length; i < dtl; i++){ 471 | if (dTables[i].table == oTbl){ 472 | dTables[i]._show(); 473 | } 474 | } 475 | } 476 | 477 | /** 478 | * Shows toolbar of the table (using effects from options) 479 | */ 480 | DynamicTable.prototype._show = function(){ 481 | if (this.toolbar){ 482 | var tb = this.toolbar; 483 | if (this.opt.fadeCreate){ 484 | var sensitivity = (this.opt.fadeCreate.sensitivity) ? this.opt.fadeCreate.sensitivity : -1; 485 | var opacity = (this.opt.fadeCreate.opacity) ? this.opt.fadeCreate.opacity : 99; 486 | var duration = (this.opt.fadeCreate.duration) ? this.opt.fadeCreate.duration : 20; 487 | // IE doesn't know table-row :( 488 | if (DynamicTable.Browser.msie) 489 | tb.style.display = "block"; 490 | else 491 | tb.style.display = "table-row"; 492 | 493 | DynamicTable.setOpacity(tb.style, opacity); 494 | DynamicTable.fadeObject(tb.style, opacity, sensitivity, duration); 495 | } else { 496 | if (DynamicTable.Browser.msie) 497 | tb.style.display = "block"; 498 | else 499 | tb.style.display = "table-row"; 500 | } 501 | } 502 | } 503 | 504 | 505 | /** 506 | * Event Handling 507 | */ 508 | var DynamicTableEvent = { 509 | observe: function(el, evt, handler){ 510 | if (el.addEventListener) 511 | el.addEventListener(evt, handler, false); 512 | else 513 | el.attachEvent("on" + evt, handler); 514 | }, 515 | 516 | stopObserving: function(el, evt, handler){ 517 | if (el.removeEventListener) 518 | el.removeEventListener(evt, handler, false); 519 | else 520 | el.detachEvent("on" + evt, handler); 521 | }, 522 | 523 | preventBubbling: function(evt) { 524 | if (window.Event) { 525 | evt.cancelBubble = true; 526 | evt.returnValue = false; 527 | } else { 528 | event.cancelBubble = true; 529 | event.returnValue = false; 530 | } 531 | return false; 532 | } 533 | 534 | }; 535 | 536 | /** 537 | * Set an opacity to the tho style object of an element 538 | * NOTE: In IE if a DIV was hidden, opacity of value less than 100 539 | * can not be applied to visible this DIV. 540 | * + in IE6 no effect will be made for opacity less than 100 541 | * if an element has no layout (size, zoom, position, ...) 542 | */ 543 | DynamicTable.setOpacity = function(style, opacity){ 544 | 545 | if (DynamicTable.Browser.msie){ 546 | if (opacity < 100){ 547 | var visib = (style.visibility != "hidden"); 548 | style.zoom = "100%"; 549 | if (!visib) 550 | style.visibility = "visible"; 551 | style.filter = "alpha(opacity=" + opacity + ")"; 552 | // place back old visibility 553 | if (!visib) 554 | style.visibility = "hidden"; 555 | } else 556 | style.filter = ""; 557 | 558 | } else { 559 | opacity /= 100.0; 560 | 561 | if (typeof style.KhtmlOpacity != "undefined") 562 | style.KhtmlOpacity = opacity; 563 | else if (typeof style.MozOpacity != "undefined") // older Mozilla and Firefox 564 | style.MozOpacity = opacity; 565 | else if (typeof style.KHTMLOpacity != "undefined") // Safary < 1.2, Konqueror 566 | style.KHTMLOpacity = opacity; 567 | else if (typeof style.opacity != "undefined") // Safary > 1.2, newer Firefox, CSS3 568 | style.opacity = opacity; 569 | 570 | } 571 | } 572 | 573 | /** 574 | * Changes objects css style declaration part 575 | * setting opacity changing it by sensitivity 576 | * until duration ellpased 577 | */ 578 | DynamicTable.fadeObject = function(style, opacity, sensitivity, duration){ 579 | DynamicTable.setOpacity(style, opacity); 580 | if (opacity < 100 && opacity > 1){ 581 | opacity += 1 * sensitivity; 582 | var fof = function(){ 583 | DynamicTable.fadeObject(style, opacity, sensitivity, duration); 584 | } 585 | setTimeout(fof, duration); 586 | // setTimeout(function(){ 587 | // DynamicTable.fadeObject(style, opacity, sensitivity, duration); 588 | // }, duration); 589 | } 590 | } 591 | 592 | /** 593 | * Pre-defined sort methods 594 | */ 595 | DynamicTable.prototype.sortFunctions = { 596 | "alpha": function(a, b){ 597 | return a.toLowerCase().localeCompare(b.toLowerCase()); 598 | }, 599 | "number": function(a, b){ 600 | return Number(a) - Number(b); 601 | }, 602 | "czdate" : function(a, b){ 603 | var _a = a.split("."); 604 | var _b = b.split("."); 605 | var d_a = new Date(_a[2], _a[1], _a[0]); 606 | var d_b = new Date(_b[2], _b[1], _b[0]); 607 | return d_a.getTime() - d_b.getTime(); 608 | }, 609 | "date": function(a, b){ 610 | var _a = a.split("-"); 611 | var _b = b.split("-"); 612 | var d_a = new Date(_a[0], _a[1], _a[2]); 613 | var d_b = new Date(_b[0], _b[1], _b[2]); 614 | return d_a.getTime() - d_b.getTime(); 615 | } 616 | }; 617 | 618 | // pre-defined function that filter rows 619 | DynamicTable.prototype.filterFunction = function(a, b){ 620 | return a.toLowerCase().search(b.toLowerCase()); 621 | } 622 | 623 | window.DynamicTable = DynamicTable; 624 | 625 | }(this)) 626 | 627 | --------------------------------------------------------------------------------