how to convert whole html design to pdf with javascript - html

I try to convert html design to pdf using this <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.3/jspdf.min.js"></script>
I tried to design table as i want,
the table looks in html like
but when i try to convert pdf it become
my html code
<div id="content">
<table id="example1" class="display table table-bordered table-striped row-
border order-column" cellspacing="0" width="auto">
<thead style="background-color: #b6b37e">
<tr>
<th>No</th>
<th>PO Number</th>
<th>Article Code</th>
<th>Description</th>
<th>Qty</th>
<th>Price</th>
<th>Discount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in listData">
<td>{{x.nomer}}</td>
<td>{{x.po_code}}</td>
<td>{{x.article_code}}</td>
<td>{{x.long_description}}</td>
<td>{{x.qty}}</td>
<td >{{x.price | number:0}}</td>
<td>{{x.discountpct}}</td>
</tr>
</tbody>
</table>
</div>
this my Javascript code
<script>
function onClick() {
var pdf = new jsPDF('p', 'pt', 'letter');
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 100 * 8.5;
var isi = document.getElementById("content");
pdf.fromHTML(isi);
pdf.save('Purchase_Order.pdf');
};
var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
</script>
how to make my pdf file same like html design?

Use html2canvas with jsPDF. Alone jsPDF can not keep css style.
You must need some plugin with jsPDF.
Below is working example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<button id="clickbind">Click</button>
<div id="content">
<table id="example1" class="display table table-bordered table-striped row-
border order-column" cellspacing="0" width="auto">
<thead style="background-color: #b6b37e">
<tr>
<th>No</th>
<th>PO Number</th>
<th>Article Code</th>
<th>Description</th>
<th>Qty</th>
<th>Price</th>
<th>Discount</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in listData">
<td>{{x.nomer}}</td>
<td>{{x.po_code}}</td>
<td>{{x.article_code}}</td>
<td>{{x.long_description}}</td>
<td>{{x.qty}}</td>
<td>{{x.price | number:0}}</td>
<td>{{x.discountpct}}</td>
</tr>
</tbody>
</table>
</div>
<script>
function onClick() {
html2canvas(document.body, {
onrendered: function(canvas) {
var img = canvas.toDataURL("image/png");
var doc = new jsPDF();
doc.addImage(img, 'JPEG', 20, 20);
doc.save('test.pdf');
}
});
};
var element = document.getElementById("clickbind");
element.addEventListener("click", onClick);
</script>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.0.272/jspdf.debug.js"></script>
<style>
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<input type="button" value="Print Div Contents" id="btnPrint" />
<div>
<table>
<tbody>
<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>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>
</tbody>
</table>
</div>
</form>
</body>
<script type="text/javascript">
$("#btnPrint").click(function () {
let doc = new jsPDF('p', 'pt', 'a4');
doc.addHTML(document.body, function () {
doc.save('testpoc.pdf');
});
});
</script>
</html>

Related

How to hover <td> that contain specific data

I need to display red background color in <td> that I hovered. For example, if I hovered 'Apple', then 'Apple' in all <td> shall be hovered same color as well. Currently can only hover one <td>Apple</td>.
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
td:hover{
background-color:red
}
html {
font-size: 24px;
}
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td>Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td>Apple</td>
</tr>
</table>
Codepen
You can do that with the help of jQuery. Try running the following snippet.
$('.apple').hover(
function(){
$('.apple').css({"background":"red"});
},function(){
$('.apple').css({"background":"white"});
})
$('.orange').hover(
function(){
$('.orange').css({"background":"orange"});
}
,function(){
$('.orange').css({"background":"white"});
}
)
$('.lemon').hover(
function(){
$('.lemon').css({"background":"yellow"});
}, function(){
$('.lemon').css({"background":"white"});
})
html {
font-size: 24px;
}
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
td span {
display: block;
}
td:hover span.apple {
background-color:red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td><span class="apple">Apple</span></td>
<td><span class="orange">Orange</span></td>
<td><span class="lemon">Lemon</span></td>
</tr>
<tr>
<td><span class="orange">Orange</span></td>
<td><span class="lemon">Lemon</span></td>
<td><span class="apple">Apple</span></td>
</tr>
</table>
This cannot be done with just HTML and CSS as CSS is not aware of content.
Using Javascript you can set CSS variables that in turn will set the background of a cell.
This snippet goes through each td element and sets the style background: var(--name of fruit) so for example all apple cells have the style="background: var(--apple);" added to them. Then when a td is hovered the JS sets the --apple to red and when the mouse moves out it sets it to transparent.
That way all those tds with background: var(--apple) get highlighted.
There is no need to iterate through all the cells in the table each time a hover takes place, you can do it by setting everything up once at the start.
function setHighlight(e) {
table.style.setProperty('--' + e.target.textContent, 'red');
}
function removeHighlight(e) {
table.style.setProperty('--' + e.target.textContent, 'transparent');
}
const table = document.querySelector('table');
const tds = document.querySelectorAll('td');
tds.forEach(td => {
td.addEventListener('mouseover', setHighlight);
td.style.backgroundColor = 'var(--' + td.textContent + ')';
});
tds.forEach(td => {
td.addEventListener('mouseout', removeHighlight);
});
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td>Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td>Apple</td>
</tr>
</table>
Add a class in every td and use JQuery.
See the example below.
$(document).ready(function(){
$("td.apple").hover(function(){
$(".apple").css("background-color", "red");
}, function(){
$(".apple").css("background-color", "white");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td class="apple">Apple</td>
<td class="apple">Apple</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td class="apple">Apple</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td class="apple">Apple</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>
If You don't want to add extra IDs and add jquery as dependency to Your code, You can use vanilla JS
// Get all TDs
const tds = Array.from(document.querySelectorAll("td"));
tds.map(td => {
// bind mouseenter to TDs to paint BG
td.addEventListener("mouseenter", (event) => {
const text = event.target.textContent;
// paint TDs with same text
tds.map(td => {
if(td.textContent === text) {
td.style.background = 'red';
}
});
});
// bind mouseleave to TDs to remove BG
td.addEventListener("mouseleave", (event) => {
tds.map(td => {
td.style.background = 'transparent';
});
})
});
Working example: https://codepen.io/ipasha/pen/eYRKxpP
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
.apple:hover{
background-color:red
}
html {
font-size: 24px;
}
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td class="apple">Apple</td>
<td>Orange</td>
<td>Lemon</td>
</tr>
<tr>
<td>Orange</td>
<td>Lemon</td>
<td class="apple">Apple</td>
</tr>
</table>
This is one way you can try:
html {
font-size: 24px;
}
table {
margin: 2rem;
}
th, td {
border: 1px solid #333;
}
td span {
display: block;
}
td:hover span.apple {
background-color:red
}
<h3>Table 1</h3>
<table>
<tr>
<th>Header 1.1</th>
<th>Header 1.2</th>
<th>Header 1.3</th>
</tr>
<tr>
<td><span class="apple">Apple</span></td>
<td><span>Orange</span></td>
<td><span>Lemon</span></td>
</tr>
<tr>
<td><span>Orange</span></td>
<td><span>Lemon</span></td>
<td><span class="apple">Apple</span></td>
</tr>
</table>

Counting values on click in table

I'm trying to make a table that when you click on it the clicked row turns green and the value that is in the table gets counted, right now it just counts the amount of rows clicked but I want to change this to the amount that is under the value.
$(function() {
var countEl = $("#count");
var countE2 = $("#Value")
var count = 0;
$('tbody tr').click(function() {
$(this).toggleClass("green-cell");
if ($(this).hasClass("green-cell")) {
count++;
} else {
count--;
}
countEl.html(count);
});
});
.green-cell {
background: rgb(29, 247, 0);
}
table {
border-collapse: collapse;
}
td,
th {
border: solid 1px #cccccc;
}
td,
th {
padding: 5px;
}
tbody tr {
cursor: pointer;
}
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
Count: <span id="count"> 0</span>
<br/><br/>
<table class="table " id="onclick">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>1</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>2</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>3</td>
</tr>
<tr>
<td>henk</td>
<td>janssen</td>
<td>4</td>
</tr>
<tr>
<td>piet</td>
<td>Paulisma</td>
<td>5</td>
</tr>
<tr>
<td>Theo</td>
<td>van gogh</td>
<td>6</td>
</tr>
<tr>
<td>Erik</td>
<td>Doerustig</td>
<td>7</td>
</tr>
<tr>
<td>Jan</td>
<td>de steen</td>
<td>8</td>
</tr>
</tbody>
</table>
</div>
</body>
Get the row's last TD element by using .eq( -1 )
Get it's .text() and use parseInt to convert string to integer:
$(function() {
var countEl = $("#count");
var countE2 = $("#Value")
var count = 0;
$('tbody tr').click(function() {
var $td = $(this).find("td").eq( -1 ); // Get desired row's cell
var tdVal = parseInt( $td.text(), 10); // Convert content string to integer
$(this).toggleClass("green-cell");
if ($(this).hasClass("green-cell")) {
count+= tdVal;
} else {
count-= tdVal;
}
countEl.html(count);
});
});
.green-cell {
background: rgb(29, 247, 0);
}
table {
border-collapse: collapse;
}
td,
th {
border: solid 1px #cccccc;
}
td,
th {
padding: 5px;
}
tbody tr {
cursor: pointer;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
Count: <span id="count"> 0</span>
<br/><br/>
<table class="table " id="onclick">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>1</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>2</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>3</td>
</tr>
<tr>
<td>henk</td>
<td>janssen</td>
<td>4</td>
</tr>
<tr>
<td>piet</td>
<td>Paulisma</td>
<td>5</td>
</tr>
<tr>
<td>Theo</td>
<td>van gogh</td>
<td>6</td>
</tr>
<tr>
<td>Erik</td>
<td>Doerustig</td>
<td>7</td>
</tr>
<tr>
<td>Jan</td>
<td>de steen</td>
<td>8</td>
</tr>
</tbody>
</table>
If I understand what your trying to do correctly, which is add the value found in the count column when you click a row you could do something like this:
var countEl = $("#count");
var countE2 = $("#Value")
var count = 0;
$('tbody tr').click(function() {
$(this).toggleClass("green-cell");
if ($(this).hasClass("green-cell")) {
count += parseInt($(this).find('td:last-of-type()').text());
} else {
count -= parseInt($(this).find('td:last-of-type()').text());
}
countEl.html(count);
});
Just change this:
$('tbody tr').click(function() {
$(this).toggleClass("green-cell");
if ($(this).hasClass("green-cell")) {
count++;
} else {
count--;
}
countEl.html(count);
});
To this:
$('tbody tr').click(function() {
$(this).toggleClass("green-cell");
var value = parseInt($(this).children("td:last").html());
if ($(this).hasClass("green-cell")) {
count +=value;
} else {
count -=value;
}
countEl.html(count);
});
We grab the last TD, the one with the value, and convert that to INT with parseInt
If I understand you correct you want to have the sum of all values of column "Count".
By now you're just increasing your local counter. Instead you need to get the value of the column Count and add it to your current value.
So basically you need to change your Javascript like this
$(function() {
var countEl = $("#count");
var countE2 = $("#Value")
var count = 0;
$('tbody tr').click(function() {
$(this).toggleClass("green-cell");
var curCount = parseInt($(this).find('td:last').text());
if ($(this).hasClass("green-cell")) {
count = count + curCount;
} else {
count = count - curCount;
}
countEl.html(count);
});
});
My jQuery is pretty rusty, but what you in essence want to do here is find your last table cell in the clicked row and add/subtract that instead of just incrementing/decrementing your counter.
let amount = Number.parseInt($el.children('td').last().text());
This line is saying that the amount is equal to an integer found at the last td of the clicked row. Then you would add it to your count, the only other complication is the need to subtract if the cell isn't active, it is generally good practice to avoid else conditions (helps remove catch all unexplained effects) so I edited the code to add in all cases and to make the number negative in the case of an inactive cell.
$(function() {
const $countEl = $('#count');
let count = 0;
$('tbody').on('click', 'tr', function() {
const $el = $(this);
let amount = Number.parseInt($el.children('td').last().text());
$el.toggleClass('green-cell')
if (!$el.hasClass('green-cell')) {
amount = -amount;
}
count += amount;
$countEl.text(count);
});
});
.green-cell {
background: rgb(29, 247, 0);
}
table {
border-collapse: collapse;
}
td,
th {
border: solid 1px #cccccc;
}
td,
th {
padding: 5px;
}
tbody tr {
cursor: pointer;
}
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
Count: <span id="count"> 0</span>
<br/><br/>
<table class="table " id="onclick">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>1</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>2</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>3</td>
</tr>
<tr>
<td>henk</td>
<td>janssen</td>
<td>4</td>
</tr>
<tr>
<td>piet</td>
<td>Paulisma</td>
<td>5</td>
</tr>
<tr>
<td>Theo</td>
<td>van gogh</td>
<td>6</td>
</tr>
<tr>
<td>Erik</td>
<td>Doerustig</td>
<td>7</td>
</tr>
<tr>
<td>Jan</td>
<td>de steen</td>
<td>8</td>
</tr>
</tbody>
</table>
</div>
</body>
You can grab the amount from the last cell from the row by using cells property of the <tr> element.
const amount = +this.cells[this.cells.length - 1].innerText;
if ($(this).hasClass("green-cell")) {
count += amount
} else {
count -= amount
}
Then, instead of incrementing or decrementing, use this value to add/subtract.
$(function() {
var countEl = $("#count");
var countE2 = $("#Value")
var count = 0;
$('tbody tr').click(function() {
$(this).toggleClass("green-cell");
const amount = +this.cells[this.cells.length - 1].innerText;
if ($(this).hasClass("green-cell")) {
count += amount
} else {
count -= amount
}
countEl.html(count);
});
});
.green-cell {
background: rgb(29, 247, 0);
}
table {
border-collapse: collapse;
}
td, th {
border: solid 1px #cccccc;
}
td, th {
padding: 5px;
}
tbody tr {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Count: <span id="count"> 0</span>
<table class="table " id="onclick">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>1</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>2</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>3</td>
</tr>
<tr>
<td>henk</td>
<td>janssen</td>
<td>4</td>
</tr>
<tr>
<td>piet</td>
<td>Paulisma</td>
<td>5</td>
</tr>
<tr>
<td>Theo</td>
<td>van gogh</td>
<td>6</td>
</tr>
<tr>
<td>Erik</td>
<td>Doerustig</td>
<td>7</td>
</tr>
<tr>
<td>Jan</td>
<td>de steen</td>
<td>8</td>
</tr>
</tbody>
</table>

How to get the selected row from a table in angularjs

I would like to get the values of a selected row from a table.This is what i tried so far and the attached plunkr. https://plnkr.co/edit/QDPh4q0hQdlW09orayyL?p=preview
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' +
document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x"src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr ng-click="getData()">
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</table>
</body>
It is better to iterate each person via ng-repeat and pass them to your function explicitly instead of hardcoding in HTML and so working with DOM:
$scope.people = [{
name: 'Jill',
lastName: 'Smith',
age: 50
},
....
]
$scope.getData = function(person) {
console.log('Selected person is ' + person.name);
}
<table style="width:100%">
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr ng-repeat='person in people' ng-click="getData(person)">
<td>{{person.name}}</td>
<td>{{person.lastName}}</td>
<td>{{person.age}}</td>
</tr>
</table>
angular.module("MyApp",[])
.controller("MyCtrl", function($scope){
var table = document.getElementsByTagName("table")[0];
var tbody = table.getElementsByTagName("tbody")[0];
tbody.onclick = function (e) {
e = e || window.event;
var data = [];
var target = e.srcElement || e.target;
while (target && target.nodeName !== "TR") {
target = target.parentNode;
}
if (target) {
var cells = target.getElementsByTagName("td");
for (var i = 0; i < cells.length; i++) {
data.push(cells[i].innerHTML);
}
}
alert(data);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<table border="1">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>
<tr>
<td>Eve</td>
<td>Jackson</td>
<td>94</td>
</tr>
<tr>
<td>John</td>
<td>Doe</td>
<td>80</td>
</tr>
</tbody>
</table>
</div>
</div>
Try this
$scope.getData=function(event){
console.log(event.target);
}
<tr ng-click="getData($event)">
<td>Jill</td>
<td>Smith</td>
<td>50</td>
</tr>

Semantic UI - Keep thead visible when scrolling tbody

I'm trying to figure out how to keep the table head visible when scrolling. Is there a setting in semantic ui for this? Or will I just have to use a non-semantic ui solution?
You'll need to view "Full page" to see the table correctly.
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.12.0/semantic.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/1.12.0/semantic.css" rel="stylesheet" />
<div style="height:200px;overflow:auto">
<table class="ui small celled striped table" sytle="width:100%">
<thead>
<tr>
<th>Date</th>
<th>Status</th>
<th>Facility Name</th>
<th>Phone</th>
</tr>
</thead>
<tbody data-bind="foreach:FollowupEntries">
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
<tr>
<td>Date</td>
<td>Status</td>
<td>Facility Name</td>
<td>Phone</td>
</tr>
</tbody>
</table>
</div>
I solved the problem with position: sticky, like this:
.ui.table thead tr:first-child > th {
position: sticky !important;
top: 0;
z-index: 2;
}
As #Stewartside suggested, this isn't current built into Semantic UI, but it has been discussed.
Though I don't recommend it if you really really want it to work even with hacks this should work for you:
<table class="semantic's class" style="margin-bottom:0px;border-bottom:none">
<thead>...</thead>
</table>
<table class="semantic's class" style="margin-top:0px; border-top: none">
<div style="overflow-y:scroll; height: YOUR-REQUIRED-HEIGHT">
<thead style="visible:hidden">...</thead>
<tbody>...</tbody>
</div>
</table>
This script will probably do the job for you. Just add the class "sticky" to your table tag and adjust the offset from the top:
$(document).ready(function(){
var tableTop = $('.sticky.table').offset().top;
$('.sticky.table').children('thead').children('tr').children('th').each( function() {
$(this).css({ width: $(this).outerWidth() });
});
$(window).scroll(function() {
var fromTop = $(window).scrollTop();
if($('.sticky.table').length > 0){
stickyTableHead(fromTop);
}
});
function stickyTableHead(fromTop){
if(fromTop > tableTop ){
$('.sticky.table').children('thead').css({'position': 'fixed', top: 0 });
}else{
$('.sticky.table').children('thead').css({'position': 'relative', top: 0});
}
};
});
Applying Ashkan's solution to any table.
table{
width:100%;
}
table,th,td{
border: 1px solid grey;
border-collapse: collapse;
}
thead {
background-color: grey;
position: sticky !important;
top: 0;
z-index: 2;
}
<div style="overflow: auto; height:100px;">
<table>
<thead>
<tr>
<th>ID</th>
<th>ONE</th>
<th>TWO</th>
<th>THREE</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>A</td><td>B</td><td>C</td>
</tr>
<tr>
<td>2</td><td>D</td><td>E</td><td>F</td>
</tr>
<tr>
<td>3</td><td>G</td><td>H</td><td>I</td>
</tr>
<tr>
<td>4</td><td>J</td><td>K</td><td>L</td>
</tr>
<tr>
<td>5</td><td>M</td><td>N</td><td>O</td>
</tr>
<tr>
<td>6</td><td>P</td><td>Q</td><td>R</td>
</tr>
<tr>
<td>7</td><td>S</td><td>T</td><td>U</td>
</tr>
<tr>
<td>8</td><td>V</td><td>W</td><td>X</td>
</tr>
<tr>
<td>9</td><td>Y</td><td>Z</td><td>0</td>
</tr>
</tbody>
</table>
</div>
Check out this JSFiddle, I think it is the kind of thing you're looking for.. specifically check out the CSS for the thead tag.
thead {
position: fixed;
top: 0;
left: 0;
background-color: white;
}

Expand table code using css and jquery

I have this html file to make a page that table can expand and collapse by click on + or - :
var $headers = $('.header').click(function() {
$(this).find('span').text(function(_, value) {
return value == '-' ? '+' : '-'
});
$(this).nextUntil('tr.header').slideToggle(100, function() {});
});
$headers.find('span').text('+')
$('table tr:not(.header)').hide()
table,
tr,
td,
th {
border: 1px solid black;
border-collapse: collapse;
}
tr.header {
cursor: pointer;
}
<table border="0">
<tr class="header">
<th colspan="2">Header <span>-</span>
</th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th colspan="2">Header <span>-</span>
</th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
I don't know what problem with my file ? It's not run
you have to write script on bottom like this -
<head>
<style type="text/css">
table, tr, td, th
{
border: 1px solid black;
border-collapse:collapse;
}
tr.header {
cursor:pointer;
}
</style>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<table border="0">
<tr class="header">
<th colspan="2">Header <span>-</span>
</th>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr class="header">
<th colspan="2">Header <span>-</span>
</th>
</tr>
<tr>
<td>date</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
<tr>
<td>data</td>
<td>data</td>
</tr>
</table>
<script type="text/javascript">
var $headers = $('.header').click(function () {
$(this).find('span').text(function (_, value) {
return value == '-' ? '+' : '-'
});
$(this).nextUntil('tr.header').slideToggle(100, function () {});
});
$headers.find('span').text('+')
$('table tr:not(.header)').hide()
</script>
<body>
or put your script inready function
like this:-
<script type="text/javascript">
$(document).ready(function(){
var $headers = $('.header').click(function () {
$(this).find('span').text(function (_, value) {
return value == '-' ? '+' : '-'
});
$(this).nextUntil('tr.header').slideToggle(100, function () {});
});
$headers.find('span').text('+')
$('table tr:not(.header)').hide()
})
</script>
all you need to do is put you code inside $(document).ready(function({}). check DEMO
$(document).ready(function(){
/// your code here
});
you can learn more about ready() function HERE