├── img └── demonstration.png ├── RECOMMENDATIONS.md ├── bower.json ├── package.json ├── LICENSE ├── docs ├── narrow-jumbotron.css ├── dist │ └── js │ │ └── freeze-table.js └── index.html ├── README.md ├── dist └── js │ ├── freeze-table.min.js │ └── freeze-table.js └── src └── js └── freeze-table.js /img/demonstration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yidas/jquery-freeze-table/HEAD/img/demonstration.png -------------------------------------------------------------------------------- /RECOMMENDATIONS.md: -------------------------------------------------------------------------------- 1 | RECOMMENDATIONS 2 | =============== 3 | 4 | ### Artsiom Chorny 5 | 6 | Артём Чёрный \<1203994@gmail.com\> *Dec 14, 2018* 7 | 8 | > Hi Nick, 9 | > 10 | > I faced a need to apply freezing for header and column of table at the same time during development. So, I've found your library (jquery-freeze-table) after few days of searching. It's completely that I wanted to get. 11 | > 12 | > Therefore I'd like to Thank you and show respect. Because I've finally got happiness. It's due to your merit and great work. You rock :) 13 | > 14 | > **Yours respectfully,** 15 | > **Artsiom Chorny** 16 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-freeze-table", 3 | "description": "RWD Table with freezing head and columns for jQuery", 4 | "version": "1.1.0", 5 | "keywords": [ 6 | "RWD", 7 | "responsive", 8 | "tables", 9 | "freeze", 10 | "fixed", 11 | "row", 12 | "column", 13 | "head", 14 | "scorll bar" 15 | ], 16 | "homepage": "https://github.com/yidas/jquery-freeze-table", 17 | "authors": [ 18 | "Nick Tsai " 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "git://github.com/yidas/jquery-freeze-table.git" 23 | }, 24 | "license": "MIT", 25 | "main": [ 26 | "dist/js/freeze-table.js" 27 | ], 28 | "ignore": [ 29 | ".*", 30 | "docs" 31 | ], 32 | "dependencies": { 33 | "jquery": ">=1.10.1" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-freeze-table", 3 | "description": "RWD Table with freezing head and columns for jQuery", 4 | "version": "1.3.0", 5 | "keywords": [ 6 | "RWD", 7 | "responsive", 8 | "tables", 9 | "freeze", 10 | "fixed", 11 | "row", 12 | "column", 13 | "head", 14 | "scorll bar" 15 | ], 16 | "homepage": "https://github.com/yidas/jquery-freeze-table", 17 | "authors": [ 18 | "Nick Tsai " 19 | ], 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/yidas/jquery-freeze-table.git" 23 | }, 24 | "bugs": { 25 | "url": "https://github.com/yidas/jquery-freeze-table/issues" 26 | }, 27 | "license": { 28 | "type": "MIT", 29 | "url": "https://github.com/yidas/js-freeze-table/blob/master/LICENSE" 30 | }, 31 | "main": "dist/js/freeze-table.js" 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Nick Tsai 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/narrow-jumbotron.css: -------------------------------------------------------------------------------- 1 | /* Space out content a bit */ 2 | body { 3 | padding-top: 1.5rem; 4 | padding-bottom: 1.5rem; 5 | } 6 | 7 | /* Everything but the jumbotron gets side spacing for mobile first views */ 8 | .header, 9 | .marketing, 10 | .footer { 11 | padding-right: 1rem; 12 | padding-left: 1rem; 13 | } 14 | 15 | /* Custom page header */ 16 | .header { 17 | padding-bottom: 1rem; 18 | border-bottom: .05rem solid #e5e5e5; 19 | } 20 | /* Make the masthead heading the same height as the navigation */ 21 | .header h3 { 22 | margin-top: 0; 23 | margin-bottom: 0; 24 | line-height: 3rem; 25 | } 26 | 27 | /* Custom page footer */ 28 | .footer { 29 | padding-top: 1.5rem; 30 | color: #777; 31 | border-top: .05rem solid #e5e5e5; 32 | } 33 | 34 | /* Customize container */ 35 | @media (min-width: 48em) { 36 | .container { 37 | max-width: 46rem; 38 | } 39 | } 40 | .container-narrow > hr { 41 | margin: 2rem 0; 42 | } 43 | 44 | /* Main marketing message and sign up button */ 45 | .jumbotron { 46 | text-align: center; 47 | border-bottom: .05rem solid #e5e5e5; 48 | } 49 | .jumbotron .btn { 50 | padding: .75rem 1.5rem; 51 | font-size: 1.5rem; 52 | } 53 | 54 | /* Supporting marketing content */ 55 | .marketing { 56 | margin: 3rem 0; 57 | } 58 | .marketing p + h4 { 59 | margin-top: 1.5rem; 60 | } 61 | 62 | /* Responsive: Portrait tablets and up */ 63 | @media screen and (min-width: 48em) { 64 | /* Remove the padding we set earlier */ 65 | .header, 66 | .marketing, 67 | .footer { 68 | padding-right: 0; 69 | padding-left: 0; 70 | } 71 | /* Space out the masthead */ 72 | .header { 73 | margin-bottom: 2rem; 74 | } 75 | /* Remove the bottom border on the jumbotron for visual effect */ 76 | .jumbotron { 77 | border-bottom: 0; 78 | } 79 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

RWD Freeze Table

6 |
7 |

8 | 9 | [![npm version](https://img.shields.io/npm/v/jquery-freeze-table.svg)](https://www.npmjs.com/package/jquery-freeze-table) 10 | [![License](https://img.shields.io/github/license/yidas/jquery-freeze-table.svg)](https://github.com/yidas/jquery-freeze-table/blob/master/LICENSE) 11 | 12 | RWD Table with freezing head and columns for jQuery 13 | 14 | FEATURES 15 | -------- 16 | 17 | - *Freeze the **head rows and columns** for large table with RWD* 18 | 19 | - ***Optional features** such as Freeze Scroll Bar* 20 | 21 | - ***Namespace support** for multiple tables* 22 | 23 | --- 24 | 25 | OUTLINE 26 | ------- 27 | 28 | - [Demonstration](#demonstration) 29 | - [Requirements](#requirements) 30 | - [Installation](#installation) 31 | - [Bower Installation](#bower-installation) 32 | - [Assets include](#assets-include) 33 | - [Initialize via JavaScript](#initialize-via-javascript) 34 | - [Options](#options) 35 | - [Implementation](#implementation) 36 | - [Resize](#resize) 37 | - [Update for Dynamic Content](#update-for-dynamic-content) 38 | - [Namespace](#namespace) 39 | - [Table Opacity](#table-opacity) 40 | - [API Usage](#api-usage) 41 | 42 | --- 43 | 44 | DEMONSTRATION 45 | ------------- 46 | 47 | [https://yidas.github.io/jquery-freeze-table/](https://yidas.github.io/jquery-freeze-table/) 48 | 49 | 50 | 51 | --- 52 | 53 | REQUIREMENTS 54 | ------------ 55 | This library requires the following: 56 | 57 | - jQuery 1.11.0+ | 2.0+ | 3.0+ 58 | 59 | --- 60 | 61 | INSTALLATION 62 | ------------ 63 | 64 | ### Bower Installation 65 | 66 | ``` 67 | bower install jquery-freeze-table 68 | ``` 69 | 70 | > You could also download by [NPM](https://www.npmjs.com/package/jquery-freeze-table) or directly copy [`dist`](https://github.com/yidas/jquery-freeze-table/tree/master/dist) assets. 71 | 72 | ### Assets include 73 | 74 | Add JavaScript file either to the ``, or to the bottom of `` 75 | 76 | ```html 77 | 78 | ``` 79 | 80 | ### Markup 81 | 82 | Add the classes `.table` to the tables as usual when using Bootstrap, then wrap them with a identity such as `.freeze-table` 83 | 84 | ```html 85 |
86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
...
...
94 |
95 | ``` 96 | 97 | ### Initialize via JavaScript 98 | 99 | You can initialize Freeze Table by jQuery extension call: 100 | 101 | ```html 102 | 107 | ``` 108 | 109 | Or initialize an element by newing object from Freeze Table class: 110 | 111 | ```html 112 | 117 | ``` 118 | 119 | > The parameter `{}` is [options](#options) configuration 120 | 121 | 122 | 123 | ### Options 124 | 125 | Options could be passed via JavaScript with object. 126 | 127 | |Name |Type |Default |Description| 128 | |:-- |:-- |:-- |:-- | 129 | |freezeHead |boolean |true |Enable to freeze ``| 130 | |freezeColumn |boolean |true |Enable to freeze column(s)| 131 | |freezeColumnHead|boolean |true |Enable to freeze column(s) head (Entire column)| 132 | |scrollBar |boolean |false |Enable fixed scrollBar for X axis| 133 | |fixedNavbar |string\|jQuery\|Element |'.navbar-fixed-top'|Fixed navbar deviation consideration. **Example**: `'#navbar'`| 134 | |scrollable |boolean |false |Enable Scrollable mode for inner scroll Y axis| 135 | |fastMode |boolean |false |Enable Fast mode for better performance but less accuracy| 136 | |namespace |string |'freeze-table' |Table namespace for unbind| 137 | |container |string\|jQuery\|Element |false|Specify a document role element that contains the table. Default container is `window`. This option is particularly useful in that it allows you to position the table in the flow of the document near the triggering element - which will make the freeze table support in containers such as Bootstrap Modal. **Example**: `'#myModal'`| 138 | |columnNum |integer |1 |The number of column(s) for freeze| 139 | |columnKeep |boolean |false |Freeze column(s) will always be displayed to support interactive table| 140 | |columnBorderWidth|interger|1 |The addon border width for freeze column(s)| 141 | |columnWrapStyles |object |null |Customized CSS styles for freeze column(s) wrap. `{'style': 'value'}`| 142 | |headWrapStyles |object |null |Customized CSS styles for freeze head(s) wrap. `{'style': 'value'}`| 143 | |columnHeadWrapStyles|object|null |Customized CSS styles for freeze column-head wrap. `{'style': 'value'}`| 144 | |callback |function|null |Plugin after initialization callback function| 145 | |shadow |boolean |false |Enable default `box-shadow` UI| 146 | |backgroundColor |string\|boolean |'white' |Default table background color for Boostrap transparent UI. `white`, `#FFFFFF`, `rgb(255,255,255,1)`, or `false` to skip.| 147 | 148 | --- 149 | 150 | IMPLEMENTATION 151 | -------------- 152 | 153 | ### Resize 154 | 155 | There is an resize method which you can call when the page container has changed but not triggering window resize. The method will resize Freeze Table to ensure the size fits. 156 | 157 | ```javascript 158 | $('.freeze-table').freezeTable('resize'); 159 | ``` 160 | 161 | Or using API usage to update: 162 | 163 | ```javascript 164 | var freezeTable = new FreezeTable('.freeze-table', {'namespace': 'first-table'}); 165 | // Resize Freeze Table while the page container is distorted 166 | $('.sider-bar-switch').click(function () { 167 | freezeTable.resize(); 168 | }); 169 | ``` 170 | 171 | > Trigger `$(window).resize()` will also work for every Freeze Table. 172 | 173 | ### Update for Dynamic Content 174 | 175 | There is an update method which you can call when the table or it's contents has changed. The method will reinitialze Freeze Table to ensure that everything is alright with the same options. 176 | 177 | ```javascript 178 | $('.freeze-table').freezeTable('update'); 179 | ``` 180 | 181 | Or using API usage to update: 182 | 183 | ```javascript 184 | var freezeTable = new FreezeTable('.freeze-table', {'namespace': 'first-table'}); 185 | // Update Freeze Table while the original table is distorted 186 | $('.freeze-table > table .btn-expand').click(function () { 187 | freezeTable.update(); 188 | }); 189 | ``` 190 | 191 | ### Namespace 192 | 193 | To destroy or update Freeze Tables, it's recommended to define namespaces to each Freeze Table so that they could able to destroy itself. 194 | 195 | Namespace has default value which Freeze Tables with same namespace would affect each other. 196 | 197 | ```javascript 198 | $("#table-first").freezeTable({ 199 | 'namespace': 'table-first', 200 | }); 201 | ``` 202 | 203 | ### Table Opacity 204 | 205 | Bootstrap sets table's `background-color` as `transparent` by default, so that you may need to define `backgroundColor` option for your own page: 206 | 207 | ```javascript 208 | $(".table-black").freezeTable({ 209 | 'backgroundColor': 'rgb(0,0,0,1)', 210 | }); 211 | ``` 212 | 213 | --- 214 | 215 | API USAGE 216 | --------- 217 | 218 | ### resize() 219 | 220 | Resize trigger for current same namespace 221 | 222 | *See [Resize](#resize)* 223 | 224 | ### update() 225 | 226 | Update for Dynamic Content 227 | 228 | *See [Update for Dynamic Content](#update-for-dynamic-content)* 229 | 230 | ### destroy() 231 | 232 | Destroy Freeze Table by same namespace 233 | 234 | ### unbind() 235 | 236 | Unbind all events by same namespace 237 | 238 | --- 239 | 240 | Finally, I hope that you guys will like this library and enjoy it, and I want to thanks for all your [RECOMMENDATIONS](https://github.com/yidas/jquery-freeze-table/blob/master/RECOMMENDATIONS.md). 241 | 242 | Other kit reference: 243 | 244 | - [jquery-reflow-table](https://github.com/yidas/jquery-reflow-table) - RWD reflow table switch for mobile UI/UX by collapsing columns 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /dist/js/freeze-table.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * RWD Table with freezing head and columns for jQuery 3 | * 4 | * @author Nick Tsai 5 | * @version 1.3.0 6 | * @see https://github.com/yidas/jquery-freeze-table 7 | */ 8 | !function(i,e){"use strict";var t=function(t,s){return this.$tableWrapper=i(t).first(),this.options=s||{},this.namespace=this.options.namespace||"freeze-table",this.callback,this.scrollBarHeight,this.shadow,this.fastMode,this.backgroundColor,this.scrollable,this.$table=this.$tableWrapper.children("table"),this.$container=void 0!==this.options.container&&this.options.container&&i(this.options.container).length?i(this.options.container):i(e),this.$headTableWrap,this.$columnTableWrap,this.$columnHeadTableWrap,this.$scrollBarWrap,this.fixedNavbarHeight,this.isWindowScrollX=!1,this.headWrapClass="clone-head-table-wrap",this.columnWrapClass="clone-column-table-wrap",this.columnHeadWrapClass="clone-column-head-table-wrap",this.scrollBarWrapClass="clone-scroll-bar-wrap",this.init(),this};t.prototype.init=function(){if(!this.$table.length)throw"The element must contain a table dom";if("update"===this.options)this.destroy(),this.options=this.$tableWrapper.data("freeze-table-data");else{if("resize"===this.options)return this.options=this.$tableWrapper.data("freeze-table-data"),this.namespace=this.options.namespace||this.namespace,void this.resize();this.$tableWrapper.data("freeze-table-data",this.options)}var t=this.options,s=void 0===t.freezeHead||t.freezeHead,a=void 0===t.freezeColumn||t.freezeColumn,l=void 0===t.freezeColumnHead||t.freezeColumnHead,o=void 0!==t.scrollBar&&t.scrollBar,r=t.fixedNavbar||".navbar-fixed-top",n=t.callback||null;this.namespace=this.options.namespace||this.namespace,this.scrollBarHeight=i.isNumeric(t.scrollBarHeight)?t.scrollBarHeight:e.innerWidth-document.documentElement.clientWidth,this.shadow=void 0!==t.shadow&&t.shadow,this.fastMode=void 0!==t.fastMode&&t.fastMode,this.backgroundColor=void 0!==t.backgroundColor?t.backgroundColor:"white",this.scrollable=void 0!==t.scrollable&&t.scrollable,this.fixedNavbarHeight=r&&i(r).outerHeight()||0,this.isInit()&&this.destroy(),this.scrollable||this.$tableWrapper.css("height","100%").css("min-height","100%").css("max-height","100%"),s&&this.buildHeadTable(),a&&(this.buildColumnTable(),this.$tableWrapper.css("overflow-x","scroll")),l&&s&&a&&this.buildColumnHeadTable(),o&&this.buildScrollBar();var h=function(){this.$container.scrollLeft()>0?(this.isWindowScrollX=!0,this.$headTableWrap&&this.$headTableWrap.css("visibility","hidden"),this.$columnTableWrap&&this.$columnTableWrap.css("visibility","hidden"),this.$columnHeadTableWrap&&this.$columnHeadTableWrap.css("visibility","hidden"),this.$scrollBarWrap&&this.$scrollBarWrap.css("visibility","hidden")):this.isWindowScrollX=!1}.bind(this);this.$container.on("scroll."+this.namespace,function(){h()}),this.resize(),"function"==typeof n&&n()},t.prototype.buildHeadTable=function(){var t=this,s=this.clone(this.$table);if(this.fastMode)s=this.simplifyHead(s);var a=this.options.headWrapStyles||null;if(this.$headTableWrap=i('
').append(s).css("position","fixed").css("overflow","hidden").css("visibility","hidden").css("top",0+this.fixedNavbarHeight).css("z-index",2),this.shadow&&this.$headTableWrap.css("box-shadow","0px 6px 10px -5px rgba(159, 159, 160, 0.8)"),a&&"object"==typeof a&&i.each(a,function(i,e){t.$headTableWrap.css(i,e)}),this.$tableWrapper.append(this.$headTableWrap),this.$tableWrapper.on("scroll."+this.namespace,function(){t.$headTableWrap.scrollLeft(i(this).scrollLeft())}),this.scrollable){var l=function(i,e){var t=e.$tableWrapper.offset().top;e.$tableWrapper.scrollTop()>0&&t>e.fixedNavbarHeight?(e.$headTableWrap.offset({top:t}),e.$headTableWrap.css("visibility","visible")):e.$headTableWrap.css("visibility","hidden")};this.$tableWrapper.on("scroll."+this.namespace,function(){l(0,t)}),this.$container.on("scroll."+this.namespace,function(){l(0,t)})}else i.isWindow(t.$container.get(0))?this.$container.on("scroll."+this.namespace,function(){var i=t.$container.scrollTop()+t.fixedNavbarHeight,e=t.$table.offset().top-1;e-1<=i&&e+t.$table.outerHeight()-1>=i?t.$headTableWrap.css("visibility","visible"):t.$headTableWrap.css("visibility","hidden")}):this.$container.on("scroll."+this.namespace,function(){var s=i(e).scrollTop(),a=t.$table.offset().top-1;a<=s&&a+t.$table.outerHeight()-1>=s?(t.$headTableWrap.offset({top:s}),t.$headTableWrap.css("visibility","visible")):t.$headTableWrap.css("visibility","hidden")});this.$container.on("resize."+this.namespace,function(){var i=t.scrollable?t.$tableWrapper.width()-t.scrollBarHeight:t.$tableWrapper.width();i=i>0?i:t.$tableWrapper.width(),t.$headTableWrap.css("width",i),t.$headTableWrap.css("height",t.$table.find("thead").outerHeight())})},t.prototype.buildColumnTable=function(){var e=this,t=this.options.columnWrapStyles||null,s=this.options.columnNum||1,a=void 0!==this.options.columnKeep&&this.options.columnKeep,l=this.shadow?0:1,o=void 0!==this.options.columnBorderWidth?this.options.columnBorderWidth:l,r=this.clone(this.$table);if(this.$columnTableWrap=i('
').append(r).css("position","fixed").css("overflow","hidden").css("visibility","hidden").css("z-index",1),this.shadow&&this.$columnTableWrap.css("box-shadow","6px 0px 10px -5px rgba(159, 159, 160, 0.8)"),t&&"object"==typeof t&&i.each(t,function(i,t){e.$columnTableWrap.css(i,t)}),this.scrollable){var n=this.$tableWrapper.height()-this.scrollBarHeight;n=n>0?n:this.$tableWrapper.height(),this.$columnTableWrap.height(n)}this.$tableWrapper.append(this.$columnTableWrap);var h=function(){e.$columnTableWrap.offset({top:e.$tableWrapper.offset().top})};a?this.$columnTableWrap.css("visibility","visible"):e.scrollable?this.$tableWrapper.on("scroll."+this.namespace,function(){i(this).scrollLeft()>0?(e.$columnTableWrap.scrollTop(e.$tableWrapper.scrollTop()),e.$columnTableWrap.css("visibility","visible")):e.$columnTableWrap.css("visibility","hidden")}):this.$tableWrapper.on("scroll."+this.namespace,function(){e.isWindowScrollX||(i(this).scrollLeft()>0?e.$columnTableWrap.css("visibility","visible"):e.$columnTableWrap.css("visibility","hidden"))}),this.$container.on("resize."+this.namespace,function(){r.width(e.$table.width());for(var i=0+o,t=1;t<=s;t++){var a=e.$table.find("th:nth-child("+t+")").outerWidth();i+=a>0?a:e.$table.find("td:nth-child("+t+")").outerWidth()}e.$columnTableWrap.width(i),h()}),this.$container.on("scroll."+this.namespace,function(){h()})},t.prototype.buildColumnHeadTable=function(){var t=this;this.$columnHeadTableWrap=this.clone(this.$headTableWrap),this.fastMode&&(this.$columnHeadTableWrap=this.simplifyHead(this.$columnHeadTableWrap));var s=this.options.columnHeadWrapStyles||null;if(this.$columnHeadTableWrap.removeClass(this.namespace).addClass(this.columnHeadWrapClass).css("z-index",3),this.shadow&&this.$columnHeadTableWrap.css("box-shadow","none"),s&&"object"==typeof s&&i.each(s,function(i,e){this.$columnHeadTableWrap.css(i,e)}),this.$tableWrapper.append(this.$columnHeadTableWrap),this.scrollable){var a=function(){var i=t.$tableWrapper.offset().top;t.$tableWrapper.scrollTop()>0&&i>t.fixedNavbarHeight?(t.$columnHeadTableWrap.offset({top:i}),t.$columnHeadTableWrap.css("visibility","visible")):t.$columnHeadTableWrap.css("visibility","hidden")};i(this.$tableWrapper).on("scroll."+this.namespace,function(){a()})}else if(i.isWindow(this.$container.get(0)))a=function(){var i=t.$container.scrollTop()+t.fixedNavbarHeight,e=t.$table.offset().top-1;e-1<=i&&e+t.$table.outerHeight()-1>=i&&t.$tableWrapper.scrollLeft()>0?t.$columnHeadTableWrap.css("visibility","visible"):t.$columnHeadTableWrap.css("visibility","hidden")};else a=function(){var s=i(e).scrollTop(),a=t.$table.offset().top-1;a<=s&&a+t.$table.outerHeight()-1>=s&&t.$tableWrapper.scrollLeft()>0?(t.$columnHeadTableWrap.offset({top:s}),t.$columnHeadTableWrap.css("visibility","visible")):t.$columnHeadTableWrap.css("visibility","hidden")};this.$container.on("scroll."+this.namespace,function(){a()}),this.$tableWrapper.on("scroll."+this.namespace,function(){t.isWindowScrollX||a()}),this.$container.on("resize."+this.namespace,function(){t.$columnHeadTableWrap.find("> table").css("width",t.$table.width()),t.$columnHeadTableWrap.css("width",t.$columnTableWrap.width()),t.$columnHeadTableWrap.css("height",t.$table.find("thead").outerHeight())})},t.prototype.buildScrollBar=function(){var e=this,t=this.$table.find("thead").outerHeight(),s=i('
').css("width",this.$table.width()).css("height",1);this.$scrollBarWrap=i('
').css("position","fixed").css("overflow-x","scroll").css("visibility","hidden").css("bottom",0).css("z-index",2).css("width",this.$tableWrapper.width()).css("height",this.scrollBarHeight),this.$scrollBarWrap.append(s),this.$tableWrapper.append(this.$scrollBarWrap),this.$scrollBarWrap.on("scroll."+this.namespace,function(){e.$tableWrapper.scrollLeft(i(this).scrollLeft())}),this.$tableWrapper.on("scroll."+this.namespace,function(){e.$scrollBarWrap.scrollLeft(i(this).scrollLeft())}),this.$container.on("scroll."+this.namespace,function(){var i=e.$container.scrollTop()+e.$container.height()-t+e.fixedNavbarHeight;e.$table.offset().top-1<=i&&e.$table.offset().top+e.$table.outerHeight()-1>=i?e.$scrollBarWrap.css("visibility","visible"):e.$scrollBarWrap.css("visibility","hidden")}),this.$container.on("resize."+this.namespace,function(){s.css("width",e.$table.width()),e.$scrollBarWrap.css("width",e.$tableWrapper.width())})},t.prototype.clone=function(e){var t=i(e).clone().removeAttr("id");return this.backgroundColor&&t.css("background-color",this.backgroundColor),t},t.prototype.simplifyHead=function(e){var t=this,s=i(e);return s.find("> tr, > tbody > tr, tfoot > tr").not(":first").remove(),i.each(s.find("> thead > tr:nth-child(1) >"),function(e,s){var a=t.$table.find("> thead > tr:nth-child(1) > :nth-child("+parseInt(e+1)+")").outerWidth();i(this).css("width",a)}),s},t.prototype.isInit=function(){return!!this.$tableWrapper.find("."+this.headWrapClass).length||(!!this.$tableWrapper.find("."+this.columnWrapClass).length||(!!this.$tableWrapper.find("."+this.columnHeadWrapClass).length||!!this.$tableWrapper.find("."+this.scrollBarWrapClass).length))},t.prototype.unbind=function(){this.$container.off("resize."+this.namespace),this.$container.off("scroll."+this.namespace),this.$tableWrapper.off("scroll."+this.namespace)},t.prototype.destroy=function(){this.unbind(),this.$tableWrapper.find("."+this.headWrapClass).remove(),this.$tableWrapper.find("."+this.columnWrapClass).remove(),this.$tableWrapper.find("."+this.columnHeadWrapClass).remove(),this.$tableWrapper.find("."+this.scrollBarWrapClass).remove()},t.prototype.resize=function(){return this.$container.trigger("resize."+this.namespace),this.$container.trigger("scroll."+this.namespace),this.$tableWrapper.trigger("scroll."+this.namespace),!0},t.prototype.update=function(){return this.options="update",this.init(),this},e.FreezeTable=t,i.fn.freezeTable=function(i){if(1===this.length)return new t(this,i);if(this.length>1){var e=[];return this.each(function(){e.push(new t(this,i))}),e}return!1}}(jQuery,window); -------------------------------------------------------------------------------- /dist/js/freeze-table.js: -------------------------------------------------------------------------------- 1 | /** 2 | * RWD Table with freezing head and columns for jQuery 3 | * 4 | * @author Nick Tsai 5 | * @version 1.3.0 6 | * @see https://github.com/yidas/jquery-freeze-table 7 | */ 8 | (function ($, window) { 9 | 10 | 'use strict'; 11 | 12 | /** 13 | * Main object 14 | * 15 | * @param {element} element 16 | * @param {object} options 17 | */ 18 | var FreezeTable = function(element, options) { 19 | 20 | // Target element initialization 21 | this.$tableWrapper = $(element).first(); 22 | 23 | // Options 24 | this.options = options || {}; 25 | this.namespace = this.options.namespace || 'freeze-table'; 26 | this.callback; 27 | this.scrollBarHeight; 28 | this.shadow; 29 | this.fastMode; 30 | this.backgroundColor; 31 | this.scrollable; 32 | 33 | // Caches 34 | this.$table = this.$tableWrapper.children("table"); 35 | this.$container = ((typeof this.options.container !== 'undefined') && this.options.container && $(this.options.container).length) ? $(this.options.container) : $(window); 36 | this.$headTableWrap; 37 | this.$columnTableWrap; 38 | this.$columnHeadTableWrap; 39 | this.$scrollBarWrap; 40 | this.fixedNavbarHeight; 41 | this.isWindowScrollX = false; 42 | 43 | // Static class names for clone wraps 44 | this.headWrapClass = 'clone-head-table-wrap'; 45 | this.columnWrapClass = 'clone-column-table-wrap'; 46 | this.columnHeadWrapClass = 'clone-column-head-table-wrap'; 47 | this.scrollBarWrapClass = 'clone-scroll-bar-wrap'; 48 | 49 | this.init(); 50 | 51 | return this; 52 | } 53 | 54 | /** 55 | * Initialization 56 | */ 57 | FreezeTable.prototype.init = function() { 58 | 59 | // Element check 60 | if (!this.$table.length) { 61 | throw "The element must contain a table dom"; 62 | } 63 | 64 | /** 65 | * Update Mode 66 | */ 67 | if (this.options==='update') { 68 | 69 | this.destroy(); 70 | this.options = this.$tableWrapper.data('freeze-table-data'); 71 | } 72 | else if (this.options==='resize') { 73 | 74 | this.options = this.$tableWrapper.data('freeze-table-data'); 75 | // Get selected FreezeTable's namespace 76 | this.namespace = this.options.namespace || this.namespace; 77 | this.resize(); 78 | // Skip init for better performance usage 79 | return; 80 | } 81 | else { 82 | // Save to DOM data 83 | this.$tableWrapper.data('freeze-table-data', this.options); 84 | } 85 | 86 | /** 87 | * Options Setting 88 | */ 89 | var options = this.options; 90 | var freezeHead = (typeof options.freezeHead !== 'undefined') ? options.freezeHead : true; 91 | var freezeColumn = (typeof options.freezeColumn !== 'undefined') ? options.freezeColumn : true; 92 | var freezeColumnHead = (typeof options.freezeColumnHead !== 'undefined') ? options.freezeColumnHead : true; 93 | var scrollBar = (typeof options.scrollBar !== 'undefined') ? options.scrollBar : false; 94 | var fixedNavbar = options.fixedNavbar || '.navbar-fixed-top'; 95 | var callback = options.callback || null; 96 | this.namespace = this.options.namespace || this.namespace; 97 | // Default to get window scroll bar height 98 | this.scrollBarHeight = ($.isNumeric(options.scrollBarHeight)) ? options.scrollBarHeight : (window.innerWidth - document.documentElement.clientWidth); 99 | this.shadow = (typeof options.shadow !== 'undefined') ? options.shadow : false; 100 | this.fastMode = (typeof options.fastMode !== 'undefined') ? options.fastMode : false; 101 | this.backgroundColor = (typeof options.backgroundColor !== 'undefined') ? options.backgroundColor : 'white'; 102 | this.scrollable = (typeof options.scrollable !== 'undefined') ? options.scrollable : false; 103 | 104 | // Get navbar height for keeping fixed navbar 105 | this.fixedNavbarHeight = (fixedNavbar) ? $(fixedNavbar).outerHeight() || 0 : 0; 106 | 107 | // Check existence 108 | if (this.isInit()) { 109 | this.destroy(); 110 | } 111 | 112 | // Release height of the table wrapper 113 | if (!this.scrollable) { 114 | this.$tableWrapper.css('height', '100%') 115 | .css('min-height', '100%') 116 | .css('max-height', '100%'); 117 | } 118 | 119 | /** 120 | * Building 121 | */ 122 | // Switch for freezeHead 123 | if (freezeHead) { 124 | this.buildHeadTable(); 125 | } 126 | // Switch for freezeColumn 127 | if (freezeColumn) { 128 | this.buildColumnTable(); 129 | // X scroll bar 130 | this.$tableWrapper.css('overflow-x', 'scroll'); 131 | } 132 | // Switch for freezeColumnHead 133 | if (freezeColumnHead && freezeHead && freezeColumn) { 134 | this.buildColumnHeadTable(); 135 | } 136 | // Switch for scrollBar 137 | if (scrollBar) { 138 | this.buildScrollBar(); 139 | } 140 | 141 | // Body scroll-x prevention 142 | var detectWindowScroll = (function (){ 143 | // If body scroll-x is opened, close library to prevent Invalid usage 144 | if (this.$container.scrollLeft() > 0) { 145 | // Mark 146 | this.isWindowScrollX = true; 147 | // Hide all components 148 | if (this.$headTableWrap) { 149 | this.$headTableWrap.css('visibility', 'hidden'); 150 | } 151 | if (this.$columnTableWrap) { 152 | this.$columnTableWrap.css('visibility', 'hidden'); 153 | } 154 | if (this.$columnHeadTableWrap) { 155 | this.$columnHeadTableWrap.css('visibility', 'hidden'); 156 | } 157 | if (this.$scrollBarWrap) { 158 | this.$scrollBarWrap.css('visibility', 'hidden'); 159 | } 160 | 161 | } else { 162 | // Unmark 163 | this.isWindowScrollX = false; 164 | } 165 | 166 | }).bind(this); 167 | // Listener of Body scroll-x prevention 168 | this.$container.on('scroll.'+this.namespace, function () { 169 | 170 | detectWindowScroll(); 171 | }); 172 | 173 | // Initialization 174 | this.resize(); 175 | 176 | // Callback 177 | if (typeof callback === 'function') { 178 | callback(); 179 | } 180 | } 181 | 182 | /** 183 | * Freeze thead table 184 | */ 185 | FreezeTable.prototype.buildHeadTable = function() { 186 | 187 | var that = this; 188 | 189 | // Clone the table as Fixed thead 190 | var $headTable = this.clone(this.$table); 191 | 192 | // Fast Mode 193 | if (this.fastMode) { 194 | var $headTable = this.simplifyHead($headTable); 195 | } 196 | 197 | var headWrapStyles = this.options.headWrapStyles || null; 198 | // Wrap the Fixed Column table 199 | this.$headTableWrap = $('
') 200 | .append($headTable) 201 | .css('position', 'fixed') 202 | .css('overflow', 'hidden') 203 | .css('visibility', 'hidden') 204 | .css('top', 0 + this.fixedNavbarHeight) 205 | .css('z-index', 2); 206 | // Shadow option 207 | if (this.shadow) { 208 | this.$headTableWrap.css('box-shadow', '0px 6px 10px -5px rgba(159, 159, 160, 0.8)'); 209 | } 210 | // Styles option 211 | if (headWrapStyles && typeof headWrapStyles === "object") { 212 | $.each(headWrapStyles, function(key, value) { 213 | that.$headTableWrap.css(key, value); 214 | }); 215 | } 216 | // Add into target table wrap 217 | this.$tableWrapper.append(this.$headTableWrap); 218 | 219 | /** 220 | * Listener - Table scroll for effecting Freeze Column 221 | */ 222 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 223 | 224 | // this.$headTableWrap.css('left', this.$table.offset().left); 225 | that.$headTableWrap.scrollLeft($(this).scrollLeft()); 226 | }); 227 | 228 | // Scrollable option 229 | if (this.scrollable) { 230 | 231 | var handler = function (window, that) { 232 | 233 | var top = that.$tableWrapper.offset().top; 234 | 235 | // Detect Current container's top is in the table scope 236 | if (that.$tableWrapper.scrollTop() > 0 && top > that.fixedNavbarHeight) { 237 | 238 | that.$headTableWrap.offset({top: top}); 239 | that.$headTableWrap.css('visibility', 'visible'); 240 | 241 | } else { 242 | 243 | that.$headTableWrap.css('visibility', 'hidden'); 244 | } 245 | } 246 | 247 | /** 248 | * Listener - Window scroll for effecting freeze head table 249 | */ 250 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 251 | 252 | handler(window, that); 253 | }); 254 | 255 | this.$container.on('scroll.'+this.namespace, function() { 256 | 257 | handler(window, that); 258 | }); 259 | 260 | } 261 | // Default with window container 262 | else if ($.isWindow(that.$container.get(0))) { 263 | 264 | /** 265 | * Listener - Window scroll for effecting freeze head table 266 | */ 267 | this.$container.on('scroll.'+this.namespace, function() { 268 | 269 | // Current container's top position 270 | var topPosition = that.$container.scrollTop() + that.fixedNavbarHeight; 271 | var tableTop = that.$table.offset().top - 1; 272 | 273 | // Detect Current container's top is in the table scope 274 | if (tableTop - 1 <= topPosition && (tableTop + that.$table.outerHeight() - 1) >= topPosition) { 275 | 276 | that.$headTableWrap.css('visibility', 'visible'); 277 | 278 | } else { 279 | 280 | that.$headTableWrap.css('visibility', 'hidden'); 281 | } 282 | }); 283 | } 284 | // Container setting 285 | else { 286 | 287 | /** 288 | * Listener - Window scroll for effecting freeze head table 289 | */ 290 | this.$container.on('scroll.'+this.namespace, function() { 291 | 292 | var windowTop = $(window).scrollTop(); 293 | var tableTop = that.$table.offset().top - 1; 294 | 295 | // Detect Current container's top is in the table scope 296 | if (tableTop <= windowTop && (tableTop + that.$table.outerHeight() - 1) >= windowTop) { 297 | 298 | that.$headTableWrap.offset({top: windowTop}); 299 | that.$headTableWrap.css('visibility', 'visible'); 300 | 301 | } else { 302 | 303 | that.$headTableWrap.css('visibility', 'hidden'); 304 | } 305 | }); 306 | } 307 | 308 | /** 309 | * Listener - Window resize for effecting freeze head table 310 | */ 311 | this.$container.on('resize.'+this.namespace, function() { 312 | 313 | // Scrollable check and prevention 314 | var headTableWrapWidth = (that.scrollable) ? that.$tableWrapper.width() - that.scrollBarHeight : that.$tableWrapper.width(); 315 | headTableWrapWidth = (headTableWrapWidth > 0) ? headTableWrapWidth : that.$tableWrapper.width(); 316 | that.$headTableWrap.css('width', headTableWrapWidth); 317 | that.$headTableWrap.css('height', that.$table.find("thead").outerHeight()); 318 | }); 319 | } 320 | 321 | /** 322 | * Freeze column table 323 | */ 324 | FreezeTable.prototype.buildColumnTable = function() { 325 | 326 | var that = this; 327 | 328 | /** 329 | * Setting 330 | */ 331 | var columnWrapStyles = this.options.columnWrapStyles || null; 332 | var columnNum = this.options.columnNum || 1; 333 | var columnKeep = (typeof this.options.columnKeep !== 'undefined') ? this.options.columnKeep : false; 334 | // Shadow option 335 | var defaultColumnBorderWidth = (this.shadow) ? 0 : 1; 336 | var columnBorderWidth = (typeof this.options.columnBorderWidth !== 'undefined') ? this.options.columnBorderWidth : defaultColumnBorderWidth; 337 | 338 | // Clone the table as Fixed Column table 339 | var $columnTable = this.clone(this.$table); 340 | 341 | // Wrap the Fixed Column table 342 | this.$columnTableWrap = $('
') 343 | .append($columnTable) 344 | .css('position', 'fixed') 345 | .css('overflow', 'hidden') 346 | .css('visibility', 'hidden') 347 | .css('z-index', 1); 348 | // Shadow option 349 | if (this.shadow) { 350 | this.$columnTableWrap.css('box-shadow', '6px 0px 10px -5px rgba(159, 159, 160, 0.8)'); 351 | } 352 | // Styles option 353 | if (columnWrapStyles && typeof columnWrapStyles === "object") { 354 | $.each(columnWrapStyles, function(key, value) { 355 | that.$columnTableWrap.css(key, value); 356 | }); 357 | } 358 | // Scrollable 359 | if (this.scrollable) { 360 | // Scrollable check and prevention 361 | var columnTableWrapHeight = this.$tableWrapper.height() - this.scrollBarHeight; 362 | columnTableWrapHeight = (columnTableWrapHeight > 0) ? columnTableWrapHeight : this.$tableWrapper.height(); 363 | this.$columnTableWrap.height(columnTableWrapHeight); 364 | } 365 | // Add into target table wrap 366 | this.$tableWrapper.append(this.$columnTableWrap); 367 | 368 | /** 369 | * localize the column wrap to current top 370 | */ 371 | var localizeWrap = function () { 372 | 373 | that.$columnTableWrap.offset({top: that.$tableWrapper.offset().top}); 374 | } 375 | 376 | // Column keep option 377 | if (columnKeep) { 378 | 379 | this.$columnTableWrap.css('visibility', 'visible'); 380 | 381 | } else { 382 | 383 | // Scrollable option 384 | if (that.scrollable) { 385 | 386 | /** 387 | * Listener - Table scroll for effecting Freeze Column 388 | */ 389 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 390 | 391 | 392 | // Detect for horizontal scroll 393 | if ($(this).scrollLeft() > 0) { 394 | 395 | // Scrollable localization 396 | that.$columnTableWrap.scrollTop(that.$tableWrapper.scrollTop()); 397 | that.$columnTableWrap.css('visibility', 'visible'); 398 | 399 | } else { 400 | 401 | that.$columnTableWrap.css('visibility', 'hidden'); 402 | } 403 | }); 404 | 405 | } else { 406 | 407 | /** 408 | * Listener - Table scroll for effecting Freeze Column 409 | */ 410 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 411 | 412 | // Disable while isWindowScrollX 413 | if (that.isWindowScrollX) 414 | return; 415 | 416 | // Detect for horizontal scroll 417 | if ($(this).scrollLeft() > 0) { 418 | 419 | that.$columnTableWrap.css('visibility', 'visible'); 420 | 421 | } else { 422 | 423 | that.$columnTableWrap.css('visibility', 'hidden'); 424 | } 425 | }); 426 | } 427 | } 428 | 429 | /** 430 | * Listener - Window resize for effecting tables 431 | */ 432 | this.$container.on('resize.'+this.namespace, function() { 433 | 434 | // Follows origin table's width 435 | $columnTable.width(that.$table.width()); 436 | 437 | /** 438 | * Dynamic column calculation 439 | */ 440 | // Get width by fixed column with number setting 441 | var width = 0 + columnBorderWidth; 442 | for (var i = 1; i <= columnNum; i++) { 443 | // th/td detection 444 | var th = that.$table.find('th:nth-child('+i+')').outerWidth(); 445 | var addWidth = (th > 0) ? th : that.$table.find('td:nth-child('+i+')').outerWidth(); 446 | width += addWidth; 447 | } 448 | that.$columnTableWrap.width(width); 449 | 450 | localizeWrap(); 451 | }); 452 | 453 | /** 454 | * Listener - Window scroll for effecting freeze column table 455 | */ 456 | this.$container.on('scroll.'+this.namespace, function() { 457 | 458 | localizeWrap(); 459 | }); 460 | } 461 | 462 | /** 463 | * Freeze column thead table 464 | */ 465 | FreezeTable.prototype.buildColumnHeadTable = function() { 466 | 467 | var that = this; 468 | 469 | // Clone head table wrap 470 | this.$columnHeadTableWrap = this.clone(this.$headTableWrap); 471 | 472 | // Fast Mode 473 | if (this.fastMode) { 474 | this.$columnHeadTableWrap = this.simplifyHead(this.$columnHeadTableWrap); 475 | } 476 | 477 | var columnHeadWrapStyles = this.options.columnHeadWrapStyles || null; 478 | 479 | this.$columnHeadTableWrap.removeClass(this.namespace) 480 | .addClass(this.columnHeadWrapClass) 481 | .css('z-index', 3); 482 | // Shadow option 483 | if (this.shadow) { 484 | this.$columnHeadTableWrap.css('box-shadow', 'none'); 485 | } 486 | // Styles option 487 | if (columnHeadWrapStyles && typeof columnHeadWrapStyles === "object") { 488 | $.each(columnHeadWrapStyles, function(key, value) { 489 | this.$columnHeadTableWrap.css(key, value); 490 | }); 491 | } 492 | 493 | // Add into target table wrap 494 | this.$tableWrapper.append(this.$columnHeadTableWrap); 495 | 496 | // Scrollable option 497 | if (this.scrollable) { 498 | 499 | var detect = function () { 500 | 501 | var top = that.$tableWrapper.offset().top; 502 | 503 | // Detect Current container's top is in the table scope 504 | if (that.$tableWrapper.scrollTop() > 0 && top > that.fixedNavbarHeight) { 505 | 506 | that.$columnHeadTableWrap.offset({top: top}); 507 | that.$columnHeadTableWrap.css('visibility', 'visible'); 508 | 509 | } else { 510 | 511 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 512 | } 513 | } 514 | 515 | /** 516 | * Listener - Window scroll for effecting freeze head table 517 | */ 518 | $(this.$tableWrapper).on('scroll.'+this.namespace, function() { 519 | 520 | detect(); 521 | }); 522 | 523 | } 524 | // Default with window container 525 | else if ($.isWindow(this.$container.get(0))) { 526 | 527 | var detect = function () { 528 | 529 | // Current container's top position 530 | var topPosition = that.$container.scrollTop() + that.fixedNavbarHeight; 531 | var tableTop = that.$table.offset().top - 1; 532 | 533 | // Detect Current container's top is in the table scope 534 | if (tableTop - 1 <= topPosition && (tableTop + that.$table.outerHeight() - 1) >= topPosition && that.$tableWrapper.scrollLeft() > 0) { 535 | 536 | that.$columnHeadTableWrap.css('visibility', 'visible'); 537 | 538 | } else { 539 | 540 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 541 | } 542 | } 543 | } 544 | // Container setting 545 | else { 546 | 547 | var detect = function () { 548 | 549 | var windowTop = $(window).scrollTop(); 550 | var tableTop = that.$table.offset().top - 1; 551 | 552 | // Detect Current container's top is in the table scope 553 | if (tableTop <= windowTop && (tableTop + that.$table.outerHeight() - 1) >= windowTop && that.$tableWrapper.scrollLeft() > 0) { 554 | 555 | that.$columnHeadTableWrap.offset({top: windowTop}); 556 | that.$columnHeadTableWrap.css('visibility', 'visible'); 557 | 558 | } else { 559 | 560 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 561 | } 562 | } 563 | } 564 | 565 | /** 566 | * Listener - Window scroll for effecting Freeze column-head table 567 | */ 568 | this.$container.on('scroll.'+this.namespace, function() { 569 | 570 | detect(); 571 | }); 572 | 573 | /** 574 | * Listener - Table scroll for effecting Freeze column-head table 575 | */ 576 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 577 | 578 | // Disable while isWindowScrollX 579 | if (that.isWindowScrollX) 580 | return; 581 | 582 | detect(); 583 | }); 584 | 585 | /** 586 | * Listener - Window resize for effecting freeze column-head table 587 | */ 588 | this.$container.on('resize.'+this.namespace, function() { 589 | 590 | // Table synchronism 591 | that.$columnHeadTableWrap.find("> table").css('width', that.$table.width()); 592 | that.$columnHeadTableWrap.css('width', that.$columnTableWrap.width()); 593 | that.$columnHeadTableWrap.css('height', that.$table.find("thead").outerHeight()); 594 | }); 595 | } 596 | 597 | /** 598 | * Freeze scroll bar 599 | */ 600 | FreezeTable.prototype.buildScrollBar = function() { 601 | 602 | var that = this; 603 | 604 | var theadHeight = this.$table.find("thead").outerHeight(); 605 | 606 | // Scroll wrap container 607 | var $scrollBarContainer = $('
') 608 | .css('width', this.$table.width()) 609 | .css('height', 1); 610 | 611 | // Wrap the Fixed Column table 612 | this.$scrollBarWrap = $('
') 613 | .css('position', 'fixed') 614 | .css('overflow-x', 'scroll') 615 | .css('visibility', 'hidden') 616 | .css('bottom', 0) 617 | .css('z-index', 2) 618 | .css('width', this.$tableWrapper.width()) 619 | .css('height', this.scrollBarHeight); 620 | 621 | // Add into target table wrap 622 | this.$scrollBarWrap.append($scrollBarContainer); 623 | this.$tableWrapper.append(this.$scrollBarWrap); 624 | 625 | /** 626 | * Listener - Freeze scroll bar effected Table 627 | */ 628 | this.$scrollBarWrap.on('scroll.'+this.namespace, function() { 629 | 630 | that.$tableWrapper.scrollLeft($(this).scrollLeft()); 631 | }); 632 | 633 | /** 634 | * Listener - Table scroll for effecting Freeze scroll bar 635 | */ 636 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 637 | 638 | // this.$headTableWrap.css('left', $table.offset().left); 639 | that.$scrollBarWrap.scrollLeft($(this).scrollLeft()); 640 | }); 641 | 642 | /** 643 | * Listener - Window scroll for effecting scroll bar 644 | */ 645 | this.$container.on('scroll.'+this.namespace, function() { 646 | 647 | // Current container's top position 648 | var bottomPosition = that.$container.scrollTop() + that.$container.height() - theadHeight + that.fixedNavbarHeight; 649 | 650 | // Detect Current container's top is in the table scope 651 | if (that.$table.offset().top - 1 <= bottomPosition && (that.$table.offset().top + that.$table.outerHeight() - 1) >= bottomPosition) { 652 | 653 | that.$scrollBarWrap.css('visibility', 'visible'); 654 | 655 | } else { 656 | 657 | that.$scrollBarWrap.css('visibility', 'hidden'); 658 | } 659 | }); 660 | 661 | /** 662 | * Listener - Window resize for effecting scroll bar 663 | */ 664 | this.$container.on('resize.'+this.namespace, function() { 665 | 666 | // Update width 667 | $scrollBarContainer.css('width', that.$table.width()) 668 | // Update Wrap 669 | that.$scrollBarWrap.css('width', that.$tableWrapper.width()); 670 | }); 671 | } 672 | 673 | /** 674 | * Clone element 675 | * 676 | * @param {element} element 677 | */ 678 | FreezeTable.prototype.clone = function (element) { 679 | 680 | var $clone = $(element).clone() 681 | .removeAttr('id') // Remove ID 682 | 683 | // Bootstrap background-color transparent problem 684 | if (this.backgroundColor) { 685 | $clone.css('background-color', this.backgroundColor); 686 | } 687 | 688 | return $clone; 689 | } 690 | 691 | /** 692 | * simplify cloned head table 693 | * 694 | * @param {element} table Table element 695 | */ 696 | FreezeTable.prototype.simplifyHead = function (table) { 697 | 698 | var that = this; 699 | 700 | var $headTable = $(table); 701 | // Remove non-display DOM but keeping first row for accuracy 702 | $headTable.find("> tr, > tbody > tr, tfoot > tr").not(':first').remove(); 703 | // Each th/td width synchronism 704 | $.each($headTable.find("> thead > tr:nth-child(1) >"), function (key, value) { 705 | 706 | var width = that.$table.find("> thead > tr:nth-child(1) > :nth-child("+parseInt(key+1)+")").outerWidth(); 707 | $(this).css('width', width); 708 | }); 709 | 710 | return $headTable; 711 | } 712 | 713 | /** 714 | * Detect is already initialized 715 | */ 716 | FreezeTable.prototype.isInit = function() { 717 | 718 | // Check existence DOM 719 | if (this.$tableWrapper.find("."+this.headWrapClass).length) 720 | return true; 721 | if (this.$tableWrapper.find("."+this.columnWrapClass).length) 722 | return true; 723 | if (this.$tableWrapper.find("."+this.columnHeadWrapClass).length) 724 | return true; 725 | if (this.$tableWrapper.find("."+this.scrollBarWrapClass).length) 726 | return true; 727 | 728 | return false; 729 | 730 | } 731 | 732 | /** 733 | * Unbind all events by same namespace 734 | */ 735 | FreezeTable.prototype.unbind = function() { 736 | 737 | this.$container.off('resize.'+this.namespace); 738 | this.$container.off('scroll.'+this.namespace); 739 | this.$tableWrapper.off('scroll.'+this.namespace); 740 | } 741 | 742 | /** 743 | * Destroy Freeze Table by same namespace 744 | */ 745 | FreezeTable.prototype.destroy = function() { 746 | 747 | this.unbind(); 748 | this.$tableWrapper.find("."+this.headWrapClass).remove(); 749 | this.$tableWrapper.find("."+this.columnWrapClass).remove(); 750 | this.$tableWrapper.find("."+this.columnHeadWrapClass).remove(); 751 | this.$tableWrapper.find("."+this.scrollBarWrapClass).remove(); 752 | } 753 | 754 | /** 755 | * Resize trigger for current same namespace 756 | */ 757 | FreezeTable.prototype.resize = function() { 758 | 759 | this.$container.trigger('resize.'+this.namespace); 760 | this.$container.trigger('scroll.'+this.namespace); 761 | this.$tableWrapper.trigger('scroll.'+this.namespace); 762 | 763 | return true; 764 | } 765 | 766 | /** 767 | * Update for Dynamic Content 768 | */ 769 | FreezeTable.prototype.update = function() { 770 | 771 | // Same as re-new object 772 | this.options = 'update'; 773 | this.init(); 774 | return this; 775 | } 776 | 777 | /** 778 | * Interface 779 | */ 780 | // Class for single element 781 | window.FreezeTable = FreezeTable; 782 | // jQuery interface 783 | $.fn.freezeTable = function (options) { 784 | 785 | // Single/Multiple mode 786 | if (this.length === 1) { 787 | 788 | return new FreezeTable(this, options) 789 | } 790 | else if (this.length > 1) { 791 | 792 | var result = []; 793 | // Multiple elements bundle 794 | this.each(function () { 795 | result.push(new FreezeTable(this, options)); 796 | }); 797 | 798 | return result; 799 | } 800 | 801 | return false; 802 | } 803 | 804 | })(jQuery, window); 805 | -------------------------------------------------------------------------------- /src/js/freeze-table.js: -------------------------------------------------------------------------------- 1 | /** 2 | * RWD Table with freezing head and columns for jQuery 3 | * 4 | * @author Nick Tsai 5 | * @version 1.3.0 6 | * @see https://github.com/yidas/jquery-freeze-table 7 | */ 8 | (function ($, window) { 9 | 10 | 'use strict'; 11 | 12 | /** 13 | * Main object 14 | * 15 | * @param {element} element 16 | * @param {object} options 17 | */ 18 | var FreezeTable = function(element, options) { 19 | 20 | // Target element initialization 21 | this.$tableWrapper = $(element).first(); 22 | 23 | // Options 24 | this.options = options || {}; 25 | this.namespace = this.options.namespace || 'freeze-table'; 26 | this.callback; 27 | this.scrollBarHeight; 28 | this.shadow; 29 | this.fastMode; 30 | this.backgroundColor; 31 | this.scrollable; 32 | 33 | // Caches 34 | this.$table = this.$tableWrapper.children("table"); 35 | this.$container = ((typeof this.options.container !== 'undefined') && this.options.container && $(this.options.container).length) ? $(this.options.container) : $(window); 36 | this.$headTableWrap; 37 | this.$columnTableWrap; 38 | this.$columnHeadTableWrap; 39 | this.$scrollBarWrap; 40 | this.fixedNavbarHeight; 41 | this.isWindowScrollX = false; 42 | 43 | // Static class names for clone wraps 44 | this.headWrapClass = 'clone-head-table-wrap'; 45 | this.columnWrapClass = 'clone-column-table-wrap'; 46 | this.columnHeadWrapClass = 'clone-column-head-table-wrap'; 47 | this.scrollBarWrapClass = 'clone-scroll-bar-wrap'; 48 | 49 | this.init(); 50 | 51 | return this; 52 | } 53 | 54 | /** 55 | * Initialization 56 | */ 57 | FreezeTable.prototype.init = function() { 58 | 59 | // Element check 60 | if (!this.$table.length) { 61 | throw "The element must contain a table dom"; 62 | } 63 | 64 | /** 65 | * Update Mode 66 | */ 67 | if (this.options==='update') { 68 | 69 | this.destroy(); 70 | this.options = this.$tableWrapper.data('freeze-table-data'); 71 | } 72 | else if (this.options==='resize') { 73 | 74 | this.options = this.$tableWrapper.data('freeze-table-data'); 75 | // Get selected FreezeTable's namespace 76 | this.namespace = this.options.namespace || this.namespace; 77 | this.resize(); 78 | // Skip init for better performance usage 79 | return; 80 | } 81 | else { 82 | // Save to DOM data 83 | this.$tableWrapper.data('freeze-table-data', this.options); 84 | } 85 | 86 | /** 87 | * Options Setting 88 | */ 89 | var options = this.options; 90 | var freezeHead = (typeof options.freezeHead !== 'undefined') ? options.freezeHead : true; 91 | var freezeColumn = (typeof options.freezeColumn !== 'undefined') ? options.freezeColumn : true; 92 | var freezeColumnHead = (typeof options.freezeColumnHead !== 'undefined') ? options.freezeColumnHead : true; 93 | var scrollBar = (typeof options.scrollBar !== 'undefined') ? options.scrollBar : false; 94 | var fixedNavbar = options.fixedNavbar || '.navbar-fixed-top'; 95 | var callback = options.callback || null; 96 | this.namespace = this.options.namespace || this.namespace; 97 | // Default to get window scroll bar height 98 | this.scrollBarHeight = ($.isNumeric(options.scrollBarHeight)) ? options.scrollBarHeight : (window.innerWidth - document.documentElement.clientWidth); 99 | this.shadow = (typeof options.shadow !== 'undefined') ? options.shadow : false; 100 | this.fastMode = (typeof options.fastMode !== 'undefined') ? options.fastMode : false; 101 | this.backgroundColor = (typeof options.backgroundColor !== 'undefined') ? options.backgroundColor : 'white'; 102 | this.scrollable = (typeof options.scrollable !== 'undefined') ? options.scrollable : false; 103 | 104 | // Get navbar height for keeping fixed navbar 105 | this.fixedNavbarHeight = (fixedNavbar) ? $(fixedNavbar).outerHeight() || 0 : 0; 106 | 107 | // Check existence 108 | if (this.isInit()) { 109 | this.destroy(); 110 | } 111 | 112 | // Release height of the table wrapper 113 | if (!this.scrollable) { 114 | this.$tableWrapper.css('height', '100%') 115 | .css('min-height', '100%') 116 | .css('max-height', '100%'); 117 | } 118 | 119 | /** 120 | * Building 121 | */ 122 | // Switch for freezeHead 123 | if (freezeHead) { 124 | this.buildHeadTable(); 125 | } 126 | // Switch for freezeColumn 127 | if (freezeColumn) { 128 | this.buildColumnTable(); 129 | // X scroll bar 130 | this.$tableWrapper.css('overflow-x', 'scroll'); 131 | } 132 | // Switch for freezeColumnHead 133 | if (freezeColumnHead && freezeHead && freezeColumn) { 134 | this.buildColumnHeadTable(); 135 | } 136 | // Switch for scrollBar 137 | if (scrollBar) { 138 | this.buildScrollBar(); 139 | } 140 | 141 | // Body scroll-x prevention 142 | var detectWindowScroll = (function (){ 143 | // If body scroll-x is opened, close library to prevent Invalid usage 144 | if (this.$container.scrollLeft() > 0) { 145 | // Mark 146 | this.isWindowScrollX = true; 147 | // Hide all components 148 | if (this.$headTableWrap) { 149 | this.$headTableWrap.css('visibility', 'hidden'); 150 | } 151 | if (this.$columnTableWrap) { 152 | this.$columnTableWrap.css('visibility', 'hidden'); 153 | } 154 | if (this.$columnHeadTableWrap) { 155 | this.$columnHeadTableWrap.css('visibility', 'hidden'); 156 | } 157 | if (this.$scrollBarWrap) { 158 | this.$scrollBarWrap.css('visibility', 'hidden'); 159 | } 160 | 161 | } else { 162 | // Unmark 163 | this.isWindowScrollX = false; 164 | } 165 | 166 | }).bind(this); 167 | // Listener of Body scroll-x prevention 168 | this.$container.on('scroll.'+this.namespace, function () { 169 | 170 | detectWindowScroll(); 171 | }); 172 | 173 | // Initialization 174 | this.resize(); 175 | 176 | // Callback 177 | if (typeof callback === 'function') { 178 | callback(); 179 | } 180 | } 181 | 182 | /** 183 | * Freeze thead table 184 | */ 185 | FreezeTable.prototype.buildHeadTable = function() { 186 | 187 | var that = this; 188 | 189 | // Clone the table as Fixed thead 190 | var $headTable = this.clone(this.$table); 191 | 192 | // Fast Mode 193 | if (this.fastMode) { 194 | var $headTable = this.simplifyHead($headTable); 195 | } 196 | 197 | var headWrapStyles = this.options.headWrapStyles || null; 198 | // Wrap the Fixed Column table 199 | this.$headTableWrap = $('
') 200 | .append($headTable) 201 | .css('position', 'fixed') 202 | .css('overflow', 'hidden') 203 | .css('visibility', 'hidden') 204 | .css('top', 0 + this.fixedNavbarHeight) 205 | .css('z-index', 2); 206 | // Shadow option 207 | if (this.shadow) { 208 | this.$headTableWrap.css('box-shadow', '0px 6px 10px -5px rgba(159, 159, 160, 0.8)'); 209 | } 210 | // Styles option 211 | if (headWrapStyles && typeof headWrapStyles === "object") { 212 | $.each(headWrapStyles, function(key, value) { 213 | that.$headTableWrap.css(key, value); 214 | }); 215 | } 216 | // Add into target table wrap 217 | this.$tableWrapper.append(this.$headTableWrap); 218 | 219 | /** 220 | * Listener - Table scroll for effecting Freeze Column 221 | */ 222 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 223 | 224 | // this.$headTableWrap.css('left', this.$table.offset().left); 225 | that.$headTableWrap.scrollLeft($(this).scrollLeft()); 226 | }); 227 | 228 | // Scrollable option 229 | if (this.scrollable) { 230 | 231 | var handler = function (window, that) { 232 | 233 | var top = that.$tableWrapper.offset().top; 234 | 235 | // Detect Current container's top is in the table scope 236 | if (that.$tableWrapper.scrollTop() > 0 && top > that.fixedNavbarHeight) { 237 | 238 | that.$headTableWrap.offset({top: top}); 239 | that.$headTableWrap.css('visibility', 'visible'); 240 | 241 | } else { 242 | 243 | that.$headTableWrap.css('visibility', 'hidden'); 244 | } 245 | } 246 | 247 | /** 248 | * Listener - Window scroll for effecting freeze head table 249 | */ 250 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 251 | 252 | handler(window, that); 253 | }); 254 | 255 | this.$container.on('scroll.'+this.namespace, function() { 256 | 257 | handler(window, that); 258 | }); 259 | 260 | } 261 | // Default with window container 262 | else if ($.isWindow(that.$container.get(0))) { 263 | 264 | /** 265 | * Listener - Window scroll for effecting freeze head table 266 | */ 267 | this.$container.on('scroll.'+this.namespace, function() { 268 | 269 | // Current container's top position 270 | var topPosition = that.$container.scrollTop() + that.fixedNavbarHeight; 271 | var tableTop = that.$table.offset().top - 1; 272 | 273 | // Detect Current container's top is in the table scope 274 | if (tableTop - 1 <= topPosition && (tableTop + that.$table.outerHeight() - 1) >= topPosition) { 275 | 276 | that.$headTableWrap.css('visibility', 'visible'); 277 | 278 | } else { 279 | 280 | that.$headTableWrap.css('visibility', 'hidden'); 281 | } 282 | }); 283 | } 284 | // Container setting 285 | else { 286 | 287 | /** 288 | * Listener - Window scroll for effecting freeze head table 289 | */ 290 | this.$container.on('scroll.'+this.namespace, function() { 291 | 292 | var windowTop = $(window).scrollTop(); 293 | var tableTop = that.$table.offset().top - 1; 294 | 295 | // Detect Current container's top is in the table scope 296 | if (tableTop <= windowTop && (tableTop + that.$table.outerHeight() - 1) >= windowTop) { 297 | 298 | that.$headTableWrap.offset({top: windowTop}); 299 | that.$headTableWrap.css('visibility', 'visible'); 300 | 301 | } else { 302 | 303 | that.$headTableWrap.css('visibility', 'hidden'); 304 | } 305 | }); 306 | } 307 | 308 | /** 309 | * Listener - Window resize for effecting freeze head table 310 | */ 311 | this.$container.on('resize.'+this.namespace, function() { 312 | 313 | // Scrollable check and prevention 314 | var headTableWrapWidth = (that.scrollable) ? that.$tableWrapper.width() - that.scrollBarHeight : that.$tableWrapper.width(); 315 | headTableWrapWidth = (headTableWrapWidth > 0) ? headTableWrapWidth : that.$tableWrapper.width(); 316 | that.$headTableWrap.css('width', headTableWrapWidth); 317 | that.$headTableWrap.css('height', that.$table.find("thead").outerHeight()); 318 | }); 319 | } 320 | 321 | /** 322 | * Freeze column table 323 | */ 324 | FreezeTable.prototype.buildColumnTable = function() { 325 | 326 | var that = this; 327 | 328 | /** 329 | * Setting 330 | */ 331 | var columnWrapStyles = this.options.columnWrapStyles || null; 332 | var columnNum = this.options.columnNum || 1; 333 | var columnKeep = (typeof this.options.columnKeep !== 'undefined') ? this.options.columnKeep : false; 334 | // Shadow option 335 | var defaultColumnBorderWidth = (this.shadow) ? 0 : 1; 336 | var columnBorderWidth = (typeof this.options.columnBorderWidth !== 'undefined') ? this.options.columnBorderWidth : defaultColumnBorderWidth; 337 | 338 | // Clone the table as Fixed Column table 339 | var $columnTable = this.clone(this.$table); 340 | 341 | // Wrap the Fixed Column table 342 | this.$columnTableWrap = $('
') 343 | .append($columnTable) 344 | .css('position', 'fixed') 345 | .css('overflow', 'hidden') 346 | .css('visibility', 'hidden') 347 | .css('z-index', 1); 348 | // Shadow option 349 | if (this.shadow) { 350 | this.$columnTableWrap.css('box-shadow', '6px 0px 10px -5px rgba(159, 159, 160, 0.8)'); 351 | } 352 | // Styles option 353 | if (columnWrapStyles && typeof columnWrapStyles === "object") { 354 | $.each(columnWrapStyles, function(key, value) { 355 | that.$columnTableWrap.css(key, value); 356 | }); 357 | } 358 | // Scrollable 359 | if (this.scrollable) { 360 | // Scrollable check and prevention 361 | var columnTableWrapHeight = this.$tableWrapper.height() - this.scrollBarHeight; 362 | columnTableWrapHeight = (columnTableWrapHeight > 0) ? columnTableWrapHeight : this.$tableWrapper.height(); 363 | this.$columnTableWrap.height(columnTableWrapHeight); 364 | } 365 | // Add into target table wrap 366 | this.$tableWrapper.append(this.$columnTableWrap); 367 | 368 | /** 369 | * localize the column wrap to current top 370 | */ 371 | var localizeWrap = function () { 372 | 373 | that.$columnTableWrap.offset({top: that.$tableWrapper.offset().top}); 374 | } 375 | 376 | // Column keep option 377 | if (columnKeep) { 378 | 379 | this.$columnTableWrap.css('visibility', 'visible'); 380 | 381 | } else { 382 | 383 | // Scrollable option 384 | if (that.scrollable) { 385 | 386 | /** 387 | * Listener - Table scroll for effecting Freeze Column 388 | */ 389 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 390 | 391 | 392 | // Detect for horizontal scroll 393 | if ($(this).scrollLeft() > 0) { 394 | 395 | // Scrollable localization 396 | that.$columnTableWrap.scrollTop(that.$tableWrapper.scrollTop()); 397 | that.$columnTableWrap.css('visibility', 'visible'); 398 | 399 | } else { 400 | 401 | that.$columnTableWrap.css('visibility', 'hidden'); 402 | } 403 | }); 404 | 405 | } else { 406 | 407 | /** 408 | * Listener - Table scroll for effecting Freeze Column 409 | */ 410 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 411 | 412 | // Disable while isWindowScrollX 413 | if (that.isWindowScrollX) 414 | return; 415 | 416 | // Detect for horizontal scroll 417 | if ($(this).scrollLeft() > 0) { 418 | 419 | that.$columnTableWrap.css('visibility', 'visible'); 420 | 421 | } else { 422 | 423 | that.$columnTableWrap.css('visibility', 'hidden'); 424 | } 425 | }); 426 | } 427 | } 428 | 429 | /** 430 | * Listener - Window resize for effecting tables 431 | */ 432 | this.$container.on('resize.'+this.namespace, function() { 433 | 434 | // Follows origin table's width 435 | $columnTable.width(that.$table.width()); 436 | 437 | /** 438 | * Dynamic column calculation 439 | */ 440 | // Get width by fixed column with number setting 441 | var width = 0 + columnBorderWidth; 442 | for (var i = 1; i <= columnNum; i++) { 443 | // th/td detection 444 | var th = that.$table.find('th:nth-child('+i+')').outerWidth(); 445 | var addWidth = (th > 0) ? th : that.$table.find('td:nth-child('+i+')').outerWidth(); 446 | width += addWidth; 447 | } 448 | that.$columnTableWrap.width(width); 449 | 450 | localizeWrap(); 451 | }); 452 | 453 | /** 454 | * Listener - Window scroll for effecting freeze column table 455 | */ 456 | this.$container.on('scroll.'+this.namespace, function() { 457 | 458 | localizeWrap(); 459 | }); 460 | } 461 | 462 | /** 463 | * Freeze column thead table 464 | */ 465 | FreezeTable.prototype.buildColumnHeadTable = function() { 466 | 467 | var that = this; 468 | 469 | // Clone head table wrap 470 | this.$columnHeadTableWrap = this.clone(this.$headTableWrap); 471 | 472 | // Fast Mode 473 | if (this.fastMode) { 474 | this.$columnHeadTableWrap = this.simplifyHead(this.$columnHeadTableWrap); 475 | } 476 | 477 | var columnHeadWrapStyles = this.options.columnHeadWrapStyles || null; 478 | 479 | this.$columnHeadTableWrap.removeClass(this.namespace) 480 | .addClass(this.columnHeadWrapClass) 481 | .css('z-index', 3); 482 | // Shadow option 483 | if (this.shadow) { 484 | this.$columnHeadTableWrap.css('box-shadow', 'none'); 485 | } 486 | // Styles option 487 | if (columnHeadWrapStyles && typeof columnHeadWrapStyles === "object") { 488 | $.each(columnHeadWrapStyles, function(key, value) { 489 | this.$columnHeadTableWrap.css(key, value); 490 | }); 491 | } 492 | 493 | // Add into target table wrap 494 | this.$tableWrapper.append(this.$columnHeadTableWrap); 495 | 496 | // Scrollable option 497 | if (this.scrollable) { 498 | 499 | var detect = function () { 500 | 501 | var top = that.$tableWrapper.offset().top; 502 | 503 | // Detect Current container's top is in the table scope 504 | if (that.$tableWrapper.scrollTop() > 0 && top > that.fixedNavbarHeight) { 505 | 506 | that.$columnHeadTableWrap.offset({top: top}); 507 | that.$columnHeadTableWrap.css('visibility', 'visible'); 508 | 509 | } else { 510 | 511 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 512 | } 513 | } 514 | 515 | /** 516 | * Listener - Window scroll for effecting freeze head table 517 | */ 518 | $(this.$tableWrapper).on('scroll.'+this.namespace, function() { 519 | 520 | detect(); 521 | }); 522 | 523 | } 524 | // Default with window container 525 | else if ($.isWindow(this.$container.get(0))) { 526 | 527 | var detect = function () { 528 | 529 | // Current container's top position 530 | var topPosition = that.$container.scrollTop() + that.fixedNavbarHeight; 531 | var tableTop = that.$table.offset().top - 1; 532 | 533 | // Detect Current container's top is in the table scope 534 | if (tableTop - 1 <= topPosition && (tableTop + that.$table.outerHeight() - 1) >= topPosition && that.$tableWrapper.scrollLeft() > 0) { 535 | 536 | that.$columnHeadTableWrap.css('visibility', 'visible'); 537 | 538 | } else { 539 | 540 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 541 | } 542 | } 543 | } 544 | // Container setting 545 | else { 546 | 547 | var detect = function () { 548 | 549 | var windowTop = $(window).scrollTop(); 550 | var tableTop = that.$table.offset().top - 1; 551 | 552 | // Detect Current container's top is in the table scope 553 | if (tableTop <= windowTop && (tableTop + that.$table.outerHeight() - 1) >= windowTop && that.$tableWrapper.scrollLeft() > 0) { 554 | 555 | that.$columnHeadTableWrap.offset({top: windowTop}); 556 | that.$columnHeadTableWrap.css('visibility', 'visible'); 557 | 558 | } else { 559 | 560 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 561 | } 562 | } 563 | } 564 | 565 | /** 566 | * Listener - Window scroll for effecting Freeze column-head table 567 | */ 568 | this.$container.on('scroll.'+this.namespace, function() { 569 | 570 | detect(); 571 | }); 572 | 573 | /** 574 | * Listener - Table scroll for effecting Freeze column-head table 575 | */ 576 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 577 | 578 | // Disable while isWindowScrollX 579 | if (that.isWindowScrollX) 580 | return; 581 | 582 | detect(); 583 | }); 584 | 585 | /** 586 | * Listener - Window resize for effecting freeze column-head table 587 | */ 588 | this.$container.on('resize.'+this.namespace, function() { 589 | 590 | // Table synchronism 591 | that.$columnHeadTableWrap.find("> table").css('width', that.$table.width()); 592 | that.$columnHeadTableWrap.css('width', that.$columnTableWrap.width()); 593 | that.$columnHeadTableWrap.css('height', that.$table.find("thead").outerHeight()); 594 | }); 595 | } 596 | 597 | /** 598 | * Freeze scroll bar 599 | */ 600 | FreezeTable.prototype.buildScrollBar = function() { 601 | 602 | var that = this; 603 | 604 | var theadHeight = this.$table.find("thead").outerHeight(); 605 | 606 | // Scroll wrap container 607 | var $scrollBarContainer = $('
') 608 | .css('width', this.$table.width()) 609 | .css('height', 1); 610 | 611 | // Wrap the Fixed Column table 612 | this.$scrollBarWrap = $('
') 613 | .css('position', 'fixed') 614 | .css('overflow-x', 'scroll') 615 | .css('visibility', 'hidden') 616 | .css('bottom', 0) 617 | .css('z-index', 2) 618 | .css('width', this.$tableWrapper.width()) 619 | .css('height', this.scrollBarHeight); 620 | 621 | // Add into target table wrap 622 | this.$scrollBarWrap.append($scrollBarContainer); 623 | this.$tableWrapper.append(this.$scrollBarWrap); 624 | 625 | /** 626 | * Listener - Freeze scroll bar effected Table 627 | */ 628 | this.$scrollBarWrap.on('scroll.'+this.namespace, function() { 629 | 630 | that.$tableWrapper.scrollLeft($(this).scrollLeft()); 631 | }); 632 | 633 | /** 634 | * Listener - Table scroll for effecting Freeze scroll bar 635 | */ 636 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 637 | 638 | // this.$headTableWrap.css('left', $table.offset().left); 639 | that.$scrollBarWrap.scrollLeft($(this).scrollLeft()); 640 | }); 641 | 642 | /** 643 | * Listener - Window scroll for effecting scroll bar 644 | */ 645 | this.$container.on('scroll.'+this.namespace, function() { 646 | 647 | // Current container's top position 648 | var bottomPosition = that.$container.scrollTop() + that.$container.height() - theadHeight + that.fixedNavbarHeight; 649 | 650 | // Detect Current container's top is in the table scope 651 | if (that.$table.offset().top - 1 <= bottomPosition && (that.$table.offset().top + that.$table.outerHeight() - 1) >= bottomPosition) { 652 | 653 | that.$scrollBarWrap.css('visibility', 'visible'); 654 | 655 | } else { 656 | 657 | that.$scrollBarWrap.css('visibility', 'hidden'); 658 | } 659 | }); 660 | 661 | /** 662 | * Listener - Window resize for effecting scroll bar 663 | */ 664 | this.$container.on('resize.'+this.namespace, function() { 665 | 666 | // Update width 667 | $scrollBarContainer.css('width', that.$table.width()) 668 | // Update Wrap 669 | that.$scrollBarWrap.css('width', that.$tableWrapper.width()); 670 | }); 671 | } 672 | 673 | /** 674 | * Clone element 675 | * 676 | * @param {element} element 677 | */ 678 | FreezeTable.prototype.clone = function (element) { 679 | 680 | var $clone = $(element).clone() 681 | .removeAttr('id') // Remove ID 682 | 683 | // Bootstrap background-color transparent problem 684 | if (this.backgroundColor) { 685 | $clone.css('background-color', this.backgroundColor); 686 | } 687 | 688 | return $clone; 689 | } 690 | 691 | /** 692 | * simplify cloned head table 693 | * 694 | * @param {element} table Table element 695 | */ 696 | FreezeTable.prototype.simplifyHead = function (table) { 697 | 698 | var that = this; 699 | 700 | var $headTable = $(table); 701 | // Remove non-display DOM but keeping first row for accuracy 702 | $headTable.find("> tr, > tbody > tr, tfoot > tr").not(':first').remove(); 703 | // Each th/td width synchronism 704 | $.each($headTable.find("> thead > tr:nth-child(1) >"), function (key, value) { 705 | 706 | var width = that.$table.find("> thead > tr:nth-child(1) > :nth-child("+parseInt(key+1)+")").outerWidth(); 707 | $(this).css('width', width); 708 | }); 709 | 710 | return $headTable; 711 | } 712 | 713 | /** 714 | * Detect is already initialized 715 | */ 716 | FreezeTable.prototype.isInit = function() { 717 | 718 | // Check existence DOM 719 | if (this.$tableWrapper.find("."+this.headWrapClass).length) 720 | return true; 721 | if (this.$tableWrapper.find("."+this.columnWrapClass).length) 722 | return true; 723 | if (this.$tableWrapper.find("."+this.columnHeadWrapClass).length) 724 | return true; 725 | if (this.$tableWrapper.find("."+this.scrollBarWrapClass).length) 726 | return true; 727 | 728 | return false; 729 | 730 | } 731 | 732 | /** 733 | * Unbind all events by same namespace 734 | */ 735 | FreezeTable.prototype.unbind = function() { 736 | 737 | this.$container.off('resize.'+this.namespace); 738 | this.$container.off('scroll.'+this.namespace); 739 | this.$tableWrapper.off('scroll.'+this.namespace); 740 | } 741 | 742 | /** 743 | * Destroy Freeze Table by same namespace 744 | */ 745 | FreezeTable.prototype.destroy = function() { 746 | 747 | this.unbind(); 748 | this.$tableWrapper.find("."+this.headWrapClass).remove(); 749 | this.$tableWrapper.find("."+this.columnWrapClass).remove(); 750 | this.$tableWrapper.find("."+this.columnHeadWrapClass).remove(); 751 | this.$tableWrapper.find("."+this.scrollBarWrapClass).remove(); 752 | } 753 | 754 | /** 755 | * Resize trigger for current same namespace 756 | */ 757 | FreezeTable.prototype.resize = function() { 758 | 759 | this.$container.trigger('resize.'+this.namespace); 760 | this.$container.trigger('scroll.'+this.namespace); 761 | this.$tableWrapper.trigger('scroll.'+this.namespace); 762 | 763 | return true; 764 | } 765 | 766 | /** 767 | * Update for Dynamic Content 768 | */ 769 | FreezeTable.prototype.update = function() { 770 | 771 | // Same as re-new object 772 | this.options = 'update'; 773 | this.init(); 774 | return this; 775 | } 776 | 777 | /** 778 | * Interface 779 | */ 780 | // Class for single element 781 | window.FreezeTable = FreezeTable; 782 | // jQuery interface 783 | $.fn.freezeTable = function (options) { 784 | 785 | // Single/Multiple mode 786 | if (this.length === 1) { 787 | 788 | return new FreezeTable(this, options) 789 | } 790 | else if (this.length > 1) { 791 | 792 | var result = []; 793 | // Multiple elements bundle 794 | this.each(function () { 795 | result.push(new FreezeTable(this, options)); 796 | }); 797 | 798 | return result; 799 | } 800 | 801 | return false; 802 | } 803 | 804 | })(jQuery, window); 805 | -------------------------------------------------------------------------------- /docs/dist/js/freeze-table.js: -------------------------------------------------------------------------------- 1 | /** 2 | * RWD Table with freezing head and columns for jQuery 3 | * 4 | * @author Nick Tsai 5 | * @version 1.3.0 6 | * @see https://github.com/yidas/jquery-freeze-table 7 | */ 8 | (function ($, window) { 9 | 10 | 'use strict'; 11 | 12 | /** 13 | * Main object 14 | * 15 | * @param {element} element 16 | * @param {object} options 17 | */ 18 | var FreezeTable = function(element, options) { 19 | 20 | // Target element initialization 21 | this.$tableWrapper = $(element).first(); 22 | 23 | // Options 24 | this.options = options || {}; 25 | this.namespace = this.options.namespace || 'freeze-table'; 26 | this.callback; 27 | this.scrollBarHeight; 28 | this.shadow; 29 | this.fastMode; 30 | this.backgroundColor; 31 | this.scrollable; 32 | 33 | // Caches 34 | this.$table = this.$tableWrapper.children("table"); 35 | this.$container = ((typeof this.options.container !== 'undefined') && this.options.container && $(this.options.container).length) ? $(this.options.container) : $(window); 36 | this.$headTableWrap; 37 | this.$columnTableWrap; 38 | this.$columnHeadTableWrap; 39 | this.$scrollBarWrap; 40 | this.fixedNavbarHeight; 41 | this.isWindowScrollX = false; 42 | 43 | // Static class names for clone wraps 44 | this.headWrapClass = 'clone-head-table-wrap'; 45 | this.columnWrapClass = 'clone-column-table-wrap'; 46 | this.columnHeadWrapClass = 'clone-column-head-table-wrap'; 47 | this.scrollBarWrapClass = 'clone-scroll-bar-wrap'; 48 | 49 | this.init(); 50 | 51 | return this; 52 | } 53 | 54 | /** 55 | * Initialization 56 | */ 57 | FreezeTable.prototype.init = function() { 58 | 59 | // Element check 60 | if (!this.$table.length) { 61 | throw "The element must contain a table dom"; 62 | } 63 | 64 | /** 65 | * Update Mode 66 | */ 67 | if (this.options==='update') { 68 | 69 | this.destroy(); 70 | this.options = this.$tableWrapper.data('freeze-table-data'); 71 | } 72 | else if (this.options==='resize') { 73 | 74 | this.options = this.$tableWrapper.data('freeze-table-data'); 75 | // Get selected FreezeTable's namespace 76 | this.namespace = this.options.namespace || this.namespace; 77 | this.resize(); 78 | // Skip init for better performance usage 79 | return; 80 | } 81 | else { 82 | // Save to DOM data 83 | this.$tableWrapper.data('freeze-table-data', this.options); 84 | } 85 | 86 | /** 87 | * Options Setting 88 | */ 89 | var options = this.options; 90 | var freezeHead = (typeof options.freezeHead !== 'undefined') ? options.freezeHead : true; 91 | var freezeColumn = (typeof options.freezeColumn !== 'undefined') ? options.freezeColumn : true; 92 | var freezeColumnHead = (typeof options.freezeColumnHead !== 'undefined') ? options.freezeColumnHead : true; 93 | var scrollBar = (typeof options.scrollBar !== 'undefined') ? options.scrollBar : false; 94 | var fixedNavbar = options.fixedNavbar || '.navbar-fixed-top'; 95 | var callback = options.callback || null; 96 | this.namespace = this.options.namespace || this.namespace; 97 | // Default to get window scroll bar height 98 | this.scrollBarHeight = ($.isNumeric(options.scrollBarHeight)) ? options.scrollBarHeight : (window.innerWidth - document.documentElement.clientWidth); 99 | this.shadow = (typeof options.shadow !== 'undefined') ? options.shadow : false; 100 | this.fastMode = (typeof options.fastMode !== 'undefined') ? options.fastMode : false; 101 | this.backgroundColor = (typeof options.backgroundColor !== 'undefined') ? options.backgroundColor : 'white'; 102 | this.scrollable = (typeof options.scrollable !== 'undefined') ? options.scrollable : false; 103 | 104 | // Get navbar height for keeping fixed navbar 105 | this.fixedNavbarHeight = (fixedNavbar) ? $(fixedNavbar).outerHeight() || 0 : 0; 106 | 107 | // Check existence 108 | if (this.isInit()) { 109 | this.destroy(); 110 | } 111 | 112 | // Release height of the table wrapper 113 | if (!this.scrollable) { 114 | this.$tableWrapper.css('height', '100%') 115 | .css('min-height', '100%') 116 | .css('max-height', '100%'); 117 | } 118 | 119 | /** 120 | * Building 121 | */ 122 | // Switch for freezeHead 123 | if (freezeHead) { 124 | this.buildHeadTable(); 125 | } 126 | // Switch for freezeColumn 127 | if (freezeColumn) { 128 | this.buildColumnTable(); 129 | // X scroll bar 130 | this.$tableWrapper.css('overflow-x', 'scroll'); 131 | } 132 | // Switch for freezeColumnHead 133 | if (freezeColumnHead && freezeHead && freezeColumn) { 134 | this.buildColumnHeadTable(); 135 | } 136 | // Switch for scrollBar 137 | if (scrollBar) { 138 | this.buildScrollBar(); 139 | } 140 | 141 | // Body scroll-x prevention 142 | var detectWindowScroll = (function (){ 143 | // If body scroll-x is opened, close library to prevent Invalid usage 144 | if (this.$container.scrollLeft() > 0) { 145 | // Mark 146 | this.isWindowScrollX = true; 147 | // Hide all components 148 | if (this.$headTableWrap) { 149 | this.$headTableWrap.css('visibility', 'hidden'); 150 | } 151 | if (this.$columnTableWrap) { 152 | this.$columnTableWrap.css('visibility', 'hidden'); 153 | } 154 | if (this.$columnHeadTableWrap) { 155 | this.$columnHeadTableWrap.css('visibility', 'hidden'); 156 | } 157 | if (this.$scrollBarWrap) { 158 | this.$scrollBarWrap.css('visibility', 'hidden'); 159 | } 160 | 161 | } else { 162 | // Unmark 163 | this.isWindowScrollX = false; 164 | } 165 | 166 | }).bind(this); 167 | // Listener of Body scroll-x prevention 168 | this.$container.on('scroll.'+this.namespace, function () { 169 | 170 | detectWindowScroll(); 171 | }); 172 | 173 | // Initialization 174 | this.resize(); 175 | 176 | // Callback 177 | if (typeof callback === 'function') { 178 | callback(); 179 | } 180 | } 181 | 182 | /** 183 | * Freeze thead table 184 | */ 185 | FreezeTable.prototype.buildHeadTable = function() { 186 | 187 | var that = this; 188 | 189 | // Clone the table as Fixed thead 190 | var $headTable = this.clone(this.$table); 191 | 192 | // Fast Mode 193 | if (this.fastMode) { 194 | var $headTable = this.simplifyHead($headTable); 195 | } 196 | 197 | var headWrapStyles = this.options.headWrapStyles || null; 198 | // Wrap the Fixed Column table 199 | this.$headTableWrap = $('
') 200 | .append($headTable) 201 | .css('position', 'fixed') 202 | .css('overflow', 'hidden') 203 | .css('visibility', 'hidden') 204 | .css('top', 0 + this.fixedNavbarHeight) 205 | .css('z-index', 2); 206 | // Shadow option 207 | if (this.shadow) { 208 | this.$headTableWrap.css('box-shadow', '0px 6px 10px -5px rgba(159, 159, 160, 0.8)'); 209 | } 210 | // Styles option 211 | if (headWrapStyles && typeof headWrapStyles === "object") { 212 | $.each(headWrapStyles, function(key, value) { 213 | that.$headTableWrap.css(key, value); 214 | }); 215 | } 216 | // Add into target table wrap 217 | this.$tableWrapper.append(this.$headTableWrap); 218 | 219 | /** 220 | * Listener - Table scroll for effecting Freeze Column 221 | */ 222 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 223 | 224 | // this.$headTableWrap.css('left', this.$table.offset().left); 225 | that.$headTableWrap.scrollLeft($(this).scrollLeft()); 226 | }); 227 | 228 | // Scrollable option 229 | if (this.scrollable) { 230 | 231 | var handler = function (window, that) { 232 | 233 | var top = that.$tableWrapper.offset().top; 234 | 235 | // Detect Current container's top is in the table scope 236 | if (that.$tableWrapper.scrollTop() > 0 && top > that.fixedNavbarHeight) { 237 | 238 | that.$headTableWrap.offset({top: top}); 239 | that.$headTableWrap.css('visibility', 'visible'); 240 | 241 | } else { 242 | 243 | that.$headTableWrap.css('visibility', 'hidden'); 244 | } 245 | } 246 | 247 | /** 248 | * Listener - Window scroll for effecting freeze head table 249 | */ 250 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 251 | 252 | handler(window, that); 253 | }); 254 | 255 | this.$container.on('scroll.'+this.namespace, function() { 256 | 257 | handler(window, that); 258 | }); 259 | 260 | } 261 | // Default with window container 262 | else if ($.isWindow(that.$container.get(0))) { 263 | 264 | /** 265 | * Listener - Window scroll for effecting freeze head table 266 | */ 267 | this.$container.on('scroll.'+this.namespace, function() { 268 | 269 | // Current container's top position 270 | var topPosition = that.$container.scrollTop() + that.fixedNavbarHeight; 271 | var tableTop = that.$table.offset().top - 1; 272 | 273 | // Detect Current container's top is in the table scope 274 | if (tableTop - 1 <= topPosition && (tableTop + that.$table.outerHeight() - 1) >= topPosition) { 275 | 276 | that.$headTableWrap.css('visibility', 'visible'); 277 | 278 | } else { 279 | 280 | that.$headTableWrap.css('visibility', 'hidden'); 281 | } 282 | }); 283 | } 284 | // Container setting 285 | else { 286 | 287 | /** 288 | * Listener - Window scroll for effecting freeze head table 289 | */ 290 | this.$container.on('scroll.'+this.namespace, function() { 291 | 292 | var windowTop = $(window).scrollTop(); 293 | var tableTop = that.$table.offset().top - 1; 294 | 295 | // Detect Current container's top is in the table scope 296 | if (tableTop <= windowTop && (tableTop + that.$table.outerHeight() - 1) >= windowTop) { 297 | 298 | that.$headTableWrap.offset({top: windowTop}); 299 | that.$headTableWrap.css('visibility', 'visible'); 300 | 301 | } else { 302 | 303 | that.$headTableWrap.css('visibility', 'hidden'); 304 | } 305 | }); 306 | } 307 | 308 | /** 309 | * Listener - Window resize for effecting freeze head table 310 | */ 311 | this.$container.on('resize.'+this.namespace, function() { 312 | 313 | // Scrollable check and prevention 314 | var headTableWrapWidth = (that.scrollable) ? that.$tableWrapper.width() - that.scrollBarHeight : that.$tableWrapper.width(); 315 | headTableWrapWidth = (headTableWrapWidth > 0) ? headTableWrapWidth : that.$tableWrapper.width(); 316 | that.$headTableWrap.css('width', headTableWrapWidth); 317 | that.$headTableWrap.css('height', that.$table.find("thead").outerHeight()); 318 | }); 319 | } 320 | 321 | /** 322 | * Freeze column table 323 | */ 324 | FreezeTable.prototype.buildColumnTable = function() { 325 | 326 | var that = this; 327 | 328 | /** 329 | * Setting 330 | */ 331 | var columnWrapStyles = this.options.columnWrapStyles || null; 332 | var columnNum = this.options.columnNum || 1; 333 | var columnKeep = (typeof this.options.columnKeep !== 'undefined') ? this.options.columnKeep : false; 334 | // Shadow option 335 | var defaultColumnBorderWidth = (this.shadow) ? 0 : 1; 336 | var columnBorderWidth = (typeof this.options.columnBorderWidth !== 'undefined') ? this.options.columnBorderWidth : defaultColumnBorderWidth; 337 | 338 | // Clone the table as Fixed Column table 339 | var $columnTable = this.clone(this.$table); 340 | 341 | // Wrap the Fixed Column table 342 | this.$columnTableWrap = $('
') 343 | .append($columnTable) 344 | .css('position', 'fixed') 345 | .css('overflow', 'hidden') 346 | .css('visibility', 'hidden') 347 | .css('z-index', 1); 348 | // Shadow option 349 | if (this.shadow) { 350 | this.$columnTableWrap.css('box-shadow', '6px 0px 10px -5px rgba(159, 159, 160, 0.8)'); 351 | } 352 | // Styles option 353 | if (columnWrapStyles && typeof columnWrapStyles === "object") { 354 | $.each(columnWrapStyles, function(key, value) { 355 | that.$columnTableWrap.css(key, value); 356 | }); 357 | } 358 | // Scrollable 359 | if (this.scrollable) { 360 | // Scrollable check and prevention 361 | var columnTableWrapHeight = this.$tableWrapper.height() - this.scrollBarHeight; 362 | columnTableWrapHeight = (columnTableWrapHeight > 0) ? columnTableWrapHeight : this.$tableWrapper.height(); 363 | this.$columnTableWrap.height(columnTableWrapHeight); 364 | } 365 | // Add into target table wrap 366 | this.$tableWrapper.append(this.$columnTableWrap); 367 | 368 | /** 369 | * localize the column wrap to current top 370 | */ 371 | var localizeWrap = function () { 372 | 373 | that.$columnTableWrap.offset({top: that.$tableWrapper.offset().top}); 374 | } 375 | 376 | // Column keep option 377 | if (columnKeep) { 378 | 379 | this.$columnTableWrap.css('visibility', 'visible'); 380 | 381 | } else { 382 | 383 | // Scrollable option 384 | if (that.scrollable) { 385 | 386 | /** 387 | * Listener - Table scroll for effecting Freeze Column 388 | */ 389 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 390 | 391 | 392 | // Detect for horizontal scroll 393 | if ($(this).scrollLeft() > 0) { 394 | 395 | // Scrollable localization 396 | that.$columnTableWrap.scrollTop(that.$tableWrapper.scrollTop()); 397 | that.$columnTableWrap.css('visibility', 'visible'); 398 | 399 | } else { 400 | 401 | that.$columnTableWrap.css('visibility', 'hidden'); 402 | } 403 | }); 404 | 405 | } else { 406 | 407 | /** 408 | * Listener - Table scroll for effecting Freeze Column 409 | */ 410 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 411 | 412 | // Disable while isWindowScrollX 413 | if (that.isWindowScrollX) 414 | return; 415 | 416 | // Detect for horizontal scroll 417 | if ($(this).scrollLeft() > 0) { 418 | 419 | that.$columnTableWrap.css('visibility', 'visible'); 420 | 421 | } else { 422 | 423 | that.$columnTableWrap.css('visibility', 'hidden'); 424 | } 425 | }); 426 | } 427 | } 428 | 429 | /** 430 | * Listener - Window resize for effecting tables 431 | */ 432 | this.$container.on('resize.'+this.namespace, function() { 433 | 434 | // Follows origin table's width 435 | $columnTable.width(that.$table.width()); 436 | 437 | /** 438 | * Dynamic column calculation 439 | */ 440 | // Get width by fixed column with number setting 441 | var width = 0 + columnBorderWidth; 442 | for (var i = 1; i <= columnNum; i++) { 443 | // th/td detection 444 | var th = that.$table.find('th:nth-child('+i+')').outerWidth(); 445 | var addWidth = (th > 0) ? th : that.$table.find('td:nth-child('+i+')').outerWidth(); 446 | width += addWidth; 447 | } 448 | that.$columnTableWrap.width(width); 449 | 450 | localizeWrap(); 451 | }); 452 | 453 | /** 454 | * Listener - Window scroll for effecting freeze column table 455 | */ 456 | this.$container.on('scroll.'+this.namespace, function() { 457 | 458 | localizeWrap(); 459 | }); 460 | } 461 | 462 | /** 463 | * Freeze column thead table 464 | */ 465 | FreezeTable.prototype.buildColumnHeadTable = function() { 466 | 467 | var that = this; 468 | 469 | // Clone head table wrap 470 | this.$columnHeadTableWrap = this.clone(this.$headTableWrap); 471 | 472 | // Fast Mode 473 | if (this.fastMode) { 474 | this.$columnHeadTableWrap = this.simplifyHead(this.$columnHeadTableWrap); 475 | } 476 | 477 | var columnHeadWrapStyles = this.options.columnHeadWrapStyles || null; 478 | 479 | this.$columnHeadTableWrap.removeClass(this.namespace) 480 | .addClass(this.columnHeadWrapClass) 481 | .css('z-index', 3); 482 | // Shadow option 483 | if (this.shadow) { 484 | this.$columnHeadTableWrap.css('box-shadow', 'none'); 485 | } 486 | // Styles option 487 | if (columnHeadWrapStyles && typeof columnHeadWrapStyles === "object") { 488 | $.each(columnHeadWrapStyles, function(key, value) { 489 | this.$columnHeadTableWrap.css(key, value); 490 | }); 491 | } 492 | 493 | // Add into target table wrap 494 | this.$tableWrapper.append(this.$columnHeadTableWrap); 495 | 496 | // Scrollable option 497 | if (this.scrollable) { 498 | 499 | var detect = function () { 500 | 501 | var top = that.$tableWrapper.offset().top; 502 | 503 | // Detect Current container's top is in the table scope 504 | if (that.$tableWrapper.scrollTop() > 0 && top > that.fixedNavbarHeight) { 505 | 506 | that.$columnHeadTableWrap.offset({top: top}); 507 | that.$columnHeadTableWrap.css('visibility', 'visible'); 508 | 509 | } else { 510 | 511 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 512 | } 513 | } 514 | 515 | /** 516 | * Listener - Window scroll for effecting freeze head table 517 | */ 518 | $(this.$tableWrapper).on('scroll.'+this.namespace, function() { 519 | 520 | detect(); 521 | }); 522 | 523 | } 524 | // Default with window container 525 | else if ($.isWindow(this.$container.get(0))) { 526 | 527 | var detect = function () { 528 | 529 | // Current container's top position 530 | var topPosition = that.$container.scrollTop() + that.fixedNavbarHeight; 531 | var tableTop = that.$table.offset().top - 1; 532 | 533 | // Detect Current container's top is in the table scope 534 | if (tableTop - 1 <= topPosition && (tableTop + that.$table.outerHeight() - 1) >= topPosition && that.$tableWrapper.scrollLeft() > 0) { 535 | 536 | that.$columnHeadTableWrap.css('visibility', 'visible'); 537 | 538 | } else { 539 | 540 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 541 | } 542 | } 543 | } 544 | // Container setting 545 | else { 546 | 547 | var detect = function () { 548 | 549 | var windowTop = $(window).scrollTop(); 550 | var tableTop = that.$table.offset().top - 1; 551 | 552 | // Detect Current container's top is in the table scope 553 | if (tableTop <= windowTop && (tableTop + that.$table.outerHeight() - 1) >= windowTop && that.$tableWrapper.scrollLeft() > 0) { 554 | 555 | that.$columnHeadTableWrap.offset({top: windowTop}); 556 | that.$columnHeadTableWrap.css('visibility', 'visible'); 557 | 558 | } else { 559 | 560 | that.$columnHeadTableWrap.css('visibility', 'hidden'); 561 | } 562 | } 563 | } 564 | 565 | /** 566 | * Listener - Window scroll for effecting Freeze column-head table 567 | */ 568 | this.$container.on('scroll.'+this.namespace, function() { 569 | 570 | detect(); 571 | }); 572 | 573 | /** 574 | * Listener - Table scroll for effecting Freeze column-head table 575 | */ 576 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 577 | 578 | // Disable while isWindowScrollX 579 | if (that.isWindowScrollX) 580 | return; 581 | 582 | detect(); 583 | }); 584 | 585 | /** 586 | * Listener - Window resize for effecting freeze column-head table 587 | */ 588 | this.$container.on('resize.'+this.namespace, function() { 589 | 590 | // Table synchronism 591 | that.$columnHeadTableWrap.find("> table").css('width', that.$table.width()); 592 | that.$columnHeadTableWrap.css('width', that.$columnTableWrap.width()); 593 | that.$columnHeadTableWrap.css('height', that.$table.find("thead").outerHeight()); 594 | }); 595 | } 596 | 597 | /** 598 | * Freeze scroll bar 599 | */ 600 | FreezeTable.prototype.buildScrollBar = function() { 601 | 602 | var that = this; 603 | 604 | var theadHeight = this.$table.find("thead").outerHeight(); 605 | 606 | // Scroll wrap container 607 | var $scrollBarContainer = $('
') 608 | .css('width', this.$table.width()) 609 | .css('height', 1); 610 | 611 | // Wrap the Fixed Column table 612 | this.$scrollBarWrap = $('
') 613 | .css('position', 'fixed') 614 | .css('overflow-x', 'scroll') 615 | .css('visibility', 'hidden') 616 | .css('bottom', 0) 617 | .css('z-index', 2) 618 | .css('width', this.$tableWrapper.width()) 619 | .css('height', this.scrollBarHeight); 620 | 621 | // Add into target table wrap 622 | this.$scrollBarWrap.append($scrollBarContainer); 623 | this.$tableWrapper.append(this.$scrollBarWrap); 624 | 625 | /** 626 | * Listener - Freeze scroll bar effected Table 627 | */ 628 | this.$scrollBarWrap.on('scroll.'+this.namespace, function() { 629 | 630 | that.$tableWrapper.scrollLeft($(this).scrollLeft()); 631 | }); 632 | 633 | /** 634 | * Listener - Table scroll for effecting Freeze scroll bar 635 | */ 636 | this.$tableWrapper.on('scroll.'+this.namespace, function() { 637 | 638 | // this.$headTableWrap.css('left', $table.offset().left); 639 | that.$scrollBarWrap.scrollLeft($(this).scrollLeft()); 640 | }); 641 | 642 | /** 643 | * Listener - Window scroll for effecting scroll bar 644 | */ 645 | this.$container.on('scroll.'+this.namespace, function() { 646 | 647 | // Current container's top position 648 | var bottomPosition = that.$container.scrollTop() + that.$container.height() - theadHeight + that.fixedNavbarHeight; 649 | 650 | // Detect Current container's top is in the table scope 651 | if (that.$table.offset().top - 1 <= bottomPosition && (that.$table.offset().top + that.$table.outerHeight() - 1) >= bottomPosition) { 652 | 653 | that.$scrollBarWrap.css('visibility', 'visible'); 654 | 655 | } else { 656 | 657 | that.$scrollBarWrap.css('visibility', 'hidden'); 658 | } 659 | }); 660 | 661 | /** 662 | * Listener - Window resize for effecting scroll bar 663 | */ 664 | this.$container.on('resize.'+this.namespace, function() { 665 | 666 | // Update width 667 | $scrollBarContainer.css('width', that.$table.width()) 668 | // Update Wrap 669 | that.$scrollBarWrap.css('width', that.$tableWrapper.width()); 670 | }); 671 | } 672 | 673 | /** 674 | * Clone element 675 | * 676 | * @param {element} element 677 | */ 678 | FreezeTable.prototype.clone = function (element) { 679 | 680 | var $clone = $(element).clone() 681 | .removeAttr('id') // Remove ID 682 | 683 | // Bootstrap background-color transparent problem 684 | if (this.backgroundColor) { 685 | $clone.css('background-color', this.backgroundColor); 686 | } 687 | 688 | return $clone; 689 | } 690 | 691 | /** 692 | * simplify cloned head table 693 | * 694 | * @param {element} table Table element 695 | */ 696 | FreezeTable.prototype.simplifyHead = function (table) { 697 | 698 | var that = this; 699 | 700 | var $headTable = $(table); 701 | // Remove non-display DOM but keeping first row for accuracy 702 | $headTable.find("> tr, > tbody > tr, tfoot > tr").not(':first').remove(); 703 | // Each th/td width synchronism 704 | $.each($headTable.find("> thead > tr:nth-child(1) >"), function (key, value) { 705 | 706 | var width = that.$table.find("> thead > tr:nth-child(1) > :nth-child("+parseInt(key+1)+")").outerWidth(); 707 | $(this).css('width', width); 708 | }); 709 | 710 | return $headTable; 711 | } 712 | 713 | /** 714 | * Detect is already initialized 715 | */ 716 | FreezeTable.prototype.isInit = function() { 717 | 718 | // Check existence DOM 719 | if (this.$tableWrapper.find("."+this.headWrapClass).length) 720 | return true; 721 | if (this.$tableWrapper.find("."+this.columnWrapClass).length) 722 | return true; 723 | if (this.$tableWrapper.find("."+this.columnHeadWrapClass).length) 724 | return true; 725 | if (this.$tableWrapper.find("."+this.scrollBarWrapClass).length) 726 | return true; 727 | 728 | return false; 729 | 730 | } 731 | 732 | /** 733 | * Unbind all events by same namespace 734 | */ 735 | FreezeTable.prototype.unbind = function() { 736 | 737 | this.$container.off('resize.'+this.namespace); 738 | this.$container.off('scroll.'+this.namespace); 739 | this.$tableWrapper.off('scroll.'+this.namespace); 740 | } 741 | 742 | /** 743 | * Destroy Freeze Table by same namespace 744 | */ 745 | FreezeTable.prototype.destroy = function() { 746 | 747 | this.unbind(); 748 | this.$tableWrapper.find("."+this.headWrapClass).remove(); 749 | this.$tableWrapper.find("."+this.columnWrapClass).remove(); 750 | this.$tableWrapper.find("."+this.columnHeadWrapClass).remove(); 751 | this.$tableWrapper.find("."+this.scrollBarWrapClass).remove(); 752 | } 753 | 754 | /** 755 | * Resize trigger for current same namespace 756 | */ 757 | FreezeTable.prototype.resize = function() { 758 | 759 | this.$container.trigger('resize.'+this.namespace); 760 | this.$container.trigger('scroll.'+this.namespace); 761 | this.$tableWrapper.trigger('scroll.'+this.namespace); 762 | 763 | return true; 764 | } 765 | 766 | /** 767 | * Update for Dynamic Content 768 | */ 769 | FreezeTable.prototype.update = function() { 770 | 771 | // Same as re-new object 772 | this.options = 'update'; 773 | this.init(); 774 | return this; 775 | } 776 | 777 | /** 778 | * Interface 779 | */ 780 | // Class for single element 781 | window.FreezeTable = FreezeTable; 782 | // jQuery interface 783 | $.fn.freezeTable = function (options) { 784 | 785 | // Single/Multiple mode 786 | if (this.length === 1) { 787 | 788 | return new FreezeTable(this, options) 789 | } 790 | else if (this.length > 1) { 791 | 792 | var result = []; 793 | // Multiple elements bundle 794 | this.each(function () { 795 | result.push(new FreezeTable(this, options)); 796 | }); 797 | 798 | return result; 799 | } 800 | 801 | return false; 802 | } 803 | 804 | })(jQuery, window); 805 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | yidas/jquery-freeze-table Demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 22 | 23 | 24 | 25 |
26 |
27 | 37 |

jQuery Freeze Table

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 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 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 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 |
CompanyLast TradeTrade TimeChangePrev CloseOpenBidAsk1y Target EstLoremIpsum
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
235 |
236 | 237 |
238 | 239 |
240 |
Example Code
241 |
242 |
$(".table-basic").freezeTable();
243 |
244 |
245 | 246 | 247 |
248 | 249 |
Scrollable Table
250 | 251 |
252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 |
CompanyLast TradeTrade TimeChangePrev CloseOpenBidAsk1y Target EstLoremIpsum
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
446 |
447 | 448 |
449 | 450 |
451 |
Example Code
452 |
453 |
$(".table-scrollable").freezeTable({
 454 |   'scrollable': true,
 455 | });
456 |
457 |
458 | 459 | 460 |
461 | 462 |
Table in Bootstrap Modal
463 | 464 |

The freezeHead may has the transparent problem with some browser.

465 | 466 | 467 |
468 | 471 | 472 |
473 | 474 | 475 | 476 | 867 | 868 |
869 | 870 |
871 |
Example Code
872 |
873 |
$('#table-modal').one('shown.bs.modal', function (e) {
 874 | 
 875 |   $(this).find(".table-modal").freezeTable({
 876 |     'container': '#table-modal.modal',
 877 |   });
 878 | });
879 |
880 |
881 | 882 | 883 |
884 | 885 |
Freeze Column(s) only
886 |
887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 |
#DateTextBank (1930)Eget kapital John Doe (2010)Eget kapital Jane Doe (2020)Utgående moms 25 % (2610)Moms varuförvärv EU 25 % (2615)Ingående moms 25 % (2640)Ingående moms utland (2645)Moms redovisningskonto (2650)Momspliktiga intäkter (3000)Inköp varor EU 25 % (4056)Förbrukningsinventarier (5400)Kontorsmaterial och trycksaker (6100)Övriga externa tjänster (6500)Bankavgifter (6570)Årets resultat (8999)
CreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebit
12014-01-11Office stuff100 SEK25 SEK75 SEK
22014-02-12iPad5000 SEK1250 SEK3750 SEK
32014-03-20Office stuff100 SEK25 SEK75 SEK
42014-04-11iPhone7000 SEK1750 SEK5250 SEK
12 200 SEK3050 SEK8000 SEK150 SEK
1122 |
1123 |
1124 | 1125 |
1126 |
Example Code
1127 |
1128 |
$(".table-columns-only").freezeTable({
1129 |   'freezeHead': false,
1130 | });
1131 |
1132 |
1133 | 1134 | 1135 |
1136 | 1137 |
Freeze Head only
1138 |
1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1185 | 1186 | 1187 | 1188 | 1189 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | 1196 | 1197 | 1198 | 1199 | 1200 | 1201 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1220 | 1221 | 1222 | 1223 | 1224 | 1225 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | 1232 | 1233 | 1234 | 1235 | 1236 | 1237 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | 1248 | 1249 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | 1256 | 1257 | 1258 | 1259 | 1260 | 1261 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | 1268 | 1269 | 1270 | 1271 | 1272 | 1273 | 1274 | 1275 | 1276 | 1277 | 1278 | 1279 | 1280 | 1281 | 1282 | 1283 | 1284 | 1285 | 1286 | 1287 | 1288 | 1289 | 1290 | 1291 | 1292 | 1293 | 1294 | 1295 | 1296 | 1297 | 1298 | 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | 1305 | 1306 | 1307 | 1308 | 1309 | 1310 | 1311 | 1312 | 1313 | 1314 | 1315 | 1316 | 1317 | 1318 | 1319 | 1320 | 1321 | 1322 | 1323 | 1324 | 1325 | 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 |
CompanyLast TradeTrade TimeChangePrev CloseOpenBidAsk1y Target EstLoremIpsum
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
1333 |
1334 | 1335 |
1336 | 1337 |
1338 |
Example Code
1339 |
1340 |
$(".table-head-only").freezeTable({
1341 |   'freezeColumn': false,
1342 | });
1343 |
1344 |
1345 | 1346 | 1347 |
1348 | 1349 |
Multi-Columns Freeze Table
1350 |
1351 | 1352 | 1353 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1360 | 1361 | 1362 | 1363 | 1364 | 1365 | 1366 | 1367 | 1368 | 1369 | 1370 | 1371 | 1372 | 1373 | 1374 | 1375 | 1376 | 1377 | 1378 | 1379 | 1380 | 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | 1389 | 1390 | 1391 | 1392 | 1393 | 1394 | 1395 | 1396 | 1397 | 1398 | 1399 | 1400 | 1401 | 1402 | 1403 | 1404 | 1405 | 1406 | 1407 | 1408 | 1409 | 1410 | 1411 | 1412 | 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | 1421 | 1422 | 1423 | 1424 | 1425 | 1426 | 1427 | 1428 | 1429 | 1430 | 1431 | 1432 | 1433 | 1434 | 1435 | 1436 | 1437 | 1438 | 1439 | 1440 | 1441 | 1442 | 1443 | 1444 | 1445 | 1446 | 1447 | 1448 | 1449 | 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | 1458 | 1459 | 1460 | 1461 | 1462 | 1463 | 1464 | 1465 | 1466 | 1467 | 1468 | 1469 | 1470 | 1471 | 1472 | 1473 | 1474 | 1475 | 1476 | 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | 1485 | 1486 | 1487 | 1488 | 1489 | 1490 | 1491 | 1492 | 1493 | 1494 | 1495 | 1496 | 1497 | 1498 | 1499 | 1500 | 1501 | 1502 | 1503 | 1504 | 1505 | 1506 | 1507 | 1508 | 1509 | 1510 | 1511 | 1512 | 1513 | 1514 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | 1522 | 1523 | 1524 | 1525 | 1526 | 1527 | 1528 | 1529 | 1530 | 1531 | 1532 | 1533 | 1534 | 1535 | 1536 | 1537 | 1538 | 1539 | 1540 | 1541 | 1542 | 1543 | 1544 | 1545 | 1546 | 1547 | 1548 | 1549 | 1550 | 1551 | 1552 | 1553 | 1554 | 1555 | 1556 | 1557 | 1558 | 1559 | 1560 | 1561 | 1562 | 1563 | 1564 | 1565 | 1566 | 1567 | 1568 | 1569 | 1570 | 1571 | 1572 | 1573 | 1574 | 1575 | 1576 | 1577 | 1578 | 1579 | 1580 | 1581 | 1582 | 1583 | 1584 | 1585 |
#DateTextBank (1930)Eget kapital John Doe (2010)Eget kapital Jane Doe (2020)Utgående moms 25 % (2610)Moms varuförvärv EU 25 % (2615)Ingående moms 25 % (2640)Ingående moms utland (2645)Moms redovisningskonto (2650)Momspliktiga intäkter (3000)Inköp varor EU 25 % (4056)Förbrukningsinventarier (5400)Kontorsmaterial och trycksaker (6100)Övriga externa tjänster (6500)Bankavgifter (6570)Årets resultat (8999)
CreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebit
12014-01-11Office stuff100 SEK25 SEK75 SEK
22014-02-12iPad5000 SEK1250 SEK3750 SEK
32014-03-20Office stuff100 SEK25 SEK75 SEK
42014-04-11iPhone7000 SEK1750 SEK5250 SEK
12 200 SEK3050 SEK8000 SEK150 SEK
1586 |
1587 |
1588 | 1589 |
1590 |
Example Code
1591 |
1592 |
$(".table-multi-columns").freezeTable({
1593 |   'columnNum' : 2,
1594 | });
1595 |
1596 |
1597 | 1598 | 1599 |
1600 | 1601 |
Shadow Enabled Table
1602 |
1603 | 1604 | 1605 | 1606 | 1607 | 1608 | 1609 | 1610 | 1611 | 1612 | 1613 | 1614 | 1615 | 1616 | 1617 | 1618 | 1619 | 1620 | 1621 | 1622 | 1623 | 1624 | 1625 | 1626 | 1627 | 1628 | 1629 | 1630 | 1631 | 1632 | 1633 | 1634 | 1635 | 1636 | 1637 | 1638 | 1639 | 1640 | 1641 | 1642 | 1643 | 1644 | 1645 | 1646 | 1647 | 1648 | 1649 | 1650 | 1651 | 1652 | 1653 | 1654 | 1655 | 1656 | 1657 | 1658 | 1659 | 1660 | 1661 | 1662 | 1663 | 1664 | 1665 | 1666 | 1667 | 1668 | 1669 | 1670 | 1671 | 1672 | 1673 | 1674 | 1675 | 1676 | 1677 | 1678 | 1679 | 1680 | 1681 | 1682 | 1683 | 1684 | 1685 | 1686 | 1687 | 1688 | 1689 | 1690 | 1691 | 1692 | 1693 | 1694 | 1695 | 1696 | 1697 | 1698 | 1699 | 1700 | 1701 | 1702 | 1703 | 1704 | 1705 | 1706 | 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | 1713 | 1714 | 1715 | 1716 | 1717 | 1718 | 1719 | 1720 | 1721 | 1722 | 1723 | 1724 | 1725 | 1726 | 1727 | 1728 | 1729 | 1730 | 1731 | 1732 | 1733 | 1734 | 1735 | 1736 | 1737 | 1738 | 1739 | 1740 | 1741 | 1742 | 1743 | 1744 | 1745 | 1746 | 1747 | 1748 | 1749 | 1750 | 1751 | 1752 | 1753 | 1754 | 1755 | 1756 | 1757 | 1758 | 1759 | 1760 | 1761 | 1762 | 1763 | 1764 | 1765 | 1766 | 1767 | 1768 | 1769 | 1770 | 1771 | 1772 | 1773 | 1774 | 1775 | 1776 | 1777 | 1778 | 1779 | 1780 | 1781 | 1782 | 1783 | 1784 | 1785 | 1786 | 1787 | 1788 | 1789 | 1790 | 1791 | 1792 | 1793 | 1794 | 1795 | 1796 |
CompanyLast TradeTrade TimeChangePrev CloseOpenBidAsk1y Target EstLoremIpsum
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
1797 |
1798 | 1799 |
1800 | 1801 |
1802 |
Example Code
1803 |
1804 |
$(".table-shadow").freezeTable({
1805 |   'shadow': true,
1806 | });
1807 |
1808 |
1809 | 1810 | 1811 |

1812 |
Customized Styles Table
1813 |
1814 | 1815 | 1816 | 1817 | 1818 | 1819 | 1820 | 1821 | 1822 | 1823 | 1824 | 1825 | 1826 | 1827 | 1828 | 1829 | 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | 1838 | 1839 | 1840 | 1841 | 1842 | 1843 | 1844 | 1845 | 1846 | 1847 | 1848 | 1849 | 1850 | 1851 | 1852 | 1853 | 1854 | 1855 | 1856 | 1857 | 1858 | 1859 | 1860 | 1861 | 1862 | 1863 | 1864 | 1865 | 1866 | 1867 | 1868 | 1869 | 1870 | 1871 | 1872 | 1873 | 1874 | 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | 1881 | 1882 | 1883 | 1884 | 1885 | 1886 | 1887 | 1888 | 1889 | 1890 | 1891 | 1892 | 1893 | 1894 | 1895 | 1896 | 1897 | 1898 | 1899 | 1900 | 1901 | 1902 | 1903 | 1904 | 1905 | 1906 | 1907 | 1908 | 1909 | 1910 | 1911 | 1912 | 1913 | 1914 | 1915 | 1916 | 1917 | 1918 | 1919 | 1920 | 1921 | 1922 | 1923 | 1924 | 1925 | 1926 | 1927 | 1928 | 1929 | 1930 | 1931 | 1932 | 1933 | 1934 | 1935 | 1936 |
#Group AGroup BGroup CGroup DGroup EGroup FGroup GGroup HGroup I
#Column A.1Column A.2Column B.1Column B.2Column C.1Column C.2Column D.1Column D.2Column E.1Column E.2Column F.1Column F.2Column G.1Column G.2Column H.1Column H.2Column I.1Column I.2
1Column A.1Column A.2Column B.1Column B.1Column C.1Column C.2Column D.1Column D.2Column E.1Column E.2Column F.1Column F.2Column G.1Column G.2Column H.1Column H.2Column I.1Column I.2
2Column AColumn AColumn BColumn BColumn CColumn CColumn DColumn DColumn EColumn EColumn FColumn FColumn GColumn GColumn HColumn HColumn IColumn I
3Column AColumn AColumn BColumn BColumn CColumn CColumn DColumn DColumn EColumn EColumn FColumn FColumn GColumn GColumn HColumn HColumn IColumn I
4Column AColumn AColumn BColumn BColumn CColumn CColumn DColumn DColumn EColumn EColumn FColumn FColumn GColumn GColumn HColumn HColumn IColumn I
1937 |
1938 |
1939 | 1940 |
1941 |
Example Code
1942 |
1943 |
$(".table-wrap-styles").freezeTable({
1944 |   'headWrapStyles': {'box-shadow': '0px 9px 10px -5px rgba(159, 159, 160, 0.8)'},
1945 | });
1946 |
1947 |
1948 | 1949 | 1950 |
1951 | 1952 |
Freeze Scroll Bar Table (Fixed on the bottom of the screen)
1953 |
1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 | 1961 | 1962 | 1963 | 1964 | 1965 | 1966 | 1967 | 1968 | 1969 | 1970 | 1971 | 1972 | 1973 | 1974 | 1975 | 1976 | 1977 | 1978 | 1979 | 1980 | 1981 | 1982 | 1983 | 1984 | 1985 | 1986 | 1987 | 1988 | 1989 | 1990 | 1991 | 1992 | 1993 | 1994 | 1995 | 1996 | 1997 | 1998 | 1999 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | 2006 | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | 2026 | 2027 | 2028 | 2029 | 2030 | 2031 | 2032 | 2033 | 2034 | 2035 | 2036 | 2037 | 2038 | 2039 | 2040 | 2041 | 2042 | 2043 | 2044 | 2045 | 2046 | 2047 | 2048 | 2049 | 2050 | 2051 | 2052 | 2053 | 2054 | 2055 | 2056 | 2057 | 2058 | 2059 | 2060 | 2061 | 2062 | 2063 | 2064 | 2065 | 2066 | 2067 | 2068 | 2069 | 2070 | 2071 | 2072 | 2073 | 2074 | 2075 | 2076 | 2077 | 2078 | 2079 | 2080 | 2081 | 2082 | 2083 | 2084 | 2085 | 2086 | 2087 | 2088 | 2089 | 2090 | 2091 | 2092 | 2093 | 2094 | 2095 | 2096 | 2097 | 2098 | 2099 | 2100 | 2101 | 2102 | 2103 | 2104 | 2105 | 2106 | 2107 | 2108 | 2109 | 2110 | 2111 | 2112 | 2113 | 2114 | 2115 | 2116 | 2117 | 2118 | 2119 | 2120 | 2121 | 2122 | 2123 | 2124 | 2125 | 2126 | 2127 | 2128 | 2129 | 2130 | 2131 | 2132 | 2133 | 2134 | 2135 | 2136 | 2137 | 2138 | 2139 | 2140 | 2141 | 2142 | 2143 | 2144 | 2145 | 2146 | 2147 | 2148 | 2149 | 2150 | 2151 | 2152 | 2153 | 2154 | 2155 | 2156 | 2157 | 2158 | 2159 | 2160 | 2161 | 2162 | 2163 | 2164 | 2165 | 2166 | 2167 | 2168 | 2169 | 2170 | 2171 | 2172 | 2173 | 2174 | 2175 | 2176 | 2177 | 2178 | 2179 | 2180 | 2181 | 2182 | 2183 | 2184 | 2185 | 2186 | 2187 | 2188 | 2189 | 2190 | 2191 | 2192 | 2193 | 2194 | 2195 | 2196 | 2197 | 2198 | 2199 | 2200 | 2201 | 2202 | 2203 | 2204 | 2205 | 2206 | 2207 | 2208 | 2209 | 2210 | 2211 | 2212 | 2213 | 2214 | 2215 | 2216 | 2217 | 2218 | 2219 | 2220 | 2221 | 2222 | 2223 | 2224 | 2225 | 2226 | 2227 | 2228 | 2229 | 2230 | 2231 | 2232 | 2233 | 2234 | 2235 | 2236 | 2237 | 2238 | 2239 | 2240 | 2241 | 2242 | 2243 | 2244 | 2245 | 2246 | 2247 | 2248 | 2249 | 2250 | 2251 | 2252 | 2253 | 2254 | 2255 | 2256 | 2257 | 2258 | 2259 | 2260 | 2261 | 2262 | 2263 | 2264 | 2265 | 2266 | 2267 | 2268 | 2269 | 2270 | 2271 | 2272 | 2273 | 2274 | 2275 | 2276 | 2277 | 2278 | 2279 | 2280 | 2281 | 2282 | 2283 | 2284 | 2285 | 2286 | 2287 | 2288 | 2289 | 2290 | 2291 | 2292 | 2293 | 2294 | 2295 | 2296 | 2297 | 2298 | 2299 | 2300 | 2301 | 2302 | 2303 | 2304 | 2305 | 2306 | 2307 | 2308 | 2309 | 2310 | 2311 | 2312 | 2313 | 2314 | 2315 | 2316 | 2317 | 2318 | 2319 | 2320 | 2321 | 2322 | 2323 | 2324 | 2325 | 2326 | 2327 | 2328 | 2329 | 2330 | 2331 | 2332 | 2333 | 2334 | 2335 | 2336 | 2337 | 2338 | 2339 | 2340 | 2341 | 2342 | 2343 | 2344 | 2345 | 2346 | 2347 | 2348 | 2349 | 2350 | 2351 | 2352 | 2353 | 2354 | 2355 | 2356 | 2357 | 2358 | 2359 | 2360 | 2361 | 2362 | 2363 | 2364 | 2365 | 2366 | 2367 | 2368 | 2369 | 2370 | 2371 | 2372 | 2373 | 2374 | 2375 | 2376 | 2377 | 2378 | 2379 | 2380 | 2381 | 2382 | 2383 | 2384 | 2385 | 2386 | 2387 | 2388 | 2389 | 2390 | 2391 | 2392 | 2393 | 2394 | 2395 | 2396 | 2397 | 2398 | 2399 | 2400 | 2401 | 2402 | 2403 | 2404 | 2405 | 2406 | 2407 | 2408 | 2409 | 2410 | 2411 |
CompanyLast TradeTrade TimeChangePrev CloseOpenBidAsk1y Target EstLoremIpsum
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
GOOG Google Inc.597.7412:12PM14.81 (2.54%)582.93597.95597.73 x 100597.91 x 300731.10Spanning cell
AAPL Apple Inc.378.9412:22PM5.74 (1.54%)373.20381.02378.92 x 300378.99 x 100505.94Spanning cell
AMZN Amazon.com Inc.191.5512:23PM3.16 (1.68%)188.39194.99191.52 x 300191.58 x 100240.32Spanning cell
ORCL Oracle Corporation31.1512:44PM1.41 (4.72%)29.7430.6731.14 x 650031.15 x 320036.11Spanning cell
MSFT Microsoft Corporation25.5012:27PM0.66 (2.67%)24.8425.3725.50 x 7110025.51 x 1780031.50Non-spanningNon-spanning
CSCO Cisco Systems, Inc.18.6512:45PM0.97 (5.49%)17.6818.2318.65 x 1030018.66 x 2400021.12Non-spanningNon-spanning
YHOO Yahoo! Inc.15.8112:25PM0.11 (0.67%)15.7015.9415.79 x 610015.80 x 1700018.16Non-spanningNon-spanning
2412 |
2413 |
2414 | 2415 |
2416 |
Example Code
2417 |
2418 |
$(".table-with-scrollbar").freezeTable({
2419 |   'scrollBar': true,
2420 | });
2421 |
2422 |
2423 | 2424 | 2425 |
2426 | 2427 | 2428 |
Freeze Column(s) Keep
2429 |

Freeze column(s) will always be displayed to support interactive table.

2430 |
2431 | 2432 | 2433 | 2434 | 2435 | 2436 | 2437 | 2438 | 2439 | 2440 | 2441 | 2442 | 2443 | 2444 | 2445 | 2446 | 2447 | 2448 | 2449 | 2450 | 2451 | 2452 | 2453 | 2454 | 2455 | 2456 | 2457 | 2458 | 2459 | 2460 | 2461 | 2462 | 2463 | 2464 | 2465 | 2466 | 2467 | 2468 | 2469 | 2470 | 2471 | 2472 | 2473 | 2474 | 2475 | 2476 | 2477 | 2478 | 2479 | 2480 | 2481 | 2482 | 2483 | 2484 | 2485 | 2486 | 2487 | 2488 | 2489 | 2490 | 2491 | 2492 | 2493 | 2494 | 2495 | 2496 | 2497 | 2498 | 2499 | 2500 | 2501 | 2502 | 2503 | 2504 | 2505 | 2506 | 2507 | 2508 | 2509 | 2510 | 2511 | 2512 | 2513 | 2514 | 2515 | 2516 | 2517 | 2518 | 2519 | 2520 | 2521 | 2522 | 2523 | 2524 | 2525 | 2526 | 2527 | 2528 | 2529 | 2530 | 2531 | 2532 | 2533 | 2534 | 2535 | 2536 | 2537 | 2538 | 2539 | 2540 | 2541 | 2542 | 2543 | 2544 | 2545 | 2546 | 2547 | 2548 | 2549 | 2550 | 2551 | 2552 | 2553 | 2554 | 2555 | 2556 | 2557 | 2558 | 2559 | 2560 | 2561 | 2562 | 2563 | 2564 | 2565 | 2566 | 2567 | 2568 | 2569 | 2570 | 2571 | 2572 | 2573 | 2574 | 2575 | 2576 | 2577 | 2578 | 2579 | 2580 | 2581 | 2582 | 2583 | 2584 | 2585 | 2586 | 2587 | 2588 | 2589 | 2590 | 2591 | 2592 | 2593 | 2594 | 2595 | 2596 | 2597 | 2598 | 2599 | 2600 | 2601 | 2602 | 2603 | 2604 | 2605 | 2606 | 2607 | 2608 | 2609 | 2610 | 2611 | 2612 | 2613 | 2614 | 2615 | 2616 | 2617 | 2618 | 2619 | 2620 | 2621 | 2622 | 2623 | 2624 | 2625 | 2626 | 2627 | 2628 | 2629 | 2630 | 2631 | 2632 | 2633 | 2634 | 2635 | 2636 | 2637 | 2638 | 2639 | 2640 | 2641 | 2642 | 2643 | 2644 | 2645 | 2646 | 2647 | 2648 | 2649 | 2650 | 2651 | 2652 | 2653 | 2654 | 2655 | 2656 | 2657 | 2658 | 2659 | 2660 | 2661 | 2662 | 2663 | 2664 | 2665 |
#SelectTextBank (1930)Eget kapital John Doe (2010)Eget kapital Jane Doe (2020)Utgående moms 25 % (2610)Moms varuförvärv EU 25 % (2615)Ingående moms 25 % (2640)Ingående moms utland (2645)Moms redovisningskonto (2650)Momspliktiga intäkter (3000)Inköp varor EU 25 % (4056)Förbrukningsinventarier (5400)Kontorsmaterial och trycksaker (6100)Övriga externa tjänster (6500)Bankavgifter (6570)Årets resultat (8999)
CreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebitCreditDebit
1Office stuff100 SEK25 SEK75 SEK
2iPad5000 SEK1250 SEK3750 SEK
3Office stuff100 SEK25 SEK75 SEK
4iPhone7000 SEK1750 SEK5250 SEK
12 200 SEK3050 SEK8000 SEK150 SEK
2666 |
2667 |
2668 | 2669 |
2670 |
Example Code
2671 |
2672 |
$(".table-column-keep").freezeTable({
2673 |   'columnNum': 2,
2674 |   'columnKeep': true,
2675 | });
2676 |
2677 |
2678 | 2679 | 2680 | 2681 | 2684 | 2685 |
2686 | 2687 | 2688 | 2689 | 2690 | 2740 | 2741 | 2742 | --------------------------------------------------------------------------------