jqGrid frozen header - javascript

We use latest version of free-jqgrid.
We want to make for all our grids fixed (frozen) header: verticall scrollbar insided the grid, which scrolls only the content.
As I know, this can be achieved using fixed grid's height, but it would be great to have the height fit to user's screen height. (May be we should change the size on page load somehow?)
What is the best way to implement this?
Example: https://jsfiddle.net/qrxkuvfz/1/
Setting width: 400 does bad job.
I just want the scroll to be inside the grid. And height - max available.

If I correctly understand your requirements, then you need just add `` option to jqGrid. For example, the modified demo https://jsfiddle.net/OlegKi/qrxkuvfz/2/ uses
rowNum: 15,
maxHeight: 330,
The maxHeight is large enough to display all 15 rows specified in rowNum, but if the user increase .
Alternatively you can use onPaging callback (see the wiki article), where you use setGridHeight method to set height option of jqGrid to some numeric value or to "auto" depend on the newRowNum and currentRowNum properties of the options parameter.

Basically, you can use your css to fix your headers (frozen), and use a bit of javascript/jquery to assign height to the tbody so that the table fits on to the screen.
Also add an overflow property to enable scrollbar in your css after the specific height.
Refer code:
$("tbody").height($(window).innerHeight() + "px");
table {
position: relative;
width: 700px;
background-color: #aaa;
overflow: hidden;
border-collapse: collapse;
}
/*thead*/
thead {
position: relative;
display: block;
/*seperates the header from the body allowing it to be positioned*/
width: 700px;
overflow: visible;
}
thead th {
background-color: #99a;
min-width: 120px;
height: 36px;
min-height: 36px;
border: 1px solid #222;
}
thead th:nth-child(1) {
/*first cell in the header*/
position: relative;
display: block;
background-color: #88b;
}
/*tbody*/
tbody {
display: block;
width: 700px;
overflow-y: auto;
}
tbody td {
background-color: #bbc;
min-width: 120px;
border: 1px solid #222;
height: 36px;
min-height: 36px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<table>
<thead>
<tr>
<th>Name</th>
<th>Town</th>
<th>County</th>
<th>Age</th>
<th>Profession</th>
<th>Anual Income</th>
<th>Matital Status</th>
<th>Children</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Smith</td>
<td>Macelsfield</td>
<td>Cheshire</td>
<td>52</td>
<td>Brewer</td>
<td>£47,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>Jenny Jones</td>
<td>Threlkeld</td>
<td>Cumbria</td>
<td>34</td>
<td>Shepherdess</td>
<td>£28,000</td>
<td>Single</td>
<td>0</td>
</tr>
<tr>
<td>Peter Frampton</td>
<td>Avebury</td>
<td>Wiltshire</td>
<td>57</td>
<td>Musician</td>
<td>£124,000</td>
<td>Married</td>
<td>4</td>
</tr>
<tr>
<td>Simon King</td>
<td>Malvern</td>
<td>Worchestershire</td>
<td>48</td>
<td>Naturalist</td>
<td>£65,000</td>
<td>Married</td>
<td>2</td>
</tr>
<tr>
<td>Lucy Diamond</td>
<td>St Albans</td>
<td>Hertfordshire</td>
<td>67</td>
<td>Pharmasist</td>
<td>Retired</td>
<td>Married</td>
<td>3</td>
</tr>
<tr>
<td>Austin Stevenson</td>
<td>Edinburgh</td>
<td>Lothian</td>
<td>36</td>
<td>Vigilante</td>
<td>£86,000</td>
<td>Single</td>
<td>Unknown</td>
</tr>
<tr>
<td>Wilma Rubble</td>
<td>Bedford</td>
<td>Bedfordshire</td>
<td>43</td>
<td>Housewife</td>
<td>N/A</td>
<td>Married</td>
<td>1</td>
</tr>
<tr>
<td>Kat Dibble</td>
<td>Manhattan</td>
<td>New York</td>
<td>55</td>
<td>Policewoman</td>
<td>$36,000</td>
<td>Single</td>
<td>1</td>
</tr>
<tr>
<td>Henry Bolingbroke</td>
<td>Bolingbroke</td>
<td>Lincolnshire</td>
<td>45</td>
<td>Landowner</td>
<td>Lots</td>
<td>Married</td>
<td>6</td>
</tr>
<tr>
<td>Alan Brisingamen</td>
<td>Alderley</td>
<td>Cheshire</td>
<td>352</td>
<td>Arcanist</td>
<td>A pile of gems</td>
<td>Single</td>
<td>0</td>
</tr>
</tbody>
</table>
</body>

Related

How to Fix the TD elements of first column of the table body while the rows are scrolling?

The title is not clear, I know. Let me explain what I mean:
First column has td elements which have varying rowspans. What I want is to keep the td text in first column 'fixed' at the top while scrolling down.
But only as long as the rest of the td elements in the remaining columns are in scope.
Once all the rows (which the first column cell is spanning) is out of table view, the td element should scroll out of the view and the next td should now start fixing.
After Scrolling a bit:
And after All the animal rows are scrolled out, the fixed 'Animal' td would also go up and then 'Cars' would be fixed and then Hats would be fixed like this:
I got it working by setting
vertical-align: top; for the element
and created a div under the td element which contains the actual value for the cell
then applied position: sticky; top:0; z-index: 1; to the div.
Working fiddle: https://jsfiddle.net/ankitkraken/yw0jhzpu/1/
HTML:
<td class="td-class-name" rowspan="3">
<div class="level-1">
"Cars"
</div>
</td>
CSS:
.td-class-names{
vertical-align: top;
}
.level-1{
position: sticky ;
top: 80px;
z-index: -1;
}
I had to use top: 80px;, top:0; was putting the td contents BEHIND the sticky table header.
You can acheive this result with the sticky positioning:
thead tr:first-of-type {
position: sticky;
top: 0px;
z-index: 10;
}
thead tr:first-of-type th {
background: yellow;
}
th {
border: 1px solid;
padding: 6px;
}
td {
border: 1px solid;
padding: 6px;
}
th[rowspan]>.box {
vertical-align: top;
position: sticky;
top: 34px;
}
th[rowspan][data-order='first'] {
background: orange;
}
th[rowspan][data-order='second'] {
background: green;
}
th[rowspan][data-order='third'] {
background: indianred;
}
th[rowspan][data-order='fourth'] {
background: lightblue;
}
.main-container {
position: relative;
}
.table-container {
position: static;
max-height: 180px;
max-width: 350px;
;
overflow-y: scroll;
}
.fake {
width: 100%;
height: 100px;
}
<div class="main-container">
<div class='table-container'>
<table>
<thead>
<tr>
<th>CATEGORY</th>
<th>TYPE</th>
<th>NAME</th>
</tr>
</thead>
<tbody>
<tr>
<th data-order='first' rowspan='5'>
<div class='box'>Animals</div>
</th>
<td>Dog</td>
<td>Bob</td>
</tr>
<tr>
<td>Dog</td>
<td>Flash</td>
</tr>
<tr>
<td>Cat</td>
<td>Mimi</td>
</tr>
<tr>
<td>Dog</td>
<td>Casper</td>
</tr>
<tr>
<td>Horse</td>
<td>Wind Lady</td>
</tr>
<tr>
<th data-order='second' rowspan='5'>
<div class='box'>Cars</div>
</th>
<td>Chrysler</td>
<td>Ann</td>
</tr>
<tr>
<td>Dodge</td>
<td>Christine</td>
</tr>
<tr>
<td>Ford</td>
<td>Foo</td>
</tr>
<tr>
<td>Ferrari</td>
<td>Dandy</td>
</tr>
<tr>
<td>Mercedes</td>
<td>A200</td>
</tr>
<tr>
<th data-order='third' rowspan='5'>
<div class='box'>Food</div>
</th>
<td>Apple</td>
<td>George</td>
</tr>
<tr>
<td>Banana</td>
<td>Rocco</td>
</tr>
<tr>
<td>Strawberry</td>
<td>Liza</td>
</tr>
<tr>
<td>Ananas</td>
<td>Ted</td>
</tr>
<tr>
<td>Avocado</td>
<td>Gary</td>
</tr>
<tr>
<th data-order='fourth' rowspan='5'>
<div class='box'>Phones</div>
</th>
<td>Iphone XXI</td>
<td>ObiWan</td>
</tr>
<tr>
<td>Nokia 8110</td>
<td>Neo</td>
</tr>
<tr>
<td>Ericsson</td>
<td>Dr. Who</td>
</tr>
<tr>
<td>Huawei Mate 40</td>
<td>Dead or Alive</td>
</tr>
<tr>
<td>Xiaomi</td>
<td>Ping</td>
</tr>
</tbody>
</table>
<div class='fake'>
</div>
</div>
</div>
Sticky positioning is not always straightforward, expecially when dealing with overflow properties and display: table. Here are some useful resources about these topics:
Position: stuck; — and a way to fix it
CSS Position Sticky - How It Really Works!
Creating sliding effects using sticky positioning
Position Sticky on <td> with colspan?

Horizontal scrolling for some columns in a table?

Within a table I need to 'pin' a column in place and have other other colums horizontally scrollable. Here is a visual example:
I tried using overflow scroll but it appears to do nothing:
.horizontal-scrolling {
display: flex;
width: 500px;
overflow: scroll;
}
.horizontal-scrolling th {
width: 250px;
}
<table>
<thead>
<tr>
<th>First</th>
<span class="horizontal-scrolling">
<th>Second</th>
<th>Third</th>
<th>Fourth</th>
</span>
</tr>
<thead>
</table>
I've modified the w3schools standart table, to where one column sticks to the left. this kind of styling can be applied to a specific column of your table by javascript
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 1000px;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
tr th:nth-of-type(1),/*this is where the table column gets its*/
tr td:nth-of-type(1){/*styling to stick to the left and stay ontop of the rest*/
position:sticky;
left: 0;
z-index: 1;
background: white;
width: 150px
}
div {
width: 600px;
overflow: auto;
}
<body>
<h2>HTML Table</h2>
<div>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</table>
</div>
</body>

How to apply inner border in html tables

I have html tables,and I would like to click each cells and change it's classes to outpatient
td, th {
border: 5px ;
cursor: pointer;
padding: 2.5px;*/
position: relative;
}
.outpatient {
background-color: rgb(0,255,0);
border: 5px solid aqua;
}
When I tried this class the result is like below.
It seems border is not collapsed and some cells are distorted.
https://gyazo.com/a6e5ef991b345934c070ed77d8949305
I guess it must be inner bordered to it's cells.
How can I fix it?
Thanks
I hope that you will agree with it. Thanks
$(function() {
$("td").click(function() {
$(this).addClass('outpatient');
});
});
td, th {
border:1px solid #ccc;
cursor: pointer;
padding: 2.5px;
position: relative;
text-align:center;
box-sizing:border-box;
}
.outpatient {
background-color: rgb(0,255,0);
outline: 3px solid #546565;
outline-offset: -4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>4</td>
<td>5</td>
<td>6</td>
</tr>
<tr>
<td>7</td>
<td>8</td>
<td>9</td>
</tr>
<tr>
<td>10</td>
<td>11</td>
<td>12</td>
</tr>
<tr>
<td>13</td>
<td>14</td>
<td>15</td>
</tr>
<tr>
<td>16</td>
<td>17</td>
<td>18</td>
</tr>
</table>
You can set to the td, th style box-sizing:border-box and it will make the border to be in the inner width, and not the outer. as I understand, it is what you looking for
set a 5px border for cells and test it now!
td, th {
border:5px solid transparent;
}

Freeze first row and first column of table

I am trying to freeze/lock the first row and the first column of a table.
I have tried giving thead position: absolute; or position: fixed; but it looks strange.
I have followed some answers but I am still confused how to make it.
My HTML / CSS Code :
th {
font-size: 80%;
text-align: center;
}
td {
font-size : 65%;
white-space: pre;
text-align: center;
}
.inner {
overflow-x: scroll;
overflow-y: scroll;
width: 300px;
height: 100px;
}
input {
font-size : 65%;
}
<body>
<div class="inner">
<form method="POST" action="dashboard">
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Tanggal</th>
<th>Judul Pekerjaan</th>
<th>Deskripsi</th>
<th>Level</th>
<th>Category</th>
<th>Severity</th>
</tr>
</thead>
</form>
<tbody>
<tr>
<td>1</td>
<td>1 May 2017</td>
<td>Satu</td>
<td>Satu</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
</tbody>
</table>
</div>
</body>
Freeze First Row
Freezing the first row can be done with CSS by setting the table body to overflow: auto, and giving a fixed width to the table cells. (See example 1)
Freeze First Row & First Column
However, to get this behavior for both first row and first column, you need to separate the first row, first column, and first cell from the table, and then continuously set the position of these elements based on the scrolled position of the table body, upon a scroll event. (See example 2)
Example 1: (Freeze first row only)
table thead tr {
display: block;
}
table th, table td {
width: 80px;
}
table tbody {
display: block;
height: 90px;
overflow: auto;
}
th {
text-align: center;
}
td {
text-align: center;
white-space: pre;
}
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Tanggal</th>
<th>Judul Pekerjaan</th>
<th>Deskripsi</th>
<th>Level</th>
<th>Category</th>
<th>Severity</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1 May 2017</td>
<td>Satu</td>
<td>Satu</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
</tbody>
</table>
Example 2: (Freeze first row and first column)
$(document).ready(function() {
$('tbody').scroll(function(e) {
$('thead').css("left", -$("tbody").scrollLeft());
$('thead th:nth-child(1)').css("left", $("tbody").scrollLeft()-5);
$('tbody td:nth-child(1)').css("left", $("tbody").scrollLeft()-5);
});
});
body {
margin: 0;
}
th, td {
text-align: center;
background-color: white
}
table {
position: relative;
width: 400px;
overflow: hidden;
}
thead {
position: relative;
display: block;
width: 400px;
overflow: visible;
}
thead th {
min-width: 80px;
height: 40px;
}
thead th:nth-child(1) {
position: relative;
display: block;
height: 40px;
padding-top: 20px;
}
tbody {
position: relative;
display: block;
width: 400px;
height: 90px;
overflow: scroll;
}
tbody td {
min-width: 80px;
}
tbody tr td:nth-child(1) {
position: relative;
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Tanggal</th>
<th>Judul Pekerjaan</th>
<th>Deskripsi</th>
<th>Level</th>
<th>Category</th>
<th>Severity</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1 May 2017</td>
<td>Satu</td>
<td>Satu</td>
<td>5</td>
<td>Lorem</td>
<td>Ipsum</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>2</td>
<td>2 May 2017</td>
<td>Dua</td>
<td>Dua</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
<tr>
<td>3</td>
<td>3 May 2017</td>
<td>Tiga</td>
<td>Tiga</td>
</tr>
</tbody>
</table>
If anyone struggles with such problem here is a solution for modern browsers without using jQuery or even JS - just pure HTML and CSS.
The trick is to set table to relative position and first row and/or column cells to sticky position. I added explicitly background color and z-index values to have this overlapping feeling.
.wrapper {
overflow: auto;
height: 100px;
width: 200px;
}
table {
position: relative;
border-collapse: separate;
border-spacing: 0;
}
table th,
table td {
width: 50px;
padding: 5px;
background-color: white;
}
table tbody {
height: 90px;
}
table th {
text-align: center;
position: sticky;
top: 0;
z-index: 2;
}
table th:nth-child(1) {
left: 0;
z-index: 3;
}
table td {
text-align: center;
white-space: pre;
}
table tbody tr td:nth-child(1) {
position: sticky;
left: 0;
z-index: 1;
}
<div class="wrapper">
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
<th>Country</th>
<th>Hobbies</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>George</td>
<td>43</td>
<td>New Zealand</td>
</tr>
<tr>
<td>2</td>
<td>Ann</td>
<td>25</td>
<td>Great Britain</td>
</tr>
<tr>
<td>3</td>
<td>Alexander</td>
<td>41</td>
<td>Spain</td>
</tr>
<tr>
<td>4</td>
<td>Wasilij</td>
<td>63</td>
<td>Ukraine</td>
</tr>
<tr>
<td>1</td>
<td>George</td>
<td>43</td>
<td>New Zealand</td>
</tr>
<tr>
<td>1</td>
<td>George</td>
<td>43</td>
<td>New Zealand</td>
</tr>
<tr>
<td>1</td>
<td>George</td>
<td>43</td>
<td>New Zealand</td>
</tr>
</tbody>
</table>
</div>
I resoved this issue from myself with my colleague together yesterday. The adapted CSS is:
.pcvBody {
overflow-x: auto;
width: calc(100vw - 110px);
}
/* CSS START for freezing table column*/
#prodTable {
position: relative;
overflow: hidden;
}
#prodTable thead {
position: relative;
display: block;
overflow: visible;
}
#prodTable thead th {
min-width: 150px;
width: 1000px;
}
#prodTable thead th:nth-child(1), #prodTable thead th:nth-child(2) {
position: relative;
/*display: block;*/
max-width: 150px;
width: 50px;
border-left: 1px solid #ededed;
}
#prodTable tbody {
position: relative;
display: block;
}
#prodTable tbody td {
min-width: 150px;
width: 1000px;
}
#prodTable tbody input {
max-width: 120px;
}
#prodTable tbody tr td:nth-child(1), #prodTable tbody tr td:nth-child(2) {
position: relative;
/*display: block;*/
background-color: white;
min-height: 20px;
max-width: 150px;
width: 50px;
border-left: 1px solid #ededed;
}
/* CSS END for freezing table column*/
And the adjusted scroll event is:
$('#pcvBody').scroll(function(e) {
var scrollLeft = $("#pcvBody").scrollLeft();
//$('#prodTable thead').css("left", -tbodyScrollLeft);
//$('#prodTable thead th:nth-child(1)').css("left", tbodyScrollLeft - 5);
//$('#prodTable tbody td:nth-child(1)').css("left", tbodyScrollLeft - 5);
$('#prodTable thead th:nth-child(1)').css("left", scrollLeft);
$('#prodTable tbody td:nth-child(1)').css("left", scrollLeft);
$('#prodTable thead th:nth-child(2)').css("left", scrollLeft);
$('#prodTable tbody td:nth-child(2)').css("left", scrollLeft);
});
And in addition, I added a 'div' to wrap the table.

Different width of column in the HTML table

I am trying to make the width of tds different in the HTML tale but I am unable to do so.
HTML Code
<table class="TFtable" border="1">
<tr>
<th >Heading1</th>
<th >Heading2</th>
<th >Heading3</th>
</tr>
<tr>
<td>Text jshdf hjkhsdk jhfkhds fkjhf sdjkh dsfkjh</td>
<td >Text</td>
<td >Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
</table>
CSS
.TFtable {
width: 50%;
border-collapse: collapse;
table-layout: fixed;
}
.TFtable tr {
padding: 7px;
border: #4e95f4 1px solid;
}
/* provide some minimal visual accomodation for IE8 and below */
.TFtable tr {
background: #FFFFFF;
}
/* Define the background color for all the ODD background rows */
.TFtable tr:nth-child(odd) {
background: #FFFFFF;
}
/* Define the background color for all the EVEN background rows */
.TFtable tr:nth-child(even) {
background: #BCCECE;
}
.TFtable td{
table-layout: fixed;
width: 20px;
height:auto;
overflow: auto;
}
Link to JSFiddle.
Here
You can use this HTML Code to make different td`s width without using CSS
<table border="1" width="100%;">
<tr>
<th >Heading1</th>
<th >Heading2</th>
<th >Heading3</th>
</tr>
<tr>
<td width="20%">Text jshdf hjkhsdk jhfkhds fkjhf sdjkh dsfkjh</td>
<td width="30%">Text</td>
<td width="50%">Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
<tr>
<td>Text</td>
<td>Text</td>
<td>Text</td>
</tr>
</table>

Categories

Resources