How to append divs into another div inside a variable? - javascript

So, I am trying to create a HTML code generator just for fun. My actual problem is: How can I append divs from a loop inside another div that does not exist and is saved in a variable?
I hope I have been clear, thank you.
My little JavaScript until now:
colCont = $("<div class=\"stab-cont\"><div class=\"stab-row\"></div></div>");
function repeat(n) {
for (var i = 1; i < n + 1; i++) {
//Here I need to insert the n DIVs generated by this loop
}
}
repeat(3);
console.log(colCont);
JSFiddle: http://jsfiddle.net/qo3vdwhv/

Maybe I am under thinking it here, but this should work.
My code:
colCont = $("<div class=\"stab-cont\"></div>");
function repeat(n) {
for (var i = 1; i < n + 1; i++) {
$("<div class=\"stab-row\"></div>").appendTo(colCont); //build your div like you did with "colCont" and append the new div to colCont
}
}
repeat(3);
colCont.appendTo($("body"))
.stab-cont div {
border: 1px solid #c00;
margin: 10px;
float: left;
width: 200px;
height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Here's something to consider; instead of making your repeat() function dependent on colCont, make it a jQuery function instead.
In this case I've created a function that will repeat the contents of a jQuery object N times (N >= 1).
colCont = $("<div class=\"stab-cont\"></div>");
jQuery.fn.times = function(n) {
var len = this.length;
for (var i = 1; i < n; ++i) {
for (var k = 0; k < len; ++k) {
this.push(this[0].cloneNode(true));
}
}
return this;
};
colCont
.append($('<div class="stab-row"></div>').times(3))
.appendTo('body');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

add onclick event to dynamically create element

I would like to create list of divs,
one of the divs should like this:
<div onclick="myFunc(this, 'arrayValue')"></div>
I want to achieve it by iterating through my array and passing index value to my function. One of the solutions that worked was using setAttribute :
for(var i = 0; i < array.length; i++){
var div = document.createElement("div");
div.setAttribute("onclick", 'myFunc(this, \''+array[i]+'\')');
myDiv.appendChild(div);
}
The only problem is that this part looks really ugly: \''+array[i]+'\')'
Is there other way to achieve this? That would look like this or something similar:
div.setAttribute("onclick", myFunc(this, array[i]);
btw. other solutions: when I used div.onclick the onclick attr was not visible on div (result: <div></div>), possibly I did something wrong.
var array = ['bla1','bla2'];
var myFunc = function(value) {
alert('click : '+ value);
};
var myDiv = document.getElementById('myDiv');
for(var i = 0; i < array.length; i++){
var div = document.createElement("div");
div.className = 'bla';
myDiv.appendChild(div);
div.addEventListener('click', myFunc.bind(this, array[i]));
}
.bla {
border: 1px solid black;
width: 20px;
height: 20px;
margin: 10px;
}
<div id="myDiv"></div>
Is that you want ?

(vanilla javascript calculator) How do I get the nodeValue from this nodeList?

What I'm trying to do is grab the node that was clicked and add it to the innerHTML of the screen I have set up. However, it seems as though my for loop is completing before I can get that value. In my case, keys[3] doesn't exist, so it is returning an error, but I would like to have the loop stop on the 'clicked' element and grab that value.
JS Bin snippit
What you need to do is use textContent instead of nodeValue to get 1, 2, or 3. Next, use this instead of keys[i].
var screen = document.getElementById("screen");
var keys = document.querySelectorAll('.keys');
for (var i = 0; i < keys.length; i++) {
keys[i].addEventListener('click', function() {
screen.innerHTML += this.textContent;
});
}
#calculator {
width: 500px;
height: 600px;
border: 1px solid black;
}
#screen {
width: 100%;
height: 100px;
border: 1px solid black;
}
.keys {
width: 24%;
display: inline-block;
border: 1px solid black;
height: 50px;
cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="calculator">
<div id="screen">
</div>
<div class="keys">1</div>
<div class="keys">2</div>
<div class="keys">3</div>
</div>
</body>
</html>
Now this should be working properly as it gets the text content, and instead of keys[i], it uses this as i doesn't exist outside the loop. this references the current element. You could always define the anonymous function outside, and use a for-each loop.
The i variable exists only in the loop, it does not exist in the click event.
Try changing this:
screen.innerHTML += keys[i].firstChild.nodeValue;
To this:
screen.innerHTML += this.outerHTML;
for (var i = 0; i < keys.length; i++) {
keys[i].addEventListener('click', function(e) {
console.log(e, e.target)
screen.innerHTML += e.target.innerHTML;
});
i would use e.target to get anything out of div.
this feels more clean.
That is if you goal is to get any text that is in a container.
Although this would not be the most effective way to make a calculator.
http://jsbin.com/rifekejivi/1/edit?html,css,js,console,output
I would use let not var. This works:
for (let i = 0; i < keys.length; i++) {
keys[i].addEventListener('click', function() {
screen.innerHTML += keys[i].firstChild.nodeValue;
});
Ok: Edit:
var screen = document.getElementById("screen");
var keys = document.querySelectorAll('.keys');
var val = 0;
screen.innerHTML = 0;
for (let i = 0; i < keys.length; i++) {
keys[i].addEventListener('click', function() {
val += parseInt(keys[i].firstChild.nodeValue);
screen.innerHTML = val;
});
}
And to clarify: I would (allways) use let i = 0 in a loop because it also works with async operations in a loop because it is a block scope.
Not applying to this particular case but try this:
var x = [1,2,3,4];
for(var i = 0; i<x.length; i++){
window.setTimeout(function(){
console.log(i);
},Math.random())
}
//console.log returns: 4 4 4 4
for(let i = 0; i<x.length; i++){
window.setTimeout(function(){
console.log(i);
},Math.random())
}
//console.log returns 0 1 2 3
See the difference?
just add a click event to the body, and check if the targets class name equals key, then add the textContent of the target to screen
"use strict"
var screen = document.getElementById("screen");
var keys = document.querySelectorAll('.keys');
// for (var i = 0; i < keys.length; i++) {
// keys[i].addEventListener('click', function() {
// screen.innerHTML += this.textContent;
// });
// }
document.body.addEventListener('click', function(e) {
let target = e.target;
switch(target.className) {
case "keys":
screen.innerHTML += target.textContent;
break;
default:
}
})

jquery loop not working properly

this is my loop. I want to print 7 li tag and 5 ul tags. This is my code.
for (var i = 0; i <= 4 ; i++) {
$("#calendar").append("<ul></ul>");
for (var j = 0; j <= 6; j++) {
$("#calendar ul").append("<li></li>").addClass("days");
$("#calendar ul li").addClass("day");
count = count + 1;
};
};
but the result is quite different from the expectation. There are 35, 28, 21, 14 and 7 li tags in each consecutive loop. I understand why it is so. The li tags are appended to all the ul's in the #calendar div.
Now, what is the proper way to appended li to the ul tags without the repeatation? Thanks.
It is because $("#calendar ul") will select all the ul elements in calendar including the previously added one's.
for (var i = 0; i <= 4; i++) {
var $ul = $("<ul></ul>").appendTo('#calendar').addClass('days');
for (var j = 0; j <= 6; j++) {
$("<li></li>", {
'class': 'day'
}).appendTo($ul);
};
};
.days {
border: 1px solid grey;
margin-bottom: 2px;
}
.day {
border: 1px solid blue;
margin-bottom: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="calendar"></div>
You can also try
var $ul = $(new Array(6).join('<ul class="days"></ul>')).appendTo('#calendar');
$ul.append(new Array(8).join('<li class="day"></li>'));
.days {
border: 1px solid grey;
margin-bottom: 2px;
}
.day {
border: 1px solid blue;
margin-bottom: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="calendar"></div>
Try to rewrite you code like below,
for(var i = 0; i <= 4 ; i++) {
var ul = $("<ul>").appendTo("#calendar").addClass("days");
for(var j = 0; j <= 6; j++) {
$("<li>").appendTo(ul).addClass("day");
count = count + 1;
};
};
You are using a generic selector $("#something ul"), that will select all the UL elements inside of that div. So you have to collect the newly generated ul in a variable and use it for further manipulations.
Recent edit: inspired from APJhony's code.
The part $("#calendar ul").append("<li></li>").addClass("days"); will append a li to all existing ul's in the calendar element.
Best to do is to save a reference to the ul you want to append the li's to, and do this in the first loop. Then, in the second loop, add the li's.
for (var i = 0; i <= 4 ; i++) {
var $ul = $('<ul/>', { class: 'days'} );
for (var j = 0; j <= 6; j++) {
var $li = $('<li/>', { class: 'day', text: 'li test' });
$ul.append($li);
};
$('#calendar').append($ul);
};
https://jsfiddle.net/s7fkw641/
for (var i = 0; i <= 4 ; i++) {
$("#calendar").append("<ul></ul>");
for (var j = 0; j <= 6; j++) {
$("#calendar ul:last-child").append("<li></li>").addClass("days");
$("#calendar ul:last-child li").addClass("day");
};
};
You can only add ul:last-child
Each time you run $("#calendar ul").append(...), you append data to every single element in the DOM that matches #calendar ul. I recommend building up your elements one by one assigning the results of $(some_html_string) to variables. This way ul will only mean one <ul> element at a time. For example:
var calendar = $("#calendar");
for (var i = 0; i <= 4; i++) {
var ul = $("<ul></ul>");
ul.addClass("days");
for (var j = 0; j <= 6; j++) {
var li = $("<li></li>");
li.addClass("day");
ul.append(li);
count = count + 1;
}
calendar.append(ul);
}
I think you want to create dynamically 5 ul's and inside which 7 li's
Updated Code
jQuery(document).ready(function($){
for (var i = 0; i <= 4 ; i++) {
$("#calendar").append("<ul></ul>");
}
for (var j = 0; j <= 6; j++) {
$("#calendar ul").append("<li></li>").addClass("days");
$("#calendar ul li").addClass("day");
}
});
Hope this helps!
The error is here its appending li to all the class items every and each time he goes in second loop(starting from first ul) to prevent that block it with id (i left the class name assuming it is important to handle css or something).
here is the simple solution
for (var i = 1; i <= 5 ; i++) {
$("#calendar").append("<ul class='days' id='"+i+"'></ul>")
for (var j = 1; j <= 7; j++) {
$("#calendar #"+i+".days ").append("<li class='day'></li>");
};
};

Creating Grid on the fly with jquery

I'm new to frontend and I'm trying to practice doing this simple task: I have to create a grid on the fly that is n * n (n being inputed by the user).
I succesfully created a fix sized grid, but my problem is when trying to do this dynamically.
This is the code I wrote for a 3*3 grid: http://jsfiddle.net/y7c2h8yk/
For trying to create it dynamically I wrote the following function:
var setGridDimensions = function(n) {
// emptying current grid
$(".row").empty();
var $grid = $("#grid");
for (var i = 0; i < n; i++) {
// adding row
$grid.append('<div class="row">');
// adding each to element to row
**var $row = $(".row")[i];**
for (var j = 0; j < n; j++) {
$row.append('<div class="col"></div>');
}
}
};
Now, I understand there is a problem with line var $row = $(".row")[i]. What I need is inside the loop first create the row, then select the row created and then loop again and create each column. How can i do that ?
Any help would be really appreciated. Thanks.
You don't have to force jQuery to search for the .row element in the DOM tree n times. You have easy way to cache the element by setting it as variable.
Another thing, is that you should empty() the whole #grid element instead of .row. empty() method remove contents of the element, but not the element itself.
Alternatively, you could remove rows using $(".row").remove();
.empty() reference
.remove() reference
Code (I would however use the next one)
var setGridDimensions = function(n) {
var $grid = $("#grid").empty();
for (var i = 0; i < n; i++) {
// create .row and cache it setting as '$row' variable:
var $row = $('<div class="row"/>').appendTo($grid);
for (var j = 0; j < n; j++) {
$row.append('<div class="col"></div>');
}
}
};
DEMO
This would be faster than the one above, as it's single DOM modification:
var setGridDimensions = function(n) {
var html ='';
for (var i = 0; i < n; i++) {
html += '<div class="row">';
for (var j = 0; j < n; j++) {
html += '<div class="col"></div>';
}
html += '</div>';
}
// modify the DOM only once:
$("#grid").html(html);
};
DEMO
$(".row")[i] get the HTML element. So late, the $row.append('<div class="col"></div>'); will not work since .append() is a jQuery method.
If you want to select a specific index and keep it as a jQuery object, use .eq() :
var $row = $(".row").eq(i);
for (var j = 0; j < n; j++) {
$row.append('<div class="col"></div>');
}
Here's a way to do it without jQuery.
https://jsfiddle.net/lemoncurry/evxqybaL/1/
<div id="grid-holder"></div>
-
#grid-holder {
width: 100%;
}
.row {
clear: left;
background-color: red;
}
.cell {
width: 50px;
height: 50px;
border: 1px dashed blue;
float: left;
}
-
var gridly = function (n) {
var grid = document.getElementById("grid-holder");
for (var i = 0; i < n; i++) {
var row = document.createElement('div');
row.classList.add("row");
grid.appendChild(row);
for (var j = 0; j < n; j++) {
var cell = document.createElement('div');
cell.classList.add("cell");
row.appendChild(cell);
}
}
}
gridly(5);
use isotope http://isotope.metafizzy.co/ it uses the help of Javascript but it is very popular, so you will find plenty of docs
if you find it very complicated then there are many premium plugins that based their development on isotope already, for example the Media Boxes http://codecanyon.net/item/media-boxes-responsive-jquery-grid/5683020

Adding elements on loop jQuery

I am trying to generate a row of 16 boxes on load of webpage.
Here is my code:
var box = $("<div></div>").addClass("box");
$(document).ready(function(){
for(var i = 0; i < 16; i++) {
$("#container").append(box);
}
});
I also tried this within the for loop's code block:
if($("#container:contains(box)")) {
$(box).append(box);
}
I kind of understand why this does not work. That var box is only referencing an element and is not a copy of an element?
As you can likely tell, I'm new. I would really appreciate some pointers on how I can achieve this. Thanks.
Why not just use like this?
for(var i = 0; i < 16; i++) {
$("#container").append('<div class="box box-'+i+'" />');
}
You're appending the same div over and over. That will just move it (in this case, right back where it was). For a new div each time:
$(document).ready(function(){
var ctr = $('#container');
for(var i = 0; i < 16; i++) {
ctr.append("<div class='box'></div>");
}
});
$(document).ready(function() {
var ctr = $('#container');
for (var i = 0; i < 16; i++) {
ctr.append("<div class='box'></div>");
}
});
.box {
margin: 10px;
height: 25px;
width: 25px;
background-color: red;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="container"></div>
I recommend against using append in a loop, bad performance. I suggest this:
var buffer = [];
for(var i = 0; i < 16; i++) {
buffer.push("<div class='box'></div>");
}
var html=buffer.join('');
$('#container').append(html);

Categories

Resources