How to restrict changes to jQuery variable value? - javascript

I have table and each tr element alternates between a white and gray background. When the user hovers over a tr element, the background changes to green. When the user clicks on a tr element, a hidden tr element that is below the clicked on tr element appears. At that time, the tr element the user click on and the hidden on that appear have their backgrounds set to blue. When the user clicks the tr element again, the tr element below once again is hidden. At that point, the background color should go back to it's default color of white or gray. Instead, it stays the blue color.
I know why it's happening, I am just not sure how to fix it in jQuery. Here is my HTML:
<div class="retail-listing">
<div class="container">
<table>
<tr>
<th>Date</th>
<th>Sales Price</th>
<th>Odometer</th>
<th>Year</th>
<th>Series</th>
<th>Body</th>
<th>Drive Type</th>
</tr>
<tr class="retail-list-top">
<td>09/09/2013</td>
<td>$25,200</td>
<td>8,231</td>
<td>2011</td>
<td>Pick-up</td>
<td>Quad Cab</td>
<td>4WD</td>
</tr>
</table>
<table>
<tr class="retail-list-detail">
<td>Vin#: 107RV1GP8BS000000</td>
<td>Make: Dodge Truck</td>
<td>Model: Ram 1500</td>
<td>Sale Type: Dealer</td>
<td>Region: New England</td>
</tr>
</table>
<table>
<tr class="retail-list-top">
<td>09/09/2013</td>
<td>$25,200</td>
<td>8,231</td>
<td>2011</td>
<td>Pick-up</td>
<td>Quad Cab</td>
<td>4WD</td>
</tr>
</table>
<table>
<tr class="retail-list-detail">
<td>Vin#: 107RV1GP8BS000000</td>
<td>Make: Dodge Truck</td>
<td>Model: Ram 1500</td>
<td>Sale Type: Dealer</td>
<td>Region: New England</td>
</tr>
</table>
<table>
<tr class="retail-list-top">
<td>09/09/2013</td>
<td>$25,200</td>
<td>8,231</td>
<td>2011</td>
<td>Pick-up</td>
<td>Quad Cab</td>
<td>4WD</td>
</tr>
</table>
<table>
<tr class="retail-list-detail">
<td>Vin#: 107RV1GP8BS000000</td>
<td>Make: Dodge Truck</td>
<td>Model: Ram 1500</td>
<td>Sale Type: Dealer</td>
<td>Region: New England</td>
</tr>
</table>
</div>
Here is my script:
$(function() {
var bgColor = $('.retail-list-top').css('background-color');
$('.retail-list-detail').hide();
$('.retail-list-top').hover(function () {
$(this).css("background-color", "#c9e9a4");
},
function() {
$(this).css("background-color", bgColor);
}
);
$('.retail-list-top').bind('click', function() {
$(this).toggleClass('detail-slide');
if ($(this).hasClass('detail-slide')) {
$(this).closest('table').next().find('.retail-list-detail').show();
$(this).css({backgroundColor :"#e1eff4", border : "none"});
$(this).hover(function () {
$(this).css("background-color", "#e1eff4");
},
function () {
$(this).css("background-color", "#e1eff4");
}
);
} else {
$(this).closest('table').next().find('.retail-list-detail').hide();
$(this).css({backgroundColor : bgColor, borderBottom : "1px solid #c4c4c4"});
}
})
});

I recommend simplifying this greatly through the use of CSS. I've done so, here.
I also made use of adding and removing a class, blue, to give the "opened" table row a blue background. This way, it is not an inline style when clicked, but just in a class.
JS
$(function() {
$('.retail-list-top').click( function() {
$(this).toggleClass('detail-slide');
if ($(this).hasClass('detail-slide')) {
$(this).closest('table').next().find('.retail-list-detail').show();
$(this).addClass('blue');
} else {
$(this).closest('table').next().find('.retail-list-detail').hide();
$(this).removeClass('blue');
}
})
});
CSS
.retail-list-top:hover{
background:#c9e9a4;
}
.retail-list-detail{
display:none;
}
.blue{
background:#e1eff4;
}

Take a look at this. Is that what you are looking for?
http://jsfiddle.net/55chh/1/
JS
$(function() {
var bgColor = $('.retail-list-top').css('background-color');
$('.retail-list-top').bind('click', function() {
$(this).toggleClass('detail-slide');
if ($(this).hasClass('detail-slide')) {
$(this).closest('table').next().find('.retail-list-detail').show();
$(this).css({background:"#e1eff4", border : "none"});
$(this).removeClass("retail-list-hover");
} else {
$(this).closest('table').next().find('.retail-list-detail').hide();
$(this).css({backgroundColor : bgColor, borderBottom : "1px solid #c4c4c4"});
$(this).addClass("retail-list-hover");
}
})
});
CSS
.retail-list-hover:hover {
background: #c9e9a4;
}
.retail-list-detail {
display: none;
}

Related

Call Function on Tabel Row Hover

I want to call a function that prints the contents of a row every time I hover over it in a table. So far I have this:
function tablemouseover(event) {
console.log(event.target);
}
<table>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
However this just gets me <td> I am hovered over.
You can get the text of the cell by calling textContent. If you want the col/row indices, you can get them by grabbing the positional index of the element within it's row or table (body).
const getChildIndex = node =>
Array.prototype.indexOf.call(node.parentNode.children, node);
function tablemouseover(event) {
const
row = event.currentTarget,
col = event.target,
rowIndex = getChildIndex(row),
colIndex = getChildIndex(col),
allText = [...row.children].map(td => td.textContent);
console.log(`Cell (${colIndex}, ${rowIndex}): ${event.target.textContent}`);
console.log(`Row [${rowIndex}]: ${JSON.stringify(allText)}`);
}
table, th, td { border: thin solid grey; }
table { border-collapse: collapse; }
th, td { padding: 0.5em; }
.as-console-wrapper { max-height: 5.25em !important; }
<table>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
Use closest('tr') to search up the DOM tree for the closest tr parent and then log its innerHTML like so:
function tablemouseover(event){
console.log(event.target.closest('tr').innerHTML);
}
<table>
<tr onmouseover='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>
Use onmouseenter not onmouseover
Read what different between
function tablemouseover(event){
console.log(event.target.innerHTML);
}
<table>
<tr onmouseenter ='tablemouseover(event)'>
<td>times[row]</td>
<td>locations[row][0]</td>
<td>locations[row][1]</td>
<td>AllDistances[row]m</td>
</tr>
</table>

CSS wildcard selection

I use this wildcard in css to select the data containing "," commas.
td[data-content*=","]{
background-color: yellow;
}
Is there a way to make a distinction for the numbers of "," in the data. I can highlight data containing one comma in yellow. I'd like to highlight data containing two commas in green. Is there a way to do this with CSS? Thanks.
I want to use different colors at the same time according to the number of commas data contains. So the data like (1,2) will be yellow. and the data like (1,2,3) will be green.
Here's a jQuery solution:
$('td').each(function() {
var c = $(this).text();
if (!c) return;
var commas = c.split(",").length - 1;
if (commas === 1) $(this).css("background-color", "yellow");
if (commas === 2) $(this).css("background-color", "green");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>a</td>
<td>a,b</td>
<td>a,b,c</td>
</tr>
</tbody>
</table>
Should be pretty self-explanatory:
grab tds
read data-content attribute and count commas
set style
You cannot do this in pure CSS.
The CSS attribute selectors only allow literal matching and no wildcard/glob/regexp matching
See here for a definition: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
I have made a VanillaJS solution. In that I count the comma matches in the data-content attribute and add a new data-content-classification attribute with different values depending on number of matches.
console.clear()
// Start after loading of the document
window.addEventListener('load', function() {
// get all the table cells with data-content attribute
var tdContents = document.querySelectorAll('td[data-content]');
// loop over those cells
for (var i = 0; i < tdContents.length; i++) {
// anonymous function which gets a single table cell element as argument
;(function(el) {
// get the attribute's value
var dc = el.getAttribute('data-content')
// react according to the length of the comma matches (with fallback to prevent error)
switch ((dc.match(/,/g) || []).length) {
case 0:
// if no comma found
el.setAttribute('data-content-classification', 0);
break;
case 1:
// if one comma found
el.setAttribute('data-content-classification', 1);
break;
default:
// default, meaning more than one comma
el.setAttribute('data-content-classification', 2);
}
})(tdContents[i]);
}
})
#charset "UTF-8";
td[data-content-classification="1"] {
background-color: yellow;
}
td[data-content-classification="2"] {
background-color: red;
}
td:after,
td:before {
order: -2;
content: "data-content: " attr(data-content);
background-color: goldenrod;
min-width: 50px;
display: inline-block;
margin: 2px;
padding: 2px;
margin-right: 10px;
}
td:after {
order: -1;
content: "data-content-classifiction: " attr(data-content-classification) " ";
}
td {
padding: 3px;
display: flex;
width: 100%;
}
<table>
<tr>
<td>Lorem, ipsum dolor.</td>
</tr>
<tr>
<td data-content="1">Lorem, ipsum dolor.</td>
</tr>
<tr>
<td data-content="1,2">Lorem, ipsum dolor.</td>
</tr>
<tr>
<td data-content="2,3">Eveniet, sunt reiciendis.</td>
</tr>
<tr>
<td data-content="1,2,3">Accusantium, quam impedit.</td>
</tr>
<tr>
<td data-content="1,2,3,5">Accusantium, quam impedit.</td>
</tr>
</table>
Note that this answer contains jQuery notation, and so it will require a jQuery library to work.
What you could do is loop through all your data-content that has a , like you initially wanted with your wildcard selector.
You can then use $(this).attr() to get the contents of your custom attribute.
You can then take that string, turn it into an array using .split(). After that you count the length of the array. Remember to subtract by 1, because arrays count from 0.
You then check for the condition of commas and set your CSS logic by using the css() function.
Example:
function testing() {
$('[data-content*=","]').each(function() {
var myAttr=$(this).attr('data-content');
var myArr=myAttr.split(",");
var countCommas=myArr.length - 1;
var yellow=1;
var green=2;
if(countCommas == yellow) {
$(this).css("background-color", "yellow");
}
else if(countCommas == green) {
$(this).css("background-color", "green");
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td data-content="1,2">
1,2
</td>
</tr>
<tr>
<td data-content="1,2,3">
1,2,3
</td>
</tr>
<tr>
<td>
No color
</td>
</tr>
</table>
<br />
<button onclick="testing();">Test</button>
You don't need to trigger the function via a button click, I just added that for test purposes, so that you could see the effect.
If you want it to run automatically, all you have to do is put it inside a document.ready block.
Example:
$(document).ready(function() {
$('[data-content*=","]').each(function() {
var myAttr=$(this).attr('data-content');
var myArr=myAttr.split(",");
var countCommas=myArr.length - 1;
var yellow=1;
var green=2;
if(countCommas == yellow) {
$(this).css("background-color", "yellow");
}
else if(countCommas == green) {
$(this).css("background-color", "green");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td data-content="1,2">
1,2
</td>
</tr>
<tr>
<td data-content="1,2,3">
1,2,3
</td>
</tr>
<tr>
<td>
No color
</td>
</tr>
</table>

Apply CSS "stripe" effect to dynamically-inserted table rows in JavaScript

I have made a table. In that, when I click on button, a row is added. I want to assign alternate color to the row inserted.
$("#new-row").click(function() {
$('#first').clone(true).insertAfter('#demo tbody>tr:last');
if ($('#demo tr:last').hasClass("lgrey")) {
$('#demo tr:last').removeClass("lgrey");
$('#demo tr:last').addClass("dgrey");
} else if ($('#demo tr:last').hasClass("dgrey")) {
$('#demo tr:last').removeClass("dgrey");
$('#demo tr:last').addClass("lgrey");
};
});
.lgrey {
background-color: #eee;
}
.dgrey {
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="demo">
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
</tr>
<tr class="lgrey" id="first">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<button id="new-row">ADD ROW</button>
But running this code does not give desired result.
Please help in assigning an alternate color to inserted rows.
You don't need JavaScript for this . . . use the :nth-child(an+b) selector instead. This approach is much clearer than messing around with unnecessary classes and jQuery code.
Replace the .lgrey and .dgrey selectors with #demo tr:nth-child(2n+2), and #demo tr:nth-child(2n+3), respectively.
(Note that using even and odd, as some others have suggested, will not allow you to leave the header row unstyled.)
$('#new-row').click(function () {
$('#first').clone(true).insertAfter('#demo tr:last')
})
#demo tr:nth-child(2n+2) {
background-color: #eee;
}
#demo tr:nth-child(2n+3) {
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="demo">
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
</tr>
<tr id="first">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<button id="new-row">ADD ROW</button>
Use tr:nth-child css property like:
tr:nth-child(even) {
background-color: #004400;
}
tr:nth-child(odd) {
background-color: #000000;
}
It will handle the alternate color for each tr either generated static or dynamic.
You should really use CSS's nth-child(even) and nth-child(even)for this.
$("#new-row").click(function() {
$('#first').clone(true).insertAfter('#demo tbody>tr:last');
});
tr:nth-child(even) {
background-color: #eee;
}
tr:nth-child(odd) {
background-color: #ccc;;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="demo">
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
</tr>
<tr class="lgrey" id="first">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<button id="new-row">ADD ROW</button>
Use css to handle alternate row colors
tr:nth-child(even) {
background-color: #eee;
}
tr:nth-child(even) {
background-color: #ccc;
}
DEMO
I select row color before add new row as following:
$("#new-row").click(function() {
if ($('#demo tr:last').hasClass("lgrey")) {
var add = "dgrey";
var remove = "lgrey";
} else if ($('#demo tr:last').hasClass("dgrey")) {
var add = "lgrey";
var remove = "dgrey";
};
$('#first').clone(true).insertAfter('#demo tbody>tr:last');
$('#demo tr:last').removeClass(remove);
$('#demo tr:last').addClass(add);
});
.lgrey {
background-color: #eee;
}
.dgrey {
background-color: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="demo">
<tr>
<th>H1</th>
<th>H2</th>
<th>H3</th>
</tr>
<tr class="lgrey" id="first">
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
<button id="new-row">ADD ROW</button>

Remove <tr> if the <td> does not contain the value of the <input>

I'm trying to implement a live search (filtering) feature with jQuery for a table. The table contains a list of people and their grad year and high school. When the user starts typing inside the search input, the table will start filtering out all the rows that do not contain the value of the search input. It will also add the class of highlight to the td that the searched text was in.
How can I filter each row and highlight the td element when the user searches something? I tried implementing this with the code below but to no avail. What can I tweak in this code to get this working correctly?
Below is my code. Here is my jsFiddle: http://jsfiddle.net/mikerodriguez/jybrnt22/2/
jQuery
$("#search").on("keyup", function(){
var input = $(this).val();
$("#search_table tbody tr").each(function(){
var row = $(this);
var td_element = $("#search_table tbody tr td");
if(input !== td_element.text()){
row.hide();
}else{
row.show();
td_element().addClass("highlight");
}
})
});
CSS
body {
margin: 0;
padding: 0;
font-family: Arial;
font-size: 14px;
}
.search_field {
padding: 15px;
}
.search_field input[type="text"] {
padding: 15px;
width: 98%;
font-size: 18px;
}
.search_table_container {
padding: 15px;
}
.search_table {
width: 100%;
}
.search_table th {
background-color: #AAA;
font-weight: bold;
padding: 10px 0px;
}
.search_table td {
text-align: center;
background-color: #CCC;
padding: 15px 0px;
}
HTML
<div class="search_field">
<input type="text" id="search" placeholder="Search for Person, Class, or High School">
</div>
<div class="search_table_container">
<table id="search_table" class="search_table">
<thead>
<tr>
<th>Name</th>
<th>Class</th>
<th>High School</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Smith</td>
<td>2014</td>
<td>Some High School</td>
</tr>
<tr>
<td>Homer Simpson</td>
<td>2015</td>
<td>Springfield High School</td>
</tr>
<tr>
<td>Bugs Bunny</td>
<td>2050</td>
<td>Looney Tunes High School</td>
</tr>
<tr>
<td>George Washington</td>
<td>1749</td>
<td>Georgetown Academy</td>
</tr>
<tr>
<td>Marty McFly</td>
<td>1991</td>
<td>Back to the Future</td>
</tr>
<tr>
<td>Doc Emmet Brown</td>
<td>1965</td>
<td>One Point Twenty-one Gigawatts</td>
</tr>
</tbody>
</table>
</div>
One problem is:
input !== td_element.text()
You're comparing partial input values to the entire contents of your columns. Instead it should be something like
td_element.text().indexOf(input) == -1
But there were actually quite a few issues (including simple syntax errors, e.g., td_element is not a function). I tweaked your example to something that works: http://jsfiddle.net/gh5kjku5/2/
$("#search").on("keyup", function(){
var input = $(this).val();
$("#search_table tbody tr").each(function(){
var row = $(this);
var td_elements = row.find('td');
var colText = td_elements.text();
if(colText.indexOf(input) == -1){
row.hide();
}else{
row.show();
td_elements.addClass("highlight");
}
})});
You'll need to do a bit more work to do things like reset the td background colors when the search box is cleared. Good luck!
hi try this it's working.
$("#search").on("keyup", function () {
var input = $(this).val();
if (input == '') {
$("#search_table tbody tr").show();
} else {
$("#search_table tbody tr").show();
$("#search_table tbody tr").each(function () {
var row = $(this);
var td_element = $("#search_table tbody tr td");
if ($(row).text().trim().toUpperCase().indexOf(input.toUpperCase()) > -1) {
row.hide();
} else {
row.show();
}
});
}
});
see jsfiddle link http://jsfiddle.net/jybrnt22/14/

Pure Javascript table column hover effect?

I need a pure Javascript (no jQuery) hover effect for HTML table columns.
I found this which supposedly contains a fix for Firefox yet it still looks broken to me.
I found this which works only for the first column.
Unfortunately, my Javascript skills are amateur at best, so my attempts to modify either of these turned out to be fruitless.
Is this possible? Any suggestions would be appreciated.
Here's a column-based approach. When the mouse enters/leaves a cell, find the corresponding <col/> by index and apply/remove the desired class:
(() => {
const myTable = document.getElementById("myTable");
const cols = myTable.querySelectorAll("col");
const events = {
mouseover: e => {
const t = e.target.closest("td");
if (t) {
const cellIndex = t.cellIndex;
for (let i = 0, n = cols.length; i < n; i++) {
cols[i].classList[i === cellIndex ? "add" : "remove"]("hovered");
}
}
},
mouseout: e => {
const t = e.target;
if (t.nodeName === "TD" && !t.contains(e.relatedTarget)) {
cols[t.cellIndex].classList.remove("hovered");
}
}
};
for (let event in events) {
myTable.addEventListener(event, events[event]);
}
})();
.hovered {
background-color: #FF0000;
}
<table id="myTable" cellspacing="0">
<col />
<col />
<col />
<tbody>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
</tr>
<tr>
<td>Col1</td>
<td>Col2
<span>nested</span>
</td>
<td>Col3</td>
</tr>
<tr>
<td>Col1</td>
<td>Col2</td>
<td>Col3</td>
</tr>
</tbody>
</table>
See also:
Element.classList
Node.Contains()
Element.Closest()
Here are your codes (+ demo):
var HOVER_CLASS = 'hovered';
var hovered;
table.addEventListener('mouseover', function (e) {
if (e.target.tagName.toLowerCase() == 'td') {
var index = e.target.cellIndex;
hovered && hovered.forEach(function (cell) {
cell.classList.remove(HOVER_CLASS);
});
hovered = Array.prototype.map.call(
table.rows,
function (row) {
var i = index;
while (!cell && i >= 0) {
var cell = row.cells[i];
i -= 1;
}
return cell;
}
);
hovered.forEach(function (cell) {
cell.classList.add(HOVER_CLASS);
});
}
}, true);
table.addEventListener('mouseout', function (e) {
hovered && hovered.forEach(function (cell) {
cell.classList.remove(HOVER_CLASS);
});
hovered = null;
}, true);
Best method I can think of is to give each <td> a class name that identifies the column it's in. i.e. "col1, col2, etc"
Then you can use the document.getElementsByClassName("colX") function to get an array of those <td>s, loop through the array and modify the style. Warning, this may not work in older browsers that don't have a getElementsByClassName function, but there are workarounds you can find easily for that. The best of which would be to use jQuery, not sure why you're against it.
You create a class in css
.HoverTabla > tbody > tr:hover,
.HoverTabla > tbody > tr:focus {
background-color: #42C6F7;
}
and then you call it from the table in the html
<table class="table HoverTabla" id="tbl_Plan">
<thead>
<tr>
<th>Tipo de plan</th>
<th>Tiempo en días</th>
<th>Max. Usuario</th>
<th>Max. Capacidad</th>
<th>Max. Casos</th>
<th>Valor plan</th>
<th></th>
</tr>
</thead>
</table>
CSS-only answer I found after a little bit of googling: https://css-tricks.com/simple-css-row-column-highlighting/
Each cell (<td>) in the table is given some padding through pseudo elements, which is used to create the hover effect. To make sure the hover effect doesn't extend further than the table itself, an overflow: hidden is used.
The sub-title in the article summarizes it all: "The trick is using huge pseudo elements on the <td>s, hidden by the table overflow"
Try
<td onMouseOver="this.bgColor='yellow';" onMouseOut="this.bgColor='white';">
This will work, no javascript needed. So it should work even when people turn javascript off.
Jfiddle: http://jsfiddle.net/vJacZ/
​
Html:
​<table>
<tr>
<td class="column1">
Column1
</td>
<td class="column2">
Column2
</td>
</tr>
</table>
Css:
.column1{
color:black;
}
.column1:hover{
color:red;
}
.column2{
color:black;
}
.column2:hover{
color:green;
}

Categories

Resources