I am making a TODO list. I have difficulties with setting the input text on my card. Everything I write in the input, I want to select and to put on the card.
I tried to select the innerHTML of an input when I type something in. I don't know how to select the typed input text. I would then create a new element with the text inside, and would append it to the card.
let btn = document.querySelector('.add');
let textspace = document.querySelector('.todotext');
const input = document.querySelector('input');
// eventlistner by button clicked
btn.addEventListener('click', function() {
var txt = document.getElementsByClassName('input').innerHTML;
});
<div class="card">
<div class="todoheader">TODO List</div>
<div class="todotext"></div>
<ul class="list"></ul>
<div class="addtodo">
<buton class="add" type="button"> + </buton>
<input type="text" class="input" placeholder="add todo" />
</div>
</div>
To get the value of the input use the value property, not innerHTML. Also note that you already have a reference to the input Element in the input variable, so you don't need to use getElementsByClassName() to retrieve it - not least of all because the syntax there is flawed.
Once you have the text you can use createElement() to add a new p element to the .todotext container:
const btn = document.querySelector('.add');
const textspace = document.querySelector('.todotext');
const input = document.querySelector('input');
btn.addEventListener('click', function() {
const txt = input.value;
if (!txt)
return;
const p = document.createElement('p');
p.textContent = txt;
textspace.appendChild(p);
input.value = '';
});
<div class="card">
<div class="todoheader">TODO List</div>
<div class="todotext"></div>
<ul class="list"></ul>
<div class="addtodo">
<button class="add" type="button"> + </button>
<input type="text" class="input" placeholder="add todo" />
</div>
</div>
As others already answered your question. I just wanted to point out that there is a misspelling in your code (buton instead of button). Fix that and the button element would be rendered correctly.
First, getElementsByClassName will return HTMLCollection which is array-like, you need to use querySelector instead, also the innerHTML, textContent, innerText properties all are empty string for the input because the input is a self-closing tag without content inside, you need to use value property.
let btn = document.querySelector('.add');
let textspace = document.querySelector('.todotext');
const input = document.querySelector('input');
// eventlistner by button clicked
btn.addEventListener('click', function() {
var txt = input.value;
console.log(txt)
});
<div class="card">
<div class="todoheader">TODO List</div>
<div class="todotext"></div>
<ul class="list"></ul>
<div class="addtodo">
<buton class="add" type="button"> + </buton>
<input type="text" class="input" placeholder="add todo" />
</div>
</div>
btn.addEventListener('click', function() {
var txt = document.getElementByClassName('input').value;
});
You were using getElementByClassName which will be HTMLCollection.To loop over each element you need to convert it into an array loop over them.
var txt = document.getElementsByClassName('input').value;
You should get the value of an input , not the innerHTML
Also assign a unique id to you input fields and select them with it, it's much better :)
Related
Can anyone tell me what is wrong with my code? This works for all the other elements on the page but not this one, which is the parent to all of them.
let addButton = document.querySelector('.add-note');
addButton.addEventListener('click', (event) => {
//prevent refresh
event.preventDefault();
//note input value
let noteInput = document.querySelector(".note-input");
//create note container
let noteList = document.querySelector(".notes");
//create note
let note = document.createElement("li");
note.classList.add("note");
noteList.appendChild(note);
});
<div class="title">
<h1>To Do List</h1>
</div>
<br>
<form>
<div class="add-note">
<input class="note-input" type="text" placeholder="Enter to-do item here"></input>
<button class="add" type="submit">+</button>
</div>
</form>
<br>
<ul className="notes" id="notes"></ul>
Is this a React project? className is only available when using React.
<ul className="notes" id="notes"></ul>
change to
<ul class="notes" id="notes"></ul>
Your question i a tad unclear, but i think part of it is that you added the event listener to the div instead of the submit button. Change the class in your query selector to ".add" instead of ".add-note".
This solution below works for adding and removing list items. I had to implement Math.random() in order to set a unique id for each element. I was thinking in the professional world this definitely wouldn't cut it considering the chance of a repeating ID.
Wanted to know what would be a more suitable implementation? Any feedback welcome!
Thanks!
HTML
<html>
<head>
<body>
<p id = 'listTitle'> Your List </p>
<form onsubmit = "return false">
<input id = 'inputBar' type = "text" placeholder = "Enter Item"></input>
<input type = "submit" onclick = "getName()"></input>
<input type = "button" value = "Remove" </input>
</form>
<ol id = 'demo'>
</ol>
</body>
</head>
</html>
JS
function getName() {
var input = document.getElementById('inputBar').value
var list = document.getElementById('demo')
var entry = document.createElement('li')
entry.setAttribute("id", Math.floor(Math.random()* (100 - 1) + 1 ))
console.log(entry.id)
entry.setAttribute("onclick", "removeName(this.id)")
entry.appendChild(document.createTextNode(input))
list.appendChild(entry)
}
function removeName(removeID) {
var listItem = document.getElementById(removeID)
listItem.remove()
}
There's no need for dynamic IDs. When appending the new element, just attach a listener that calls entry.remove() when clicked. You can also assign to the textContent instead of using the unnecessarily verbose createTextNode / appendChild.
function getName() {
const inputValue = document.getElementById('inputBar').value;
const li = document.getElementById('demo').appendChild(document.createElement('li'));
li.onclick = () => li.remove();
li.textContent = inputValue;
}
<p id='listTitle'> Your List </p>
<form onsubmit="return false">
<input id='inputBar' type="text" placeholder="Enter Item"></input>
<input type="submit" onclick="getName()"></input>
<input type="button" value="Remove" </input>
</form>
<ol id='demo'>
</ol>
I have a form having two input fields:
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
And a button:
<button id="add-input-button"><strong>+</strong></button>
Everytime the button is clicked, two input fields will be added to the form:
document.getElementById("add-input-button").onclick = () => {
const input = `
<div class="form-row">
<select></select>
<input>
</div>
`;
document.getElementById("import-products-form").innerHTML += input;
};
The problem here is whenever the button is clicked, the values of the existed fields will be reset to default. In DevTools, I saw that the entire form was reloaded when the button clicked.
Is there anyway to keep the values of the existed fields when new fields added to the form?
Don't assign to innerHTML. That causes all the elements inside the form to be recreated from scratch, and any dynamic state is lost.
Use insertAdjacentHTML instead. This parses the new HTML and appends the DOM elements, without disturbing the original elements.
document.getElementById("import-products-form").insertAdjacentHTML('beforeend', input);
x.innerHTML += input effectively runs
x.innerHTML = (x.innerHTML + input) and you lose the state
You should create new element and append it.
document.getElementById("add-input-button").onclick = (e) => {
const input = `
<select></select>
<input>
`;
let div = document.createElement('div')
div.classList.add('form-row')
div.innerHTML=input
document.getElementById("import-products-form").appendChild(div)
};
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
<button id="add-input-button"><strong>+</strong></button>
For this specific use case, no need to create element from text every time.
{
const input = `
<select></select>
<input>
`;
let div = document.createElement('div')
div.classList.add('form-row')
div.innerHTML=input
document.getElementById("add-input-button").onclick = (e) => {
document.getElementById("import-products-form").appendChild(div.cloneNode(true))
};
}
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
<button id="add-input-button"><strong>+</strong></button>
Try using appendChild instead of innerHTML.
document.getElementById("add-input-button").onclick = () => {
var div = document.createElement('div');
var select = document.createElement('select');
var input = document.createElement('input');
div.classList.add('form-row');
div.appendChild(select);
div.appendChild(input);
document.getElementById("import-products-form").appendChild(div);
};
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
<button id="add-input-button"><strong>+</strong></button>
I have bunch of inputs like:
<input />
<input />
<input />
and a button which ads extra input
<button>Add Input</button>
The issue is that when a user put the text in the input(s) and add
additional input afterwards (i.e. press Add Input) the entered text in old inputs disappears.
JSFiddle:
<div id="inputs"></div>
<button onclick="document.getElementById('inputs').innerHTML += '<input /><br>'">Add Input</button>
So I decided to update <input> value attribute. I have tried with onchange but had no luck.
The code with errors and trials is super simple and looks like:
function change_value(el) {
document.getElementById('some-id').value = el.value
}
<input id="some-id" value="${this.value}" onchange="change_value(this)" />
Will be grateful for any suggestions about how to keep <input value up-to-date with user text.
It depends on what content you want to update. You can find a snippet below, that works oninput and updates the textContent of a span.
const input = document.getElementById('some-id')
const display = document.getElementById('updated')
input.addEventListener('input', function(e) {
display.textContent = this.value
})
<input id="some-id" value="" /><br /><br />
<div>Updated value: <span id="updated"></span></div>
EDIT
A new snippet may clear things up a bit.
const btnAdd = document.getElementById('add')
btnAdd.addEventListener('click', function(e) {
var input = document.createElement('input');
input.type = "text";
document.getElementById('inputs').appendChild(input)
})
<div id="inputs"></div>
<button id="add">Add Input</button>
Use createElement() instead of innerHTML.
Try using innerHtml like this
document.getElementById('some-id').innerHtml instead of value
https://www.w3schools.com/js/js_htmldom_html.asp
Actually, it is not possible this way, maybe with some tricks like with any change store the value and create new input with the new value or change the innerHtml, maybe it works.
I have a form having two input fields:
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
And a button:
<button id="add-input-button"><strong>+</strong></button>
Everytime the button is clicked, two input fields will be added to the form:
document.getElementById("add-input-button").onclick = () => {
const input = `
<div class="form-row">
<select></select>
<input>
</div>
`;
document.getElementById("import-products-form").innerHTML += input;
};
The problem here is whenever the button is clicked, the values of the existed fields will be reset to default. In DevTools, I saw that the entire form was reloaded when the button clicked.
Is there anyway to keep the values of the existed fields when new fields added to the form?
Don't assign to innerHTML. That causes all the elements inside the form to be recreated from scratch, and any dynamic state is lost.
Use insertAdjacentHTML instead. This parses the new HTML and appends the DOM elements, without disturbing the original elements.
document.getElementById("import-products-form").insertAdjacentHTML('beforeend', input);
x.innerHTML += input effectively runs
x.innerHTML = (x.innerHTML + input) and you lose the state
You should create new element and append it.
document.getElementById("add-input-button").onclick = (e) => {
const input = `
<select></select>
<input>
`;
let div = document.createElement('div')
div.classList.add('form-row')
div.innerHTML=input
document.getElementById("import-products-form").appendChild(div)
};
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
<button id="add-input-button"><strong>+</strong></button>
For this specific use case, no need to create element from text every time.
{
const input = `
<select></select>
<input>
`;
let div = document.createElement('div')
div.classList.add('form-row')
div.innerHTML=input
document.getElementById("add-input-button").onclick = (e) => {
document.getElementById("import-products-form").appendChild(div.cloneNode(true))
};
}
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
<button id="add-input-button"><strong>+</strong></button>
Try using appendChild instead of innerHTML.
document.getElementById("add-input-button").onclick = () => {
var div = document.createElement('div');
var select = document.createElement('select');
var input = document.createElement('input');
div.classList.add('form-row');
div.appendChild(select);
div.appendChild(input);
document.getElementById("import-products-form").appendChild(div);
};
<form id="import-products-form">
<div class="form-row">
<select></select>
<input>
</div>
</form>
<button id="add-input-button"><strong>+</strong></button>