├── 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 | [](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 |
17 | - pager: 15 rows in one page, default page is the third one
18 | - sorting: the first two columns alphanumerically, the next two by numbers
19 | - filtering; search by substring, case-agnostic
20 |
21 |
22 |
23 |
24 | | AFN | Afghanistan Afghanis | 75.3966389450 | 0.0132631907 |
25 | | ALL | Albania Leke | 149.7174910491 | 0.0066792463 |
26 | | ALL | Albania Leke | 120.1585000394 | 0.0083223409 |
27 | | DZD | Algeria Dinars | 99.2654544315 | 0.0100739981 |
28 | | DZD | Algeria Dinars | 237.3437015458 | 0.0042132991 |
29 | | ARS | Argentina Pesos | 4.9634293411 | 0.2014736045 |
30 | | AUD | Australia Dollars | 7.1224860217 | 0.1404004159 |
31 | | AUD | Australia Dollars | 1.6790396091 | 0.5955785644 |
32 | | BSD | Bahamas Dollars | 1.5661952419 | 0.6384900000 |
33 | | BHD | Bahrain Dinars | 0.5903772964 | 1.6938320732 |
34 | | BDT | Bangladesh Taka | 107.4409935943 | 0.0093074344 |
35 | | BBD | Barbados Dollars | 3.1088975632 | 0.3216574299 |
36 | | BMD | Bermuda Dollars | 1.5661952419 | 0.6384900000 |
37 | | BRL | Brazil Reais | 2.6100330567 | 0.3831369099 |
38 | | BGN | Bulgaria Leva | 1.9248539683 | 0.5195199306 |
39 | | XOF | CFA BCEAO Francs | 655.9570000000 | 0.0015244902 |
40 | | XAF | CFA BEAC Francs | 655.9570000000 | 0.0015244902 |
41 | | CAD | Canada Dollars | 1.5876523673 | 0.6298608062 |
42 | | CLP | Chile Pesos | 711.0526398221 | 0.0014063656 |
43 | | CNY | China Yuan Renminbi | 10.9798117433 | 0.0910762428 |
44 | | COP | Colombia Pesos | 2758.8529155175 | 0.0003624695 |
45 | | XPF | Comptoirs Français du Pacifique Francs | 119.3317422434 | 0.0083800000 |
46 | | CRC | Costa Rica Colones | 769.3151031455 | 0.0012998575 |
47 | | HRK | Croatia Kuna | 7.2621340976 | 0.1377005694 |
48 | | CZK | Czech Republic Koruny | 123.6113329888 | 0.0080898731 |
49 | | CZK | Czech Republic Koruny | 25.2783912042 | 0.0395594796 |
50 | | DKK | Denmark Kroner | 7.4795219972 | 0.1336983834 |
51 | | DOP | Dominican Republic Pesos | 52.8371626807 | 0.0189260730 |
52 | | DOP | Dominican Republic Pesos | 61.9779918245 | 0.0161347596 |
53 | | XCD | East Caribbean Dollars | 4.1504173910 | 0.2409396226 |
54 | | EGP | Egypt Pounds | 8.3966076211 | 0.1190957164 |
55 | | EEK | Estonia Krooni | 15.6466400000 | 0.0639114851 |
56 | | EUR | Euro | 4.1780000000 | 0.2393489708 |
57 | | EUR | Euro | 1.0000000000 | 1.0000000000 |
58 | | FJD | Fiji Dollars | 2.3446036555 | 0.4265113200 |
59 | | FJD | Fiji Dollars | 2.8580718561 | 0.3498862346 |
60 | | XAU | Gold Ounces | 0.0017694084 | 565.1606477424 |
61 | | HKD | Hong Kong Dollars | 12.2030102273 | 0.0819469935 |
62 | | HUF | Hungary Forint | 247.9130475425 | 0.0040336723 |
63 | | XDR | IMF Special Drawing Rights | 0.9540000000 | 1.0482180294 |
64 | | ISK | Iceland Kronur | 115.0699306176 | 0.0086903676 |
65 | | ISK | Iceland Kronur | 460.9701420539 | 0.0021693379 |
66 | | INR | India Rupees | 210.1952262369 | 0.0047574820 |
67 | | INR | India Rupees | 62.7261194380 | 0.0159423221 |
68 | | IDR | Indonesia Rupiahs | 14424.9714169368 | 0.0000693242 |
69 | | IRR | Iran Rials | 43966.4145092327 | 0.0000227446 |
70 | | IRR | Iran Rials | 14037.8079531394 | 0.0000712362 |
71 | | IQD | Iraq Dinars | 1880.2173878996 | 0.0005318534 |
72 | | ILS | Israel New Shekels | 5.4581904180 | 0.1832109039 |
73 | | JMD | Jamaica Dollars | 113.1576062272 | 0.0088372318 |
74 | | JPY | Japan Yen | 163.5108459020 | 0.0061158023 |
75 | | JPY | Japan Yen | 424.9646884994 | 0.0023531367 |
76 | | JOD | Jordan Dinars | 1.1104324265 | 0.9005500705 |
77 | | KES | Kenya Shillings | 97.4173440461 | 0.0102651125 |
78 | | KES | Kenya Shillings | 302.9679399834 | 0.0033006793 |
79 | | KWD | Kuwait Dinars | 0.4162163855 | 2.4025964252 |
80 | | KWD | Kuwait Dinars | 1.5812060486 | 0.6324286458 |
81 | | LBP | Lebanon Pounds | 2366.5210105092 | 0.0004225612 |
82 | | MYR | Malaysia Ringgits | 4.9326536046 | 0.2027306355 |
83 | | MUR | Mauritius Rupees | 40.2120628358 | 0.0248681597 |
84 | | MXN | Mexico Pesos | 23.6918977588 | 0.0422085225 |
85 | | MXN | Mexico Pesos | 16.3844382841 | 0.0610335236 |
86 | | MAD | Morocco Dirhams | 11.4802658348 | 0.0871059969 |
87 | | NZD | New Zealand Dollars | 2.0023023070 | 0.4994250851 |
88 | | NOK | Norway Kroner | 20.2058368964 | 0.0494906499 |
89 | | NOK | Norway Kroner | 8.0245579414 | 0.1246174565 |
90 | | OMR | Oman Rials | 0.6029068584 | 1.6586309910 |
91 | | OMR | Oman Rials | 1.3655840342 | 0.7322874133 |
92 | | PKR | Pakistan Rupees | 100.6906921578 | 0.0099314046 |
93 | | XPD | Palladium Ounces | 0.0035474411 | 281.8933350005 |
94 | | PEN | Peru Nuevos Soles | 4.3437641936 | 0.2302150751 |
95 | | PHP | Philippines Pesos | 65.4982852167 | 0.0152675753 |
96 | | XPT | Platinum Ounces | 0.0008003042 | 1249.5249300061 |
97 | | PLN | Poland Zlotych | 3.4392864414 | 0.2907579863 |
98 | | QAR | Qatar Riyals | 5.7009306396 | 0.1754099573 |
99 | | QAR | Qatar Riyals | 3.9165393494 | 0.2553274487 |
100 | | RON | Romania New Lei | 3.6446929474 | 0.2743715354 |
101 | | RUB | Russia Rubles | 68.6687152500 | 0.0145626723 |
102 | | RUB | Russia Rubles | 36.9982301994 | 0.0270283199 |
103 | | SAR | Saudi Arabia Riyals | 5.8744853639 | 0.1702276775 |
104 | | XAG | Silver Ounces | 0.3595153564 | 2.7815223528 |
105 | | XAG | Silver Ounces | 0.0931145704 | 10.7394578043 |
106 | | SGD | Singapore Dollars | 2.1326895644 | 0.4688914958 |
107 | | SKK | Slovakia Koruny | 32.3998809692 | 0.0308643109 |
108 | | SKK | Slovakia Koruny | 32.1730818024 | 0.0310818841 |
109 | | ZAR | South Africa Rand | 11.9782611884 | 0.0834845713 |
110 | | KRW | South Korea Won | 1557.0878165672 | 0.0006422245 |
111 | | KRW | South Korea Won | 736.5025372363 | 0.0013577686 |
112 | | LKR | Sri Lanka Rupees | 168.6792276648 | 0.0059284123 |
113 | | SDG | Sudan Pounds | 3.1008238187 | 0.3224949428 |
114 | | SDG | Sudan Pounds | 3.1641059374 | 0.3160450439 |
115 | | SEK | Sweden Kronor | 9.3744616204 | 0.1066727926 |
116 | | CHF | Switzerland Francs | 5.6787713981 | 0.1760944278 |
117 | | CHF | Switzerland Francs | 1.6229698194 | 0.6161544029 |
118 | | TWD | Taiwan New Dollars | 47.5136650535 | 0.0210465768 |
119 | | THB | Thailand Baht | 49.4073971882 | 0.0202398842 |
120 | | TTD | Trinidad and Tobago Dollars | 9.8043822067 | 0.1019952077 |
121 | | TND | Tunisia Dinars | 1.2056580369 | 0.8294225803 |
122 | | TND | Tunisia Dinars | 1.8239909787 | 0.5482483256 |
123 | | TRY | Turkey New Lira | 2.0106814515 | 0.4973438230 |
124 | | AED | United Arab Emirates Dirhams | 5.7518520259 | 0.1738570456 |
125 | | GBP | United Kingdom Pounds | 0.7898087676 | 1.2661292721 |
126 | | USD | United States Dollars | 1.5661952419 | 0.6384900000 |
127 | | VEF | Venezuela Bolivares Fuertes | 14.3805772996 | 0.0695382375 |
128 | | VEF | Venezuela Bolivares Fuertes | 3.3630910429 | 0.2973455037 |
129 | | VND | Vietnam Dong | 25228.2729023791 | 0.0000396381 |
130 | | ZMK | Zambia Kwacha | 5411.2045607605 | 0.0001848017 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
157 |
158 |
159 |
160 | Table 2
161 |
162 | - sorting: rows: 1: alphanumeric, 2: custom (by last character), 3: number, 4: date, 5: nothing
163 | - filtering: custom: by substring, case-agnostic
164 | - Fade-in effect
165 | - Toolbar shows up when hovering over the table
166 |
167 |
168 |
169 |
170 |
171 | | apple |
172 | Strawberry |
173 | 45 |
174 | 2001-03-13 |
175 | Item 0 |
176 |
177 |
178 | | Banana |
179 | orange |
180 | 7698 |
181 | 1789-07-14 |
182 | Item 1 |
183 |
184 |
185 | | orange |
186 | Banana |
187 | 4546 |
188 | 1949-07-04 |
189 | Item 2 |
190 |
191 |
192 | | Strawberry |
193 | apple |
194 | 987 |
195 | 1975-08-19 |
196 | Item 3 |
197 |
198 |
199 | | Pear |
200 | blueberry |
201 | 98743 |
202 | 2001-01-01 |
203 | Item 4 |
204 |
205 |
206 | | blueberry |
207 | Pear |
208 | 4 |
209 | 2001-04-18 |
210 | Item 5 |
211 |
212 |
213 |
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 |
--------------------------------------------------------------------------------