Can't change image source of element ID when using variable name instead of string - javascript

I am writing a function to change the src of an image based on two strings passed to the function, a, which is the element ID, and b, which is the new source for the image.
In this instance, I have confirmed that both variables are passed to the function correctly.
console.log(a); is layerAddButton
console.log(b); is images/layerAdd-blue.svg
Here is my code :
function swapImg(id,url)
{
var a = id;
var b = url;
document.getElementById(a).src = b;
}
This does not change the url of the image as expected, but gives an error in chrome :
functions.js:3025 Uncaught TypeError: Cannot set properties of null
(setting 'src')
at swapImg (functions.js:3025:32)
at HTMLButtonElement.onmouseleave (app.htm:1132:274)
This works fine when I hard code like so :
document.getElementById('layerAddButton').src = 'images/layerAdd-blue.svg';

I tried it and it works. Make sure to write the Id correctly when passing it to the function. And make sure the script is in the HTML after the element and not in the head.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<img
src="https://www.testingtime.com/app/uploads/2017/07/Grundregeln_fuer_User_Testing-750x500.jpg"
alt=""
id="imgElement"
/>
<body>
<script>
function swapImg(id, url) {
var a = id;
var b = url;
console.log(document.getElementById(a));
document.getElementById(a).src = b;
}
swapImg("imgElement", "https://source.unsplash.com/random");
</script>
</body>
</html>

To fix this, you just needed to pass the variable to the getElementById() function and not just the variable name.
The correct code should be :
function swapImg(id,url)
{
var a = id;
var b = url;
document.getElementById(a).src = b;
}

Related

Get current input value in function that is set as variable within another function. (I AM STUMPED) code examples within

I have a difficult question, I am trying to get the input value of an input field, however, I need this to happen within another function.
I already have code that works outside of this other function but I need to refactor it to work inside another function that I am calling.
Examples of working code and non-working code are below.
Here is the HTML where I am getting the input:
<!DOCTYPE HTML>
<HTML>
<head>
<title></title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="css/styles.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="js/require.js"></script>
<script type="text/javascript">
(function () {
var config = {
baseUrl: "js",
};
var dependencies = ["otherFile"];
require(config, dependencies);
})();
</script>
</head>
<body>
<div>
<label>Input URL</label>
<input type="url" />
<p id="targetInput"></p>
</div>
</body>
</html>
Here is the non-working JS that I am trying to call within another function:
function someOtherFunction() {
var getCurrentInput = function() { };
var input = document.querySelector("input");
var log = document.getElementById("targetInput");
input.addEventListener("input", getCurrentInput);
var getCurrentInput = function (e) {
log.currentInput = e.target.value;
};
}
});
Lastly here is the working code that works outside of the scope of someOtherFunction
var getCurrentInput = "";
var input = document.querySelector("input");
var log = document.getElementById("targetInput");
input.addEventListener("input", getCurrentInput);
function getCurrentInput(e) {
log.currentInput = e.target.value;
}
Now you may notice that there isn't a form being submitted here, the reason for this is because this code is running on an iframe that is being called into another app. The submit is happening there but requires me to call a function to make it happen and technically isn't a submit, meaning I don't have control over it like a regular submit. This is why I need to call the current input value inside someOtherFunction.
Any help would be greatly appreciated here! Essentially I want to get the value inside the input and update my API with the value as a JSON string. There must be a better way!
Was a bit difficult to follow at first given the nesting, but something like this?
const doThing = (e) => {
let input = document.getElementById("input");
let log = document.getElementById("targetInput");
log.textContent = input.value;
}
<div>
<label>Input URL</label>
<input type="url" id="input"/>
<p id="targetInput"> </p>
</div>
<button onclick="doThing()">Click</button>
Essentially an external submit that takes an internal input value, and injects it into another internal element?

Toggle properties of anchor and image elements via JavaScript

I currently have a single web page that contains two elements:
image (wrapped in anchor, loads URL in iframe)
iframe (loads themes.html by default)
The image, on-click, toggles/switches the iframe between themes.html and styles.html, as well as the image source. However, despite the numerous tutorials and forum posts I have read online, I cannot get it to work.
How would I go about having the image toggle when clicked, as well as toggling the source of the iframe between the two HTML files?
<!DOCTYPE HTML>
<html>
<head>
<title>Manager</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<div class="switch">
<a href="styles.html" target="switchframe" id="toggleURL" onclick="toggleURL();">
<img src="images/segment-theme.png" id="toggleImage" onclick="toggleImage();"/></a>
<iframe id="frame" name="switchframe" src="themes.html"></iframe>
</div>
<script>
function toggleImage() {
var img1 = "images/segment-theme.png";
var img2 = "images/segment-style.png";
var imgElement = document.getElementById('toggleImage');
imgElement.src = (imgElement.src === img1)? img2 : img1;
}
function toggleURL() {
var url1 = "themes.html"
var url2 = "styles.html"
var urlElement = document.getElementById('toggleURL');
urlElement.href = (urlElement.href === url1)? url2 : url1;
}
</script>
</body>
</html>
EDIT: I figure I could maybe have it just toggle the iframe's src property directly, but if I can't even get the image's src to toggle to begin with, I fear I won't be able to get that working either.
EDIT 2: I can get it to load styles.html in the iframe with the code below; however, I cannot get it to toggle back to themes.html:
function toggleURL() {
var url1 = "themes.html"
var url2 = "styles.html"
var urlElement = document.getElementById('frame');
urlElement.src = (urlElement.src === url1)? url2 : url1;
}
I believe you're having issues because you're using element.attribute instead of element.getAttribute('attribute-name').
Since image.src will return the absolute path www.domain.com/path/to/image.png where getAttribute returns the value specified in the element.
Also you need only one event handler for your case.
<html>
<head>
<title>Manager</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="stylesheet" href="assets/css/main.css" />
</head>
<body>
<div class="switch">
<a href="styles.html" id="toggleURL" onclick="toggle(event);">
<img src="images/segment-theme.png" id="toggleImage" />
</a>
<iframe id="frame" src="themes.html"></iframe>
</div>
<script>
function toggle(e) {
e.preventDefault();
var img1 = "images/segment-theme.png";
var img2 = "images/segment-style.png";
var imgElement = document.getElementById('toggleImage');
var src = imgElement.getAttribute('src');
imgElement.setAttribute('src', (src === img1) ? img2 : img1)
var url1 = "themes.html"
var url2 = "styles.html"
var urlElement = document.getElementById('toggleURL');
var href = urlElement.getAttribute('href');
document.getElementById('frame').setAttribute('src', href)
urlElement.setAttribute('href', (href === url1) ? url2 : url1)
}
</script>
</body>
</html>

How to replace text in a html document using Javascript

I have written this code which I thought was correct, but although it runs without error, nothing is replaced.
Also I am not sure what event I should use to execute the code.
The test a simple template for a landing page. The tokens passed in on the url will be used to replace tags or tokens in the template.
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// gets passed variables frm the url
function getQueryVar(str) {
return 'Newtext'; // JUST SCAFFOLD FOR TESTING
}
function searchReplace() {
/**/
var t = 0;
var tags = Array('keyword', 'locale', 'advert_ID');
if (document.readyState === 'complete') {
var str = document.body.innerText;
for (t = 0; t < tags.length; t++) {
//replace in str every instance of the tag with the correct value
if (tags[t].length > 0) {
var sToken = '{ltoken=' + tags[t] + '}';
var sReplace = getQueryVar(tags[t]);
str.replace(sToken, sReplace);
} else {
var sToken = '{ltoken=' + tags[t] + '}'
var sReplace = '';
str.replace(sToken, sReplace);
//str.replace(/sToken/g,sReplace); //all instances
}
}
document.body.innerText = str;
}
}
</script>
</head>
<body>
<H1> THE HEADING ONE {ltoken=keyword}</H1>
<H2> THE HEADING TWO</H2>
<H3> THE HEADING THREE</H3>
<P>I AM A PARAGRAPH {ltoken=keyword}</P>
<div>TODO write content</div>
<input type="button" onclick="searchReplace('keyword')">
</body>
</html>
So when the documment has finished loading I want to execute this code and it will replace {ltoken=keyword} withe value for keyword returned by getQueryVar.
Currently it replaces nothing, but raises no errors
Your problem is the fact you don't reassign the replacement of the string back to it's parent.
str.replace(sToken,sReplace);
should be
str = str.replace(sToken,sReplace);
The .replace method returns the modified string, it does not perform action on the variable itself.
Use innerHTML instead innerText and instead your for-loop try
tags.forEach(t=> str=str.replace(new RegExp('{ltoken='+ t+'}','g'), getQueryVar(t)))
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
// gets passed variables frm the url
function getQueryVar(str)
{
return'Newtext';// JUST SCAFFOLD FOR TESTING
}
function searchReplace() {
/**/
var t=0;
var tags =Array('keyword','locale','advert_ID');
if (document.readyState==='complete'){
var str = document.body.innerHTML;
tags.forEach(t=> str=str.replace(new RegExp('{ltoken='+ t+'}','g'), getQueryVar(t)));
//tags.forEach(t=> str=str.replace(new RegExp('{ltoken='+ tags[t]+'}', 'g'), getQueryVar(tags[t])));
document.body.innerHTML=str;
}
}
</script>
</head>
<body >
<H1> THE HEADING ONE {ltoken=keyword}</H1>
<H2> THE HEADING TWO</H2>
<H3> THE HEADING THREE</H3>
<P>I AM A PARAGRAPH {ltoken=keyword}</P>
<div>TODO write content</div>
<input type ="button" onclick="searchReplace('keyword')" value="Clicke ME">
</body>
</html>

Unable to call a Javascript class from HTML

Please have a look at the below code
TTSScript.js
function TTS()
{
var msg = new SpeechSynthesisUtterance("yohan");
var voices = window.speechSynthesis.getVoices();
this.speakText = function()
{
window.speechSynthesis.speak(msg);
}
}
index.html
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="/scripts/TTSScript.js"></script>
<script>
function speak()
{
var msg = new SpeechSynthesisUtterance('Hello World');
window.speechSynthesis.speak(msg);
}
function speak2()
{
var TTS = new TTS();
TTS.speakText();
}
</script>
</head>
<body>
<div><button onclick="speak2()">Click me</button></div>
</body>
</html>
Unfortunatly when I click on the button in the html page, what I get is an error. It is below.
Uncaught TypeError: undefined is not a function (13:42:13:817 | error, javascript)
at speak2 (public_html/index.html:23:26)
at onclick (public_html/index.html:31:126)
I am not much familiar with JavaScript, can you please let me know why I am getting this error and how to fix it?
After declaring a function, its name becomes a (locally) preserved word. It means that creating a variable with the same name might cause some problems.
I took your code and changed
var TTS = new TTS();
TTS.speakText();
Into
var tts = new TTS();
tts.speakText();
And the error disappeared.
I solved your problem.. :
don't use all capital names as variables
var tts = new TTS();
tts.speakText();
correct speak call is in the fiddle
http://jsfiddle.net/bpprwfxa/4/
var msg = new SpeechSynthesisUtterance('Yohan');
window.speechSynthesis.speak(msg);

document.createElement fails for new window

I have two HTML files, FirstWindow and SecondWindow. FirstWindow has FirstWindowJS.js as its script and SecondWindow has SecondWindowJS.js as its script.
Through FirstWindowJS.js, I open SecondWindow.html. However, I am unable to create an element for it. Here's the code along with the problem -
FirstWindow.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>FirstWindow</title>
</head>
<body>
<script type="text/javascript" src="FirstWindowJS.js"></script>
</body>
</html>
SecondWindow.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>SecondWindow</title>
</head>
<body>
<script type="text/javascript" src="SecondWindowJS.js"></script>
</body>
</html>
FirstWindowJS.js
main();
function main()
{
var myWindow = window.open("SecondWindow.html", "My Window",
"resizable=0,width=700,height=600");
var e = myWindow.document.createElement("currentUserElement");
e.setAttribute("id", "currentUserElement");
e.setAttribute("value","John");
}
SecondWindowJS.js
main();
function main()
{
var e = document.getElementById("currentUserElement");
var value = e.getAttribute("value");
console.log("value = "+value);
}
The error that I get in the SecondWindowJS.js is -
TypeError: e is null
Why is "e" null? What is the mistake?
It's possible that the new window runs its JavaScript before the opener's script continues, but it's more likely that you can't use getElementById on an element that has not been appended to the document yet.
myWindow.document.body.appendChild(e);
You create the element, but it doesn't look like you are adding it to the DOM. An element doesn't exist in the DOM until you explicitly add it using the parentNode.appendChild() method.
In your case it would look something like this, if you just want to add the element as the last element in your body-element:
function main()
{
var myWindow = window.open("SecondWindow.html", "My Window",
"resizable=0,width=700,height=600");
var e = myWindow.document.createElement("currentUserElement");
e.setAttribute("id", "currentUserElement");
e.setAttribute("value","John");
// The element doesn't exist in the DOM until you explicitly add it
myWindow.document.body.appendChild(e);
}

Categories