Why is only one div being appended? - javascript

I'm trying to append several div elements dynamically. However, only one div element is being created/displayed in the browser when I go to test the code. I tried looking for similar questions/issues like this, but found nothing. Any help would be appreciated.
.divcreate {
height:75px;
width:75px;
border:2px solid #000000;
display:inline-block;
}
$(document).ready(function () {
for (var i=0; i < 12; i++) {
$("body").append("<div></div>").addClass('divcreate');
}
});

Because the addClass function applies to your body selector, your code is adding 12 divs, but then applying the divcreate class to your body element. Below is a simple working version that sets the class inline.
$(document).ready(function (){
for (var i=0; i < 12; i++) {
$("<div></div>").addClass('divcreate').appendTo(document.body)
}
});
.divcreate {
height:75px;
width:75px;
border:2px solid #000000;
display:inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

You are adding the class to the body. If you put text in the div you will see that the div is in fact being added 12 times. See this jsfiddle -> https://jsfiddle.net/ehj6wzew/

Add class first and then append
$(document).ready(function (){
for (var i=0; i < 12; i++) {
$("body").after($('<div></div>').addClass('divcreate'));
}
});
.divcreate {
height:75px;
width:75px;
border:2px solid #000000;
display:inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Related

Want less repetition when using javascript to change styles onclick

This code currently works, and when each div is clicked the background color and font size will change. In addition, the formatting for one of the other two divs which was already clicked will be removed. The problem is that this will end up requiring a lot of code, what I imagine is far more than is needed. I'm wondering how to repeat less. It is not such a big deal in this example, with only three divs, but my actual project will need many, many more.
I tried including multiple divs, so it would look like this;
document.querySelector(".div2, .div1").classList.remove("styles");
but that did not seem to work.
const div1 = document.querySelector(".div1");
const div2 = document.querySelector(".div2");
const div3 = document.querySelector(".div3");
function makeBigDiv1 () {
document.querySelector(".div1").classList.add("styles");
document.querySelector(".div2").classList.remove("styles");
document.querySelector(".div3").classList.remove("styles");
}
div1.addEventListener("click", makeBigDiv1);
function makeBigDiv2 () {
document.querySelector(".div2").classList.add("styles");
document.querySelector(".div1").classList.remove("styles");
document.querySelector(".div3").classList.remove("styles");
}
div2.addEventListener("click", makeBigDiv2);
function makeBigDiv3 () {
document.querySelector(".div3").classList.add("styles");
document.querySelector(".div1").classList.remove("styles");
document.querySelector(".div2").classList.remove("styles");
}
div3.addEventListener("click", makeBigDiv3);
.div1 {
width:500px;
height:100px;
border: 2px solid black;
}
.div2 {
width:500px;
height:100px;
border: 2px solid black;
}
.div3 {
width:500px;
height:100px;
border: 2px solid black;
}
.styles {
font-size: 50px;
background-color: grey;
}
<div class="div1">One</div>
<div class="div2">Two</div>
<div class="div3">Three</div>
Well as I mentioned the code works, but would just become prohibitively verbose I feel if applied to a large project. I'm relatively new to this and want to write DRY - don't repeat yourself - code. Thanks!
If you want the three divs to have the shared style, you can style them all at once. You can also make a lot of your click functionality reusable. This is what I would do:
const elements = document.querySelectorAll("div")
function attachClickHandler(className) {
return () => {
document.querySelector(`.${className}`).classList.add('styles');
document.querySelectorAll(`div:not(.${className})`).forEach(element => { element.classList.remove('styles') });
}
}
elements.forEach(element => {
element.addEventListener("click", attachClickHandler(element.className))
})
<html>
<head>
<style>
.div1, .div2, .div3 {
width:500px;
height:100px;
border: 2px solid black;
}
.styles {
font-size: 50px;
background-color: grey;
}
</style>
</head>
<body>
<div class="div1">One</div>
<div class="div2">Two</div>
<div class="div3">Three</div>
<script>
</script>
</body>
</html>
In context you would probably not want to add event listeners to every div so you could just add a class to all divs you want to make selectable and find all by class name instead of find all of type div. This would also allow you to add the base styling for the shared class instead of to all 3 divs.
You can do this quite easily just by looping thru the divs. here is an example. There is some optimization you can do but you get the idea
const div = document.querySelectorAll('.div');
for (var i = 0; i < div.length; i++) {
div[i].addEventListener('click', function(event) {
for (var j = 0; j < div.length; j++) {
// remove styles class from all the div classes
div[j].classList.remove("styles");
}
// add styles class only to the clicked item
this.classList.add("styles");
});
}
.styles {
font-size: 50px;
background-color: grey;
}
<div class="div">One</div>
<div class="div">Two</div>
<div class="div">Three</div>
this.classList.add("styles"); The this refers to the clicked item
Here are some changes:
Use the same className for each block, and give it a specific name (i.e. box).
Same for the added className, make it clear. (i.e. is-selected).
Don't duplicate functions for the same action and use forEach instead to loop through each box.
// Get all boxes
const boxes = document.querySelectorAll('.box');
// For each box
[...boxes].forEach(box => {
// Attach an event click listener
box.addEventListener('click', () => {
// Add the `is-selected` className to the clicked one
box.classList.add('is-selected');
// Remove the `is-selected` className to all the others
[...boxes].filter(el => el !== box).forEach(box => {
box.classList.remove('is-selected');
})
});
});
.box {
width: 500px;
height: 100px;
border: 2px solid black;
}
.box.is-selected {
font-size: 50px;
background-color: grey;
}
<div class="box">One</div>
<div class="box">Two</div>
<div class="box">Three</div>

How to display a js variable value in HTML,<div id> with mouseover effect

In javascript I have a variable which contains some value which i get from JSON.
var a =recipe[0].step[1].processingTime;//here processing time is stored in var a
I want to display this value by showing a description box, when I hover my mouse over a small div id in HTML.
<tr>
<td>Recipe 0</td>
<td>
<div id="p1"><div>
</td>
</tr>
How to do that? Can anyone please show me a easy solution.
If you only want the simple native html tooltip you can just set the elements title atrribute. For example the ones that get shown when you hover over the SO voting arrows
document.getElementById("p1").setAttribute("title",recipe[0].step[1].processingTime);
Demo
var text = "13ms";
document.getElementById("p1").setAttribute("title",text);
#p1 {
width:80px;
height:80px;
background:#323232;
}
<div id="p1"></div>
If however you are wanting a fancier one, you can do this with a little javascript and using css :hover, :after, attr css function, and the content property.
Give your div (or whatever element) a css class like below:
.withTooltip:hover:after {
content:attr(data-tooltip);
display:block;
padding:10px;
background:#323232;
border-radius:4px;
border:#000000;
color:#FFFFFF;
}
:hover will cause the style to applied only when the element is
hovered over.
:after will create a pseudo-element
conent you can use to set the text that the pseudo-element will display
attr will take the passed attribute name and get the value of that
attribute
Then use javascript to set the attribute to your saved text (in this case using data-tooltip)
document.querySelector("p1").dataset.tooltip = recipe[0].step[1].processingTime;
//or
document.querySelector("p1").setAttribute("data-tooltip",recipe[0].step[1].processingTime);
Demo
var someData = ["13ms","100ms","8ms","67ms"];
var elements = document.querySelectorAll(".withTooltip");
for(var i=0; i<elements.length; i++){
elements[i].dataset.tooltip = someData[i];
}
.box {
width:50px;
height:50px;
background:#86DDFF;
margin:10px;
position:relative;
display:inline-block;
}
.withTooltip:after {
content:attr(data-tooltip);
display:block;
padding:10px;
position:absolute;
right:-40px;
top:0px;
background:#323232;
border-radius:4px;
border:#000000;
color:#FFFFFF;
opacity:0;
transition:all 0.3s;
z-index:100;
pointer-events:none;
}
.withTooltip:hover:after {
opacity:1;
}
<div class="box withTooltip"></div>
<div class="box withTooltip"></div>
<div class="box withTooltip"></div>
<div class="box withTooltip"></div>
Here's a vanilla javascript version:
var a = "something to show";
function showProcTime(elem) {
elem.addEventListener("mouseout", clearProcTime);
elem.innerHTML = '<div class="popupBox">' + a + '</div>';
elem.style.backgroundColor = "#EFEFEF";
}
function clearProcTime(e) {
var elem = e.target;
elem.removeEventListener("mouseout", clearProcTime);
elem.innerHTML = "";
elem.style.backgroundColor = "#CCCCCC";
}
.popupBox {
display: block;
width: 200px;
height: 20px;
position: absolute;
top: 20px;
left: 20px;
background-color: #EFEFEF;
border: 1px solid;
padding: 10px;
}
<div id="p1" style="background-color:#CCCCCC;display:inline-block;width:200px;height:20px;" onMouseOver='showProcTime(this)'>roll over me
<div>
You could use jQuery:
var a =recipe[0].step[1].processingTime;
$('#p1').mouseenter(function(){
$(this).html(a)
}).mouseout(function(){
$(this).html('');
});
Have you tried jquery hover method? http://www.w3schools.com/jquery/event_hover.asp
and if you are using simple javascript try this: http://www.w3schools.com/jsref/event_onmouseover.asp
I think this is simple:
<html>
<script>
var a = 'the processing time you got from json';
function displayTitle(e){
e.title = a;
}
</script>
<body>
<table border>
<tr>
<td>Recipe 0</td>
<td onMouseOver='displayTitle(this);'>
<div id="p1"><div>
</td>
</table>
</body>

nth child not working with within body

I'm trying to draw a 6x6 grid with divs, but when I create them with javascript and css, it doesn't show as expected.
css:
div{
width:30px;
height:30px;
margin:0px;
border:1px solid black;
float:left;
}
div:nth-child(6n+1){
clear:both;
}
javascript:
for(var i=0; i<36; i++){
document.body.appendChild(document.createElement('div'));
}
https://jsfiddle.net/kqzhorq0/
The above link demonstrates what I see in the browser.
But, when I select onload or onDomReady settings in jsfiddle, the grid shows as expected.
How can I get the grid to show properly using onload or onDomReady, and why isn't it showing properly without it?
If you can wrap your divs in a container and specify your selectors to target from within the container your code will work.
Here is a working snippet:
for(var i=0; i<36; i++){
document.getElementById("foo").appendChild(document.createElement('div'));
}
#foo div{
width:30px;
height:30px;
margin:0px;
border:1px solid black;
float:left;
}
#foo div:nth-child(6n+1){
clear:both;
}
<div id="foo"></div>
I also created an interactive demo on nth-child to help explain it further: http://xengravity.com/demo/nth-child/
The problem here, the first child of the body in the fiddle is the script element. You can inspect the html of the result panel to see the script element.
The nth-child will consider all the elements while using the index to search for an element, but using nth-of-type you can search for a particular type.
One choice is to use the :nth-of-type selector as below
div {
width:30px;
height:30px;
margin:0px;
border:1px solid black;
float:left;
}
div:nth-of-type(6n+1) {
clear:both;
}
Demo: Fiddle
Another is to insert the divs before the script like
for (var i = 0; i < 36; i++) {
document.body.insertBefore(document.createElement('div'), document.body.firstChild);
}
Demo: Fiddle
But a better solution will be use a custom container element instead of the body element
var ct = document.getElementById('container');
for (var i = 0; i < 36; i++) {
ct.appendChild(document.createElement('div'));
}
then
#container > div {
width:30px;
height:30px;
margin:0px;
border:1px solid black;
float:left;
}
#container div:nth-child(6n+1) {
clear:both;
}
Demo: Fiddle

Generate div columns using jquery

following code on jsfiddle:
<div id="container">
<div class="b">test1</div>
<div class="b">test2</div>
<div class="b">test3</div>
<div class="b">test4</div>
<div class="b">test5</div>
<div class="b">test6</div>
</div>
CSS
.b {
display:inline-block;
position: relative;
margin: 2px;
float:left;
width: calc(16.7% - 10px);
height:400px;
background-color: white;
border: 1px solid black;
}
http://jsfiddle.net/329vcLLc/ does work, it shows 5 columns the way I would like them to be formatted.
I must loop over an array to generate the divs according to the number of elements of the div. I thought I could use the append() function, what do you think? and how can I set the width property for each div (cause it depends on the number of columns)
any ideas?
I don't quite understand what the number of the divs depends on, but if you need to generate some known number of divs you may do this:
var n=8;
var $cont=$('#container');
for(var i=1; i<=n; i++)
{
var d=$('<div>').addClass('b').html('test '+(i)).css('width', 'calc('+(100/n)+'% - 10px)');
$cont.append(d);
}
.b {
display:inline-block;
position: relative;
margin: 2px;
float:left;
height:400px;
background-color: white;
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
According to your provided css you can do something like this:
var divs = ['a','b','c','d','e', 'f', 'g'];
var con_width = parseInt($('#container').width()); //get the width of the container
var width = (con_width / divs.length) - 10; //divide trough the number of divs,
//subtract 10 to make them fit
$.each(divs, function(index, value){
var div = $('<div />').addClass('b').text(value).css('width', width + 'px'); //generate new div
$('#container').append(div); //append it to the container
});
Demo
Reference
.each()
.width()
.css()
.addClass()
.text()

Make checkbox checkable

I have hidden checkbox and I can't reach JS code which allows me to do checkbox checkable. How can I do it?
I tryied some JS from stackoverflow, but it didn't work.
Here is my code http://fiddle.jshell.net/ta7w7bb8/
CSS:
.obalform label.checkbox{
font-size:18px;
color:#2d2f36;
width:478px;
margin:auto;
text-align: left;
display:inline-block;
float:none;
cursor:pointer;
}
.checkbox::before{
content:"";
width:25px;
height:25px;
background:url(http://i.imgbox.com/dMtoesFn.png) 0 0 no-repeat;
float:left;
cursor:pointer;
margin-top: 14px;
margin-right: 15px;
}
.checkbox.checked::before{
content:"";
width:25px;
height:25px;
background:url(http://i.imgbox.com/fpOcnxmf.png) 0 0 no-repeat;
float:left;
cursor:pointer;
margin-top: 14px;
margin-right: 15px;
}
.checkbox:hover::before{
content:"";
width:25px;
height:25px;
background:url(http://i.imgbox.com/fpOcnxmf.png) 0 0 no-repeat;
float:left;
cursor:pointer;
margin-top: 14px;
margin-right: 15px;
}
input[type=checkbox]{display:none;}
HTML:
<div class="obalform">
<div class="radek">
<label class="checkbox" for="check1">souhlas se zasíláním slevových kupónů,akcí a novinek</label><input id="check1" type="checkbox" name="souhlas">
</div>
</div>
And I tryied solution from this topic -> HTML checkbox onclick called in Javascript
You have to use the CSS3 :checked selector but you MUST change the HTML structure before... I have wrote a sample for you:
http://fiddle.jshell.net/Clear/ta7w7bb8/4/ (with this code you don't need to javascript)
Know that in my sample I used an iconic font called "Font Awesome". It's better because with this font you shouldn't use images and the page load is lesser
If you'd like to do the same with-out jQuery you could do it like this:
function getLabel(needle) {
var labels = document.getElementsByTagName("label");
var texts = [] ;
for (var i = 0; i < labels.length; i++) {
var label = labels[i];
if(label.getAttribute("for") == needle) {
return label;
}
}
return null;
}
function checked() {
var label = getLabel('check1');
var selection = this.checked ? "checkbox checked": "checkbox";
if ( selection ) label.setAttribute('class', selection);
else label.removeAttribute('class');
}
// add event listener to checkbox
var el = document.getElementById("check1");
el.addEventListener("click", checked, false);
It's more code than jQuery but it's lighter and loads faster. It depends on what you're going to do.
You can find the fiddle here.
Your code is artificially inserting an image that represents the checkbox's state. The image looks checked when the "checked" class is applied to the <label>. You either need to reorganize your CSS/HTML, or you can write some JavaScript that adds or removes the "checked" class to the <label> when the checkbox is updated.
The following is a simple jQuery script that will fix the problem with your "checked" class.
$(function() {
$("input[type='checkbox']").on('change', function() {
var $this = $(this);
var checked = $this.is(":checked");
if (checked)
$this.closest(".radek").find("label").addClass("checked");
else
$this.closest(".radek").find("label").removeClass("checked");
});
});
Updated Fiddle

Categories