javascript: dynamically remove divs - javascript

I'm very new to javascript. The page I am creating has a bunch of forms on it that will hold different data. I've managed to put together the following script that allows me to add more divs by ID.
What I would now like to do is be able to add a button to each of the new divs that allows that specific div to be removed.
var counter = 1;
var limit = 30;
function addInput(what) {
if (counter == limit) {
alert("You have reached the limit of adding " + counter + " inputs");
}
else {
var container = document.getElementById(what);
var clone = container.cloneNode(true);
clone.setAttribute('id','div_'+document.getElementById(what).getElementsByTagName('div').length);
container.appendChild (clone);
counter++;
}
}

var remButton=document.createElement('button');
remButton.textContent='Remove';//or something else
remButton.addEventListener('click',function(){
this.parentNode.parentNode.removeChild(this.parentNode)
},false);
clone.appendChild(remButton);
Put that just before container.appendChild(clone);

Related

My jquery function is pushing elements to all my arrays

On my website, users can click on some text to open up a Modal. This Modal allows users to choose a bunch of toppings to add to their Pizza.
Through Javascript, I add each selected topping to an array and change the text display to match their selected toppings. This more or less works, but the problem is for some reason, whenever they add a topping, it is added to ALL arrays, not just the item it's selected for. Can someone help me find why this is happening?
// Open Toppings Modal
$(document).ready(function() {
var count = -1
var tplist = []
$(".order").each(function(){
count += 1
tplist.push([])
var listeners = 0
setModal(count, tplist, listeners)
});
function setModal(count, tplist, listeners) {
$("#openModal" + count).click(function(){
console.log("clicked")
$("#toppingModal" + count).modal()
if (listeners == 0) {
listeners += 1
$("input[type='checkbox']").change(function() {
// TODO: Fix Bug
// Adding to all javascript lists
if (this.checked) {
tplist[count].push($(this).val());
console.log(tplist)
}
else {
ele = $(this).val();
pos = $.inArray(ele, tplist[count])
if ( ~pos ) tplist[count].splice(pos, 1);
}
// Change text to list
if (tplist[count].length > 0) {
$("#openModal" + count).text(tplist[count])
}
else {
$("#openModal" + count).text("Select Toppings")
}
})
}
});
};
});
I am suspecting your $("input[type='checkbox']").change(function() {} is called for every model. Try setting count number somewhere when you click select topping and compare inside $("input[type='checkbox']").change(function() {} to prevent adding of toppings in all arrays

Change div id attribute on click

I have two divs. When I click on a button it moves to another div
Here is it looks like
I realize it like this
var counter = 0;
$('.click2').on('click', function () {
counter++;
if (counter > 10) {
return false;
}
else {
var elem = $(this).closest('.title');
$('.title2').append($(elem).html()).show();
}
});
But I have one problem I need to change Id of elements when it moves
I know that is realizing like this
$(this).attr('id', '.title_left');
But I can have 1-10 divs in left column and need to name it .title_left1. Next will be title_left2 and ++
How I can code it?
You can just append counter to the id attribute:
$(this).attr('id', '.title_left' + counter);

Execute a Callback function on multiple elements

I had a question about the way I could execute a callback on multiple elements in my div.
So here it is. I have a div that contains two columns (col1 and col2, both taking 50% of the parent div and on float:left) many projects displayed as images. A big project is twice bigger (height) than a small one.
The configuration created makes it possible to display properly the projects to fill the div and not leave blank parts. So, basically, if we have 3 projects, we get a big project in col1 and 2 small in col2.
With 4 projects, we get a small + big in col1 and a big + small in col2.
And so on.
Problem is, when i'm filtering the different projects (in this example, by, for example, displaying the projects made in JS only, I use show() and hide() which works properly.
If animated, the projects just disappear because the hide() seems to be called while the show() isn't completed yet.
I was then told about the call back function but it seems to work only on one element, not multiples. Which is not optimal since my filtering always displays multiple projects.
I would like to know how to execute the function properly, so it works on all the projects because it seems to apply to only one.
Thanks in advance.
<script>
function update_projects(projects_ids){
console.log("Update projects : " + projects_ids);
var projects_top = $('.projects').offset().top;
if ($(window).scrollTop() > projects_top) {
$(window).scrollTop(projects_top);
}
var projects_config = generate_configuration(projects_ids.length);
var project_index = 0;
//$('.project').show();
$('.project').slideUp(2000, function(){
var odd = false;
for (var i = 0; i < projects_config.col1.length; ++i) {
var block_type = projects_config.col1[i];
var project_id = projects_ids[project_index++];
var odd_selector = '';
if (block_type == 'small') {
if (odd == false) {
odd_selector = '.left';
} else {
odd_selector = '.right';
}
odd = !odd;
}
$('.col1 .project_' + project_id + '.' + block_type + odd_selector).show();
}
odd = false;
for (var i = 0; i < projects_config.col2.length; ++i) {
var block_type = projects_config.col2[i];
var project_id = projects_ids[project_index++];
var odd_selector = '';
if (block_type == 'small') {
if (odd == false) {
odd_selector = '.left';
} else {
odd_selector = '.right';
}
odd = !odd;
}
$('.col2 .project_' + project_id + '.' + block_type + odd_selector).show();
}
});
resize();
}
As you've discovered, the completion callback on an animation is called once per element, not once per set.
To have a callback that is invoked when all of the animations have finished, use the .promise() method on the collection:
$('.myClass').slideUp(2000).promise().then(function() {
// not called until all animations have finished
...
});

JS function to hide or show elements

I have to JSON files, I load them both into two tables like this:
$(window).load(function(){
$.getJSON('http://1xxxxxx/xxxxx_1_18.json', function(data) {
var output="<div class='outer'>";
for (var i in data.lbclassic118) {
output+="<div style='visibility:hidden;' class='lbclassic118'id="+"age" + data.lbclassic118[i].ageinweeks+">"+ '<table class="table table-responsive"><tr class="cabecera"><th colspan="3"><center><strong>Age (weeks)'+ data.lbclassic118[i].ageinweeks+'</strong></center></th></tr><tr><td rowspan="3">Body Weight (g)</td><td>average</td><td><strong>'+ data.lbclassic118[i].average+'</strong></td></tr><tr><td>range min</td><td><strong>'+ data.lbclassic118[i].rangemin+'</strong></td></tr><tr><td>range mmax</td><td><strong>'+ data.lbclassic118[i].rangemmax+'</strong></td></tr><tr><td rowspan="3">feed sonsumption</td><td>kj bird day</td><td><strong>'+ data.lbclassic118[i].kjbirdday+'</strong></td></tr><tr><td>g bird day</td><td><strong>'+ data.lbclassic118[i].gbirdday+'</strong></td></tr><tr><td>cumulative</td><td><strong>'+ data.lbclassic118[i].cumulative+'</strong></td></tr></table>' +"</div>";
}
output+="</div>";
document.getElementById("placeholder1").innerHTML=output;
});
});
$(window).load(function(){
$.getJSON('http://xxxxxx/xxxxxx.json', function(data) {
var output="<div class='outer'>";
for (var i in data.lbclassic1990) {
output+="<div style='visibility:hidden;' class='lbclassic1990'id="+"age" + data.lbclassic1990[i].ageinweeks+">"+ '<table class="table table-responsive"><tr class="cabecera"><th colspan="3"><center><strong>Age (weeks) '+ data.lbclassic1990[i].ageinweeks+'</strong></center></th></tr><tr><td>Egg No. per H.H.</td><td>cumul.</td><td><strong>'+data.lbclassic1990[i].cumul+'</strong></td></tr><tr><td rowspan="2">Rate of Lay %</td><td>per H.H.</td><td><strong>'+data.lbclassic1990[i].perhh+'</strong></td></tr><tr><td>per H.D.</td><td><strong>'+data.lbclassic1990[i].perhd+'</strong></td></tr><tr><td rowspan="2"> Egg Weight (g)</td><td>egg weight in week</td><td><strong>'+data.lbclassic1990[i].eggweightinweek+'</strong></td></tr><tr><td>egg mass cumul.</td><td><strong>'+data.lbclassic1990[i].eggmasscumul+'</strong></td></tr><tr><td rowspan="2">Egg Mass -- g/H.D. -- kg/H.H.</td><td>egg mass in week</td><td><strong>'+data.lbclassic1990[i].eggmassinweek+'</strong></td></tr><tr><td>egg mass cumul.</td><td><strong>'+data.lbclassic1990[i].eggmasscumul2+'</strong></td></tr></table>' +"</div>";
}
output+="</div>";
document.getElementById("placeholder2").innerHTML=output;
});
});
The information comes up as it should, I have no problems with that.
However, what I'm trying to do is just show ONE table at a time, not all the tables at the same time (don't want a table for each element in the JSONs) to be seen, but only one a time.
For that I'm implemeting a function that with a slider control will show or hide the tables.
Here's an images of the HTML output data structure:
Now, what I want to to is hide or show different DIVs (tables) with this script:
<script>
function leslider(valor) {
var elementos_lbclassic118 = document.getElementsByClassName("lbclassic118");
var elementos_lbclassic1990 = document.getElementsByClassName("lbclassic1990");
var total_elementos = elementos_lbclassic118.length + elementos_lbclassic1990.length;
var i;
for (i = 1; i < total_elementos.length+1; i++) {
document.getElementById("age"+i).style.visibility = "hidden";
}
document.getElementById("age"+valor).style.visibility = "visible";
}
However it won't work, the 1st JSON will show all the elements but never hide it, and the second one will place them all on top of each other, not sure where I'm failing.
I guess you are wrong "leslider" function.
How to use this "leslider" function, let's me see this code.
I found the culprit, I was getting length from a numeric, value. Here's the updated function.
<script>
function leslider(valor) {
var elementos_lbclassic118 = document.getElementsByClassName("lbclassic118");
var elementos_lbclassic1990 = document.getElementsByClassName("lbclassic1990");
var total_elementos = elementos_lbclassic118.length + elementos_lbclassic1990.length;
var i;
for (i = 1; i < total_elementos+1; i++) {
document.getElementById("age"+i).style.display = "none";
}
document.getElementById("age"+valor).style.display = "block";
}

Heatmap for Link clicks with only one function for all

I got a problem while writung a code for a Heatmap based on link clicks.
I have a Page with different articel teasers. When i click the link the artical itself opensup. Now i want to track in real time how often which articel is clicked so i can decide which articel is relevant to users and place it like on the first articel space and so on.
Therefor i wrote a function which tracks the clicks with a counter and show them in the div.
Now my problem is. That i cant write like 20 functions for counters and 20 for resets. I want to have one function which can decide which articel was clicked and add +1 to the counter of the link.
My Code for the counter and the reset + the link text gets red after more than 5 clicks.
var count1 = 0;
function heatmap(id) {
if(id==1){
count1++;
document.getElementById("count1").innerHTML = count1;
}
if(count1>=5){
document.getElementById("link1").style.color = "red";
}
}
function reset(id){
if(id==1){
count1=0;
document.getElementById("count1").innerHTML = 0;
}
}
My html code so far
<div style="text-align:center; font-size:20px; font-family: arial;">
<div id="link1" onclick="heatmap(1)">This is the first Link</div><br>
<div id="count1">0</div><br>
<button onclick="reset(1)">RESET</button>
<button onclick="save(1)">SAVE</button>
</div>
Now my main problem is that i only want one function for all the link tracking.
Is there a possibiblity to write the code in a way the variables are dynamicly so that the function can decide which link was clicked.
for example something like:
var count + ID = 0;
function heatmap(ID) {
count + ID ++;
document.getElementById("count" + ID).innerHTML = count+ID;
}
if(count + ID >=5){
document.getElementById("link + ID").style.color = "red";
}
}
function reset(id){
count + ID =0;
document.getElementById("count + ID").innerHTML = 0;
}
}
I already searched this homepage and did some google searches but all i found was working with arrays or lists. But i think this wouldnt realy work for me since i want to give my function an ID and later add this id to the varibale name like count + ID = count | count + ID = count2 same with the document.getElementById("count" + ID).innerHTML = count+ID; = document.getElementById("count1").innerHTML = count1;
As you can see the link got a onclick="heatmap(ID)" this ID will be added to every articel Link and will go from the first articel with 1 to the last articel with like 20.
If i change an Articel the counter will be resetet and the ID will be changed to its position. So there will always be a identifier with the ID which can be used for the counter.
You could loop through all articles and store a counter on each element which you update or reset once the specific button inside the article was clicked:
var articles = document.querySelectorAll('article');
for(var i=0; i < articles.length; i++) {
articles[i].querySelector('.save').addEventListener('click', updateCounter);
articles[i].querySelector('.reset').addEventListener('click', resetCounter);
articles[i]['counter'] = 0;
}
function updateCounter(ev) {
var article = ev.target.parentNode;
article.counter++;
article.querySelector('.counter').innerHTML = article.counter;
/* Some server synchronisation should go here */
}
function resetCounter(ev) {
var article = ev.target.parentNode;
article.counter = 0;
article.querySelector('.counter').innerHTML = article.counter;
/* Some server synchronisation should go here */
}
DEMO
But to permanently store the counters you have to synchronize your results with a server, respectively a database.
If you just want to use one function you could realize it like this:
var articles = document.querySelectorAll('article');
for(var i=0; i < articles.length; i++) {
articles[i].querySelector('.save').addEventListener('click', checkCounter);
articles[i].querySelector('.reset').addEventListener('click', checkCounter);
articles[i]['counter'] = 0;
}
function checkCounter(ev) {
var article = ev.target.parentNode,
button = ev.target;
if(button.classList[0] === 'save') {
article.counter++;
} else if(button.classList[0] === 'reset') {
article.counter = 0;
}
article.querySelector('.counter').innerHTML = article.counter;
}
DEMO

Categories