Jquery Hover function not changing class - javascript

I've created a grid of pixels and want it to change to black when hovered.
The problem is that the event is not working.
$(document).ready(function() {
function makeGrid(k) {
var size = 320 / k;
for (var i = 0; i < k; i++) {
$(".container").append("<div class=row></div>");
}
for (var j = 0; j < k; j++) {
$(".row").append("<div class=square></div>");
}
$('.square').css({
'height': size,
'width': size
});
}
$('.square').hover(function() {
$(this).addClass(".hover");
})
$('.reset').on('click', function() {
$(".container").empty();
makeGrid(16);
})
$('.start').on('click', function() {
var n = prompt("Set the size");
$(".container").empty();
makeGrid(n);
})
})
.square {
border-collapse: collapse;
display: inline-block;
}
.container {
text-align: -webkit-center;
position: relative;
top: 50px;
margin: 0 auto;
border: 1px solid #000000;
width: 320px;
height: 320px;
border-collapse: collapse;
}
.row {
clear: both;
content: "";
height: 20px;
}
.hover {
background-color: black;
}
button {
text-align: center;
background-color: white;
display: inline-block;
font-size: 20px;
border-radius: 2px;
top: 50%;
}
.wrap {
text-align: -webkit-center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="wrap">
<button class="clear">New Grid</button>
<button class="start">Start</button>
<button class="reset">Reset</button>
</div>
<div class="container"></div>

Since you dynamically add your divs, you can't use .hover() and have to use .on() with mouseenter instead. Also when using .addClass() you just use the class' name with no period being prefixed.
$(document).ready(function() {
function makeGrid(k) {
var size = 320 / k;
for (var i = 0; i < k; i++) {
$(".container").append("<div class=row></div>");
}
for (var j = 0; j < k; j++) {
$(".row").append("<div class=square></div>");
}
$('.square').css({
'height': size,
'width': size
});
}
$(document).on("mouseenter", ".square", function(e) {
$(this).addClass("hover");
});
$('.reset').on('click', function() {
$(".container").empty();
makeGrid(16);
})
$('.start').on('click', function() {
var n = prompt("Set the size");
$(".container").empty();
makeGrid(n);
})
})
.square {
border-collapse: collapse;
display: inline-block;
}
.container {
text-align: -webkit-center;
position: relative;
top: 50px;
margin: 0 auto;
border: 1px solid #000000;
width: 320px;
height: 320px;
border-collapse: collapse;
}
.row {
clear: both;
content: "";
height: 20px;
}
.hover {
background-color: black;
}
button {
text-align: center;
background-color: white;
display: inline-block;
font-size: 20px;
border-radius: 2px;
top: 50%;
}
.wrap {
text-align: -webkit-center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="wrap">
<button class="clear">New Grid</button>
<button class="start">Start</button>
<button class="reset">Reset</button>
</div>
<div class="container"></div>

Related

Javascript - I can not sum the inputs in the cloned divs

I'm a level 0 newbie, and I'm cloning some divs (here the script works very well), to which I added some inputs with different values, and what I'm looking for is to be able to sum the values ​​(only of the cloned inputs), but the script does not he reads. Only sum ALL the html inputs.
// Script for clone the div´s
$(document).ready(function() {
$("#comp-p1").click(function() {
$("#cont-p1").clone().appendTo(".derecha");
});
// =============
$("#comp-p2").click(function() {
$("#cont-p2").clone().appendTo(".derecha");
});
// =============
$("#comp-p3").click(function() {
$("#cont-p3").clone().appendTo(".derecha");
});
});
// =============================================================
// New Script for sum inputs
const suma = function() {
var x = document.getElementsByClassName("add-prod");
let sum = 0;
for (var i = 0; i < x.length; i++) {
console.log(x[i].value)
sum += parseFloat(x[i].value);
}
console.log(sum);
return sum;
}
//console.log(suma());
document.getElementById("total").value = suma();
// =============================================================
// Old Script for sum inputs
/*$(document).ready(function() {
function sumInputs(e) {
e.preventDefault();
var valores = $('.derecha').children('input');
var suma = 0;
$.each(valores, function() {
valor = $(this).val();
suma += Number(valor);
});
valores = document.getElementById('total');
$(valores).val(suma);
}
$('#sumup').on('click', sumInputs);
});*/
body {
margin: 0 auto;
color: #323232;
width: 100%;
height: 100%;
line-height: 1.5;
font-family: 'Roboto', serif
}
#container {
width: 500px;
margin: 0 auto
}
#container p {
display: inline-block;
margin-top: 20px
}
span {
font-weight: bold;
text-decoration: underline
}
#productos {
display: none
}
.img-prod {
display: inline-block;
float: left;
background: #000;
margin-right: 10px
}
.img-prod img {
width: 100%;
height: auto;
max-width: 70px;
display: block;
border: 0
}
#comp-p1,
#comp-p2,
#comp-p3 {
width: 120px;
height: 30px;
margin-top: 15px;
background: green;
padding: 10px 0 5px;
text-align: center;
vertical-align: middle;
color: #fff;
cursor: pointer
}
.derecha {
border: solid 1px #999;
max-height: 400px;
width: 350px;
margin: 0 auto;
text-align: center;
padding: 10px 0;
overflow-y: auto;
float: right
}
#producto-1,
#producto-2,
#producto-3 {
display: inline-block;
width: 220px;
padding: 10px;
float: left;
text-align: left;
font-size: .9em;
margin-right: 5px
}
#producto-1 {
background: green;
color: #fff
}
#producto-2 {
background: #add8e6;
color: #000
}
#producto-3 {
background: #666;
color: #fff
}
.cont-p {
display: inline-block;
margin: 7px auto;
line-height: 1
}
.bbp {
display: inline-block;
float: right;
width: 24px;
height: 24px;
text-align: center;
background: red;
color: #fff;
margin-left: 5px;
line-height: 1.5;
cursor: pointer
}
.cont-num {
float: left;
width: 24px;
height: 24px;
margin: 20px 5px 0 18px;
padding: 4px 3px 3px;
background: red;
text-align: center;
font-size: 16px;
font-family: Arial, sans-serif;
color: #fff
}
#mostrar {
display: none
}
#mostrar {
width: 100px;
margin: 70px 0 0;
padding: 10px;
text-align: center;
background: grey;
color: #fff;
cursor: pointer
}
/* ==== Style of Sume ==== */
.derecha input {
width: 40px;
display: block;
margin: 0 auto 10px 0;
padding: 2px 0;
background: #f2f2f2;
border: none;
border: 1px solid #000;
text-align: center
}
#cont-resultado {
text-align: center;
width: 110px;
margin-top: 70px;
background: grey;
padding: 5px 10px 10px;
color: #fff
}
#cont-resultado input {
display: inline-block;
margin: 10px auto;
background: #fff;
color: #000;
border: 1px solid #000;
padding: 8px 0
}
#cont-resultado p {
display: inline-block;
text-decoration: none;
color: #fff;
background: grey;
padding: 8px 10px;
cursor: pointer
}
#total {
display: block;
width: 80px;
text-align: center
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="productos">
<!-- =============== -->
<div id="cont-p1" class="cont-p">
<div id="producto-1">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"> </div>cont-p1 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp" onclick="restar();restardos();this.parentNode.parentNode.removeChild(this.parentNode);">X</div>
</div>
<!-- =============== -->
<div id="cont-p2" class="cont-p">
<div id="producto-2">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p2 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp" onclick="restar();restardos();this.parentNode.parentNode.removeChild(this.parentNode);">X</div>
</div>
<!-- =============== -->
<div id="cont-p3" class="cont-p">
<div id="producto-3">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p3 cloned!<br><br>Input Value = 198</div>
<input class="add-prod" type="num" value="198">
<div class="bbp" onclick="restar();restardos();this.parentNode.parentNode.removeChild(this.parentNode);">X</div>
</div>
<!-- =============== -->
</div>
<!-- // productos -->
<div class="derecha"></div>
<div id="comp-p1" onClick="clickME();clickME2();">Clone 1</div>
<div id="comp-p2" onClick="clickME();clickME2();">Clone 2</div>
<div id="comp-p3" onClick="clickME();clickME2();">Clone 3</div>
<div class="cont-num" id="clicks">0</div>
<div class="cont-num" id="clicksdos">0</div>
<div id="cont-resultado">
<span>RESULT:</span><br>
<input name="total" id="total">
<br>Is the sum of the cloned divs
<!--<p id='sumup'>Ver total</p>-->
</div>
<p><span>NOTE:</span><br>Here we are looking for only the cloned inputs can be sumed (and see the result in the box color gray).<br><br>The problem is that the current script does not apply a sume of the cloned inputs only... it adds ALL the inputs presents
in the html...<br><br>So (1), how do you sum only the cloned inputs, ignoring those that are outside...?<br><br>And (2) also, how to subtract from the total result all the cloned divs that are deleted...?</p>
</div>
<!-- // container -->
<script>
// Script that adds and subtracts the clicks
var clicks = 0;
function clickME() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks
}
var clicksdos = 0;
function clickME2() {
clicksdos += 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 1) {
document.getElementById("cont-resultado").style.display = "block";
}
}
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
function restar() {
if (clicks > 0) clicks -= 1;
document.getElementById("clicks").innerHTML = clicks;
}
function restardos() {
if (clicksdos > 0) clicksdos -= 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
}
</script>
Ok, you need a couple of changes.
First of you need to run a query selector and get only the elements inside the destination.
const suma = function () {
// NOTE: The query selector is very specific
let x = Array.from(document.querySelectorAll(".derecha div .add-prod"));
console.log(x);
let sum = 0;
for (var i = 0; i < x.length; i++) {
console.log(x[i].value)
sum += parseFloat(x[i].value);
}
console.log(sum);
return sum;
}
Next you will need to call you SUM method each time you add an item:
$(document).ready(function () {
$("#comp-p1").click(function () {
$("#cont-p1").clone().appendTo(".derecha");
document.getElementById("total").value = suma();
});
// =============
$("#comp-p2").click(function () {
$("#cont-p2").clone().appendTo(".derecha");
document.getElementById("total").value = suma();
});
// =============
$("#comp-p3").click(function () {
$("#cont-p3").clone().appendTo(".derecha");
document.getElementById("total").value = suma();
});
});
Here it is working:
Added code to deal with the removal of elements also.
// Script for clone the div´s
$(document).ready(function() {
$("#comp-p1").click(function() {
$("#cont-p1").clone().appendTo(".derecha");
displaySuma();
});
// =============
$("#comp-p2").click(function() {
$("#cont-p2").clone().appendTo(".derecha");
displaySuma();
});
// =============
$("#comp-p3").click(function() {
$("#cont-p3").clone().appendTo(".derecha");
displaySuma();
});
});
const getParent = (match, node) => (node.matches(match)) ? node : getParent(match, node.parentNode);
// Deal with remove
document.addEventListener('click', (event) => {
let target = event.target;
if (target.matches('.bbp')) {
restar();
restardos();
getParent('.derecha', target).removeChild(target.parentNode);
displaySuma();
}
})
// New Script for sum inputs
const displaySuma = () => document.getElementById("total").value = suma();
const suma = function() {
let x = Array.from(document.querySelectorAll(".derecha div .add-prod"));
let sum = 0;
for (var i = 0; i < x.length; i++) {
sum += parseFloat(x[i].value);
}
console.log(sum);
return sum;
}
//console.log(suma());
document.getElementById("total").value = suma();
body {
margin: 0 auto;
color: #323232;
width: 100%;
height: 100%;
line-height: 1.5;
font-family: 'Roboto', serif
}
#container {
width: 500px;
margin: 0 auto
}
#container p {
display: inline-block;
margin-top: 20px
}
span {
font-weight: bold;
text-decoration: underline
}
#productos {
display: none
}
.img-prod {
display: inline-block;
float: left;
background: #000;
margin-right: 10px
}
.img-prod img {
width: 100%;
height: auto;
max-width: 70px;
display: block;
border: 0
}
#comp-p1,
#comp-p2,
#comp-p3 {
width: 120px;
height: 30px;
margin-top: 15px;
background: green;
padding: 10px 0 5px;
text-align: center;
vertical-align: middle;
color: #fff;
cursor: pointer
}
.derecha {
border: solid 1px #999;
max-height: 400px;
width: 350px;
margin: 0 auto;
text-align: center;
padding: 10px 0;
overflow-y: auto;
float: right
}
#producto-1,
#producto-2,
#producto-3 {
display: inline-block;
width: 220px;
padding: 10px;
float: left;
text-align: left;
font-size: .9em;
margin-right: 5px
}
#producto-1 {
background: green;
color: #fff
}
#producto-2 {
background: #add8e6;
color: #000
}
#producto-3 {
background: #666;
color: #fff
}
.cont-p {
display: inline-block;
margin: 7px auto;
line-height: 1
}
.bbp {
display: inline-block;
float: right;
width: 24px;
height: 24px;
text-align: center;
background: red;
color: #fff;
margin-left: 5px;
line-height: 1.5;
cursor: pointer
}
.cont-num {
float: left;
width: 24px;
height: 24px;
margin: 20px 5px 0 18px;
padding: 4px 3px 3px;
background: red;
text-align: center;
font-size: 16px;
font-family: Arial, sans-serif;
color: #fff
}
#mostrar {
display: none
}
#mostrar {
width: 100px;
margin: 70px 0 0;
padding: 10px;
text-align: center;
background: grey;
color: #fff;
cursor: pointer
}
/* ==== Style of Sume ==== */
.derecha input {
width: 40px;
display: block;
margin: 0 auto 10px 0;
padding: 2px 0;
background: #f2f2f2;
border: none;
border: 1px solid #000;
text-align: center
}
#cont-resultado {
text-align: center;
width: 110px;
margin-top: 70px;
background: grey;
padding: 5px 10px 10px;
color: #fff
}
#cont-resultado input {
display: inline-block;
margin: 10px auto;
background: #fff;
color: #000;
border: 1px solid #000;
padding: 8px 0
}
#cont-resultado p {
display: inline-block;
text-decoration: none;
color: #fff;
background: grey;
padding: 8px 10px;
cursor: pointer
}
#total {
display: block;
width: 80px;
text-align: center
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="productos">
<!-- =============== -->
<div id="cont-p1" class="cont-p">
<div id="producto-1">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"> </div>cont-p1 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp">X</div>
</div>
<!-- =============== -->
<div id="cont-p2" class="cont-p">
<div id="producto-2">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p2 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp">X</div>
</div>
<!-- =============== -->
<div id="cont-p3" class="cont-p">
<div id="producto-3">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p3 cloned!<br><br>Input Value = 198</div>
<input class="add-prod" type="num" value="198">
<div class="bbp">X</div>
</div>
<!-- =============== -->
</div>
<!-- // productos -->
<div class="derecha"></div>
<div id="comp-p1" onClick="clickME();clickME2();">Clone 1</div>
<div id="comp-p2" onClick="clickME();clickME2();">Clone 2</div>
<div id="comp-p3" onClick="clickME();clickME2();">Clone 3</div>
<div class="cont-num" id="clicks">0</div>
<div class="cont-num" id="clicksdos">0</div>
<div id="cont-resultado">
<span>RESULT:</span><br>
<input name="total" id="total">
<br>Is the sum of the cloned divs
<!--<p id='sumup'>Ver total</p>-->
</div>
<p><span>NOTE:</span><br>Here we are looking for only the cloned inputs can be sumed (and see the result in the box color gray).<br><br>The problem is that the current script does not apply a sume of the cloned inputs only... it adds ALL the inputs presents
in the html...<br><br>So (1), how do you sum only the cloned inputs, ignoring those that are outside...?<br><br>And (2) also, how to subtract from the total result all the cloned divs that are deleted...?</p>
</div>
<!-- // container -->
<script>
// Script that adds and subtracts the clicks
var clicks = 0;
function clickME() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks
}
var clicksdos = 0;
function clickME2() {
clicksdos += 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 1) {
document.getElementById("cont-resultado").style.display = "block";
}
}
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
function restar() {
if (clicks > 0) clicks -= 1;
document.getElementById("clicks").innerHTML = clicks;
}
function restardos() {
if (clicksdos > 0) clicksdos -= 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
}
</script>

echo on button class

I'm trying to build a multi step selector which has multiple combinations in every slide. for example hou have btn1, btn2 and btn3. Every button will display other content in the next slide.
It's an inpage multistep slider so I can't use onClick, submit input or something like that.
as you can see in the code below, I'm trying to get an echo on the name or value of the button who has been clicked in the slide before.
var currentSlide = 0,
$slideContainer = $('.slide-container'),
$slide = $('.slide'),
slideCount = $slide.length,
animationTime = 300;
function setSlideDimensions () {
var windowWidth = $(window).width();
$slideContainer.width(windowWidth * slideCount);
$slide.width(windowWidth);
}
function generatePagination () {
var $pagination = $('.pagination');
for(var i = 0; i < slideCount; i ++){
var $indicator = $('<div>').addClass('indicator'),
$progressBarContainer = $('<div>').addClass('progress-bar-container'),
$progressBar = $('<div>').addClass('progress-bar'),
indicatorTagText = $slide.eq(i).attr('data-tag'),
$tag = $('<div>').addClass('tag').text(indicatorTagText);
$indicator.append($tag);
$progressBarContainer.append($progressBar);
$pagination.append($indicator).append($progressBarContainer);
}
$pagination.find('.indicator').eq(0).addClass('active');
}
function goToNextSlide () {
if(currentSlide >= slideCount - 1) return;
var windowWidth = $(window).width();
currentSlide++;
$slideContainer.animate({
left: -(windowWidth * currentSlide)
});
setActiveIndicator();
$('.progress-bar').eq(currentSlide - 1).animate({
width: '100%'
}, animationTime);
}
function goToPreviousSlide () {
if(currentSlide <= 0) return;
var windowWidth = $(window).width();
currentSlide--;
$slideContainer.animate({
left: -(windowWidth * currentSlide)
}, animationTime);
setActiveIndicator();
$('.progress-bar').eq(currentSlide).animate({
width: '0%'
}, animationTime);
}
function postitionSlides () {
var windowWidth = $(window).width();
setSlideDimensions();
$slideContainer.css({
left: -(windowWidth * currentSlide)
}, animationTime);
}
function setActiveIndicator () {
var $indicator = $('.indicator');
$indicator.removeClass('active').removeClass('complete');
$indicator.eq(currentSlide).addClass('active');
for(var i = 0; i < currentSlide; i++){
$indicator.eq(i).addClass('complete');
}
}
setSlideDimensions();
generatePagination();
$(window).resize(postitionSlides);
$('.next').on('click', goToNextSlide);
$('.previous').on('click', goToPreviousSlide);
#charset "UTF-8";
*, html, body {
font-family: "TrebuchetMS", trebuchet, sans-serif;
}
* {
box-sizing: border-box;
}
h1, h2 {
text-align: center;
}
h1 {
font-size: 24px;
line-height: 30px;
font-weight: bold;
}
h2 {
font-size: 18px;
line-height: 25px;
margin-top: 20px;
}
button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: 0;
padding: 14px 50px;
border-radius: 4px;
background-color: #37B595;
color: #FFFFFF;
text-transform: capitalize;
font-size: 18px;
line-height: 22px;
outline: none;
cursor: pointer;
transition: all 0.2s;
}
button:hover {
background-color: #1A7F75;
}
button.previous {
background-color: #A2ACAF;
}
button.previous:hover {
background-color: #5A5F61;
}
.full-width-container {
width: 100%;
min-width: 320px;
}
.sized-container {
max-width: 900px;
width: 100%;
margin: 0 auto;
}
.slide-container {
position: relative;
left: 0;
overflow: hidden;
}
.slide {
float: left;
}
.slide .sized-container {
padding: 75px 25px;
}
.button-container {
border-top: 1px solid black;
overflow: hidden;
padding-top: 30px;
}
.button-container button {
float: right;
margin-left: 30px;
}
.pagination-container {
margin-top: 120px;
}
.pagination {
width: 100%;
text-align: center;
padding: 0 25px;
}
.indicator {
width: 25px;
height: 25px;
border: 4px solid lightgray;
border-radius: 50%;
display: inline-block;
transition: all 0.3s;
position: relative;
}
.indicator .tag {
position: absolute;
top: -30px;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
color: lightgray;
white-space: nowrap;
}
.indicator.active, .indicator.complete {
border-color: #37B595;
}
.indicator.active .tag, .indicator.complete .tag {
color: #37B595;
}
.indicator.complete:after {
content: "✓";
position: absolute;
color: #37B595;
left: 4px;
top: 3px;
font-size: 14px;
}
.progress-bar-container {
width: 10%;
height: 4px;
display: inline-block;
background-color: lightgray;
position: relative;
top: -10px;
}
.progress-bar-container:last-of-type {
display: none;
}
.progress-bar-container .progress-bar {
width: 0;
height: 100%;
background-color: #37B595;
}
<div class="pagination-container full-width-container">
<div class="sized-container">
<div class="pagination"></div>
</div>
</div>
<div class="viewport full-width-container">
<ul class="slide-container">
<li class="slide" data-tag="Basic Info">
<div class="sized-container">
<h1>Slide1.</h1>
<input class="next" name="next" type="button" value="next" />
</div>
</li>
<li class="slide" data-tag="Expertise">
<div class="sized-container">
<h1>Slide2.</h1>
</div>
</li>
</ul>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
Can someone please help me out!

Create grid in HTML

I'm looking to create a grid like this: Grid
I'm using this:
$(document).ready(function() {
for (var i = 0; i < 366; i++) {
$('#div-padre').append('<div class="dia" id="div'+ i +'" /> ');
}
});
to generate 365 divs, then, with CSS, create the 'grid' style.
.dia {
width: 45px;
height: 45px;
background: white;
outline: 2px solid;
float: left;
}
.div-padre {
width: 800px;
}
I tried to clearfix but the last div goes wrong, I don't care if they are divs, tr or whatever, but in the future i would like to select one square and change color, so div or tr or something, I need you to be able to do that later
This is a border/outline management issue, take a look at this:
$(document).ready(function() {
for (var i = 0; i < 366; i++) {
$('#div-padre').append('<div class="dia" id="div'+ i +'" /> ');
}
});
.dia {
width: 45px;
height: 45px;
background: white;
border: 2px solid;
float: left;
margin-top:-2px;
margin-left:-2px;
}
.div-padre {
width: 800px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div-padre"></div>
Use border: 2px solid; margin: -1px; instead of outline: 2px solid;
$(document).ready(function() {
for (var i = 0; i < 365; i++) {
$('#div-padre')
.append(
$('<div>', {
id: 'div-' + (i+1),
class: 'dia'
}));
}
});
.dia {
width: 45px;
height: 45px;
background: white;
border: 2px solid;
margin: -1px;
float: left;
}
.div-padre {
width: 800px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div-padre"></div>

For loop runs length of array but displays one element array.length times

I'm working on a project for freeCodeCamp and I'm running a for loop through an array of twitch.tv users. I've created a table and for each username in my array, it's supposed to add the new row, fill it with the data, and move onto the next element. The problem is that every time I run the code it seems to be choosing a random index in the array and running the loop through to equal the number of elements in the array. I think it's a display issue because it's connecting to the server for each individual call.
Hopefully someone can help me out.
var twitch = ['ESL_SC2', 'OgamingSC2', 'cretetion', 'freecodecamp', 'storbeck', 'habathcx', 'RobotCaleb', 'noobs2ninjas', 'ESL_LOL', 'wow_2', 'brunofin', 'comster404']
var streams = 'https://wind-bow.gomix.me/twitch-api/streams/';
var channels = 'https://wind-bow.gomix.me/twitch-api/channels/';
var users = 'https://wind-bow.gomix.me/twitch-api/users/';
var getStream = function(data) {
if (data.stream === null) {
$('.status').append('Offline');
} else {
var streamStatus = data.stream.channel.status;
var html = '<td class="stream">' + streamStatus + '</td>';
$('.stream').html(html);
}
}
var getChannels = function(data) {
var game = data.display_name;
var logoHtml = data.logo;
var channelUrl = data.url;
var gameHtml = '' + game + '';
var logoHtml = '<img class="image" src="' + logoHtml + '">';
$('.game').html(gameHtml);
$('.logo').html(logoHtml);
}
$(document).ready(function() {
$('.choice').on('click', function() {
$('.choice').removeClass('selected');
$(this).toggleClass('selected');
});
var table = $('<table id="twitch-table"></table>').appendTo('#content');
for (var i = 0; i < twitch.length; i++) {
var row = $('<tr></tr>').appendTo(table);
$('<td class="logo"></td>').appendTo(row);
$('<td class="game"></td>').appendTo(row);
$('<td class="stream"></td>').appendTo(row);
$.getJSON(streams + twitch[i], getStream, 'jsonp');
$.getJSON(channels + twitch[i], getChannels, 'jsonp');
}
});
body {
padding: 0;
margin: 0;
font-family: 'Oswald', sans-serif;
font-size: 100%;
}
a {
text-decoration: none;
}
#main {
width: 600px;
margin: 2% auto 0;
}
#header {
padding: 0;
margin: 0;
background: #116466;
color: #d1e8e2;
line-height: 100px;
width: 100%;
}
h1 {
margin: 0 0 0 5%;
font-size: 300%;
}
#row {
background: #285277;
width: 100%;
}
ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
justify-content: space-between;
}
.choice {
position: relative;
text-align: center;
width: 33%;
background: #285277;
padding: 5px 10px;
display: inline-block;
color: #d1e8e2;
font-size: 150%;
}
.choice a {
/*padding: 5px 20px;*/
color: #d1e8e2;
}
#content {
width: 100%;
background: #efefef;
}
/*
.choice a:active {
background: #1E3D59;
}
*/
.selected {
background: #1E3D59;
}
.selected:after {
content: '';
position: absolute;
top: 100%;
right: 45%;
width: 0;
height: 0;
border-top: solid 10px #1E3D59;
border-left: solid 10px transparent;
border-right: solid 10px transparent;
}
table {
width: 600px;
}
tr {
margin: 5px 0;
display: flex;
width: 100%;
justify-content: space-between;
}
td {
border-collapse: collapse;
box-sizing: border-box;
margin: 0;
padding: 0;
display: inline-block;
white-space: nowrap;
overflow: hidden;
}
.game {
padding-left: 10px;
width: 100px;
font-size: 120%;
line-height: 75px;
text-overflow: ellipsis;
}
.game a {
color: #111;
}
.image {
height: 75px;
width: 75px;
}
.logo {
padding: 3px 5px;
box-sizing: border-box;
}
.stream {
padding-right: 10px;
width: 350px;
display: inline-block;
text-overflow: ellipsis;
line-height: 75px;
}
<!DOCTYPE html>
<html>
<head>
<title>Twitch.tv JSON API</title>
<link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
<script src="https://use.fontawesome.com/57c9bf8971.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div id='main'>
<header id='header'>
<h1>Twitch Streamers</h1>
</header>
<div id='row'>
<ul>
<li class='choice selected'><a href='#'>All</a></li>
<li class='choice'><a href='#'>Online</a></li>
<li class='choice'><a href='#'>Offline</a></li>
</ul>
</div>
<div id='content'>
</div>
</div>
</body>
</html>
The problem is in these lines:
$('.game').html(gameHtml);
$('.logo').html(logoHtml);
$('.stream').html(html);
They select all lines with game class (or logo or stream) And change them all.
See here a fixed JSfiddle.
You need to use the callback function properly. Your getStreams and getChannels functions are applying data to all rows, instead of its own individual row.
Below are the modified callback functions declarations:
var getStream = function(url, idx) {
$.getJSON(url, function(data){
if (data.stream === null) {
$('.status').append('Offline');
} else {
var streamStatus = data.stream.channel.status;
var html = '<td class="stream">' + streamStatus + '</td>';
$('tr').eq(idx).find('.stream').html(html);
}
});
}
var getChannels = function(url, idx) {
$.getJSON(url, function(data){
var game = data.display_name;
var logoHtml = data.logo;
var channelUrl = data.url;
var gameHtml = '' + game + '';
var logoHtml = '<img class="image" src="' + logoHtml + '">';
$('tr').eq(idx).find('.game').html(gameHtml);
$('tr').eq(idx).find('.logo').html(logoHtml);
});
}
And, call them within your for loop as:
getStream(streams + twitch[i], i);
getChannels(channels + twitch[i], i);
JSFiddle for your reference: https://jsfiddle.net/yogesh214/yxLu9mwg/4/
I understand your problem now:
As #Shalom Peles said, you're using $('.stream') to select all the elements in the document with the class .stream instead of just the element within your row.
Instead use .find to select within an element. For example:
let row = $('<div class="my-row"></div>'); // creates a row
row.append(/* ... */);
let elementInsideRow = row.find('.my-column'); // this selects an element *inside* the row element.
Also: use let instead of var for all declarations
I edited your code to work for streams. Do the same for channels. Read the comments.
var twitch = ['ESL_SC2', 'OgamingSC2', 'cretetion', 'freecodecamp', 'storbeck', 'habathcx', 'RobotCaleb', 'noobs2ninjas', 'ESL_LOL', 'wow_2', 'brunofin', 'comster404']
var streams = 'https://wind-bow.gomix.me/twitch-api/streams/';
var channels = 'https://wind-bow.gomix.me/twitch-api/channels/';
var users = 'https://wind-bow.gomix.me/twitch-api/users/';
// refactor this like I did below
var getChannels = function(data) {
var game = data.display_name;
var logoHtml = data.logo;
var channelUrl = data.url;
var gameHtml = '' + game + '';
var logoHtml = '<img class="image" src="' + logoHtml + '">';
$('.game').html(gameHtml);
$('.logo').html(logoHtml);
}
$(document).ready(function() {
$('.choice').on('click', function() {
$('.choice').removeClass('selected');
$(this).toggleClass('selected');
});
var table = $('<table id="twitch-table"></table>').appendTo('#content');
// you need to use `let` here because you need block scope
// in general, use `let` instead of `var` everywhere.
// https://stackoverflow.com/questions/21906133/when-should-i-use-let-and-var
for (let i = 0; i < twitch.length; i++) {
let row = $('<tr></tr>');
$.getJSON(streams + twitch[i], function(data) {
$('<td class="logo"></td>').appendTo(row);
$('<td class="game"></td>').appendTo(row);
$('<td class="stream"></td>').appendTo(row);
if (data.stream === null) {
// instead of selecting all the elements with `.status`, use `find` to select *within* the `row` element
// $('.status').append('Offline');
row.find('.status').append('Offline');
} else {
var streamStatus = data.stream.channel.status;
var html = '<td class="stream">' + streamStatus + '</td>';
row.find('.stream').html(html);
}
// apend it when you're done
row.appendTo(table);
}, 'jsonp');
// make the same changes for channel
//$.getJSON(channels + twitch[i], getChannels, 'jsonp');
}
});
body {
padding: 0;
margin: 0;
font-family: 'Oswald', sans-serif;
font-size: 100%;
}
a {
text-decoration: none;
}
#main {
width: 600px;
margin: 2% auto 0;
}
#header {
padding: 0;
margin: 0;
background: #116466;
color: #d1e8e2;
line-height: 100px;
width: 100%;
}
h1 {
margin: 0 0 0 5%;
font-size: 300%;
}
#row {
background: #285277;
width: 100%;
}
ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
justify-content: space-between;
}
.choice {
position: relative;
text-align: center;
width: 33%;
background: #285277;
padding: 5px 10px;
display: inline-block;
color: #d1e8e2;
font-size: 150%;
}
.choice a {
/*padding: 5px 20px;*/
color: #d1e8e2;
}
#content {
width: 100%;
background: #efefef;
}
/*
.choice a:active {
background: #1E3D59;
}
*/
.selected {
background: #1E3D59;
}
.selected:after {
content: '';
position: absolute;
top: 100%;
right: 45%;
width: 0;
height: 0;
border-top: solid 10px #1E3D59;
border-left: solid 10px transparent;
border-right: solid 10px transparent;
}
table {
width: 600px;
}
tr {
margin: 5px 0;
display: flex;
width: 100%;
justify-content: space-between;
}
td {
border-collapse: collapse;
box-sizing: border-box;
margin: 0;
padding: 0;
display: inline-block;
white-space: nowrap;
overflow: hidden;
}
.game {
padding-left: 10px;
width: 100px;
font-size: 120%;
line-height: 75px;
text-overflow: ellipsis;
}
.game a {
color: #111;
}
.image {
height: 75px;
width: 75px;
}
.logo {
padding: 3px 5px;
box-sizing: border-box;
}
.stream {
padding-right: 10px;
width: 350px;
display: inline-block;
text-overflow: ellipsis;
line-height: 75px;
}
<!DOCTYPE html>
<html>
<head>
<title>Twitch.tv JSON API</title>
<link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
<script src="https://use.fontawesome.com/57c9bf8971.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div id='main'>
<header id='header'>
<h1>Twitch Streamers</h1>
</header>
<div id='row'>
<ul>
<li class='choice selected'><a href='#'>All</a></li>
<li class='choice'><a href='#'>Online</a></li>
<li class='choice'><a href='#'>Offline</a></li>
</ul>
</div>
<div id='content'>
</div>
</div>
</body>
</html>

Create the list with limited elements inside

I need to create ul with a limit of 5 li's inside. If it goes more then 5 elements - create new ul with the same limitations. And so on and on. Here is the start point I made:
$(function(){
var $container = $('.container'),
el = 5,
i;
newUl = $('<ul />')
for(i=0; i < el; i++){
$container.append(newUl)
$('<li />', { html : i }).appendTo(newUl)
}
})
* {
box-sizing: border-box;
}
body {
background: #f2f2f2;
}
.wrapper {
display: table;
margin: 0 auto;
padding: 10px;
max-width: 600px;
width: 100%;
height: 100vh;
border: 2px solid rgba(0, 0, 0, 0.2);
}
.wrapper .container {
display: table-cell;
vertical-align: bottom;
}
.wrapper ul {
background: #c0c0c0;
border: 1px solid #333;
font-size: 0;
}
.wrapper ul:nth-of-type(odd) {
direction: rtl;
}
.wrapper ul li {
display: inline-block;
font-size: 16px;
width: 20%;
padding: 10px;
border: 1px solid #333;
text-align: center;
direction: rtl;
}
.status {
position: fixed;
left: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="container">
</div>
</div>
<div class="status"></div>
Any advices how to do this?
You can use the modulus operator % to determine when you have reached the max, and then you need to create a new jQuery for your new ul, and append it.
$(function(){
var $container = $('.container'),
el = 10,
max = 5,
i;
var newUl;
for(i=0; i < el; i++){
if(i%max==0) {
newUl = $('<ul/>');
$container.append(newUl);
}
$('<li />', { html : i }).appendTo(newUl)
}
});
* {
box-sizing: border-box;
}
body {
background: #f2f2f2;
}
.wrapper {
display: table;
margin: 0 auto;
padding: 10px;
max-width: 600px;
width: 100%;
height: 100vh;
border: 2px solid rgba(0, 0, 0, 0.2);
}
.wrapper .container {
display: table-cell;
vertical-align: bottom;
}
.wrapper ul {
background: #c0c0c0;
border: 1px solid #333;
font-size: 0;
}
.wrapper ul:nth-of-type(odd) {
direction: rtl;
}
.wrapper ul li {
display: inline-block;
font-size: 16px;
width: 20%;
padding: 10px;
border: 1px solid #333;
text-align: center;
direction: rtl;
}
.status {
position: fixed;
left: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="container">
</div>
</div>
<div class="status"></div>
I'm not quite following your example, so forgive me that I've just started fresh here. The first loop and the 12 on line 2 is just to generate a list of fake data to work with. Test it with 0, less than 5, multiples of 5, and 1+ a multiple of 5 just to make sure it works.
var items = [];
for(var i=0; i<12; i++) {
items.push("item " + i.toString());
}
var subItems = items.splice(0, 5);
var div = $("<div>").get(0);
while(subItems.length > 0) {
var ul = $("<ul>").get(0);
div.appendChild(ul);
for(var i=0; i<subItems.length; i++) {
ul.appendChild( $("<li>").text(subItems[i]).get(0) );
}
subItems = items.splice(0, 5);
}
You can paste this into the console to see the results. Just add console.log(div) at the end.
This will create a div with n number of ul tags, each having 5 li's (or less depending on the data)
Change line 6 to point to your div tag. And I'm not sure we can tell from your example where the data is supposed to come from so you'll need to change items and line 11 accordingly.

Categories

Resources