Fixing table header on webpage - css

I would like to know how to fix a table header even if we scroll down on a website and out of the table view.
I would like to use css style to do this. Thank you.
I would also like to know how to fix an element on a webpage so it always appears even when we scroll down. The image can be text. Use div and css

You would do something like this by tapping into the scroll event handler on window, and using another table with a fixed position to show the header at the top of the page.
Example:
var tableOffset = $("#table-1").offset().top;
var $header = $("#table-1 > thead").clone();
var $fixedHeader = $("#header-fixed").append($header);
$(window).bind("scroll", function() {
var offset = $(this).scrollTop();
if (offset >= tableOffset && $fixedHeader.is(":hidden")) {
$fixedHeader.show();
}
else if (offset < tableOffset) {
$fixedHeader.hide();
}
});
body { height: 1000px; }
#header-fixed {
position: fixed;
top: 0px; display:none;
background-color:white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="table-1">
<thead>
<tr>
<th>Header1</th>
<th>Header2</th>
<th>Header3</th>
</tr>
</thead>
<tbody>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
<tr>
<td>info</td>
<td>info</td>
<td>info</td>
</tr>
</tbody>
</table>
<table id="header-fixed"></table>

Taken from an old post of mine, here's an example of both things that you want done together in one fiddle.
JSFiddle
JQuery:
function moveScroll() {
var scroll = $('#table-container').offset().top;
var anchor_top = $("#maintable").offset().top;
var anchor_bottom = $("#bottom_anchor").offset().top;
if (scroll > anchor_top && scroll < anchor_bottom) {
clone_table = $("#clone");
if (clone_table.length === 0) {
clone_table = $("#maintable").clone();
clone_table.attr({
id: "clone"
}).css({
position: "fixed",
"pointer-events": "none",
left: $("#maintable").offset().left + 'px',
top: 130
}).width($("#maintable").width());
$("#table-container").append(clone_table);
$("#clone").width($("#maintable").width());
$("#clone thead").css({
visibility: "true"
});
$("#clone tbody").css({
visibility: "hidden"
});
var footEl = $("#clone tfoot");
if (footEl.length) {
footEl.css({
visibility: "hidden"
});
}
}
} else {
$("#clone").remove();
}
}
$('#table-container').scroll(moveScroll);

Related

Table td style for CSS

I would like my TD text to move a bit but so far I am only able to text align left, center, right:
<div class= "col-md-7" id = "recyclable-list">
<table class="table">
<thead>
<tr>
<th style=" padding-left:25px;";>RecyclableID</th>
<th style=" padding-left:100px;">Name</th>
<th style=" text-align: center;">RecyclableType</th>
</tr>
</thead>
<tbody id="recycleTable">
</tbody>
</table>
This is my script call for the database:
var myarray = [];
$.ajax({
url:"https://ecoexchange.dscloud.me:8080/api/get",
method:"GET",
// In this case, we are going to use headers as
headers:{
// The query you're planning to call
// i.e. <query> can be UserGet(0), RecyclableGet(0), etc.
query:"RecyclableGet(0)",
// Gets the apikey from the sessionStorage
apikey:sessionStorage.getItem("apikey")
},
success:function(data,xhr,textStatus) {
myarray = data;
buildTable(myarray);
console.log(myarray);
},
error:function(xhr,textStatus,err) {
console.log(err);
}
});
function buildTable(data) {
var table = document.getElementById("recycleTable")
for (var i = 0; i < data.length; i++) {
var row = `<tr>
<td>${data[i].RecyclableID}</td>
<td>${data[i].Name}</td>
<td>${data[i].RecyclableType}</td>
</tr>`
table.innerHTML += row
}
};
This is how the table looks like currently:
Table image look like
Now, how do I style this to match the header rows?
You have used inline-styles for your table head. Try to repeat the same in JQuery within the template literals where you are creating the table rows on fly to match the thead styling for all the rows.
for (var i = 0; i < data.length; i++) {
var row = `<tr>
<td style="padding-left:25px;">${data[i].RecyclableID}</td>
<td style="padding-left:100px;">${data[i].Name}</td>
<td style="text-align: center;">${data[i].RecyclableType}</td>
</tr>`
table.innerHTML += row
}
This should do it !

Fixed thead only only when scrolling to top

I have a problem with a thead: I need to fix to top the thead when scrolling to top but at the same when I scroll horizontally the thead has to scroll horizontally so I can't use the "position: fixed".
I'm using this cose but it does not work as I want.
Any ideas?
<script type="text/javascript">
$(function() {
moveScroller();
});
function moveScroller() {
var $anchor = $("#scroller-anchor");
var $scroller = $('#scroller');
var move = function() {
var st = $(window).scrollTop();
var ot = $anchor.offset().top;
if(st > ot) {
$scroller.css({
position: "fixed",
top: "0px"
});
} else {
$scroller.css({
position: "relative",
top: ""
});
}
};
$(window).scroll(move);
move();
}
</script>
<div class="col-sm-12" id="scroller-anchor">
<div class="table-responsive" id="cinquepuntodue">
<table class="table table-bordered table-hover table-condensed version" cellspacing="0" id = "cinquepuntodue_sopra">
<thead id="scroller" ></thead>

How to capture table row on button click to add css class knockout js

i have table with data and data populated by knockout js foreach bind.
i would like to know how to access specific table row's data when it gets updated.
if i could access table row then could add css class to that tr. my objective is to do bit color animation for a row which will be updated just clicking on button. when any data will be push to table row clicking on "Update Data" button then i want to add a class to that table row and after few minute remove that class too. hence i am new so no logic is coming to my mind to achieve this....any help would be appreciated. thanks
jsfiddle http://jsfiddle.net/62Ls6x9n/157/
full code
<button data-bind="click: AddNewData">Add New Data</button>
<button data-bind="click: UpdateDataByIds">Update Data</button>
<br><br>
<table class="imagetable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Price</th>
<th>Status</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody data-bind="foreach: Stocks">
<tr>
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
<td data-bind="text: price"></td>
<td data-bind="text: status"></td>
<td>edit</td>
<td>delete</td>
</tr>
</tbody>
</table>
table.imagetable {
font-family: verdana,arial,sans-serif;
font-size:11px;
color:#333333;
border-width: 1px;
border-color: #999999;
border-collapse: collapse;
}
table.imagetable th {
background:#b5cfd2 url('cell-blue.jpg');
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #999999;
}
table.imagetable td {
background:#dcddc0 url('cell-grey.jpg');
border-width: 1px;
padding: 8px;
border-style: solid;
border-color: #999999;
}
var StockItem = function(_id, _name, _price, _status){
var self = this;
self.id = ko.observable(_id);
self.name = ko.observable(_name);
self.price = ko.observable(_price);
self.status = ko.observable(_status);
};
var data= [
new StockItem("12345", "Acme Widget 1", "£25.99", "In Stock"),
new StockItem("67890", "Acme Widget 2", "£28.99", "In Stock"), new StockItem("11123","Acme Widget 3","£15.99", "In Stock"),
new StockItem("14156", "Acme Widget 4", "£33.99", "In Stock")
];
var NewData = [new StockItem("99999", "HSL Limited", "£78.99", "In Stock")];
var appViewModel = function()
{
var self = this;
self.Stocks = ko.observableArray(data);
self.AddNewData = function(){
self.Stocks.push.apply(self.Stocks,NewData);
};
self.DeleteItem = function(dataContext){
var itemToDelete = dataContext;
self.Stocks.remove(itemToDelete);
}
self.UpdateDataByIds = function(){
var id1 = '11123';
var id2 = '12345';
self.UpdateById(id1,null,null,"Out of Stock");
self.UpdateById(id2,null,"31.45",null);
};
self.UpdateById = function(_id, _name, _price, _status){
var matchedItem = ko.utils.arrayFirst(self.Stocks(), function(item) {
return item.id() === _id;
});
if (matchedItem != null){
if (_name != null) matchedItem.name(_name);
if (_price != null) matchedItem.price(_price);
if (_status != null) matchedItem.status(_status);
}
};
self.UpdateData = function(dataContext){
var itemToEdit = dataContext;
itemToEdit.status("Out of Stock");
};
};
var vm = new appViewModel();
ko.applyBindings(vm);
You can add a Mutated array to your view-model:
self.Mutated = ko.observableArray();
And upon updating / adding, add the item id to the array:
self.Mutated.push(_id);
Then in your HTML, have a mutated class on each <TR> that is indeed mutated:
<tr data-bind="css: { mutated: $root.Mutated.indexOf(id()) > -1 }">
And the CSS:
table.imagetable tr.mutated td { background-color: red; }
See Fiddle

Table cell td with max-width showing too much white space if line breaks

I am trying to make a table as small as possible. One cell may have more content then the desired width so I set "max-width". So in some cases the content will be broken into more lines, which is fine.
However, when a line breaks in two the table cell remains at the max-width, while it could be smaller if it would adjust to the now broken content.
Many words, easy to look at: http://jsfiddle.net/G3bcB/10/
<p>Too much white space:</p>
<table>
<tr>
<td class="leftcell">long texttext overflow</td>
<td>B</td>
<td>C</td>
</tr>
</table>
<p>Upper table could have same width:</p>
<table>
<tr>
<td class="leftcell">long texttext</td>
<td>B</td>
<td>C</td>
</tr>
</table>
table { width: auto; }
td { border: 1px solid black; }
td.leftcell { max-width: 100px; }
I am not sure if this is a feature of HTML, but to me it seems wrong.
Is it possible to make the field smaller (using standard css)?
You can't do this without Javascript. Fortunately it's not too complicated. I changed the class of the first cell to leftcell1 to distinguish it from the lower table and lengthened the string for demo purposes:
<td class="leftcell1">
long texttext overflow long overflow
</td>
Here's the updated jsFiddle.
And the javascript:
var el = $('.leftcell1');
//temporarily puts the text in the cell to measure it
function getWidth(el, txt) {
el.html(txt);
return el.css('width').replace('px', '');
}
//returns the string w/ the <br /> tags in the right place
function splitString(maxWidth) {
var txtArr;
var presentTxt = '';
var futureTxt = '';
var finalTxt = '';
//split the words up if longer than the max width
if (getWidth(el, el.html()) >= maxWidth) {
txtArr = el.html().split(' ');
//loop through the words and add them together
for (var i in txtArr) {
futureTxt += txtArr[i] + ' ';
//check if the string is longer than the max width
if (getWidth(el, futureTxt) > maxWidth) {
//It is. Add it to the final string with a <br />
//and chop off the trailing space
finalTxt += presentTxt.substring(0, presentTxt.length - 1) + '<br />';
futureTxt = presentTxt = txtArr[i] + ' ';
} else {
//it's not. Keep adding to it.
presentTxt = futureTxt;
}
}
} else {
finalTxt = el.html();
}
//if there is anything leftover in futureTxt add it to finalTxt
if (futureTxt != '') {
finalTxt += futureTxt;
}
return finalTxt;
}
el.html(splitString(100));

Table sorter icons in thead

I have some JavaScript that toggles the class of the th element clicked to "ascending" or "descending".
Q: In the css, how can I display a jQuery-UI icon associated with .ascending or .descending?
<table>
<thead>
<tr>
<th class="ascending">Cust</th>
<th>Name</th>
</tr>
</thead>
...
</table>
Here's the code, just in case someone spots an inefficiency:
jQuery(function($) {
$('.thSort th').click(function() {
var $th = $(this);
$th.siblings().removeClass('selected ascending descending');
$th.addClass('selected');
var column = $th.index();
var $table = $th.closest('table');
var rows = $table.find('tbody > tr').get();
if ($th.hasClass('ascending')) {
$th.removeClass('ascending');
$th.addClass('descending');
rows.sort(function(rowA,rowB) {
var keyA = $(rowA).children('td').eq(column).text().toUpperCase();
var keyB = $(rowB).children('td').eq(column).text().toUpperCase();
if (keyA < keyB) return 1;
if (keyA > keyB) return -1;
return 0;
});
} else {
$th.removeClass('descending');
$th.addClass('ascending');
rows.sort(function(rowA,rowB) {
var keyA = $(rowA).children('td').eq(column).text().toUpperCase();
var keyB = $(rowB).children('td').eq(column).text().toUpperCase();
if (keyA < keyB) return -1;
if (keyA > keyB) return 1;
return 0;
});
}
$.each(rows, function(index,row) {
$table.children('tbody').append(row);
});
return false;
});
});
taking this from the jquery Tablesorter plugin
you can write some css like this:
table thead th{
background-repeat: no-repeat;
background-position: center right;
cursor: pointer;
}
.ascending{
background-image: url(asc.gif);
}
.decending{
background-image: url(desc.gif);
}
<th scope="col"><div class="floatleft">Topic</div>
<div class="floatright ui-state-default ui-corner-all">
<span class="ui-icon ui-icon-circle-triangle-n"></span>
</div>
</th>
In JavaScript, toggle between ui-icon-circle-triangle-n and ui-icon-circle-triangle-s.
If the user clicks on a new th, replace all the html inside the previous th with only the text that is in the first div.

Resources