adding buttons after appending firstChild - javascript

Basically I want to add two more buttons to edit and delete the appended firstChild value.
How do I do that?
function writeParagraph() {
var comment = prompt("Type content for new paragraph here", "");
var newParagraph = document.createElement('p');
newParagraph.textContent = comment;
document.getElementById("updateDiv").appendChild(newParagraph);
}
function deleteParagraph() {
var items = document.querySelectorAll("#updateDiv p");
if (items.length) {
var child = items[0];
child.parentNode.removeChild(child);
}
}
HTML:
<div align="center"> <button onclick="store();prompter();">Click Me and type!</button> </div>
<div align="center"> <button onclick="undo()">Undo</button></div>
<div align="center"> <button onclick="prompter2()">Set Allign</button></div>
<div align="center"> <button id="a" onclick="writepara()">Click for a new paragraph</button></div>
<div align="center"> <button id="b" onclick="deleteParagraph()">Click to delete the new paragraph</button></div>
<div id='updateDiv' align="center"> </div>

Delete would be:
function deleteParagraph() {
var items = document.querySelectorAll("#updateDiv p");
if (items.length) {
var child = items[0];
child.parentNode.removeChild(child);
}
}
Edit would be:
function changeParagraph(newHTML) {
var items = document.querySelectorAll("#updateDiv p");
if (items.length) {
var child = items[0];
child.innerHTML = newHTML;
}
}
You will have to separately prompt from whatever text you want to pass to changeParagraph().

Related

Attaching Event to dynamically created element

I am working at my 'To Do List'. My goal is to create an 'delete' button inside previously created div, which contains note written by user.
The problem is that I can't use Jquery - click() because it doesn't work with dynamically created elements.
I tried to use on(), but it causes that 'delete' button appears in every note I made.
var ammleng;
var amount = [];
function ammcheck() {
if (amount.length == 0) {
return amount.length;
} else {
return amount.length++;
}
}
function Start() {
var start = document.getElementsByClassName('start')[0];
start.style.display = 'none';
var textarea = document.getElementsByClassName('textarea')[0];
textarea.classList.remove('locked');
var btn = document.getElementsByClassName('btn__container')[0];
btn.classList.remove('locked');
var text = document.getElementsByClassName('text')[0];
text.classList.add('after');
$('.notes').slideDown(2000);
}
function add() {
var txtarea = document.getElementsByClassName('textarea')[0];
ammleng = amount.length;
if (ammleng >= 13) {
alert('Za dużo notatek!')
} else if (txtarea.innerText.length < 1) {
alert('Nic nie napisałeś :(');
} else {
amount[ammcheck()] = document.getElementsByClassName('note');
var text = $('.textarea').html();
var cont = document.getElementsByClassName('notes')[0];
var ad = document.createElement('div');
var adding = cont.appendChild(ad);
adding.classList.add('note');
adding.innerText = text;
txtarea.innerText = '';
}
}
function reset() {
var els = document.getElementsByClassName('notes')[0];
els.innerHTML = '';
amount = [];
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class='content'>
<div class='logo'>
To Do List
</div>
<div class='text'>
<button class='start' onclick='Start()'>Zaczynajmy</button>
<div class='textarea locked' contenteditable='true' data-text='Wpisz notkę...'></div>
<div class='btn__container locked'>
<button class='dodaj' onclick='add()'>Dodaj</button>
<button class='resetuj' onclick='reset()'>resetuj</button>
</div>
</div>
<div class='notes'></div>
</div>
I tried to make it this way, but it return an error (...'appendChild() is not a function...')
var del = document.createElement('div');
del.classList.add('del');
$('.notes').on('click', '.note', function(){
$(this).appendChild(del);
})
use already existing document to bind click on
$(document).on('click', '.note', function(){
$(this).appendChild(del);
})

How to add styles to a dynamically-generated list item in an initially empty list

I am making a simple todo app, in which the todos, with respective dates are to be shown in a list form below the text input area. I have made an empty list for that and keep on appending todos, along with date. But I want that a strike through should occur across a todo(not across the date), on clicking on the todo. My code can list the todos with date but fails in causing strike-through. What should I change in function struck(ele) and correspondingly in function changeText()?
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter" onkeydown="store(this)">
<div class="todos">
<ul id="demo"></ul>
</div>
</div>
<script>
var list = document.getElementById('demo');
function store(ele){
if(event.keyCode==13){
changeText();
}
}
function changeText() {
var data = document.getElementById('todo').value;
var d = new Date();
if(data!='')
{
var entry = document.createElement('li');
var dates = document.createElement("div");
dates.appendChild(document.createTextNode(d.toDateString()));
dates.className = "myClass";
entry.appendChild(document.createTextNode(data));
entry.onclick=struck(this);
entry.appendChild((dates));
list.appendChild(entry);
}
}
function struck(ele) {
ele.style = "text-decoration:line-through; list-style-type:none";
}
</script>
The main problem is that you're calling the onclick function instead of assigning it as a handler.
Change
entry.onclick = struck(this);
to
entry.onclick = () => struck(entry);
Then separate the description into its own element, so it alone can get the strikethrough.
<body>
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter" onkeydown="store(this)">
<div class="todos">
<ul id="demo"></ul>
</div>
</div>
<script>
var list = document.getElementById('demo');
function store(ele){
if(event.keyCode==13){
changeText();
}
}
function changeText() {
var data = document.getElementById('todo').value;
var d = new Date();
if(data!='')
{
var entry = document.createElement('li');
entry.description = document.createElement('span');
entry.appendChild(entry.description);
entry.description.appendChild(document.createTextNode(data));
entry.appendChild(document.createTextNode(' ' + d.toDateString()));
entry.onclick = () => struck(entry);
list.appendChild(entry);
}
}
function struck(ele) {
ele.description.style = "text-decoration:line-through; list-style-type:none";
}
</script>
</body>
The solution that Eric has given works great but if I may suggest a minor change, your store() function doesn't function on firefox but it does on chrome, thus I made a few changes of my own to it and you could use it as I find it a better approach towards it.
var enterPressed = function(){
document.getElementById("todo").onkeyup = function(event) {
if(event.which == 13)
changeText();
};
};
enterPressed();
instead of
function store(ele){
if(event.keyCode==13){
changeText();
}
}
a
and onkeydown in input.
var list = document.getElementById('demo');
var enterPressed = function(){
document.getElementById("todo").onkeyup = function(event) {
if(event.which == 13)
changeText();
};
};
function changeText() {
var data = document.getElementById('todo').value;
var d = new Date();
if (data != '') {
var entry = document.createElement('li');
entry.description = document.createElement('span');
entry.appendChild(entry.description);
entry.description.appendChild(document.createTextNode(data));
entry.appendChild(document.createTextNode(" " + d.toDateString()));
entry.onclick = () => struck(entry);
list.appendChild(entry);
}
}
function struck(ele) {
ele.description.style = "text-decoration:line-through; list-style-type:none";
}
enterPressed();
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter">
<div class="todos">
<ul id="demo">
</ul>
</div>
</div>
var $ = function (selector) {
return document.querySelector(selector);
};
var list = $("#demo");
function store(ele) {
if (event.keyCode == 13) {
changeText();
}
}
function dynamicEvent() {
this.description.style = "text-decoration:line-through; list-style-type:none";
}
function changeText() {
var data = $("#todo").value;
var date = new Date();
if (data) {
var li = document.createElement("li");
li.description = document.createElement('span');
li.className = 'todo'; // Class name
li.innerHTML = data; // Text inside
li.appendChild(li.description);
li.description.appendChild(document.createTextNode(data));
li.appendChild(document.createTextNode(' ' + date.toDateString()));
li.onclick = dynamicEvent; // Attach the event!
$('#demo').appendChild(li); // Append it
}
}
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter" onkeydown="store(this)">
<div class="todos">
<ul id="demo"></ul>
</div>
</div>
This is how I would go about it.
var list = document.getElementById('demo');
const items = [];
const item = e => {
const el = document.createElement('li');
el.insertAdjacentHTML('beforeend', `<span class="title">${ e.t }</span><div class="time">${e.d}</div>`);
const title = el.querySelector('.title');
const time = el.querySelector('.time' );
let strike = 0;
el.addEventListener('click', _ => el.querySelector('span').style.textDecoration = !!(++strike % 2) ? 'line-through' : '');
list.appendChild(el);
return { el, title, time };
};
function store(ele) {
if (event.keyCode == 13) {
items.push(item({ t: ele.value, d: (new Date()).toDateString() }));
console.log(items);
}
}
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter" onkeydown="store(this)">
<div class="todos">
<ul id="demo"></ul>
</div>
</div>

I am having trouble in displaying date beside the entered todo element. What is wrong with changeDate() function?

Entered todo is shown but the date is not being shown. Am i using any wrong command?? On entering a data, date should be shown on the left of the todo, just below the input area.
var list = document.getElementById('demo');
var list2 = document.getElementsByTagName('todos');
function store(ele) {
if (event.keyCode == 13) {
changeText();
}
}
function changeText() {
var data = document.getElementById('todo').value;
if (data != '') {
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(data));
list.appendChild(entry);
changeDate();
}
}
function changeDate() {
var d = new Date();
var dates = document.createElement("div");
dates.className = "myClass";
dates.innerHTML = document.createTextNode(d.toDateString());
list2.innerHTML = dates;
}
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter" onkeydown="store(this)">
<div class="todos">
<ul id="demo"></ul>
</div>
</div>
First of all your JS has an issue. The list2 is a HTMLCollection and there's no .innerHTML for that. You need to use:
list2[0].innerHTML
You don't even need that. The date issue is because of the Date Object incorrectly being set / inserted.
var list = document.getElementById('demo');
var list2 = document.getElementsByTagName('todos');
function store(ele) {
if (event.keyCode == 13) {
changeText();
}
}
function changeText() {
var data = document.getElementById('todo').value;
if (data != '') {
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(data));
list.appendChild(entry);
changeDate(list);
}
}
function changeDate(which) {
var d = new Date();
which.innerHTML += d.toDateString();
}
<div class="container">
<h1>
Your todos
</h1>
<input type="text" id="todo" placeholder="Add a new todo and hit enter" onkeydown="store(this)">
<div class="todos">
<ul id="demo"></ul>
</div>
</div>
Preview
instead of this:
function changeText() {
var data = document.getElementById('todo').value;
if (data != '') {
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(data));
list.appendChild(entry);
changeDate(list);
}
}
try this:
function changeText() {
var data = document.getElementById('todo').value;
if (data != '') {
var entry = document.createElement('li');
changeDate(list); //call this before appending data
entry.appendChild(document.createTextNode(data));
list.appendChild(entry);
}
}
and CSS:
li{
display: inline-block;
}

Dynamiclly append different class with increment numereic value by click event

I have a span tag and a button tag
<span class="myspan">1</span>
<button id="add">Add +1</button>
var arr=["myspan1","myspan2","myspan3","myspan4"}
I want to append more span tag with new class from this array with increment value by clicking button.
Like this output:
<span class="myspan1">1</span>
<span class="myspan2">2</span>
<span class="myspan3">3</span>
<span class="myspan4">4</span>
i try `
this JsFiddle
But i can not add class name to new append tag from array.
Another useful link for appending tag with new class from array
http://jsbin.com/nojipowo/2/edit?html,css,js,output
...
But i can not bring my desire output at any case...enter code here
value increaseesenter code here this snippet
<script> var i = 0; function buttonClick() {i++; document.getElementById('inc').value = i; } </script> <button onclick="buttonClick();">Click Me</button> <input type="text" id="inc" value="0"></input>
another attempt...anyone can help.. to get desire output
var i=6;
var backgrounds = ["myspan1", "myspan2", "myspan4"];
var elements = document.getElementsByClassName("myspan");var len = backgrounds.length;
$("#add").click( function() {
(i < elements.length){
$(".new-field").append('<span class="myspan">1</span><script');
var value = parseInt($(".myspan").text(), 10) + 1;
elements[i].className += ' ' + backgrounds[i%len];
i++;
$(".background").text(i);
}
});
*/
<span class="myspan">1</span>
<button id="add">Add +1</button>
<div class="new-field">
</div>
<script> var i = 0; function buttonClick() {i++; document.getElementById('inc').value = i; } </script> <button onclick="buttonClick();">Click Me</button> <input type="text" id="inc" value="0"></input>
Try this check the span length via parseInt($(".myspan").length) .And use with Array#forEach for iterate the array instead of increment i.parseInt used convert ths string to number
var i=6;
var backgrounds = ["myspan1", "myspan2", "myspan4"];
var len = backgrounds.length;
$("#add").click( function() {
var len = parseInt($(".myspan").length)
backgrounds.forEach(function(a){
$(".new-field").append('<span class="'+a+'">'+(len++)+'</span>');
})
console.log($(".new-field").html())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="myspan">1</span>
<button id="add">Add +1</button>
<div class="new-field">
</div>
Check the fiddle. Hope this helps!
HTML :
<div id="mainContainer">
<span class="myspan">1</span>
</div>
<button id="add">Add +1</button>
JS :
var arr = ["myspan1", "myspan2", "myspan3", "myspan4"];
$("#add").on("click", function() {
var spans = $("span");
var classList = [];
$.each(spans, function() {
var elemCls = $(this).attr('class').length > 1 ? $(this).attr('class').split(' ') : $(this).attr('class');
if (elemCls) {
$.each(elemCls, function() {
classList.push(this.toString());
});
}
});
$.each(arr, function(i, e) {
if ($.inArray(e, classList) == -1) {
$("#mainContainer").append("<span class='" + e + "'>" + parseInt(spans.length + 1) + "</span>");
return false;
}
});
});

Read one item of array onclick javascript

<div id="wrapper">
<div class="quotes">
<p id="par"></p>
</div>
<button class="btn" onClick="randomQuote()">button</button>
</div>
function randomQuote () {
var array = [1,20,50,100];
}
document.getElementById("btn").onclick = randomQuote;
document.getElementById("par").innerHTML = array[0];//then on another btn click array[1]...
for(var i=0; i<array.length;i++){
quote[i];
}
On "btn" click number 1 from array is shown in "par" paragraph
on another btn click number 2 shows up and 1 dissapear, and so on...
Use counter cpt as index to loop through the array and show the values :
var array = [1,20,50,100];
var cpt = 0;
//Init the 'par' div before click
document.querySelector("#par").innerHTML = array[cpt];
function randomQuote ()
{
if(cpt<array.length-1)
cpt++;
else
cpt=0;
document.querySelector("#par").innerHTML = array[cpt];
}
<div id="wrapper">
<div class="quotes">
<p id="par"></p>
</div>
<button class="btn" onClick="randomQuote()">button</button>
</div>
Minified version could be :
function randomQuote ()
{
document.querySelector("#par").innerHTML = array[cpt<array.length-1?++cpt:cpt=0];
}
Snippet using Random color as you comment say :
var array = ["Quotes 1","Quotes 2","Quotes 3","Quotes 4"];
var cpt = 0;
//Init the 'par' div before click
document.querySelector("#par").innerHTML = array[cpt];
//Init Random Color before click
getRandomColor();
function randomQuote()
{
if(cpt<array.length-1)
cpt++;
else
cpt=0;
document.querySelector("#par").innerHTML = array[cpt];
}
function getRandomColor()
{
document.querySelector("#par").style.backgroundColor = '#'+Math.floor(Math.random()*16777215).toString(16);
}
<div id="wrapper">
<p id="par"></p>
<button id="btn" onClick="randomQuote();getRandomColor()">Next quote</button>
</div>
Is this what you want?
var counter = 0;
function randomQuote () {
var array = [1,20,50,100];
document.getElementById("par").innerHTML(array[counter++]);
}
save the index, increment it on each click and then reset it when its undefined.
var index = -1;
function randomQuote() {
var array = [1, 20, 50, 100];
document.getElementById('par').innerText = (array[++index] || array[index=0]);
}
<div id="wrapper">
<div class="quotes">
<p id="par"></p>
</div>
<button class="btn" onClick="randomQuote()">button</button>
</div>

Categories