I'm writing a simple html game. I want to compare the red cards' numbers to random numbers. If any one of random numbers equal to red cards' numbers, then dynamically add "BINGO" text to red square's back class when user flip red cards. It's like bingo game, user don't know which cards have "BINGO" strings before they flip red cards. I have problem with comparing array numbers to front class numbers and dynamically add "BINGO" string to red cards. Can somebody help please?
JSFIDDLE is here: http://jsfiddle.net/7emqLztp/28/
$(".treasure").flip();
var howMany = 3;
var min = 2;
var max = 5;
var a = new Array();
while (a.length < howMany) {
var n = Math.floor(Math.random() * (max - min) + 0.5) + min;
if (a.indexOf(n) == -1) {
a.push(n);
}
}
$("#button").click(function () {
$('.num').text(a)
});
.table
{
display: table;
border-collapse:separate;
/*border-spacing: 5px;*/
/*border: 1px solid #fff;*/
}
.table-row
{
display: table-row;
}
.table-cell
{
text-align: center;
display: table-cell;
border: 0.5px solid #231f20;
vertical-align: middle;
width: 50px;
height: 50px;
}
.treasure
{
background-color: red;
}
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<head>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
</head>
<div class="table">
<div class="table-row">
<div class="table-cell">
1
</div>
<div class="table-cell treasure">
<div class="front">2</div>
<div class="back"></div>
</div>
<div class="table-cell treasure">
<div class="front">3</div>
<div class="back"></div>
</div>
<div class="table-cell treasure">
<div class="front">4</div>
<div class="back"></div>
</div>
<div class="table-cell treasure">
<div class="front">5</div>
<div class="back"></div>
</div>
<div class="table-cell">
6
</div>
</div>
</div>
<button id="button">Random Num</button>
<div class="num"></div>
Please have a look at this updated code. I'm pretty sure this is working.
$(".treasure").flip().find(".back").text("-")
var cardCount = 3;
var bingoCards = [];
do {
let n = Math.floor(Math.random() * 4) + 2;
if (bingoCards.indexOf(n) === -1) {
bingoCards.push(n)
let item = $(".treasure")[n-2];
$(item).find(".back").text("BINGO")
}
} while (bingoCards.length < cardCount)
$("#button").click(function() {
$("#result").html(`The numbers are: <b>${bingoCards.join(", ")}</b>`)
});
.table {
display: table;
border-collapse: separate;
/*border-spacing: 5px;*/
/*border: 1px solid #fff;*/
}
.table-row {
display: table-row;
}
.table-cell {
text-align: center;
display: table-cell;
border: 0.5px solid #231f20;
vertical-align: middle;
width: 50px;
height: 50px;
}
.treasure {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<script src="https://cdn.rawgit.com/nnattawat/flip/master/dist/jquery.flip.min.js"></script>
<div class="table">
<div class="table-row">
<div class="table-cell">1</div>
<div class="table-cell treasure">
<div class="front">2</div><div class="back"></div>
</div>
<div class="table-cell treasure">
<div class="front">3</div><div class="back"></div>
</div>
<div class="table-cell treasure">
<div class="front">4</div><div class="back"></div>
</div>
<div class="table-cell treasure">
<div class="front">5</div><div class="back"></div>
</div>
<div class="table-cell">6</div>
</div>
</div>
<button id="button">Random Numbers</button>
<div id="result"></div>
Related
I am trying to create a list of progress bars.
The values will be between 15 and 30.
The idea is that 15 is 50% and 30 is 100%. What I'm having trouble with is using jquery to set the width of each element/progress bar to the correct width percentage according to the value provided in the data attribute.
If the value is 15 then the bar width should be 50%.
If the vaule is 30 then the bar width should be 100%.
I cannot work out what the calculation would be to make this happen?
I don't have any jQuery to show as i've not had any success so it would just be non-sense i'm afraid.
My HTML is as follows though:
.Progress {
width: 100%;
background-color: #ddd;
height: 30px;
margin-bottom: 10px;
}
.Bar {
width: 45%;
height: 30px;
background-color: #4CAF50;
padding-left: 10px;
padding-right: 10px;
line-height: 30px;
color: white;
display: block;
}
.name {
float: left;
}
.pct {
float: right;
}
<div class="Progress">
<div class="Bar" data-value="15">
<div class="name">NAME</div>
<div class="pct">15%</div>
</div>
</div>
<div class="Progress">
<div class="Bar" data-value="20">
<div class="name">NAME</div>
<div class="pct">20%</div>
</div>
</div>
<div class="Progress">
<div class="Bar" data-value="25">
<div class="name">NAME</div>
<div class="pct">25%</div>
</div>
</div>
<div class="Progress">
<div class="Bar" data-value="30">
<div class="name">NAME</div>
<div class="pct">30%</div>
</div>
</div>
I realised I needed to acheive a slightly different outcome in the end.
My goal was to have a min and max value. If the value was <= the min value the width of the progress bar would be set to 50% and if the value was >= the max value it would be set to 100% and then automatically calculated in between these values.
Using the below 2 functions I was able to acheive this
function range(start, end, step = 1) {
const len = Math.floor((end - start) / step) + 1
return Array(len).fill().map((_, idx) => start + (idx * step))
}
function trust15width(value) {
var lowEnd = 15; // This is the minimum value to be calculated
var highEnd = 18; // this is the maximum value to be calculated
if(value > highEnd) {
// if the value is bigger than the maximum value, force the percentage to be 100
var newWidth = 100;
} else if(value < lowEnd) {
// if the value is smaller than the minimum value, force the percentage to be 50
var newWidth = 50;
} else {
var result = range(lowEnd, highEnd, 0.1); // Change these variables for the start and end of the range.
var increments = result.length;
var percentageIncrease = 50 / result.length;
var position = result.indexOf(value)+1; // change this number according to the market share
var newWidth = 50 + (position * percentageIncrease);
}
return newWidth;
}
console.log(trust15width(14.7));
Using JQuery .each() on your Bar and setting the CSS width attribute by getting the data-value and doing some simple Math percentages would do the trick
$( ".Bar" ).each(function() {
let percent = $(this).attr('data-value');
percent = percent * 100 / 30;
//For too high values :
if(percent > 100){
percent = 100;
}
//$(this).css('width', percent+'%' );
//With animation as asked :
$(this).animate({width: percent+'%' }, 2000);
});
.Progress {
width: 100%;
background-color: #ddd;
height:30px;
margin-bottom:10px;
}
.Bar {
width: 45%;
height: 30px;
background-color: #4CAF50;
padding-left:10px;
padding-right:10px;
line-height: 30px;
color: white;
display:block;
}
.name {
float:left;
}
.pct {
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Progress">
<div class="Bar" data-value="15"><div class="name">NAME</div><div class="pct">15%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="20"><div class="name">NAME</div><div class="pct">20%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="25"><div class="name">NAME</div><div class="pct">25%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="30"><div class="name">NAME</div><div class="pct">30%</div></div>
</div>
I set the widths according to data-value
let bar = document.querySelectorAll(".Bar");
let biggest_value = 0;
bar.forEach(function(par){
if(Number(par.getAttribute("data-value")) > biggest_value){
biggest_value = Number(par.getAttribute("data-value"));
}
});
let rate = 100 / biggest_value;
bar.forEach(function(par){
par.style.width = (par.getAttribute("data-value")*rate) + "%";
});
* {
box-sizing:border-box;
}
.Progress {
width: 100%;
background-color: #ddd;
height:30px;
margin-bottom:10px;
}
.Bar {
width: 45%;
height: 30px;
background-color: #4CAF50;
padding-left:10px;
padding-right:10px;
line-height: 30px;
color: white;
display:block;
}
.name {
float:left;
}
.pct {
float:right;
}
<div class="Progress">
<div class="Bar" data-value="15"><div class="name">NAME</div><div class="pct">15%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="20"><div class="name">NAME</div><div class="pct">20%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="25"><div class="name">NAME</div><div class="pct">25%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="30"><div class="name">NAME</div><div class="pct">30%</div></div>
</div>
You need to divide 30 by the value of .Bar and then multiply it with 100 also. Set box-sizing:border-box
/*$('.Progress').each(function(){
let value = $(this).find('.Bar').css('width', '30')
console.log(value);
let parentWidth = getComputedStyle(this).width;
})*/
let total = 30;
$('.Bar').each(function(){
let value = (parseInt($(this).data().value)/total) * 100;
$(this).css('width',value + '%')
})
.Progress {
width: 100%;
background-color: #ddd;
height:30px;
margin-bottom:10px;
}
.Bar {
box-sizing:border-box;
height: 30px;
background-color: #4CAF50;
padding-left:10px;
padding-right:10px;
line-height: 30px;
color: white;
display:block;
}
.name {
float:left;
}
.pct {
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Progress">
<div class="Bar" data-value="15"><div class="name">NAME</div><div class="pct">15%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="20"><div class="name">NAME</div><div class="pct">20%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="25"><div class="name">NAME</div><div class="pct">25%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="30"><div class="name">NAME</div><div class="pct">30%</div></div>
</div>
this is the jQuery code you need :D
edit: oh no seems like i was to slow :(
edit2: alright, now dynamic and right numbers
$( document ).ready(function() {
var max = 0;
$('.Bar').each(function(i, obj) {
if ($(this).data("value") > max){
max = $(this).data("value");
}
});
$('.Bar').each(function(i, obj) {
$(this).css("width", (100/max)*$(this).data("value")+"%");
$(this).find(".pct").html(Math.round((100/max)*$(this).data("value"))+"%");
});
});
.Progress {
width: 100%;
background-color: #ddd;
height:30px;
margin-bottom:10px;
}
.Bar {
width: 45%;
height: 30px;
background-color: #4CAF50;
padding-left:10px;
padding-right:10px;
line-height: 30px;
color: white;
display:block;
}
.name {
float:left;
}
.pct {
float:right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Progress">
<div class="Bar" data-value="15"><div class="name">NAME</div><div class="pct">15%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="20"><div class="name">NAME</div><div class="pct">20%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="25"><div class="name">NAME</div><div class="pct">25%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="30"><div class="name">NAME</div><div class="pct">30%</div></div>
</div>
Here's a full proof solution with corresponding mathematics -
Shows the percentage on bars
Set maximum value dynamically, in your case it's 30
Handled two worst cases -
For data-value < 1, shows 0%
For data-value > Max, shows 100%
function findPercentagePer30(x, max) {
return ((x / max) * 100).toFixed(2).replace(/[.,]00$/, "");
}
$(function() {
$('.Bar').each(function() {
var dataVal = $(this).attr("data-value");
var percentage = findPercentagePer30(dataVal, 30); // max = 30 here
if(percentage > 0) {
percentage = percentage <= 100 ? percentage : 100;
$(this).css("width", percentage + '%');
$(this).find(".pct:first").text(percentage + '%');
} else {
$(this).css("background-color", 'transparent');
$(this).find(".pct:first").text('0%');
}
});
});
.Progress {
width: 100%;
background-color: #ddd;
height: 30px;
margin-bottom: 10px;
}
.Bar {
width: 45%;
height: 30px;
background-color: #4CAF50;
padding-left: 10px;
padding-right: 10px;
line-height: 30px;
color: white;
display: block;
box-sizing: border-box; /* <-- added this */
}
.name {
float: left;
}
.pct {
float: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="Progress">
<div class="Bar" data-value="15"><div class="name">NAME</div><div class="pct">15%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="20"><div class="name">NAME</div><div class="pct">20%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="25"><div class="name">NAME</div><div class="pct">25%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="30"><div class="name">NAME</div><div class="pct">30%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="0"><div class="name">WORST CASE (data-value < 1)</div><div class="pct">0%</div></div>
</div>
<div class="Progress">
<div class="Bar" data-value="35"><div class="name">WORST CASE (data-value > Max)</div><div class="pct">35%</div></div>
</div>
Note: Remember to add box-sizing: border-box; to your .Bar, so that all bars will look uniform.
I want to apply a style to an element when hovering over another element in a different parent div.
The classes are lvcontainer and rvcontainer and when I hover over lvcontainer, rvcontainer will be set to display: block.
I'm trying to make a multidimensional drop menu like blackberry navigation.
var lvcontainer = document.getElementsByClassName('lvcontainer');
var rvcontainer = document.getElementsByClassName('rvcontainer');
for (i = 0; i < 1; i++) {
lvcontainer[i].addEventListener("mouseover", function() {
rvcontainer[i].style.display = "block";
}, false);
}
body {
margin: auto;
}
#container {
display: table;
}
#lcontainer {
padding: 0 10px 0 10px;
display: table-cell;
}
#rcontainer {
padding: 0 10px 0 10px;
display: table-cell;
}
.rvcontainer {
display: none;
}
<div id="container">
<div id="lcontainer">
<div class="lvcontainer">
Country
</div>
<div class="lvcontainer">
Genre
</div>
</div>
<div id="rcontainer">
<div class="rvcontainer">
Japan
<br> Korea
<br> American
<br>
</div>
<div class="rvcontainer">
Comedy
<br> Mystery
<br> Horror
<br>
</div>
</div>
</div>
There are a few issues but you can do what you want by looping through and protecting your index.
The below assumes there will always be the same number of lvcontainer and rvcontainer
var lvcontainer = document.getElementsByClassName('lvcontainer');
var rvcontainer = document.getElementsByClassName('rvcontainer');
for (i = 0; i < lvcontainer.length; i++) { // loop to the length
(function(protectedIndex) { // protect the index so clicks won't use last increment of i
// show
lvcontainer[protectedIndex].addEventListener("mouseover", function() {
rvcontainer[protectedIndex].style.display = "block";
}, false);
// hide
lvcontainer[protectedIndex].addEventListener("mouseout", function() {
rvcontainer[protectedIndex].style.display = "none";
}, false);
})(i);
}
body {
margin: auto;
}
#container {
display: table;
}
#lcontainer {
padding: 0 10px 0 10px;
display: table-cell;
}
#rcontainer {
padding: 0 10px 0 10px;
display: table-cell;
}
.rvcontainer {
display: none;
}
<div id="container">
<div id="lcontainer">
<div class="lvcontainer">
Country
</div>
<div class="lvcontainer">
Genre
</div>
</div>
<div id="rcontainer">
<div class="rvcontainer">
Japan
<br> Korea
<br> American
<br>
</div>
<div class="rvcontainer">
Comedy
<br> Mystery
<br> Horror
<br>
</div>
</div>
</div>
After your comment, I would restructure your html to be a bit more semantically correct:
#container ul {
margin: 0;
padding: 0;
list-style: none;
}
#lcontainer {
display: inline-block;
position: relative;
}
.lvcontainer {
padding: 0.1em 0.5em 0.1em 0.1em;
}
.rvcontainer {
display: none;
position: absolute;
top: 0;
left: 100%;
}
.lvcontainer:hover>.rvcontainer {
display: block;
}
<div id="container">
<ul id="lcontainer">
<li class="lvcontainer">
Country
<ul class="rvcontainer">
<li>Japan</li>
<li>Korea</li>
<li>American</li>
</ul>
</li>
<li class="lvcontainer">
Genre
<ul class="rvcontainer">
<li>Comedy</li>
<li>Mystery</li>
<li>Horror</li>
</ul>
</li>
</ul>
</div>
Maybe is not the cleaner solution but you can try this:
<html>
<head>
<style>
body {
margin: auto;
}
#container {
display: table;
}
#lcontainer {
padding: 0 10px 0 10px;
display: table-cell;
}
#rcontainer {
padding: 0 10px 0 10px;
display: table-cell;
}
.rvcontainer-c,.rvcontainer-g {
display: none;
}
</style>
</head>
<body>
<div id="container">
<div id="lcontainer">
<div class="lvcontainer-c">
Country
</div>
<div class="lvcontainer-g">
Genre
</div>
</div>
<div id="rcontainer">
<div class="rvcontainer-c">
Japan
<br> Korea
<br> American
<br>
</div>
<div class="rvcontainer-g">
Comedy
<br> Mystery
<br> Horror
<br>
</div>
</div>
</div>
</body>
<script>
var lvcontainerC = document.getElementsByClassName('lvcontainer-c');
var rvcontainerC = document.getElementsByClassName('rvcontainer-c');
lvcontainerC[0].addEventListener("mouseover", function(){
rvcontainerC[0].style.display = "block";
}, false);
lvcontainerC[0].addEventListener("mouseout", function(){
rvcontainerC[0].style.display = "none";
}, false);
var lvcontainerG = document.getElementsByClassName('lvcontainer-g');
var rvcontainerG = document.getElementsByClassName('rvcontainer-g');
lvcontainerG[0].addEventListener("mouseover", function(){
rvcontainerG[0].style.display = "block";
}, false);
lvcontainerG[0].addEventListener("mouseout", function(){
rvcontainerG[0].style.display = "none";
}, false);
</script>
</html>
I got a row, with X amount of columns inside it. How can I, if there is an overflow of columns, replace the regular scrollbar, with left/right image arrows on each side. See the less than and greater than arrows in the below example to see what I mean.
I want to keep it vanilla JS, not jQuery.
div {
display: inline-block;
box-sizing: border-box;
position: relative;
}
.container {
width: 300px;
border: 1px solid black;
position: relative;
white-space: nowrap;
}
.row {
width: 90%;
overflow-x: scroll;
}
.col {
width: 100px;
height: 30px;
}
.grey {
background-color: #cccccc;
}
<div class="container">
<
<div class="row">
<div class="col">
one
</div>
<div class="col grey">
two
</div>
<div class="col">
three
</div>
<div class="col grey">
four
</div>
<div class="col">
five
</div>
<div class="col grey">
six
</div>
</div>
>
</div>
If you don't want to use jQuery, we can add ID's to the lt and gt symbols. This way we can target the images in an onclick event.
HTML:
<div class="container">
<span id="lt"><</span>
<div id="row">
<div class="col">
one
</div>
...
<div class="col grey">
six
</div>
</div>
<span id="gt">></span>
</div>
Then add onclick handlers to the symbols to scroll through the row.
JS:
var row = document.getElementById("row");
row.scrollRight = 0;
row.scrollLeft = 0;
document.getElementById("lt").onclick = function(){
row.scrollLeft = row.scrollLeft - 50;
}
document.getElementById("gt").onclick = function(){
row.scrollLeft = row.scrollLeft + 50;
}
Last, lets remove the horizontal scrollbar.
CSS:
#row {
width: 90%;
overflow-x: hidden;
}
Working fiddle here: https://fiddle.jshell.net/26jrtdky/1/
I have three divs in a row
One on the left, one in the middle and one on the right.
The one's on the left and right need to expand AWAY from the one in the middle.
Please see image:
my clients.php which displays them all
echo "<div style='width: 100%; display: inline-block;'>";
while ($client = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))
{
$positive = $client['Pos'];
$negative = $client['Neg'];
$total = ($positive + $negative);
// Calculate width in percentage
if ($total > 0)
{
$positiveWidth = ($positive/$total)*100;
$negativeWidth = ($negative/$total)*100;
}
else
{
$positiveWidth = "0%";
$negativeWidth = "0%";
}
echo "<div class='clientid' style='height: 50px; font-size: 18px; vertical-align: middle; display: inline-block; width: 100%'>" .
"
<div class='positive-bar' style='width: $positiveWidth;%;'></div>
<div style='display: inline-block; width: 5%;'>
<span style='font-size: 20px;' class='hover-cursor fa fa-chevron-up vote-up'></span>
</div>" .
"<div id='client-name' class='hover-cursor hvr-underline-reveal voteup votedown' data-clientid='{$client['ClientID']}' style='width: 20%; display: inline-block;'>" . $client['Client'] . "</div>" .
"<div style='display: inline-block; width: 5%;'>
<span style='font-size: 20px; text-align: right;' class='hover-cursor fa fa-chevron-down vote-down'></span>
</div>
<div class='negative-bar' style='width: $negativeWidth;%;'></div>
</div>
<br />";
}
echo "</div>";
This means that also the divs only get as big as you see in the image and push the text out of the center.
The relevant piece of CSS:
.positive-bar
{
height: 25px;
background-color: #64BE06;
display: inline-block;
border-radius: 5px;
}
.negative-bar
{
height: 25px;
background-color: red;
display: inline-block;
border-radius: 5px;
}
So my question is
How can i make the DIV's (Progress bars) Expand outwards instead of pushing in.
Try doing it using flexbox
.container{
width:100%;
display:flex;
flex-direction:row;
margin:5px 0;
}
.middleOne{
flex-grow:1;
height:25px;
text-align:center;
border:1px solid red;
}
.rightOne,.leftOne{
height:25px;
width:25%;
min-width:100px;
border:1px solid green;
display:flex;
}
.leftOne{
justify-content:flex-end;
}
.rightOne{
justify-content:flex-start;
}
.progress{
background-color:green;
margin:0;
padding:0;
height:25px;
}
<div class="container">
<div class="leftOne">
<div class="progress" style="width:70%;"></div>
</div>
<div class="middleOne">Content Here</div>
<div class="rightOne">
<div class="progress" style="width:40%;"></div>
</div>
</div>
<div class="container">
<div class="leftOne">
<div class="progress" style="width:50%;"></div>
</div>
<div class="middleOne">Content Here</div>
<div class="rightOne">
<div class="progress" style="width:40%;"></div>
</div>
</div>
<div class="container">
<div class="leftOne">
<div class="progress" style="width:30%;"></div>
</div>
<div class="middleOne">Content Here</div>
<div class="rightOne">
<div class="progress" style="width:80%;"></div>
</div>
</div>
<div class="container">
<div class="leftOne">
<div class="progress" style="width:100%;"></div>
</div>
<div class="middleOne">Content Here</div>
<div class="rightOne">
<div class="progress" style="width:0%;"></div>
</div>
</div>
EDIT : specific for The code OP gave in comments
I suggest you to make these changes (line numbers are the line numbers from this pastebin you gave)
Line 81 :: $positiveWidth = 0;
Line 82 :: $negativeWidth = 0;
Line 89 :: <div class='positive-bar hover-cursor' style='width:
".$positiveWidth."%;'></div>
Line 103 :: <div class='negative-bar hover-cursor' style='width:
".$negativeWidth."%;'></div>
Is there a way to limit the amount of cells that are selected for each table to 2?
I have tried using the closest method but I it does not seem to be working (I must not be using it correctly).
My attempt at the jquery is below and here is the
Fiddle.
$(function() {
$('.css-table-td').click(function() {
var theTable = $(this).closest('css-table');
var sCount = $('.highligh-cell').length;
//code below not working
//if (sCount < 3 || $(e.target).hasClass('highlighted'))
$(this).toggleClass("highligh-cell");
});
});
.css-table {
display: table;
background-color: #ccc;
width: 60px;
}
.css-table-tr {
display: table-row;
}
.css-table-td {
display: table-cell;
border: 1px solid #fff;
width: 30px;
height: 30px;
text-align: center;
vertical-align: middle;
}
.highligh-cell {
background: #999;
}
<div class="css-table">
<div class="css-table-tr">
<div class="css-table-td" id="1">b</div>
<div class="css-table-td" id="2">c</div>
</div>
<div class="css-table-tr">
<div class="css-table-td" id="3">e</div>
<div class="css-table-td" id="4">f</div>
</div>
</div>
<br/>
<div class="css-table">
<div class="css-table-tr">
<div class="css-table-td" id="5">b</div>
<div class="css-table-td" id="6">c</div>
</div>
<div class="css-table-tr">
<div class="css-table-td" id="7">e</div>
<div class="css-table-td" id="8">f</div>
</div>
</div>
<INPUT TYPE="submit" id="csstableinfo" VALUE="css info">
Few changes :
Use .length property with respect to the root parent css-table - .closest(..).find('..')
$(this).closest('css-table'); should be $(this).closest('.css-table');. Class selector has a . : .className'.
$('.css-table-td').click(function () {
var theTable = $(this).closest('.css-table');
var sCount = theTable.find('.css-table-td.highligh-cell').length;
if (sCount < 2 || $(this).hasClass("highligh-cell")) {
$(this).toggleClass("highligh-cell");
}
});
Updated Fiddle
You need to properly define the event variable in your onclick function $('.css-table-td').click(function(e) { and you need to only search within the current table (if you want to allow two clicks in each table) like this var sCount = $('.highligh-cell',theTable).length;
$(function() {
$('.css-table-td').click(function(e) {
var theTable = $(this.parentNode.parentNode);
var sCount = $('.highligh-cell',theTable).length;
if (sCount < 2 || $(e.target).hasClass('highligh-cell'))
$(this).toggleClass("highligh-cell");
});
});
.css-table {
display: table;
background-color: #ccc;
width: 60px;
}
.css-table-tr {
display: table-row;
}
.css-table-td {
display: table-cell;
border: 1px solid #fff;
width: 30px;
height: 30px;
text-align: center;
vertical-align: middle;
}
.highligh-cell {
background: #999;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="css-table">
<div class="css-table-tr">
<div class="css-table-td" id="1">b</div>
<div class="css-table-td" id="2">c</div>
</div>
<div class="css-table-tr">
<div class="css-table-td" id="3">e</div>
<div class="css-table-td" id="4">f</div>
</div>
</div>
<br/>
<div class="css-table">
<div class="css-table-tr">
<div class="css-table-td" id="5">b</div>
<div class="css-table-td" id="6">c</div>
</div>
<div class="css-table-tr">
<div class="css-table-td" id="7">e</div>
<div class="css-table-td" id="8">f</div>
</div>
</div>
<INPUT TYPE="submit" id="csstableinfo" VALUE="css info">