appendChild onclick will only add div once [duplicate] - javascript

This question already has answers here:
Javascript For loop appends same element once
(2 answers)
Closed 4 months ago.
I'm doing a timetable and to do list website. So, I basically add divs for each timetable block. I've used this tutorial on yt (https://youtu.be/MkESyVB4oUw) for the timetable blocks. (At 24:03) So in HTML there's inputs in a form and he uses the constant "form" for it and uses an addEventListener submit. I've used this and all my timetable blocks work fine. I can add multiple blocks and everything works well.
After that I made a to do / goals section and I decided to take the "form" into my own hands. So I did:
// I tried const and var and the same thing happened
const todoAdd = document.querySelector("#new-todo"); // This is the button
const weekDiv = document.querySelector("#week-divs");
const todoDiv = document.createElement('div');
todoDiv.classList.add("todo-div");
This is what I did for the time blocks and it worked, and then I added:
todoAdd.onclick = function(){
weekDiv.appendChild(todoDiv);
}
When I do it like this, the div is added once and that's it. If I keep clicking the div just gets replaced again and again.

I figured this out mid-writing it. Because when the addEventListener starts for the form, that's when I did all the appending. So the simple solution to this was simply adding the createElement inside the function.
todoAdd.onclick = function(){
const todoDiv = document.createElement('div');
todoDiv.classList.add("todo-div");
weekDiv.appendChild(todoDiv);
}
I probably could've realised this sooner if I wasn't so confused about it actually working just once. I thought there was something missing instead of a simple mistake. I'm guessing it only appends once because it is only read once, while in an onclick function or addEventListener it always loops and re-reads it right? That's my thoughts. Hope this helps someone maybe.

Related

How do I use Javascript to delay visibility of a text box and then hide another box after the first becomes visible

Im very new to this and have reviewed other posts similar to this question. However, I'm finding that those solutions don't work for me.
Background: I'm working in Wix's Velo platform for Javascript. (forgive me if that's not the right technical terminology here)
My goal: When my website home page loads, I want one of the text boxes on the page (#text45) to NOT be visible until 5 seconds have passed. Then, when box #text45 is visible, I want another plain box (#box2) to turn to hidden.
I have found some examples like the one below: (not all code has been pasted and I realize some elements like div1 would need to change to my specific element names)
document.getElementById("div1").style.visibility = "visible";
}
setTimeout("showIt()", 5000);
However, I get an error code: Cannot find name 'document'. Do you need to change your target library? Try changing the 'lib' compiler option to include 'dom'.
When researching this, I found out that Velo cannot access the dom and elements can only be accessed via "$w".
Would someone be kind enough to set me in the right direction on how to accomplish the "goal" above? I would really appreciate it! Thank you in advance.
Here's how you would do it. Note, that it's good practice to change the IDs of your elements to more descriptive names, but I've stuck with the names you provided in your question.
Start by setting #text45 to hidden in using the Properties & Events panel.
Then use this code (note that your page might already have an onReady. If it's there an you're not using it yet, delete all the code on the page and replace it with this):
$w.onReady( () => {
setTimeout(() => {
$w('#text45').show();
$w('#box2').hide();
}, 5000)
} );

How do I stop my dynamic content being appended to end of content?

I'm trying to write some JavaScript that once the page has finished loading will create a div in the place where the is placed.
Here is a stripped-back version of the code...
window.addEventListener('load', function () {
var content = document.createElement('div');
content.id = 'div-ID';
document.getElementsByTagName('body')[0].appendChild(content);
});
It works outside of the addEventListener(), however, when inside the event listener it always puts the created div below the rest of the page content not in the place the <script> tag is placed.
I'm certain the issue is to do with this line...
document.getElementsByTagName('body')[0].appendChild(content);
I need an alternative version to this which doesn't appendChild() but my JS isn't that good and everything I've tried hasn't worked.
Its most likely simple to achieve, I've tried searching Google and Stack Overflow but my search terms don't seem to be producing the desired results.
Any help on this would be much appreciated
You could do it with Node.insertBefore
As such, your code would be something like:
document.body.insertBefore( content, document.body.childNodes[0] );
The second parameter is the referenceNode, that has following comment:
referenceNode is not an optional parameter -- you must explicitly pass a Node or null. Failing to provide it or passing invalid values may behave differently in different browser versions.

.find() doesn't work as expected on DOMNodeInserted

I have a project which uses the jquery-ui datepicker. This date picker uses older icon that i want to change without modifiying the code of the jquery-ui-{version}.js in case of future updates.
Also, i can't use another datepicker because there is already a lot of work related to this datepicker and changing all of it would be an absolute waste of time and will possibly break the current application.
Because the datepicker is an element created via javascript, i thought that i could use the event DOMNodeInserted to modify the class of the element i want.
The architecture of my datepicker looks like this :
and here is the code i wrote :
$(document).on('DOMNodeInserted','div.ui-datepicker',function(e){
var element = e.target;
var prev = $(element).find('div.ui-datepicker-header').find('a.ui-datepicker-prev').find('span.ui-icon');
var next = $(element).find('div.ui-datepicker-header').find('a.ui-datepicker-next').find('span.ui-icon');
//The prev and next elements are not the ones i am looking for
$(prev).removeClass();
$(next).removeClass();
$(prev).empty();
$(prev).addClass('fas');
$(prev).addClass('fa-chevron-left');
$(next).empty();
$(next).addClass('fas');
$(next).addClass('fa-chevron-right');
});
As i wrote as a comment in the code, the prev and next objects are not right.
Only the first .find() worked. When i print the element on the console, it prints the element div.ui-datepicker-header as an element for prev and next. I tried separating the retrieval so to locate where the problem is, but even the .find('a.ui-datepicker-prev') doesn't work. There is no error but it still retrieves the parent eventhough i am using it to find its children. I tried using .children('a.ui-datepicker-prev') but nothing has changed.
What triggers me is that, if i take the exact same code and put it anywhere but in the .on('DOMNodeInserted') event, it works. I am a bit stuck here and i couldn't find somebody with the same problem, if you have, please share.
Any ideas are welcome.
var prev = $(element).find('div.ui-datepicker-header').find('a.ui-datepicker-prev').find('span.ui-icon');
var next = $(element).find('div.ui-datepicker-header').find('a.ui-datepicker-next').find('span.ui-icon')
shoud be
var prev = $(element).find('div.ui-datepicker-header a.ui-datepicker-prev span.ui-icon');
var next = $(element).find('div.ui-datepicker-header a.ui-datepicker-next span.ui-icon');

Polymer how to re-render element/template

I'm trying to dynamically add a page to iron-pages, but the element doesn't recognize the dynamically added content. I think this happen during html rendering, but I don't know how to trigger it again. The jsbin below demonstrates what I'm trying to do: http://jsbin.com/nuhone/4/edit?html,console,output. Basically, I have an iron-pages with one existing page. I'm trying to add a second page dynamically, but unable to do so because iron-pages doesn't recognize this newly added div.
Took a look at your code - basically 2 issues.
Polymer.domAPI
When inserting or removing nodes, use it.
Race Condition
iron-pages extends IronSelectableBehavior - ie MutationObservers have already been setup nicely to detect whenever you add/remove pages. However, this takes time to trigger. Wrap your next steps with Polymer.async() to place them at the end of the microtasks queue.
document.addEventListener("WebComponentsReady", function() {
var newDiv = document.createElement("div");
newDiv.innerHTML = "Def";
var ironPage = document.querySelector("iron-pages");
Polymer.dom(ironPage).appendChild(newDiv);
Polymer.Base.async(function () {
console.log(ironPage.items.length); // shows 2
ironPage.select(1);
});
});
Your jsbin fixed: http://jsbin.com/viqunoxesi/edit?html,console,output
It might help to use the Polymer DOM API like
Polymer.dom(document.querySelector("iron-pages"))
.appendChild(newDiv);

Submit form and return result to same page with javascript

Im trying to write a small js script that will let a user input a string of text and then output it wrapped in some html to the page.
I know how to do this with php, but it seems a little bit of an overkill for such a simple action, plus im always keen to learn something new.
I was playing around using document.myform.submit(); but i wasnt sure how to submit the form value to a variable and then output that var to the screen using document.write();
Any ideas how i would do this ?
Ive created a jsfiddle of the problem here - http://jsfiddle.net/pudle/axcLz/
There are many ways to do it. Here is the code that shows one of them:
document.getElementById("myform").onsubmit = function (event) {
var link = document.getElementById("mylink");
var textField = document.getElementById("text");
link.href = textField.value;
textNode = document.createTextNode(textField.value);
if (link.hasChildNodes()) {
link.removeChild(link.lastChild);
}
link.appendChild(textNode);
event.preventDefault();
};
jsfiddle: http://jsfiddle.net/TMJGH/5/
I added an id attribute to the a element to make things easier.
First line says that we want to change the function that handles "onsubmit" event in our form and then we define that function. The "event" argument is used only to call .preventDefault() in the last line which basically means that we don't want the form to be actually submitted.
We need to get access to DOM elements in the javascript code, so I used document.getElementById. Then I set the href attribute to the value of the textField. To change the actual link text I created a new text node with the value of the textField (it is possible to use textNode.innerHTML but that won't escape HTML code if someone inserts it in the text field). Then I check if our a element already has some text in it - if yes, it has to be removed. Finally I append the text element as a new child to our a element.
If you want to append more HTML nodes inside a node you can easily create them with document.createElement('element name') and append them to link. I also have to mention that jQuery makes playing with DOM a lot easier.

Categories

Resources