table scroll css change from Jquery - javascript

Actually I've a table where I need to set a max-height and make it scrollable.
My Table design
<table class="table table-striped table-notactiveusers table-custom-scroll" style="border: 1px solid #e7eaec;" id="tblNonUandMeUsersList" runat="server">
<thead>
<tr>
<th style="width: 5%">#</th>
<th style="width: 33%">First Name</th>
<th style="width: 30%">Country Code</th>
<th style="width: 32%">Mobile Number</th>
</tr>
</thead>
</table>
My Table css :
.table-custom-scroll > thead, .table-custom-scroll > tbody {
display: block;
}
.table-custom-scroll > tbody {
max-height: 450px;
overflow-y: auto;
overflow-x: hidden;
}
But, if the table has less rows than the max height, there is a space for the body on the right side like shown in the image
So,I thought of changing the css to display : compact, if the table rows are less than 12.
My JS to change css
<script>
$(document).ready(function () {
var notactiverowCount = $('.table-notactiveusers tr').length;
if (notactiverowCount < 12) {
$('.table-notactiveusers > thead').css('display', 'compact');
$('.table-notactiveusers > body').css('display', 'compact');
}
if (notactiverowCount < 12) {
$('.table-notactiveusers').children('head').css('display', 'compact');
$('.table-notactiveusers').children('body').css('display', 'compact');
}
});
</script>
But the css is not changing. Can anyone tell me the mistake I was doing?

what about using only css
.table-custom-scroll{
display: block;
}
see demo HERE

Related

Hover keyframe values green and red

I'm kind of stuck in a keyframe. I have a table with values from a fetch (json) and i should add a hover when the values is less than 5 in red and starting from 5 in green. This is my code in javascript ->
how do i have to implement the keyframe with it in css or is it different that i think?
// Html
<div id="group3">
<table class="table">
<thead>
<tr class="info">
<th></th>
<th>February</th>
<th>March</th>
<th>April</th>
<th>May</th>
<th>June</th>
<th>July</th>
<th>August</th>
</tr>
</thead>
<tbody id='mytable'>
</tbody>
</table>
</div>
//CSS
Keyframe?
//hover
let cells = document.querySelectorAll("tbody");
cells.forEach( el => el.addEventListener('mouseenter', function () {
if(el.textContent < 5){
el.classList.add('underfive');
} else if (el.textContent >=5){
el.classList.add('abovefive');
}
}));
// reset animationx
cells.forEach(el => el.addEventListener('mouseleave', function () {
if(el.textContent < 5){
el.classList.remove('underfive');
} else if (el.textContent >=5){
el.classList.remove('abovefive');
}
}));
it should be like this ->
this is the startpage, background is white
this is the end result how it should be, uploaded from a json file in a table, red value
this is the green value when it's 5 of higher
Based on what you say you want to show a different background color or styling in general than the default if the mouse is over the td.
So use :hover for that. You want to have a transition between those states so use transition.
You want to have a different color if it is above or below 5. So define what you want to have as default and add a class for the other case.
let data = [1,4,2,8,12,2,5,7];
const tr = document.querySelector('tr');
data.forEach(elem => {
let td = document.createElement('td');
td.textContent = elem;
td.classList.toggle('belowfive', elem < 5);
tr.appendChild(td);
});
td {
transition: background-color 1s;
background-color: white;
padding: 1rem;
border: 1px solid hsl(0 0% 50%);
}
td:hover {
background-color: green;
}
td.belowfive:hover {
background-color: red;
}
<table>
<tbody>
<tr>
</tr>
</tbody>
</table>

Is there a way I can have a separate background image for each button in localstorage?

In the website I am trying to create, I want a 7x7 table, each cell being a "button" that you can click on to toggle between images. Almost like a bingo board, you click on a cell and it will mark it as being completed by switching to another image. I am using localstorage to store which image is being shown so a user can keep their progress basically.
My problem is that since there is only 1 "backgroundImage" property, how do I have a different image in each box that I can toggle without affecting the others?
The javascript I provide is the same function twice, as it works for the first button but not for the second one, as I am guessing the background image is being conflicted with since they are both trying to access the same one.
HTML code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js" data-semver="3.0.0" data-require="jquery"></script>
<script src="js/script.js"></script>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<table>
<tr>
<th>T</th>
<th>W</th>
<th>I</th>
<th>S</th>
<th>T</th>
<th>E</th>
<th>D</th>
</tr>
<tr>
<th><button class="button1"></button></th>
<th><button class="button2"></button></th>
<th>Task 3</th>
<th>Task 4</th>
<th>Task 5</th>
<th>Task 6</th>
<th>Task 7</th>
</tr>
</table>
</body>
</html>
CSS:
button
{
display: inline-block;
width: 100%; /* set to 100% */
height: 100%; /* set to 100% */
margin-bottom: 0.5em;
padding-top: .6em;
padding-bottom: .6em;
color: #fff;
background-color: #aaabbb;
border-radius: 5px;
border: solid #cccccc 1px;
clear:right;
float:right;
height: 150px;
width: 150px;
}
JS:
$(function(){
if (localStorage.getItem('backgroundImage') !== null) {
url = localStorage.backgroundImage;
$('.button1').css('backgroundImage', url);
}
else
{
url = 'url(images/button1.png)';
}
$('.button1').click(function(){
if(url == "url(images/button1.png)"){
localStorage.removeItem('backgroundImage');
$('.button1').css('backgroundImage', 'url(images/button1no.png)');
localStorage.setItem('backgroundImage', 'url(images/button1no.png)');
}
else {
url = 'url(images/button1no.png)';
localStorage.removeItem('backgroundImage');
$('.button1').css('backgroundImage', 'url(images/button1.png)');
localStorage.setItem('backgroundImage', 'url(images/button1.png)');
}
});
});
//----------------------------------------------------------------------------
$(function(){
if (localStorage.getItem('backgroundImage') !== null) {
url = localStorage.backgroundImage;
$('.button2').css('backgroundImage', url);
}
else
{
url = 'url(images/button2.png)';
}
$('.button1').click(function(){
if(url == "url(images/button2.png)"){
localStorage.removeItem('backgroundImage');
$('.button2').css('backgroundImage', 'url(images/button2no.png)');
localStorage.setItem('backgroundImage', 'url(images/button2no.png)');
}
else {
url = 'url(images/button2no.png)';
localStorage.removeItem('backgroundImage');
$('.button2').css('backgroundImage', 'url(images/button2.png)');
localStorage.setItem('backgroundImage', 'url(images/button2.png)');
}
});
});
You need to store an array of the values instead of one value. Local Storage does not support complex values, but you can use JSON to encode it. So when you set the value, you would do something like this:
localStorage.setItem('backgroundImage', JSON.stringify(someArray));
And when you read it, parse it:
myArrayofValues = JSON.parse(localStorage.getItem('backgroundImage'))
Remember that by default the value will be empty, so you may want to set an initial value of an empty array first.
There are two questions here:
How to toggle bettween two images for each buttons
How to store the "current" image for each button
I would use data attributes to store both images url AND the current one (and a number telling which one is used). That makes it easy to maintain all the urls directly in your markup.
I would also use it to store the "index" of each button, just to simplify the correspondance of each buttons with the index of an array to be stored in localStorage.
So on click, you will simply toggle between 2 urls and store the new "image number" in the array, at the right index.
Notice that it isn't the url that is stored... it's already in the markup.
Now, as #Raymond Camden explained, localStorage can store a string... Not an object or an array. That is why JSON.stringify() and JSON.parse() are used.
$(document).ready(function() {
// retrieve localStorage if exist
let bg_numbers = [];
/*if (localStorage.getItem("bg_numbers") !== null) {
bg_numbers = JSON.parse(localStorage.getItem("bg_numbers"))
}*/
console.log(bg_numbers)
// Setting the data-bg_current and data-btn_index
$("button").each(function(index, btn) {
let $btn = $(btn);
// Get the urls for this button
let backgrounds = [$btn.data("bg_1"), $btn.data("bg_2")];
// Retreive the image number used, if any
let currentImage = (bg_numbers[index] && bg_numbers[index] === 1) ? 1 : 0;
// Set it
$btn.css("background-image", `url('${backgrounds[currentImage]}')`);
// Update the data attributes, since thos are zero on page load
$btn.data("bg_current", currentImage);
$btn.data("btn_index", index)
});
$("button").on("click", function() {
let $btn = $(this);
// Get the index of this button
let index = $btn.data("btn_index")
// Get the urls for this button
let backgrounds = [$btn.data("bg_1"), $btn.data("bg_2")];
// Toggle the image
let currentImage = ($(this).data("bg_current") === 1) ? 0 : 1;
$(this).css("background-image", `url('${backgrounds[currentImage]}')`);
// Update the array and save to localStorage
bg_numbers[index] = currentImage
//localStorage.setItem("bg_numbers", JSON.stringify(bg_numbers))
});
});
button {
display: inline-block;
width: 100%;
/* set to 100% */
height: 100%;
/* set to 100% */
margin-bottom: 0.5em;
padding-top: 0.6em;
padding-bottom: 0.6em;
color: #fff;
background-color: #aaabbb;
border-radius: 5px;
border: solid #cccccc 1px;
clear: right;
float: right;
height: 150px;
width: 150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<th>T</th>
<th>W</th>
<th>I</th>
<th>S</th>
<th>T</th>
<th>E</th>
<th>D</th>
</tr>
<tr>
<th><button data-bg_1="https://via.placeholder.com/150x150.png?text=Button 1" data-bg_2="https://loremflickr.com/150/150" data-bg_current=0 data-btn_index=0></button></th>
<th><button data-bg_1="https://via.placeholder.com/150x150.png?text=Button 2" data-bg_2="https://loremflickr.com/150/150" data-bg_current=0></button></th>
<th>Task 3</th>
<th>Task 4</th>
<th>Task 5</th>
<th>Task 6</th>
<th>Task 7</th>
</tr>
</table>
I commented all lines related to localStorage here since SO snippet are disallowing it... And it was throwing an ugly error. But see my CodePen.

Add CSS scroll to positioned element

I am building an interface to display real time records which are provided via Ajax. The records should be shown in a rectangle of a set height, and the newest record should be located at the bottom of this rectangle. As new records come in, they are inserted at the bottom of the rectangle, and the older records move up. When more records than can fit in the rectangle have arrived, the rectangle should have a scroll bar so that old records can be viewed.
Ideally, solely CSS would be used, however, JavaScript/jQuery solutions are acceptable.
My first attempt was to use CSS, and is shown below and also located at https://jsbin.com/juyapihile/edit?html,output. Note that I don't really have two tables, but have only shown two so you can see the records located at the bottom on the first and the lack of the scroll bar on the second.
For this attempt, I included the records in a table which was positioned absolute with bottom equal to 0 within a div which was positioned relative. Unfortunately, when doing so, the scroll bar doesn't work.
How can this be accomplished? Or generically,how can a positioned element have a scroll bar?
<!DOCTYPE html>
<html>
<head>
<title>Client Test</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<style type="text/css">
.table-container {
height:100px;
overflow-y: scroll;
position: relative;
border: 1px solid black;
padding: 5px;
margin-bottom: 20px;
}
#at-bottom {
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<p>This keeps the newest record at the bottom</p>
<div class="table-container">
<table id="at-bottom">
<thead><tr><td>hello</td><td></td></tr></thead>
<tbody></tbody>
</table>
</div>
<p>This uses a scroll bar</p>
<div class="table-container">
<table id="with-scroll">
<thead><tr><td>hello</td><td></td></tr></thead>
<tbody></tbody>
</table>
</div>
<p>How do I do both???</p>
<script type="text/javascript">
$(function(){
var count=0;
setInterval(function(){
console.log('x')
count++;
$("#at-bottom thead tr").clone().appendTo($('#at-bottom tbody')).find('td').eq(1).text(count);
$("#with-scroll thead tr").clone().appendTo($('#with-scroll tbody')).find('td').eq(1).text(count);
}, 2000);
});
</script>
</body>
</html>
I read your post again and wasn't sure if you wanted the text at the bottom of the div when the text was shorter than the height of the div. My other answer works if you want the text filling the div from the top and then getting a scrollbar and keeping the last text at the bottom. If you want to keep the text at the bottom all the time, then I would use a flexbox solution as follows:
var wrap = document.getElementById('wrap');
var body = document.getElementById('body');
var count = 0;
setInterval(function() {
var row = document.createElement("tr");
var data = document.createElement("td");
var text = document.createTextNode("Hello " + count);
count+=1;
data.appendChild(text);
row.appendChild(data);
body.appendChild(row);
wrap.scrollTop = wrap.scrollHeight - wrap.clientHeight;
}, 1000);
.table-container {
display:flex;
flex-direction:column;
height:75px;
width:300px;
border: 1px solid black;
padding: 5px;
margin-bottom: 10px;
justify-content:flex-end;
}
.table-container div {
overflow-y: auto;
min-height: 0px;
}
<div class="table-container">
<div id="wrap">
<table>
<tbody id="body">
</tbody>
</table>
</div>
</div>
The other answer was a good start. You have to remove the "position:absolute". Then, add an id to each div and set the "scrollTop" attribute like this any time you add elements to the table:
var div = document.getElementById('divID');
div.scrollTop = div.scrollHeight - div.clientHeight;
Here it is working:
var div = document.getElementById('divID');
div.scrollTop = div.scrollHeight - div.clientHeight;
.table-container {
height: 75px;
overflow-y: auto;
position: relative;
border: 1px solid black;
padding: 5px;
margin-bottom: 10px;
}
<div class="table-container">
<table>
<tbody>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello last</td></tr>
</tbody>
</table>
</div>
<div id="divID" class="table-container">
<table>
<tbody>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello last</td></tr>
</tbody>
</table>
</div>
The problem is the inner table's height is as tall as it needs to be, a table can't have a scrollbar, and the outer div's scrollbar is off. Also generally, scrollbars require height to be somewhat specified.
To solve your problem, I think you should remove position absolute on your table. This will cause the div to scroll. Next, every time a new update comes in via ajax you should simply el.scrollTop = 999999999; where el is el = document.querySelector('.table-container')
Also note, you may want to detect when the user is not at the bottom, and not automatically scroll the to the bottom. You can do this, but measuring el.scrollTop and add the height of the div to it and compare the scroll height of the el. This should do it: el.scrollTop + el.height === el.scrollHeight.
Remove: position: absolute; on the table:
.table-container {
height: 200px;
overflow-y: scroll;
position: relative;
border: 1px solid black;
padding: 5px;
margin-bottom: 20px;
}
.table-container table {
bottom: 0;
}
<div class="table-container">
<table>
<tbody>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
</tbody>
</table>
</div>
<div class="table-container">
<table>
<tbody>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
<tr><td></td><td>Hello</td></tr>
</tbody>
</table>
</div>

Fixed header script function floatHead is adding an extra thead

I'm trying to make fixed headers for a table in my view. I searched and didn't find much so I ended up trying a plugin found here http://mkoryak.github.io/floatThead/. After implementing its adding an extra blank thead to my tblPersons table that looks like this:
So then I try and hide the thead using this jquery code (i have two total theads on the view, this selects the one I need via the id, or lack thereof):
$('thead[id!="personsHeader"]').hide();
Which does remove the thead, but then it removes the first line of my results which is:
Kirk | Alexander | 06/02/2015
Visual:
It doesn't make sense to me because the thead is separate from the tbody where the Kirk row is located...
Finally for reference, here is my View form code:
#using (Html.BeginForm("Index", "Persons"))
{
<div class="panel panel-default">
<div class="panel-heading">
<table id="tablePanelHeader" class="table table-bordered menu-options">
<tr>
<td>
Persons Pages:
#Html.DropDownList("PersonsDDL", new SelectList(listItems, "Value", "Text"))
</td>
<td>
Search filter: <input type="text" id="search" ="Type to search">
</td>
</tr>
<tr>
<td id="rowCount">
</td>
</tr>
</table>
</div>
<div class="span3">
<table id="tblPersons" class="table table-bordered">
<thead id="personsHeader">
<tr class="page-header">
<th>First Name</th>
<th>Last Name</th>
<th>Birthdate</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#item.firstname
</td>
<td>
#item.lastname
</td>
<td>
#item.birthdate.ToString("MM/dd/yyyy")
</td>
</tr>
}
</tbody>
</table>
</div>
}
I've given it my best shot and now I'm turning to the professionals... what am I doing wrong?
There are several ways to do this. Personally I have always been a fan of going full css instead of adding the bloat of js to this mix.
See this for an example of a fixed table header with just css - http://codepen.io/tjvantoll/pen/JEKIu
.fixed_headers {
width: #table_width;
table-layout: fixed;
border-collapse: collapse;
th { text-decoration: underline; }
th, td {
padding: 5px;
text-align: left;
}
td:nth-child(1), th:nth-child(1) { min-width: #column_one_width; }
td:nth-child(2), th:nth-child(2) { min-width: #column_two_width; }
td:nth-child(3), th:nth-child(3) { width: #column_three_width; }
thead {
background-color: #header_background_color;
color: #header_text_color;
tr {
display: block;
position: relative;
}
}
tbody {
display: block;
overflow: auto;
width: 100%;
height: #table_body_height;
tr:nth-child(even) {
background-color: #alternate_row_background_color;
}
}
}
If you are set on using a javascript library try jQuery Datatables - datatables.net/examples/basic_init/scroll_y.html

Safari calculates wrong width in table

I'm working on developing a simple column resize functionality for HTML tables.
The table works OK so far - except in Safari (ver 5.1.4). For some reason Safari gives the cell widths a negative(!) value.
a JSFiddle is available here: simple-resize
The negative column width values can be seen if the style="width" attributes are removed from the <th> elements (or disabled in the code inspector)
HTML:
<div class="tblcont" id="cont">
<table id="table1" class="pivot-table pivot-fixed-layout">
<thead>
<tr id="tr1">
<th style="width: 52px;">city</th>
<th style="width: 26px;"># c</th>
<th style="width: 37px;"># id</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tel Aviv</td>
<td>814</td>
<td>1,047</td>
</tr>
<tr>
<td>Natanya</td>
<td>805</td>
<td>1,016</td>
</tr>
</tbody>
</table>
</div>
CSS:
.pivot-table.pivot-fixed-layout {
border-collapse: collapse;
table-layout: fixed;
width: 0;
}
.pivot-table td, .pivot-table th {
overflow: hidden;
padding: 0 6px;
border-right: 1px solid;
border-bottom: 1px solid;
text-overflow: ellipsis;
}
.pivot-table th {
cursor: col-resize;
}
Javascript:
var pressed = false,
$column,
$table = $("table"),
startX, startWidth,
tableInitialWidth = $('#cont').width() - 100,
currentTableWidth, newTableWidth;
$("table th").mousedown(function(e) {
$column = $(this);
pressed = true;
startX = e.pageX;
startWidth = $column.width();
$column.addClass("resizing");
});
$(document).mousemove(function(e) {
if(pressed) {
var delta = e.pageX - startX,
currentColumnWidth,
newColumnWidth;
currentColumnWidth = $column.width();
newColumnWidth = startWidth + delta;
currentTableWidth = $table.width();
newTableWidth = currentTableWidth + delta;
// no not make columns smaller than min width
if (newColumnWidth > 2) {
$column.width(newColumnWidth);
}
}
});
$(document).mouseup(function() {
if(pressed) {
$column.removeClass("resizing");
pressed = false;
}
});

Categories