so im trying to make a list of the input from the user and i keep getting this error
html
<!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>ToDo</title>
</head>
<body>
<h1>To Do List</h1>
<label>Enter What You Have To Do:</label>
<br>
<br>
<input type="text" id="toDo">
<br>
<br>
<button type="button" id="myButton">Submit</button><br>
<ul id="list"></ul>
<script src="todojs.js"></script>
</body>
</html>
javascript
document.getElementById('myButton').onclick = function () {
const doIt = document.getElementById('toDo').value;
const li ='<li>' + doIt + '</li>';
document.getElementById('list').appendChild(li);
document.getElementById('toDo').value = '';
}
Error
Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
at document.getElementById.onclick
appendChild expects a Node Element. You are passing a string.
If you want to append a string, you can use the insertAdjacentHTML function.
https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML
document.getElementById('myButton').onclick = function () {
const doIt = document.getElementById('toDo').value;
const li ='<li>' + doIt + '</li>';
document.getElementById('list').insertAdjacentHTML('beforeend', li);
document.getElementById('toDo').value = '';
}
const li = document.createElement("li");
li.innerHTML(doIt);
should do the trick instead of the one liner
if you pass a string, that string isn't a node or a real element present in the DOM, it wouldn't work.
so simply just programmatically create one element! using document.createElement()
change the text inside it, using document.textContent
try to not use innerHTML because is DANGEROUS, someone can insert in the input some malicious code scripts. textContent is more safe
one more thing, use .addEventListener()
instead of .onclick,
because if you have more event listener in one time, .onclick sometimes don't work, with .addEventListener() you can make 2 or more events work in one time.
for inserting before you can use this: https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore , just read the documentation I linked to you, and you are done!
I hope this help you!
one more thing:
if you want more custom UI,
you can write a copy of all your elements inside a <div>,
and then insert it inside a <template> tag manually...
the result is: now you have a reusable component with just regular HTML, JS
so the previus document.createElement(); it will become Node.cloneNode()
more details here: https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode
let btn = document.getElementById('myButton');
let list = document.getElementById('list');
let inputEl = document.getElementById('toDo');
btn.addEventListener('click', () => {
const getliValue = inputEl.value;
const newLi = document.createElement('li');
newLi.textContent = getliValue;
list.appendChild(newLi);
inputEl.value = '';
});
<h1>To Do List</h1>
<label>Enter What You Have To Do:</label>
<br><br>
<input type="text" id="toDo">
<br><br>
<button type="button" id="myButton">Submit</button>
<br>
<ul id="list"></ul>
<script src="script.js"></script>
Related
I'm new to javascript and programming, and I am trying to create a webpage where the user can input the data on the page, and then I wrap it around HTML code to create an HTML template. I've tried using a couple methods but the document.write() command seems to be working for what I need. However, I'm trying to add the HTML tags around the input text and not getting a usable format.Full code below:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta charset="utf-8"/>
</head>
<body>
<h1>Title<input type="textarea" id="top_field" value="" style="width:100px; height:30px"></h1>
<br/>
<h2>Position/Proposal<input type="textarea" id="subtitle_field" value="" style="width:100px; height:30px"></h2>
<br/>
<p>Body Text: <input type="textarea" id="field1" value="" style="width:100px; height:30px"></p><br/>
<button id="sub_button" type="button" onclick="myFunction()">Copy</button>
<div id="full_code" hidden>
<p id="must_have" value='text'><!DOCTYPE> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta charset="utf-8"/><br></head>
</p>
<p id="less_than"><</p>
<p id="more_than">></p>
</div>
<script>
function myFunction() {
//const html_array = ["<!DOCTYPE>", "<html>", "<head>", "<meta name="viewport" content="width=device-width, initial-scale=1"/>", "<meta charset="utf-8"/>", "</head>"];
if(document.getElementById("field1").value != "" || document.getElementById("top_field").value != "" || document.getElementById("subtitle_field").value != ""){
let p_elem = document.getElementById("less_than").innerText + "p" + document.getElementById("more_than").innerText;
let pend = document.getElementById("less_than").innerHTML + "/p" + document.getElementById("more_than").innerHTML;
let body = document.getElementById("less_than").innerHTML + "body" + document.getElementById("more_than").innerHTML;
let bodyend = document.getElementById("less_than").innerHTML + "/body" + document.getElementById("more_than").innerHTML;
var top_text = document.getElementById("must_have").innerText;
var newParagraph2 = document.createElement("p"); //creates a new paragraph element
var newText2 = document.createTextNode(top_text); //creates text along with output to be displayed
newParagraph2.appendChild(newText2); //created text is appended to the paragraph element created
document.body.appendChild(newParagraph2); // created paragraph and text along with output is appended to the document body
var main_text = document.getElementById("field1").value;
var newParagraph = document.createElement("p"); //creates a new paragraph element
var newText = document.createTextNode(main_text); //creates text along with output to be displayed
newParagraph.appendChild(newText); //created text is appended to the paragraph element created
document.body.appendChild(newParagraph); // created paragraph and text along with output is appended to the document body*/
var title_text = document.getElementById("top_field").value;
var newParagraph3 = document.createElement("p"); //creates a new paragraph element
var newText3 = document.createTextNode(title_text); //creates text along with output to be displayed
newParagraph3.appendChild(newText3); //created text is appended to the paragraph element created
document.body.appendChild(newParagraph3); // created paragraph and text along with output is appended to the document body
var less_symbol = document.getElementById("less_than").value;
var newParagraph4 = document.createElement("p"); //creates a new paragraph element
var newSymbol = document.createTextNode(less_symbol); //creates text along with output to be displayed
newParagraph4.appendChild(newSymbol); //created text is appended to the paragraph element created
document.body.appendChild(newParagraph4); // created paragraph and text along with output is appended to the document body*/
document.writeIn(newParagraph2.innerText); //
}
else{
document.write("No text");
}
}
</script>
</body>
</html>
By now I'm able to read the text input and output in the same page below, but not able to add anything around the appended child or make the original tags above appear vertically. If someone can lead me in the right direction on method I should be using I would greatly appreciate it.
I would suggest NOT writing html strings with document.write. Instead, you can use createElement and appendChild to create html tags and add them to the page. It's much more readable and less likely to cause syntax errors in your html tags.
For example, to create a div that contains text from your inputfield:
let fieldValue = document.getElementById("myfield").value
let div = document.createElement("div")
div.innerHTML = fieldValue
document.body.appendChild(div)
Hope this generic example points you in the right direction!
I am trying to access all the strong tags of a certain paragraph, therefore i looped over all the paragraphs in the document and the code explains the rest
let paragraphs = document.getElementsByTagName("p");
for(let i = 0; i < paragraphs.length; i++) {
var element = document.querySelector(`${paragraphs[i]} > strong`)
console.log(element)
if( element == null) {
continue;
}
else{
var element = document.querySelector('p > strong')
element.style = "";
break;
}
}
when i try to do this i get an error because of this line of code
var element = document.querySelector(`${paragraphs[i]} > strong`)
this is the error: Uncaught DOMException: Failed to execute 'querySelector' on 'Document': '[object HTMLParagraphElement] > strong' is not a valid selector.
any help is much appreciated, thank you..
You need to pass a selector string such a p, .class or #id in the place of that variable, not an HTML element.
I suppose you're actually looking to execute the querySelector method on the paragraph element instead of the document object:
var element = paragraphs[i].querySelector(':scope > strong')
(See here for what :scope does.)
Here's what I came up with to solve your problem:
Grab all the strong elements inside the p tags present on the page
and now you can use .forEach() method on the node list to manipulate elements.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>select strong</title>
</head>
<body>
<p><strong>strong 0</strong>something <strong>strong1</strong></p>
<p>something <strong>strong2</strong></p>
<p>something <strong>strong3</strong></p>
<div>
<div>
<p>strong inside <strong>div</strong></p>
</div>
</div>
<script>
// this is a node list with all `strong` tags inside `p`
const strongStuff = document.querySelectorAll("p > strong");
// you can use .forEach() method on a node list
strongStuff.forEach((strongEl) => console.log(strongEl.innerText));
</script>
</body>
</html>
Or, as an executable snippet:
// this is a node list with all `strong` tags inside `p`
const strongStuff = document.querySelectorAll("p > strong");
// you can use .forEach() method on a node list
strongStuff.forEach((strongEl) => console.log(strongEl.innerText));
<p><strong>strong 0</strong>something <strong>strong1</strong></p>
<p>something <strong>strong2</strong></p>
<p>something <strong>strong3</strong></p>
<div>
<div>
<p>strong inside <strong>div</strong></p>
</div>
</div>
If you need more clarification let me know.
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?
I am trying to create a media player.
I am not sure why my call to document.getElementById("#playlist-table"); returns null when I have in my HTML <table id="playlist-table"></table>. I have tried running the script just before the </body> tag to make sure the DOM was ready, and still no luck. Here is my code:
HTML(shortened)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>JAMTRACKS</title>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
<div id="media-player">
<div id="playlist">
<table id="playlist-table"></table>
</div>
</div>
</body>
</html>
JS(shortened)
function addTrack(title){
var table = document.getElementById("#playlist-table");
var tr = document.createElement("tr");
var titleTd = document.createElement("td");
var titleNode = document.createTextNode("title");
table.appendChild(tr); //ERROR IS HERE
tr.appendChild(titleTd);
titleTd.appendChild(titleNode);
...
}
addTrack(Song_Name);
Error : Uncaught TypeError: Cannot read property 'appendChild' of null
Thank you
remove the hashtag # from the selector
var table = document.getElementById("playlist-table");
if you want to keep it, you should use querySelector()
document.querySelector('#playlist-table')
Correct ways to query for id:
document.getElementById('foo');
or
document.querySelectorAll('#foo');
Returns the first element:
document.querySelector('#foo');
^^
var table = document.getElementById("playlist-table");
I am learning JS and I am not yet familiar with internal workings. Can someone point out the error in my thinking?
The basic idea is to ask a complex question, construct the answer with JS (to a CSV syntax) and feed it to a textbox. (From here it will be processed to a db.) Example included below: How many children do you have? What is their names and age?
Perhaps, the new element generated by the first button is not added to the document? How to do this, or how to address the value in it?
How can I make the values submitted to previous lines stick in the event of adding a new line. For example 'Jack' and '10' is written to the first line, the user pressed the add new line, than this information should stay in the first line.
Incorrectly working example: The save button stops working if the code in the loop is added.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<p>How many children do you have? What is their names and age?</p>
<input type="text" id="qchildren" />
<div id="qchildren-answer-wrapper"></div>
<button type="button" onclick="addNew()">Add new entry</button>
<button type="button" onclick="save()">Save</button>
<script>
var lines = 0;
function addNew() {
lines++;
document.getElementById("qchildren-answer-wrapper").innerHTML += 'Gyermek neve:<input type="text" id="qchildrenname' + window.lines + '" /> Gyermek eletkora:<input type="text" id="qchildrenage' + window.lines + '" /><br/>';
}
function save() {
var answer = '';
for (var ii = 0; ii < window.lines; ii++) {
answer += document.getElementById('qchildrenname' + ii.toString()).value.toString() + ',' + document.getElementById('qchildrenage' + ii.toString()).value.toString() + ';';
}
document.getElementById("qchildren").value = answer;
}
< /script>
</body>
</html>
=Below code should work (AddNew function changed):
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<p>How many children do you have? What is their names and age?</p>
<input type="text" id="qchildren" />
<div id="qchildren-answer-wrapper"></div>
<button type="button" onclick="addNew()">Add new entry</button>
<button type="button" onclick="save()">Save</button>
<script>
var lines=0;
function addNew()
{
lines++;
var newElement = document.createElement("span");
newElement.innerHTML = 'Gyermek neve:<input type="text" id="qchildrenname'+window.lines+'" /> Gyermek eletkora:<input type="text" id="qchildrenage'+window.lines+'" /><br/>';
document.getElementById("qchildren-answer-wrapper").appendChild(newElement);
}
function save()
{
var answer='';
for (var ii=1;ii<=window.lines;ii++)
{
answer+=document.getElementById('qchildrenname'+ii.toString()).value.toString()+','+document.getElementById('qchildrenage'+ii.toString()).value.toString()+';';
}
document.getElementById("qchildren").value=answer;
}
</script>
</body>
</html>
Try code like this:
function addNew()
{
var div = document.createElement('div');
div.innerHTML = 'Gyermek neve:<input type="text" id="qchildrenname'+window.lines+'" /> Gyermek eletkora:<input type="text" id="qchildrenage'+window.lines+'" /><br/>';
document.getElementById("qchildren-answer-wrapper").appendChild(div );
lines++;
}
Demo: http://jsfiddle.net/JByVg/8/
What happens in your case is that all previously created elements are recreated again because element.innerHTML += "some_html" is equal to element.innerHTML = element.innerHTML + "some_html" or, more clear, I suppose, var oldHtml = element.innerHTML;element.innerHTML = ""; element.innerHTML = oldHtml + "some_html"
Browser does not populate value="..." entered by user when you do var oldHtml = element.innerHTML and after += you have old elements recreated without values entered by user. At the same time, appendChild does not recreate old elements.
This example demonstrates how .innerHTML returns only initial HTML (I've added value="test" to your qchildrenname element code)