getElementByID.innerHTML is failing to change text - javascript

I am new to HTML and Javascript and I decided to try write a basic shopping cart.
I have a problem though. Why doesent this:
if(totalItems == 0)
{
document.getElementById('yourCartContains').innerHTML = "Your cart contains no items!";
}
Change this:
<b id = "yourCartContains">0</b>
To say "your cart contains no items" instead of 0?
The function definitely works, because I have tried switching the function to show an alert and it does this without any problems - so function works, but for some reason the function does not change the text.
Here is the function with the alert (I even changed totalItems to 0 to prove function is being called):
var totalItems = 0;
if(totalItems == 0)
{
alert("Random Alert is called upon function being executed");
document.getElementById('yourCartContains').innerHTML = "Your cart contains no items!"; <!-- But this isnt -->
}
I am debugging in chrome.

document.getElementByID().innerHTML definitely works.
Make sure:
document refers to the same document the element is in (you're not working with an iframe or such).
you call the function when the element is attached to the DOM.
This doesn't work:
<script>document.getElementById('foo').innerHTML = 'bar';</script>
<b id="foo"></b>
This works:
<b id="foo"></b>
<script>document.getElementById('foo').innerHTML = 'bar';</script>
your html is valid. It could be that invalid markup doesn't let your browser find the correct element.
Anyway, if you're working in chrome, you really should debug with the console and not with "alerts". Press F12 (on Windows / Linux) or Cmd + Opt + I on Mac. If there are any errors, you should see them in red in the console tab.
If there are no errors, do this:
if(totalItems == 0)
{
console.log('el: ', document.getElementById('yourCartContains'));
document.getElementById('yourCartContains').innerHTML = "Your cart contains no items!"; <!-- But this isnt -->
}
and see what your console tells you. (There probably will be an el: undefined)

This works for me. Have you loaded your script after your html?
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div><b id = "yourCartContains">0</b></div>
<script>
var totalItems = 0;
if(totalItems == 0)
{
alert("Random Alert is called upon function being executed");
document.getElementById('yourCartContains').innerHTML = "Your cart contains no items!"; <!-- But this isnt -->
}
</script>
</body>
</html>

<script type="text/javascript">
var totalItems = 0;
if(totalItems == 0)
{document.getElementById('yourCartContains').innerHTML = "Your cart contains no items!";}
</script>
<span id="yourCartContains" style="font-weight:bold"></span>

I have very painful experience using text to innerHTML.
Since my text contains a lot of dynamic element (select2 for searching option list) and I forgot to put ending quote . The text looks fine, in some cases, however, the innerHTML truncate the "submit" button is missing.
The text assigned to innerHTML is translate to other strange result automatically. if HTML syntax is not correct, it produces very weird string in innerHTML. the problem is intermittent, some case is fine, some are not good. Since project is big, I wasted whole night effort to fight to bug.
I finally figure a way to debug the dynamic element by using W3 validator (https://validator.w3.org/nu). copy and paste into a file and check the dynamic element syntax. There are some online HTML checker (https://www.freeformatter.com/html-validator.html).

Related

Missing eye icon in a password field when using template tag

I understand, why I see no eye icon in a input field with type "password", when I use the template tag.
For this example, I create a simple single HTML file:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Sample</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
document.addEventListener('click', () => {
/* It's not ok. (Second) */
const templateNode = document.getElementById('testTemplate');
const cloneNode = templateNode.content.cloneNode(true);
document.body.insertBefore(cloneNode, null);
/* It's ok. (Third) */
const form = document.createElement('form');
const input = document.createElement('input');
input.type = 'password';
form.appendChild(input);
document.body.appendChild(form);
}, { 'once': true });
</script>
</head>
<body>
<!-- Second //-->
<template id="testTemplate">
<form>
<input type="password">
</form>
</template>
<!-- First //-->
<form>
<input type="password">
</form>
</body>
</html>
You can run this local or on a server. I try it with Edge or Chrome. It's the same effect. After you click in the document, two input fields as type "password" added. The first input field shows the eye icon. The second (from template) has no eye. The third input field (created with the method createElement) has the eye, again.
I know, how I can toggle this with javascript, but I am trying to understand, where the error is. I don't think, it's a bug. I have the same result, when I split the files (html, javascript).
Thanks for your clarification.
You can't see current html element because it is used as a holder of an html, this element is not rendered by html but can be used by JavaScript (example: copying items), you could use an "iframe" as tag by setting up scr="" option with url (ex. scr="https://stackoverflow.com", the page should be on your server, it wouldn't load from any other sources) to html page if you want item to appear.
some documentation: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
Thanks for the answer.
I was firmly convinced that this eye icon is now displayed by default. But with Chrome, Firefox and Edge only Edge shows this eye....
Now about the problem in Edge. The link to the template tag was helpful, even if I already knew it. The content of the template tag is only parsed. If this is then added to the DOM with cloneNode, then it is rendered (as I understand it).
What was the solution now? In the german version of this article importNode is used instead of cloneNode. I'm from German.
I changed these lines:
const templateNode = document.getElementById('testTemplate');
const cloneNode = document.importNode(templateNode.content, true);
document.body.insertBefore(cloneNode, null);
https://developer.mozilla.org/de/docs/Web/HTML/Element/template
So the Edge shows this eye icon after adding it. Where the exact difference between cloneNode and importNode lies, I don't know yet. There I have to read again.

How do I remove functions from memory in Javascript after using Jquery .html() function to replace a <div> with a <script> included?

Below is an example of a problem I am having. I am using $(locator).html(data) to replace a DIV after an ajax call. The issue is that the DIV also have a SCRIPT tag inside it, and those functions in that SCRIPT tag are remaining in memory after I .empty() that DIV.
Is there a way to remove/de-register/undefine all functions in the SCRIPT tag automatically/programmatically? I guess I thought the Jquery .empty() would do that, but I guess not. I think I could do something manual like test1 = undefined but I don't want to have to explicitly do that for all the functions.
Thanks.
EDIT: I am working on a legacy product, so there are dozens of html files with dozens of functions that could be loaded for the newString variable. So my goal is not to change any of those, but to solve this lingering-function issue at the time of .empty() and .html() when replacing the div contents.
EDIT 2: And I can't just "delete" the function, because I don't always know what the function(s) will be. I need to do this programmatically. (seems I keep getting flagged as a duplicate question, but again, I can't delete what I don't know yet)
function change () {
// this newString is mock html data coming back from an ajax call
let newString = "<p>Reloaded page</p>";
console.log("#emptyme HTML before empty():")
console.log($("#emptyme").html());
$("#emptyme").empty();
console.log("#emptyme HTML AFTER empty():")
console.log($("#emptyme").html());
$("#emptyme").html(newString);
if (typeof test1 !== "undefined") {
$("#error").html("test1() WAS STILL FOUND!!");
console.log("test1() WAS STILL FOUND!! Function definition from memory is:");
console.log(test1);
}
console.log("finished change function.");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="emptyme">
<p>
Initial page
</p>
<script>
function test1 () {
console.log("this is test1 function.");
}
</script>
</div>
<button onclick="change()">
load change
</button>
<div id="error">
</div>
</body>
</html>
JavaScrip has an internal garbage collection and your code does not have to destroy things like you would do in C++
However, at Certain times we would want to "destroy a function" where it is resources expensive
Because js runs from top to bottom you can overwrite that function if you have called it in a variable later in the program to free up those resources. Or even do it later in the logic of the program
var ExpensiveFunction =( function () {
//..code
function getRidOfthis1(){ console.log("foo1"); }
function getRidOfthis2(){ console.log("foo2"); }
function getRidOfthis3(){ console.log("foo3"); }
function getRidOfthis4(){ console.log("foo4"); }
//initiate an internal reference to them
ExpensiveFunction.getRidOfthis1 = getRidOfthis1;
ExpensiveFunction.getRidOfthis2 = getRidOfthis2;
ExpensiveFunction.getRidOfthis3 = getRidOfthis3;
ExpensiveFunction.getRidOfthis4 = getRidOfthis4;
} );
//Functions available outside of the nesting
ExpensiveFunction()
ExpensiveFunction.getRidOfthis1();
ExpensiveFunction.getRidOfthis2();
// overidding it
ExpensiveFunction =0

Validating/Inserting text into new window with Javascript

I've searched everywhere for many different ways of inserting text into a newly opened window with javascript within a function, yet none have seemed to work which leads me to believe I'm missing a key fundamental ingredient here.
function validate2() {
var valTxt = document.webPage.txt2.value;
if (valTxt == null || valTxt == "") {
alert("Field cannot be empty!");
return false;
}
if (valTxt.length < 5) {
alert("You must enter at least 5 characters!")
return false;
}
myWin = window.open('mypopup.html', "mywin", '');
myWin.getElementById('userText').innerHTML = valTxt;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Exercise 3</title>
<script type="text/javascript" src="functions.js"></script>
</head>
<body>
<form name="webPage" action="http://thebest404pageever.com/">
Please type anything over 5 characters: <input type="text" name="txt2"><br/>
<input type="submit" name="b2" value="Confirm" onClick="return validate2()">
</form>
</body>
</html>
I have an empty HTML file for mypopup with just a h1 element with the id userText. The popup certainly shows up, but continuously shows blank. Is there anything I'm missing here? Thanks a lot.
myWin = window.open('mypopup.html', "mywin", '');
window.onload=function placeText(){
myWin.getElementById('userText').innerHTML = valTxt;
I appended it with this, and it doesn't look right and sure enough, doesnt work right either.
The loading of the new window is done asynchronously. As indicated in the MDN documentation:
Note that remote URLs won't load immediately. When window.open() returns, the window always contains about:blank. The actual fetching of the URL is deferred and starts after the current script block finishes executing. The window creation and the loading of the referenced resource are done asynchronously.
You will need to defer your changes to the DOM until after they are loaded.
I would use a window.onload handler for this:
window.onload=function() {
myWin.getElementById('userText').innerHTML = valTxt;
};

Uncaught TypeError: Cannot read property 'appendChild' of null after calling getElementById()

I've just started learning JavaScript (properly :D) and I'm having a hard time dealing with the above mentioned error. The browser that I'm using is the latest Google Chrome on a Debian Jessie 64bit system. The code is embedded inside the <script/> tag of my page:
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head/>
<body bgcolor="white">
<p><u>Counter:</u></p>
<div id="counter"/>
<p><u>Temperature conversion:</u></p>
<div id="temperature"/>
<script type="text/javascript">
function printRange(_from, _to) {
// ...
}
function fahrenheitToCelsius(fahrenheits) {
return 5/9 * (fahrenheits - 32);
}
document.getElementById("counter").innerHTML = printRange(2,-10); // (1)
var fahrenheits = prompt("Enter Fahreheit degrees", 50);
var celsius = fahrenheitToCelsius(fahrenheits);
var para = document.createElement("p");
para.textContent = fahrenheits + "F = " + celsius + "oC";
document.getElementById("temperature").appendChild(para); // (2)
</script>
</body>
</html>
The document.getElementById("counter") (marked with 1) is working fine however the mentioned error occurs at document.getElementById("temperature") (marked with 2) even though both <div/>s are basically one after the other and both appear before the <script/> tag where these are being referenced. I do understand that the error comes from document.getElementById("temperature") returning null but I haven't got the faintest idea WHY the script is unable to find the given ID through this function call.
There are only a certain subset of elements that you can use without a closing tag. That is the implicit use case of />. The subset is known as "void elements".
As a result of div not being one of those elements, your <div/> tag is simply rendered as <div> without a closing tag. The first document.getElementById("counter").innerHTML = printRange(2,-10); // (1) summarily wipes out the rest of the page with the results of the call to printRange.
Close your elements properly.
<div id="counter"></div>
technically self-closing tags are disallowed in HTML 4.x but are allowed in XHTML -- could you try not self-closing the div tags?
jsfiddle
<div id="temperature"></div>

Changing images periodically in JavaScript

So basically I want to change image in every 5 second, so I wrote the following Javascript code and tag it to html. But the console keep saying that "No javaScript on this page" and the code does not apply
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript for Programmers</title>
</head>
<body>
<h2>Mood Change</h2>
<p>The mood of this web page changes every 5 seconds.</p>
<p><img id="mood" src="frown.gif" alt="mood"></p>
<script async src="../scripts/moody.js"></scripts>
</body>
</html>
var images=[]
images[0]="smile.gif";
images[1]="frown.gif";
var myMood= document.getElementById("mood");
function change(){
if(myMood==images[0]){
myMood.src=images[1];
}
else if(myMood.src==imgaes[1]){
myMood.src=images[0];
}
}
setInterval(change,5000);
</scripts> should be </script>
Also your JS could look like this: http://jsbin.com/nawono/2/edit
var myMood= document.getElementById("mood");
var images=[
"smile.gif",
"frown.gif"
];
function change(){
myMood.src= images.reverse()[0];
}
setInterval(change,5000);
Ahh, to explain images.reverse()[0];, it reverses the array order and we always take out the 0 indexed key. Quite nice
The reason your code didn't work is you comparison is in appropriate. Where you have:
var images=[]
images[0]="smile.gif";
images[1]="frown.gif";
var myMood= document.getElementById("mood");
function change(){
if (myMood == images[0]) {
then myMood is a DOM element and images[0] is a string. Those two will never almost never be equal (unless the DOM element's toString methods produces exactly the same string).
You probably meant:
if (myMood.src == images[0]) {
so that you compare two strings that are more likely to be the same.

Categories

Resources