Center Text horizontally through out multiple <td> in table - javascript

I have a table that is a timetable.
What I want is if there are two or more of the same tasks come after each other for the border between to go. (This I have done). Also i want the text to be centered in the middle of the table.
See Example for clarification:
var tds = document.querySelectorAll("td")
for (var o = 0; o < tds.length; o++) {
if ($(tds[o]).next().html() === $(tds[o]).html() && $(tds[o]).prev().html() === $(tds[o]).html()) {
$(tds[o]).css("borderRight", "none");
$(tds[o]).css("borderLeft", "none");
} else if ($(tds[o]).next().html() === $(tds[o]).html()) {
$(tds[o]).css("borderRight", "none");
} else if ($(tds[o]).prev().html() === $(tds[o]).html()) {
$(tds[o]).css("borderLeft", "none");
}
}
table {
border-collapse: collapse;
}
td {
border: 2px solid grey;
padding: 25px;
text-align: center;
}
th {
border: 2px solid grey;
padding: 25px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>1:00</th>
<th>2:00</th>
<th>3:00</th>
<th>4:00</th>
<th>5:00</th>
<th>6:00</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sleep</td>//Should Only be one "Sleep" and it should be centered through all the "Sleep td"
<td>Sleep</td>
<td>Sleep</td>
<td>Sleep</td>
<td>Sleep</td>
<td>Wake Up</td>
</tr>
</tbody>
</table>

Use colspan.
var tds = document.querySelectorAll("td")
for (var o = 0; o < tds.length; o++) {
if ($(tds[o]).next().html() === $(tds[o]).html() && $(tds[o]).prev().html() === $(tds[o]).html()) {
$(tds[o]).css("borderRight", "none");
$(tds[o]).css("borderLeft", "none");
} else if ($(tds[o]).next().html() === $(tds[o]).html()) {
$(tds[o]).css("borderRight", "none");
} else if ($(tds[o]).prev().html() === $(tds[o]).html()) {
$(tds[o]).css("borderLeft", "none");
}
}
table {
border-collapse: collapse;
}
td {
border: 2px solid grey;
padding: 25px;
text-align: center;
}
th {
border: 2px solid grey;
padding: 25px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>1:00</th>
<th>2:00</th>
<th>3:00</th>
<th>4:00</th>
<th>5:00</th>
<th>6:00</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="5">Sleep</td> //Should Only be one "Sleep" and it should be centered through all the "Sleep td"
<td>Wake Up</td>
</tr>
</tbody>

Just remove all of the
<td>Sleep</td>
And put in:-
<td colspan="5">Sleep</td>

Related

Alternative way to know if mouse is over an element (Javascript)

I have a script which shows a "hover element" (like a zoom) when my mouse is over it. I know it's a bit messy but here's an example:
function showOverflow2(e) {
let cell = e.currentTarget;
let clone = cell.cloneNode(true);
if (cell.children[0].scrollWidth <= cell.children[0].clientWidth) {
return false;
};
clone.innerHTML = clone.children[0].innerHTML;
clone.style.position = 'absolute';
clone.style.backgroundColor = 'white';
clone.style.borderWidth = '2px';
clone.style.lineHeight = cell.scrollHeight + 'px';
clone.style.whiteSpace = 'nowrap';
x0 = (
cell.offsetLeft +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-left"].slice(0, -2)
) + 2
);
y0 = (
cell.offsetTop +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-top"].slice(0, -2)
) + 2
);
xmid = x0 + (cell.clientWidth / 2);
ymid = y0 + (cell.clientHeight / 2);
let body = document.getElementsByTagName('body')[0];
body.appendChild(clone);
clone.style.height = cell.scrollHeight + 'px';
clone.style.width = clone.scrollWidth + 'px';
xf = xmid - (clone.clientWidth / 2);
yf = ymid - (clone.clientHeight / 2);
clone.style.top = yf + 'px';
clone.style.left = xf + 'px';
// FOCUS ON THIS PART
clone.addEventListener("mouseout", function() {
clone.remove();
});
// END OF FOCUS
};
let all_cells = document.getElementsByTagName('td');
for (let i = 0; i < all_cells.length; i++) {
let current_cell = all_cells[i];
if (current_cell.className !== 'buttons') {
current_cell.addEventListener("mouseover", showOverflow2);
}
}
body {
margin: 0;
}
#container {
background-color: gainsboro;
border: 2px solid black;
border-radius: 2px;
padding: 1.2%;
max-width: 50%;
}
table {
border-collapse: separate;
border-spacing: 0 0.5rem;
table-layout: fixed;
width: 100%;
}
tr {
background-color: white;
}
td {
width: calc(100%/3);
border: solid gray;
border-width: 2px 1px 2px 0;
padding: 0.7% 1%;
text-align: center;
white-space: nowrap;
}
span {
display: block;
overflow: hidden;
}
td:first-child {
border-left-width: 2px;
border-radius: 3px 0 0 3px;
}
td:last-child {
border-right-width: 2px;
border-radius: 0 3px 3px 0;
}
<div id="container">
<table id="table">
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
</table>
</div>
To remove the "zoom" and return things to normal, I'm simply using:
clone.addEventListener("mouseout", function() {
clone.remove();
This works fine if you are smoothly moving your mouse over the elements, but with a bigger table and faster movements, you can see for yourselves that some elements don't return to normal:
function showOverflow2(e) {
let cell = e.currentTarget;
let clone = cell.cloneNode(true);
if (cell.children[0].scrollWidth <= cell.children[0].clientWidth) {
return false;
};
clone.innerHTML = clone.children[0].innerHTML;
clone.style.position = 'absolute';
clone.style.backgroundColor = 'white';
clone.style.borderWidth = '2px';
clone.style.lineHeight = cell.scrollHeight + 'px';
clone.style.whiteSpace = 'nowrap';
x0 = (
cell.offsetLeft +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-left"].slice(0, -2)
) + 2
);
y0 = (
cell.offsetTop +
parseFloat(
getComputedStyle(
cell.parentElement.parentElement.parentElement.parentElement
)["padding-top"].slice(0, -2)
) + 2
);
xmid = x0 + (cell.clientWidth / 2);
ymid = y0 + (cell.clientHeight / 2);
let body = document.getElementsByTagName('body')[0];
body.appendChild(clone);
clone.style.height = cell.scrollHeight + 'px';
clone.style.width = clone.scrollWidth + 'px';
xf = xmid - (clone.clientWidth / 2);
yf = ymid - (clone.clientHeight / 2);
clone.style.top = yf + 'px';
clone.style.left = xf + 'px';
// FOCUS ON THIS PART
clone.addEventListener("mouseout", function() {
clone.remove();
});
// END OF FOCUS
};
let all_cells = document.getElementsByTagName('td');
for (let i = 0; i < all_cells.length; i++) {
let current_cell = all_cells[i];
if (current_cell.className !== 'buttons') {
current_cell.addEventListener("mouseover", showOverflow2);
}
}
body {
margin: 0;
}
#container {
background-color: gainsboro;
border: 2px solid black;
border-radius: 2px;
padding: 1.2%;
max-width: 50%;
}
table {
border-collapse: separate;
border-spacing: 0 0.5rem;
table-layout: fixed;
width: 100%;
}
tr {
background-color: white;
}
td {
width: calc(100%/3);
border: solid gray;
border-width: 2px 1px 2px 0;
padding: 0.7% 1%;
text-align: center;
white-space: nowrap;
}
span {
display: block;
overflow: hidden;
}
td:first-child {
border-left-width: 2px;
border-radius: 3px 0 0 3px;
}
td:last-child {
border-right-width: 2px;
border-radius: 0 3px 3px 0;
}
<div id="container">
<table id="table">
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAAaAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAASAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
<tr>
<td class="cell1"><span>AAAAAAAAAABBBCC</span></td>
<td class="cell2"><span>AAAAAAAAAABBBB</span></td>
<td class="cell3"><span>AAAAAAAAAAAAABBBBB</span></td>
</td>
</tr>
</table>
</div>
If I can't trust the mouseout event, what can I do to fix this?
I thought about using a eventListener on mouse movement to test if the mouse is inside the element using absolute coordinates, but probably there's a simpler solution.
You could do something similar using CSS by repeating the content (enlarged) and showing and hiding it on hover. Simple example below.
table {
padding: 30px;
}
td {
position: relative;
padding: 4px;
border: 1px solid blue;
}
.grow {
display: none;
background-color: #fff;
border: 1px solid #000;
padding: 3px;
z-index: 10;
}
td:hover .grow {
display: block;
position: absolute;
top: 0;
left: 0;
transform: scale(1.5);
}
<html>
<head></head>
<body>
<table>
<tr>
<td>asdf<span class="grow">ASDF</span></td>
<td>fasd<span class="grow">FASD</span></td>
</table>
</body>
</html>
I'm answering my own question 'cause I needed to combine some ideas to make it work well.
First I need to point out that, for some reason, the problem I described happens in the browser only when the Developer tab (f12) is open, otherwise all works fine.
But still I wanted to be certain that no cell would freeze that way, so I used css like Ed Lucas. Still, I needed Javascript to get the centering right.
After days trying this I finally found a way to center it using css that worked with absolute positioning and the child element being larger.
I didn't remove the Javascript method because it gives me flexibility of commands to trigger and revert this event.
In the end, my code is looking like this:
function showOverflow(e) {
const div = e;
const cell = div.parentElement;
const span = div.children[0];
if (span.scrollWidth <= span.clientWidth) {
return false;
}
const clone = div.cloneNode(true);
clone.classList.add('hovercell');
cell.appendChild(clone);
let cell_style = getComputedStyle(cell);
function cloneRemove(host) {
clone.remove();
clearInterval(host.id);
}
function isInside(host) {
if (cell_style['z-index'] === '0') {
cloneRemove(host);
}
}
let host = {};
host.id = setInterval(isInside.bind(null, host), 100);
clone.addEventListener("mouseleave", function() {
cloneRemove(host);
});
}
td {
border: 2px solid gray;
padding: 0.7% 1%;
text-align: center;
white-space: nowrap;
z-index: 0;
position: relative;
}
td:hover {
z-index: 2;
}
span {
display: block;
overflow: hidden;
}
.hovercell {
background-color: white;
border: 2px solid gray;
padding: 6px 8px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(1.2);
}
<table>
<tbody>
<tr>
<td>
<div onclick="showOverflow(this)">
<span>A big cell--- 1</span>
</div>
</td>
<td>
<div onclick="showOverflow(this)">
<span>A big cell--- 2</span>
</div>
</td>
</tr>
</tbody>
</table>
Hope it helps someone.

How to get data attribute of element when click on it or it child

I am making a Table.
document.querySelector('table').addEventListener('click', (e) => {
console.log(e.target);
console.log(e.target.dataset.item);
})
td {
padding: 8px;
border: 1px solid black;
background-color: blue;
}
span {
background-color: red;
padding: 4px;
}
<table>
<tr>
<td data-item="item1"><span>1</span></td>
<td data-item="item2"><span>2</span></td>
<td data-item="item3"><span>3</span></td>
<td data-item="item4"><span>4</span></td>
<td data-item="item5"><span>5</span></td>
</tr>
</table>
When I click the BLUE PART, I can get data-item attribute. But when I click the RED PART, I can't.
I wanna fix it, if I click <span/> in <td/>, I want to get data-item attribute from <td />.
Try to use closest by your child tag instead of dataset.
document.querySelector('table').addEventListener('click', (e) => {
console.log(e.target.closest("td").dataset.item);
})
td {
padding: 8px;
border: 1px solid black;
background-color: blue;
}
span {
background-color: red;
padding: 4px;
}
<table>
<tr>
<td data-item="item1"><span>1</span></td>
<td data-item="item2"><span>2</span></td>
<td data-item="item3"><span>3</span></td>
<td data-item="item4"><span>4</span></td>
<td data-item="item5"><span>5</span></td>
</tr>
</table>
Check if name of clicked element is span select parent of it using parentNode property
document.querySelector('table').addEventListener('click', (e) => {
var ele = e.target.nodeName == "SPAN" ? e.target.parentNode : e.target;
console.log(ele.dataset.item);
})
td {
padding: 8px;
border: 1px solid black;
background-color: blue;
}
span {
background-color: red;
padding: 4px;
}
<table>
<tr>
<td data-item="item1"><span>1</span></td>
<td data-item="item2"><span>2</span></td>
<td data-item="item3"><span>3</span></td>
<td data-item="item4"><span>4</span></td>
<td data-item="item5"><span>5</span></td>
</tr>
</table>
You could check for the keys in the dataset of the clicked item and if it does have some properties then use e.target otherwise move up one level e.target.parentNode:
document.querySelector('table').addEventListener('click', (e) => {
var el = Object.keys(e.target.dataset).length ?
e.target: e.target.parentNode;
console.log(el.dataset.item);
})
td {
padding: 8px;
border: 1px solid black;
background-color: blue;
}
span {
background-color: red;
padding: 4px;
}
<table>
<tr>
<td data-item="item1"><span>1</span></td>
<td data-item="item2"><span>2</span></td>
<td data-item="item3"><span>3</span></td>
<td data-item="item4"><span>4</span></td>
<td data-item="item5"><span>5</span></td>
</tr>
</table>
Why do you listen on the whole table in the first place?
Listen only on "td" elements:
let cells = document.getElementsByTagName('td');
for (var i=0; i < cells.length; i++) {
let cell = cells[i];
cell.addEventListener('click', (e) => {
let element = e.target.nodeName;
if (element === 'TD') {
console.log(e.target.dataset.item);
} else if (element === 'SPAN') {
console.log(e.target.parentNode.dataset.item);
}
});
}
I don't think setting the listener on the table matters, because in your case, it doesn't trigger the event on the table anyways.
Some styles for better inspection:
table {
background-color: orange;
border-spacing: 10px;
}
https://jsfiddle.net/aleks351/p0b46wqs/6/

jquery excel like filter plugin

I am trying to make excel like filtering for my dynamic table. I am using this jquery plugin https://github.com/chestercharles/excel-bootstrap-table-filter. I'm using it because it resembles excel filters.
I tried it on non dynamic table coded in html everything worked good. But when I tried to implement the loading from database (php, MSSQL) it gives me this.
tds[selectedLists[j].column] is undefined
Error is in this particular function:
FilterCollection.prototype.updateRowVisibility = function (filterMenus, rows, ths) {
var showRows = rows;
var hideRows = [];
var selectedLists = filterMenus.map(function (filterMenu) {
return {
column: filterMenu.column,
selected: filterMenu.inputs.filter(function (input) {
return input.checked;
}).map(function (input) {
return input.value.trim().replace(/ +(?= )/g, '');
})
};
});
for (var i = 0; i < rows.length; i++) {
var tds = rows[i].children;
for (var j = 0; j < selectedLists.length; j++) {
var content = tds[selectedLists[j].column].innerText.trim().replace(/ +(?= )/g, '');
if (selectedLists[j].selected.indexOf(content) === -1) {
$(rows[i]).hide();
break;
}
$(rows[i]).show();
}
}
};
Does anyone have an idea why is this happening and how to correct it.
You don't require jquery to filter here is an example:
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
#myInput {
background-image: url('/css/searchicon.png');
/* Add a search icon to input */
background-position: 10px 12px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #ddd;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #ddd;
/* Add a grey border */
font-size: 18px;
/* Increase font-size */
}
#myTable th,
#myTable td {
text-align: left;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #f1f1f1;
}
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for names..">
<table id="myTable">
<tr class="header">
<th style="width:60%;">Name</th>
<th style="width:40%;">Country</th>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Germany</td>
</tr>
<tr>
<td>Berglunds snabbkop</td>
<td>Sweden</td>
</tr>
<tr>
<td>Island Trading</td>
<td>UK</td>
</tr>
<tr>
<td>Koniglich Essen</td>
<td>Germany</td>
</tr>
</table>

Crosshair highlight for table on hover

I have the code below that works perfect for crosshair function. This is fine, however wondering if there is a way to stop the highlight beyond the cursor (hover).
For example, instead of a "cross" shape highlight you end up with a backward "L" shape highlight. So instead of highlighting the whole row & column it only highlights column 3 down to row 2 and row 2 only to column 3. No extended highlight. Hope that makes sense?
Here is my css code:
table {
border-collapse: collapse;
overflow: hidden;
z-index: 1;
}
.permissions table,
th,
td {
border: 2px solid #ccc;
width:90px;
height:90px;
text-align:center;
vertical-align:middle;
font-size:13px;
}
td, th, .row, .col, .ff-fix {
cursor: pointer;
position: relative;
}
tr, col {
border: 1px solid black;
}
td:hover {
background-color:red;
}
td:hover:first-child {
background-color:red;
}
td:hover:nth-child(3n) {
background-color:red;
}
tr:last-child td:hover {
background-color:red;
}
td:hover::before,
.row:hover::before,
.ff-fix:hover::before {
background-color: #ffa;
content: '\00a0';
height: 100%;
left: -5000px;
position: absolute;
top: 0;
width: 10000px;
z-index: -1;
}
td:hover::after,
.col:hover::after,
.ff-fix:hover::after {
background-color: #ffa;
content: '\00a0';
height: 10000px;
left: 0;
position: absolute;
top: -5000px;
width: 100%;
z-index: -1;
}
Here is my html code:
<table>
<col /><col /><col />
<tr>
<th class="col">First Name</th>
<th class="col">Middle Name</th>
<th class="col">Last Name</th>
</tr>
<tr>
<td>Peter</td>
<td>Jeffery</td>
<td>Griffin</td>
</tr>
<tr>
<td>Lois</td>
<td>Marie</td>
<td>Griffin</td>
</tr>
<tr>
<td>Margie</td>
<td>Ann</td>
<td>Thatcher</td>
</tr>
</table>
Following the logic of your CSS, you apply a full-width ::before and a full-height ::after which are displayed over the table. To adjust how these are displayed (a cross vs a "backward L"), adjust the corresponding horizontal and vertical positioning.
Try replacing your td:hover::before and td:hover::after selectors with the following to display the highlighting as a "backward L". Note the positioning is set using right and bottom rule sets, as opposed to your original positioning using left and top.
td:hover::before,
.row:hover::before,
.ff-fix:hover::before {
background-color: #ffa;
content: '\00a0';
height: 100%;
right: 90px;
position: absolute;
top: 0;
width: 10000px;
z-index: -1;
}
td:hover::after,
.col:hover::after,
.ff-fix:hover::after {
background-color: #ffa;
content: '\00a0';
height: 10000px;
left: 0;
position: absolute;
bottom: 90px;
width: 100%;
z-index: -1;
}
See how it looks in this JSFiddle.
I know this is old, but here's a method using Javascript. I prefer this method because it allows for custom backgrounds, and doesn't require CSS workarounds.
HTML:
<table id="hoverTable">
<thead>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
<th>Column4</th>
</thead>
<tbody>
<tr>
<td>Item</td>
<td>Item</td>
<td>Item</td>
<td>Item</td>
</tr>
<tr>
<td>Item</td>
<td>Item</td>
<td>Item</td>
<td>Item</td>
</tr>
<tr>
<td>Item</td>
<td>Item</td>
<td>Item</td>
<td>Item</td>
</tr>
<tr>
<td>Item</td>
<td>Item</td>
<td>Item</td>
<td>Item</td>
</tr>
</tbody>
</table>
SCSS:
body {
background:grey;
}
.hoverHighlight {
background-color:yellow !important;
cursor:default;
}
#hoverTable {
font-family:arial;
border-spacing:0;
border-collapse: collapse;
th, td {
border:2px solid black;
text-align:center;
padding:5px;
margin:0;
}
th {
background:#1167b1;
color:white;
}
td {
text-align:center;
background:#d0efff;
}
}
Javascript:
window.addEventListener('load', function () {
addHoverEventsAndClasses();
})
function toggleHighlight(element, trueOrFalse) {
const currentRow = returnCurRow(element);
const index = element.currentTarget.cellIndex;
const table = document.getElementById('hoverTable').rows;
for (var i = 0; i < table.length; i++) {
const data = table[i];
const cells = data.querySelectorAll(".cell");
if(data.rowIndex === currentRow) {
cells.forEach((td) => {
trueOrFalse ? td.classList.add("hoverHighlight") : td.classList.remove("hoverHighlight");
});
}
cells.forEach((cell) => {
if(cell.cellIndex === index) {
trueOrFalse ? cell.classList.add("hoverHighlight") : cell.classList.remove("hoverHighlight");
}
});
}
};
function addHoverEventsAndClasses() {
const mainTableTDs = document.querySelectorAll("#hoverTable td");
const mainTableTRs = document.querySelectorAll("#hoverTable tr");
//Dynamically add class names to each row and cell to target
addClass(mainTableTDs, "cell");
addClass(mainTableTRs, "row");
mainTableTDs.forEach((td) => {
td.addEventListener("mouseenter", highlightCol);
td.addEventListener("mouseleave", removeHighlightCol);
});
}
//Helper function for adding highlight classes
function addClass(el, cl) {
el.forEach((child) => {
child.classList.add(cl);
});
};
//Toggle highlight functions. Did it this way so multiple arguments could be passed
function highlightCol(e) {
toggleHighlight(e, true);
}
function removeHighlightCol(e) {
toggleHighlight(e, false);
}
//Grab the current row
const returnCurRow = (e) => {
return e.currentTarget.parentElement.rowIndex;
}

Jquery/TinySort Shifting Entire DIV Container

I am trying to setup a very simple way to sort content. I found TinySort and it seems to be able to do the job, however I need the sorting to move the entire container div not just rearrange the content.
Essentially, I have set up links to activate the sorting function and they are working to sort the spans I have it looking for, however it moves the spans around within the divs containing them.
I built a simply JSFIDDLE to display my struggle.
https://jsfiddle.net/og6jfLjf/
When you sort by Price the prices move and are in order, however they didn't pull the containers with them. They just moved within each container.
$(document).ready(function() {
$(".price-sort").click(function () {
tinysort("span.price");
});
$(".title-sort").click(function () {
tinysort("span.title");
});
});
div{
width: 100px;
height:100px;
background-color: #000;
color: #fff;
margin:10px;
}
#div1{
background-color:#666;
}
#div4{
background-color:#aaa;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.2.2/tinysort.js"></script>
<div id="div4"><span class="title">Title 1</span> - $<span class="price">5</span></div>
<div id="div1"><span class="title">Title 3</span> - $<span class="price">4</span></div>
<div id="div2"><span class="title">Title 2</span> - $<span class="price">6</span></div>
Sort By Price |
Sort By Title |
Solved the problem. I wasn't telling the function to include the div. So I adjusted the script to sort the divs based on the span within them. Here is a working JSFIDDLE to show it.
https://jsfiddle.net/oym96zL5/
$(document).ready(function() {
$(".price-sort").click(function () {
tinysort('div','span.price');
});
$(".title-sort").click(function () {
tinysort('div','span.title');
});
});
You can make a table, it's easier if you have a lot of data. Click the "Item" header and the "Price" header to sort the rows.
$(document).ready(function() {
var table = document.getElementById('xtable'),
tableHead = table.querySelector('thead'),
tableHeaders = tableHead.querySelectorAll('th'),
tableBody = table.querySelector('tbody');
tableHead.addEventListener('click', function(e) {
var tableHeader = e.target,
textContent = tableHeader.textContent,
tableHeaderIndex, isAscending, order;
if (textContent !== 'add row') {
while (tableHeader.nodeName !== 'TH') {
tableHeader = tableHeader.parentNode;
}
tableHeaderIndex = Array.prototype.indexOf.call(tableHeaders, tableHeader);
isAscending = tableHeader.getAttribute('data-order') === 'asc';
order = isAscending ? 'desc' : 'asc';
tableHeader.setAttribute('data-order', order);
tinysort(tableBody.querySelectorAll('tr'), {
selector: 'td:nth-child(' + (tableHeaderIndex + 1) + ')',
order: order
});
}
});
});
table.blue {
padding: 0;
box-shadow: 0 1px 9px 1px #ccc;
border-radius: 6px;
margin: 20px auto;
}
.blue th {
color: #FFF;
background: #2C7EDB;
padding: 10px;
text-align: center;
vertical-align: middle;
}
.blue tr:nth-child(odd) {
background-color: #333;
color: #FFF;
}
.blue tr:nth-child(even) {
background-color: #D3E9FF;
color: #333;
}
.blue td {
border-style: solid;
border-width: 1px;
border-color: #264D73;
padding: 5px;
text-align: left;
vertical-align: top;
}
.blue thead th:first-child {
border-top-left-radius: 6px;
}
.blue thead th:last-child {
border-top-right-radius: 6px;
}
.blue tbody tr:last-child th:first-child {
border-bottom-left-radius: 6px;
}
.blue tbody tr:last-child td:first-child {
border-bottom-left-radius: 6px;
}
.blue tbody tr:last-child td:last-child {
border-bottom-right-radius: 6px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinysort/2.2.2/tinysort.js"></script>
<table class="blue" id="xtable">
<thead>
<tr>
<th data-order="asc">
<a>Item
</a>
</th>
<th>Qty
</th>
<th data-order="asc"><a>Price</a> </th>
<th>Desc</th>
</tr>
</thead>
<tbody>
<tr> <td> Porche </td><td>1</td> <td> $100, 000.00 </td><td>Sports car</td> </tr>
<tr><td>Toilet Paper</td> <td> 5 </td><td>$50.00</td> <td> 8 rolls </td></tr>
<tr> <td> Laptop </td><td>1</td> <td> $600.00 </td><td>HP i7 12GB 1TB</td> </tr>
</tbody>
</table>

Categories

Resources