table with fixed first header and fixed column - javascript

I need to stress that this is about HORIZONTAL scrolling with THE FIRST COLUMN FIXED because most answers are giving me solutions to vertical scrolling.
Is it possible using pure css to have a table that scrolls horizontally but the first header and first column are fixed with the rest of the content scrollable?
For example if I had this table:
<table>
<thead>
<tr>
<th class="head1">Head 1</th>
<th class="head2">Head 2</th>
<th class="head2">Head 3</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col1">Col 1</td>
<td class="col2">Col 2</td>
<td class="col3">Col 3</td>
</tr>
</tbody>
</table>
The head1 and col1 would always be shown with the other columns scrollable.

This is what I was after. The example uses 2 tables that are floated left with an overflow applied to a div that wraps the right most table. Both tables are contained in a div with a fixed width.
<div class="table-container">
<div class="left">
<table>
...
</table>
</div>
<div class="right">
<table>
...
</table>
</div>
</div>
.table-container {
position: relative;
width: 600px;
height: 100%;
display: inline-block;
}
table {
float: left;
}
.right {
overflow: auto;
}

<table >
<tr>
<th>abc</th>
<th>xyz</th>
</tr>
<tr>
<td colspan="2">
<div style="height:50px; overflow:scroll;">
<table>
<tr>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
</tr>
<tr>
<td>3</td>
<td>3</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
Please check it. It may be work.

Related

Moving table rows from one table to another using Javascript

I've got 2 tables that I'm trying to shift rows between in HTML using JavaScript, but I'm not having much luck at the moment. I've tried plenty of solutions from here but none of them seem to be working for me at the moment!
Currently my HTML code is as per below
.container {
overflow: hidden
}
.tab {
float: left
}
.tab-btn {
margin: 50px
}
button {
display: block;
margin-bottom: 20px
}
<div class="container-fluid">
<div class="card-deck">
<div class="card">
<div class="card-body">
<h5 class="card-title">Manage Schools</h5>
<div class="container">
<div class="tab">
<table class="table table-sm table-hover" id="table1">
<tr>
<th>School ID</th>
<th>School Name</th>
<th>Select</th>
</tr>
<tr>
<td>1</td>
<td>School A</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>2</td>
<td>School B</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>3</td>
<td>School C</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>4</td>
<td>School D</td>
<td><input type="checkbox"></td>
</tr>
<tr>
<td>5</td>
<td>School E</td>
<td>
<input type="checkbox" "></td>
</tr>
<tr>
<td>6</td>
<td>School F</td>
<td><input type="checkbox "></td>
</tr>
</table>
</div>
<div class="tab tab-btn ">
<button>Add</button>
<button>Remove</button>
</div>
<div class="tab ">
<table class="table table-sm table-hover " id="table2 ">
<tr>
<th>School ID</th>
<th>School Name</th>
<th>Select</th>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
Ideally, once a row has been shifted from table1 to the table2, it can then be removed from the table2 using the remove button. Also being able to select multiple rows and moving them at the same time would be a huge advantage.
Any and all help with the JavaScript would be very much appreciated!

I have a requirement where I should have vertical scroll bar for complete table but horizontal scroll bar for middle column

document.getElementById("top").onscroll = function()
{
var div = document.getElementById("top").scrollTop;
var div1 = document.getElementById("top1").scrollTop;
var div2top = document.getElementById("d3").scrollTop;
var div2left = document.getElementById("d3").scrollLeft;
if(div>0){
c = document.getElementById("d3");
c.scrollTo(div2left, div);
}
var offsetHeight = 0;
var scrollHeight = 0;
}
.table-wrapper {
display:flex;
height:100px;
overflow-y:scroll;
box-sizing:border-box;
}
.innerdiv{
//height:200px;
height:100px;
display:flex;
}
.d{
//float:left;
// position:relative;
}
.d3{
position:absolute;
width:100px;
height:100px;
left:290px;
overflow-x:overlay;
overflow-y:none;
}
#d3::-webkit-scrollbar {
width: 0px;
height:5px;
background-color: #F5F5F5;
}
.d4{
margin-left:100px;
}
<div onscroll="scroll();" class="table-wrapper" id="top">
<div class="innerdiv" id="top1">
<div class="d d1">
<table>
<thead>
<tr>
<th>Heading1</th>
<th>Heading2</th>
</tr>
</thead>
<tbody>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
</tbody>
</table>
</div>
<div class="d d2">
<table>
<thead>
<tr>
<th>Heading3</th>
<th>Heading4</th>
</tr>
</thead>
<tbody>
<tr>
<td>cont3</td>
<td>cont4</td>
</tr>
<tr>
<td>cont3</td>
<td>cont4</td>
</tr>
<tr>
<td>cont3</td>
<td>cont4</td>
</tr>
<tr>
<td>cont3</td>
<td>cont4</td>
</tr>
<tr>
<td>cont3</td>
<td>cont4</td>
</tr>
<tr>
<td>cont3</td>
<td>cont4</td>
</tr>
</tbody>
</table>
</div>
<div class="d d3" id="d3">
<table>
<thead>
<tr>
<th>Heading5</th>
<th>Heading6</th>
</tr>
</thead>
<tbody>
<tr>
<td>cont5</td>
<td>cont6</td>
</tr>
<tr>
<td>cont5</td>
<td>cont6</td>
</tr>
<tr>
<td>cont5</td>
<td>cont6</td>
</tr>
<tr>
<td>cont5</td>
<td>cont6</td>
</tr>
<tr>
<td>cont5</td>
<td>cont6</td>
</tr>
<tr>
<td>cont5</td>
<td>cont6</td>
</tr>
</tbody>
</table>
</div>
<div class="d d4">
<table>
<thead>
<tr>
<th>Heading7</th>
<th>Heading8</th>
</tr>
</thead>
<tbody>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
<tr>
<td>cont1</td>
<td>cont2</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
My original requirement, http://jsfiddle.net/f7ht9gow/9/. But, I couldn't stop horizontal scrollbar div moving vertically. So, I tried doing it with pure js using some article though something went wrong with Horizontal scrolling and it is not moving. Can anybody help me? Here is the fiddle for vertical and horizontal scroll bars.
Than you all!
I check fiddle that you share, If I understand you correctly you want an horizontal scroll in the middle
just change this part of your CSS code overflow-x:scroll;
like this
.d3{
position:absolute;
width : 100px;
height : 100px;
left : 290px;
overflow-x:scroll;
overflow-y:none;
}

Freeze Multiple Rows & Multiple Columns of HTML Table

I have a HTML table which is generated by back-end (C#). I want to Fix the Header (2 Rows having Sale Type & Location) and First Two columns (Product Name & Description).
My table looks like the following:
The Header Row has a rowspan of 2 & the First Two columns(Under Description) also need to be freezed.
I have tried the following code:
<script>
$(document).ready(function() {
$('tbody').scroll(function(e) { //detect a scroll event on the tbody
/*
Setting the thead left value to the negative valule of tbody.scrollLeft will make it track the movement
of the tbody element. Setting an elements left value to that of the tbody.scrollLeft left makes it maintain it's relative position at the left of the table.
*/
$('thead').css("left", -$("tbody").scrollLeft()); //fix the thead relative to the body scrolling
$('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first cell of the header
$('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()); //fix the first column of tdbody
$('.firstrow').css("left", $("tbody").scrollLeft());
});
});
</script>
<table id="ContentPlaceHolder1_tbl_Currentday" class="table table-responsive ReportTbl table-bordered">
<tr class="firstrow">
<th colspan="2" rowspan="2">Description</th><th colspan="12">Daily Sales</th><th colspan="11">MONTH TO DATE SALES</th><th colspan="3">FORECAST</th><th colspan="12">AVAILABLE STOCK</th><th colspan="10">IN TRANSIT QUANTITY</th>
</tr>
<tr class="firstrow">
<th>PROD QTY</th><th>KHI</th><th>HYD</th><th>LHR</th><th>MUL</th><th>ISD</th><th>SUK</th><th>FSD</th><th>PSH</th><th>GUJ</th><th>QTA</th><th class="totaltd">TOTAL</th><th>KHI</th><th>HYD</th><th>LHR</th><th>MUL</th><th>ISD</th><th>SUK</th><th>FSD</th><th>PSH</th><th>GUJ</th><th>QTA</th><th class="totaltd">TOTAL</th><th>MTD</th><th>TOTAL</th><th class="totaltd">ACH%</th><th>FAC</th><th>KHI</th><th>HYD</th><th>LHR</th><th>MUL</th><th>ISD</th><th>SUK</th><th>FSD</th><th>PSH</th><th>GUJ</th><th>QTA</th><th class="totaltd">TOTAL</th><th>HYD</th><th>LHR</th><th>MUL</th><th>ISD</th><th>SUK</th><th>FSD</th><th>PSH</th><th>GUJ</th><th>QTA</th><th class="totaltd">TOTAL</th>
</tr><tr>
<td rowspan="3" style="font-weight:bold;"> AAMRUS</td><td> AAMRUS CANDY - (BAG) - (35X60) - (670)</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td class="totaltd">0</td><td>3,572</td><td>202</td><td>926</td><td>36</td><td>414</td><td>1,417</td><td>562</td><td>0</td><td>1,310</td><td>0</td><td class="totaltd">8,439</td><td>9,065</td><td>16,997</td><td class="totaltd">93.09%</td><td>2,426</td><td>432</td><td>531</td><td>0</td><td>167</td><td>651</td><td>327</td><td>243</td><td>4</td><td>0</td><td>36</td><td class="totaltd">2,391</td><td>0</td><td>0</td><td>0</td><td>0</td><td>152</td><td>304</td><td>0</td><td>228</td><td>0</td><td class="totaltd">684</td>
</tr><tr>
<td> AAMRUS CANDY - (BOX) - (70X30) - (1032)</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td class="totaltd">0</td><td>1,126</td><td>1,462</td><td>1,270</td><td>333</td><td>737</td><td>1,576</td><td>813</td><td>575</td><td>218</td><td>60</td><td class="totaltd">8,170</td><td>9,068</td><td>17,003</td><td class="totaltd">90.1%</td><td>4,872</td><td>723</td><td>590</td><td>964</td><td>522</td><td>613</td><td>597</td><td>634</td><td>441</td><td>646</td><td>74</td><td class="totaltd">5,804</td><td>0</td><td>441</td><td>252</td><td>252</td><td>315</td><td>126</td><td>252</td><td>0</td><td>0</td><td class="totaltd">1,638</td>
</tr><tr class="totaltd">
<td>Total</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>4,698</td><td>1,664</td><td>2,196</td><td>369</td><td>1,151</td><td>2,993</td><td>1,375</td><td>575</td><td>1,528</td><td>60</td><td>16,609</td><td>18,133</td><td>34,000</td><td>91.6%</td><td>7,298</td><td>1,155</td><td>1,121</td><td>964</td><td>689</td><td>1,264</td><td>924</td><td>877</td><td>445</td><td>646</td><td>110</td><td>8,195</td><td>0</td><td>441</td><td>252</td><td>252</td><td>467</td><td>430</td><td>252</td><td>228</td><td>0</td><td>2,322</td>
</tr>
</table>
it only freezed the First Column, NOR first Two columns, NOR first two Rows.
How can I achieve this please Help
thanks
Target output
Spreadsheet example of freezed multiple rows and columns
Box structure
Make a <div> container that will be the scrollable component. Make sure the <div> container has a fixed width and height, and should be smaller than the actual content.
Let B, C, and D be the freezed rows and columns.
Let A be the actual table content.
Make the components A, B, C, and D using the <table> tag.
HTML
<div id="container">
<table id="a">
<thead>
<tr>
<th>A1</th>
<th>A2</th>
<th>A3</th>
<th>A4</th>
</tr>
<tr>
<th>B1</th>
<th>B2</th>
<th>B3</th>
<th>B4</th>
</tr>
</thead>
<tbody>
<tr>
<td>C1</td>
<td>C2</td>
<td>C3</td>
<td>C4</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
<td>D3</td>
<td>D4</td>
</tr>
</tbody>
</table>
<table id="b">
<thead>
<tr>
<th>A1</th>
<th>A2</th>
<th>A3</th>
<th>A4</th>
</tr>
<tr>
<th>B1</th>
<th>B2</th>
<th>B3</th>
<th>B4</th>
</tr>
</thead>
</table>
<table id="c">
<thead>
<tr>
<th>A1</th>
<th>A2</th>
</tr>
<tr>
<th>B1</th>
<th>B2</th>
</tr>
</thead>
<tbody>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
<tr>
<td>D1</td>
<td>D2</td>
</tr>
</tbody>
</table>
<table id="d">
<thead>
<tr>
<th>A1</th>
<th>A2</th>
</tr>
<tr>
<th>B1</th>
<th>B2</th>
</tr>
</thead>
</table>
</div>
CSS
#container{
width:90px;
max-height:90px;
overflow: auto;
position: relative;
}
#a{
position: relative;
z-index: 1
}
#b{
background: #fff;
position: absolute;
top: 0px;
left: 0px;
z-index: 2
}
#c{
background: #fff;
position: absolute;
top: 0px;
left: 0px;
z-index: 2
}
#d{
background: #fff;
position: absolute;
top: 0px;
left: 0px;
z-index: 3
}
JavaScript / jQuery
$('#container').scroll(function(event) {
var scrolledX = $(this).scrollLeft();
var scrolledY = $(this).scrollTop();
$(this).find('#c').css('left',scrolledX+'px');
$(this).find('#b').css('top',scrolledY+'px');
$(this).find('#d').css('left',scrolledX+'px');
$(this).find('#d').css('top',scrolledY+'px');
});

Make first two columns sticky in a table

I need to make the first two columns sticky in a table having n number of columns each of dynamic width.
I had tried the below CSS
td:nth-child(1), td:nth-child(2){
position:sticky;
left:0px;
}
And then I had set the left position of second column in JS by calculating the width of first column
var width = $("table tr > td:nth-child(1)").outerWidth();
$("table.matrix_class tr > td:nth-child(2)").css('left', width);
Now I need to do all the stuff in CSS not in JS. How do I do that in pure CSS?
Additionally, how do you do this when the first column width is dynamic?
You can do sticky header with using this css.
live working demo
<div class="zui-wrapper">
<div class="zui-scroller">
<table class="zui-table">
<thead>
<tr>
<th class="zui-sticky-col">Name</th>
<th class="zui-sticky-col2">Number</th>
<th>Position</th>
<th>Height</th>
<th>Born</th>
<th>Salary</th>
<th>Prior to NBA/Country</th>
</tr>
</thead>
<tbody>
<tr>
<td class="zui-sticky-col">DeMarcus Cousins</td>
<td class="zui-sticky-col2">15</td>
<td>C</td>
<td>6'11"</td>
<td>08-13-1990</td>
<td>$4,917,000</td>
<td>Kentucky/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Isaiah Thomas</td>
<td class="zui-sticky-col2">22</td>
<td>PG</td>
<td>5'9"</td>
<td>02-07-1989</td>
<td>$473,604</td>
<td>Washington/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Ben McLemore</td>
<td class="zui-sticky-col2">16</td>
<td>SG</td>
<td>6'5"</td>
<td>02-11-1993</td>
<td>$2,895,960</td>
<td>Kansas/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Marcus Thornton</td>
<td class="zui-sticky-col2">23</td>
<td>SG</td>
<td>6'4"</td>
<td>05-05-1987</td>
<td>$7,000,000</td>
<td>Louisiana State/USA</td>
</tr>
<tr>
<td class="zui-sticky-col">Jason Thompson</td>
<td class="zui-sticky-col2">34</td>
<td>PF</td>
<td>6'11"</td>
<td>06-21-1986</td>
<td>$3,001,000</td>
<td>Rider/USA</td>
</tr>
</tbody>
</table>
</div>

How to apply css overflow property on specific content

I am applying overflow property for <form>, in form i used <legend>. Here the overflow is applying to whole form so if overflow needed scroll bar includes legend also. but I want the overflow has to be applying except legend tag. I mean in form along with legend i used table . I want overflow has to be apply only for table.
here is my fiddle,
http://jsfiddle.net/raghavendram040/z6jRX/1/
my html is,
<form>
<fieldset>
<legend> Menu</legend>
<table id="tab">
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
<tr>
<td>abc</td>
</tr>
</table>
</fieldset>
my css is,
form{
border: 1px #6A6A45 solid;
border-radius:6px;
height: 200px;
overflow: auto;
background-color:#efefef ;
margin-bottom: 17px;
}
to apply overflow I tried like this but it didnt worked
#tab{ overlow: auto }
How can I solve this can anyone help me in this.
Wrap your table in a div and apply overflow to that.
Have a fiddle!
HTML
<form>
<fieldset>
<legend> Menu</legend>
<div id="scroll">
<table id="tab">
<tr>
<td>abc</td>
</tr>
...
</table>
</div>
</fieldset>
</form>
CSS
#scroll {
overflow: scroll;
height: 140px;
}
You can wrap your table with a div element:
Working Demo
<div id="tab">
<table>
</table>
</div>

Categories

Resources