How to use local storage on append child - javascript

<button id="showlinks" onclick="myFunction">show</button>
<div id="buttonlinks"></div>
function myFunction() {
var button = document.createElement("button");
document.getElementById("buttonlinks").appendChild(button);
}
I used This Code to create buttons on clicking a button. when clicking the show button the buttons appear but after refresh they are gone.
can I store the buttons with localStorage?

You can store the information about your buttons in the localStorage whenever you create a button, and add an eventListener to window.onload to read the buttons from localStorage and append it to the page when page has loaded, in the below exmpale to keep it simple, I just store the length of buttons.
<button id="showlinks" onclick="myFunction">show</button> <div id="buttonlinks"></div>
js:
let buttonsLength = 0;
document.getElementById('showlinks').addEventListener('click', function () {
createButton();
buttonsLength++;
localStorage.setItem('buttonsLength', buttonsLength)
});
function createButton() {
var button = document.createElement('button');
button.innerHTML = 'click me';
document.getElementById('buttonlinks').appendChild(button);
}
window.addEventListener('load', (event) => {
buttonsLength = Number(localStorage.getItem('buttonsLength')) || 0;
for (let i = 0; i < buttonsLength; i++) {
createButton();
}
});

const showlinks = document.getElementById('showlinks')
showlinks.addEventListener("click", function () {
localStorage.setItem("showClicked", true)
displayButtonInDom()
})
function displayButtonInDom() {
const showClicked = localStorage.getItem("showClicked")
if (showClicked) {
const button = document.createElement("button");
button.innerText = "click me"
document.getElementById("buttonlinks").appendChild(button);
}
}
displayButtonInDom()
<button id="showlinks">show</button>
<div id="buttonlinks"></div>

Foreache button created you have to add the button information to the localstorage. And on page load you execute an init function that rebuild all button created from the localstorage
<button id="showlinks" onclick="createButton('')">show</button>
<div id="buttonlinks"></div>
<script>
function Initbutton() {
//on load check if the button has been already add using the localStorage
var buttons = getButtonInformationFromLocalStorage();
if(buttons != null){
buttons.forEach(function(btnName){
createButton(btnName);
})
}
}
// fo the purpose of having different button name
// i have picket this function here https://www.codegrepper.com/code-examples/javascript/find+random+name+javascript
function getRandomString(length) {
var randomChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var result = '';
for ( var i = 0; i < length; i++ ) {
result += randomChars.charAt(Math.floor(Math.random() * randomChars.length));
}
return result;
}
function createButton(btnName){
if(btnName == undefined || btnName == ""){
btnName = "button" + getRandomString(10);
updateButtonInformationToLocalStorage(btnName);
}
var button = document.createElement("button");
button.innerHTML = btnName;
document.getElementById("buttonlinks").appendChild(button);
}
function updateButtonInformationToLocalStorage(name){
var lstrg = localStorage.getItem("alreadyaddbuttontobuttonlinks");
if(lstrg == null){
localStorage.setItem("alreadyaddbuttontobuttonlinks", name);
return name;
}else{
var nLstrg = lstrg + "|" + name;
localStorage.setItem("alreadyaddbuttontobuttonlinks", nLstrg);
return nLstrg;
}
}
function getButtonInformationFromLocalStorage(){
var lstrg = localStorage.getItem("alreadyaddbuttontobuttonlinks");
if(lstrg == null){
return null;
}else{
return lstrg.split("|");
}
}
window.onload = Initbutton();
</script>

Related

JavaScript button doesn't work on second click

I want to make a program changing background color of a div after clicking on a button.
After first click it should change one color to the second one. After second click the color should come back to the first option. And for the last time, the color should be switched again to the second option. So it should work for 3 times. But in my code it works just for the first click.
What did I do wrong?
var btn = document.getElementById('button');
var box = document.getElementById('sq');
function changeColor() {
var isPink = true;
var colorA = "#BA498B";
var colorB = "#5964E3";
var i = 0;
while (i < 3) {
if (isPink) {
change(colorB);
isPink = false;
i++;
} else {
change(colorA);
isPink = true;
i++;
}
}
}
function change(color) {
btn.addEventListener('click', function () {
box.style.backgroundColor = color;
});
}
window.onload = changeColor;
You're adding a new, identical event handler every time there's a click. Instead just add it once when the page loads, so that the redundant handlers don't cancel each other out.
var isPink = true;
function changeColor() {
var colorA = "#BA498B";
var colorB = "#5964E3";
if (isPink) {
change(colorB);
} else {
change(colorA);
}
isPink = !isPink;
}
function change(color) {
document.getElementById('sq').style.backgroundColor = color;
}
window.onload = function() {
document.getElementById('button').addEventListener('click', changeColor);
};
#sq {
width: 100px;
height: 100px;
position: relative;
}
<button id=button>CLICK</button>
<div id=sq></div>
Don't know what you wanted with the loop though, so I removed it. It runs immediately, and so you'd never see such a rapid color change.
try this:
var isPink = true;
var color = "#BA498B"
function changeColor() {
var colorA = "#BA498B";
var colorB = "#5964E3";
if (isPink) {
color = (colorB);
isPink = false;
} else {
color = (colorA);
isPink = true;
}
}
window.onload = function(){
var btn = document.getElementById('button');
var box = document.getElementById('sq');
btn.addEventListener('click', function () {
changeColor();
box.style.backgroundColor = color;
});
};
This way I'm only using 'addEventListener' on the button once
Here is an example which may help you:
var btn = document.getElementById('button');
var box = document.getElementById('sq');
var isPink = true;
function changeColor() {
var colorA = "#BA498B";
var colorB = "#5964E3";
var color=isPink?colorA:colorB;
isPink=isPink?false:true;
return color;
}
function change() {
box.style.backgroundColor = changeColor();
}
btn.addEventListener('click', change);
window.onload = change();
<h1 id="sq">Test Text for Example</h1>
<button id="button">Click</button>

how do i add functionality to each of the buttons?

The first part of the code is working correctly, but now that each button appears, how do i add functionality to each of them? currently the only button which does something when pressed is always the last one, the rest do nothing.
Change it to
{
var output = "";
var data = JSON.parse(e.target.responseText);
for(var i=0; i<data.length; i++)
{
output = data[i].title + ' ';
var p = document.createElement("p");
var div = document.getElementById("response");
var textNode = document.createTextNode(output);
p.appendChild(textNode);
var button = document.createElement("button");
button.innerHTML = "Download";
p.appendChild(button);
div.appendChild(p);
button.addEventListener ("click", () =>
{
alert("Test");
});
}
}
You are adding the below code out side the for loop
button.addEventListener ("click", () =>
{
alert("Test");
} );
Keep the above code inside the for loop. So that for each button the event listener will be added.
Another way to approach this would be to add the callback function to the onclick variable of the elements prototype:
function doStuff() {
var output = "";
var data = JSON.parse(e.target.responseText);
for (var i = 0; i < data.length; i++) {
output = data[i].title + ' ';
var p = document.createElement("p");
var div = document.getElementById("response");
var textNode = document.createTextNode(output);
p.appendChild(textNode);
var button = document.createElement("button");
button.innerHTML = "Download";
// Adds the callback function here
button.onclick = () => {
// fill in your arrow function here...
alert("Test");
};
p.appendChild(button);
div.appendChild(p);
};
}
doStuff();
Here is a jsFiddle
You should use event delegation for dynamically added elements
// sample data
var data = [{
title: 'one'
}, {
title: 'two'
},{
title: 'three'
}];
var output = "";
for (var i = 0; i < data.length; i++) {
var output = data[i].title + " ";
var p = document.createElement("p");
var div = document.getElementById("response");
var textNode = document.createTextNode(output);
p.appendChild(textNode);
var button = document.createElement("button");
// added output to button text for identification
button.innerHTML = output + " Download";
p.appendChild(button);
div.appendChild(p);
}
// Get the parent element, add a click listener
document.getElementById("response").addEventListener("click", function(e) {
// e.target is the clicked element!
// If it was a button
if (e.target && e.target.nodeName == "BUTTON") {
// Button found! Output the identifying data!
// do other work on click
document.getElementById("display").innerHTML = e.target.innerHTML + " Clicked";
}
});
<div id="response"></div>
<div id="display">Display</div>

While loop act twice JS

I used this code:
var list = was_talkWindows.querySelectorAll('.msg:not(.was_added)');
var i;
for (i = 0; i < list.length; i++)
{
list[i].className += cssClass;
var btn = document.createElement('button');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'was_addButton');
btn.addEventListener('click', function() {
was_button_act(this.parentElement);
});
btn.innerHTML = buttonName;
list[i].appendChild(btn);
}
however, friend told me that .msg:not(.was_added) is too slow, so doing it in the opposite way:
var cssClass = ' was_added';
var buttonName = 'start waiting';
if (was_set_standby_auto == true)
{
cssClass += ' was_standby';
buttonName = 'cancel';
}
try {
var currectMSG = was_talkWindows.querySelector('.msg:last-child');
while (currectMSG.classList.contains('was_added') == false)
{
currectMSG.className += cssClass;
var btn = document.createElement('button');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'was_addButton');
btn.addEventListener('click', function() {
was_button_act(this.parentElement);
});
btn.innerHTML = buttonName;
currectMSG.appendChild(btn);
currectMSG = currectMSG.previousElementSibling;
}
} catch (err) {}
but the code add the button twice each time for the last one.
not really understand this behavor.
Use previousElementSibling instead of previousSibling, so that it skips over text nodes.
And add the was_added class to the element so it won't be processed again later.
var was_talkWindows = document;
var cssClass = " newclass";
var buttonName = "Click me";
try {
var currectMSG = was_talkWindows.querySelectorAll('.msg:last-child')[0];
while (currectMSG.classList.contains('was_added') == false) {
currectMSG.className += cssClass;
currectMSG.classList.add('was_added');
var btn = document.createElement('button');
btn.setAttribute('type', 'button');
btn.setAttribute('class', 'was_addButton');
btn.addEventListener('click', function() {
was_button_act(this.parentElement);
});
btn.innerHTML = buttonName;
currectMSG.appendChild(btn);
currectMSG = currectMSG.previousElementSibling;
}
} catch (err) {}
<ol>
<li class="msg was_added">Text</li>
<li class="msg was_added">Text</li>
<li class="msg">Text</li>
<li class="msg">Text</li>
<li class="msg">Text</li>
</ol>
The problem with a site that is not under your control, it does not always know what is running, and it took me a long time to realize that the problem is not adding buttons twice (against logic), but anyone who does not I edit the code at the same time.
so declare just once:
var was_msgList = was_talkWindows.getElementsByClassName('msg');
and the loop (every 2 seconds):
for ( var i=was_msgList.length; i-- && was_msgList[i].getAttribute('data-status') == null; )
{
was_load_addButton(was_msgList[i],attStatus,buttonText);
}
any ideas for change are welcome.

Can a javascript function apply to all elements of a certain CSS class?

I have a nav bar where each button changes the background of the body. They each change it to a different color. I have created onmouseover and onmouseout functions for each button to achieve this. However, I wonder if there is a way to just write one of each function by just referring to them by their class? They all have the same class of button. Is there a way a function can apply to all elements of a certain class? My code:
function whichButton(x) {
if (x==1)
return "red";
if (x==2)
return "green";
if (x==3)
return "blue";
if (x==4)
return "orange";
if (x==0)
return initBG;
}
button1.onmouseover = function() {
document.body.style.backgroundColor = whichButton(1);
}
button1.onmouseout = function() {
document.body.style.backgroundColor = whichButton(0);
}
button2.onmouseover = function() {
document.body.style.backgroundColor = whichButton(2);
}
button2.onmouseout = function() {
document.body.style.backgroundColor = whichButton(0);
}
button3.onmouseover = function() {
document.body.style.backgroundColor = whichButton(3);
}
button3.onmouseout = function() {
document.body.style.backgroundColor = whichButton(0);
}
button4.onmouseover = function() {
document.body.style.backgroundColor = whichButton(4);
}
button4.onmouseout = function() {
document.body.style.backgroundColor = whichButton(0);
}
initBG just saves the initial background of the page.
I have tried this:
document.getElementsByClassName('button').onmouseover = function() {
document.body.style.backgroundColor = whichButton(1);
}
but it doesn't trigger the function. And I guess to do this, I'd also need to have a way to read the elements' ID as a string so I could get it's number...
This is more out of curiosity than necessity, just trying to find ways to keep my code small! I could see this being useful in many applications so I'd love to learn more about this!
Corresponding HTML:
<div id="navbar">
<p id="button1" class="button">Red</p><p id="button2" class="button">Blue</p><p id="button3" class="button">Green</p><p id="button4" class="button">Orange</p>
</div>
Here is my suggestion to solve it:
Use the data attribute and iterate over all elements with the given class.
function applyColor(element) {
var color = element.getAttribute('data-bg');
document.body.style.backgroundColor = color;
}
var buttons = document.getElementsByClassName("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("mouseover", function() {
applyColor(this);
}, false);
}
<nav>
<button class="button" data-bg="red">red</button>
<button class="button" data-bg="blue">blue</button>
<button class="button" data-bg="yellow">yellow</button>
<button class="button" data-bg="green">green</button>
<button class="button" data-bg="pink">pink</button>
<button class="button" data-bg="magenta">magenta</button>
</nav>
As previously stated, getElementsByClassName returns a collection and you can't just add the event to the collection in a way that you can in jQuery. To do this is pure JS, you need to use a for loop and then attach the event to each individual element as below:
var buttons = document.getElementsByClassName('button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].onmouseover = function (event) {
var colour = event.target.className.split(" ")[1];
document.body.style.backgroundColor = colour;
}
}
http://jsfiddle.net/andyfurniss/1n5vann9/
getElementsByClassName returns a collection. So you will have to loop over it and you shall be good.
var buttons = document.getElementsByClassName('button');
[].forEach.call(buttons, function (button){
var id = parseInt(button.id.split("").reverse().join("")); //This will give you the number from the id
button.onmouseover = = function() {
document.body.style.backgroundColor = whichButton(id);
}
button.onmouseout = function() {
document.body.style.backgroundColor = whichButton(0);
}
});
To ensure ES6 compatibility, there is much better way.
var buttons = document.getElementsByClassName("button");
for (button of buttons) {
var id = parseInt(button.id.split("").reverse().join("")); //This will give you the number from the id
button.onmouseover = = function() {
document.body.style.backgroundColor = whichButton(id);
}
button.onmouseout = function() {
document.body.style.backgroundColor = whichButton(0);
}
}
The first comment actually solved it for me. I did this:
document.onmouseover = function() {
var x = event.target;
y = x.id.toString().replace('button','');
if (y > 0 && y <= 4)
document.body.style.backgroundColor = whichButton(y);
}
document.onmouseout = function() {
var x = event.target;
y = x.id.toString().replace('button','');
if (y > 0 && y <= 4)
document.body.style.backgroundColor = whichButton(0);
}
If I mouse over a "button", it removes the word "button", leaving the number (1-4), then sends that to my whichButton function to decice which colour to use. Nice and simple, works for me.
You can use event delegation, which means attaching an event listener to an ancestor, then inspecting the event.target to decide what to do.
Demo: http://jsfiddle.net/a58tj1ak/
// given your HTML and whichButton function like this:
function whichButton(x) {
var initBG = '#fff';
if (x==1)
return "red";
if (x==2)
return "green";
if (x==3)
return "blue";
if (x==4)
return "orange";
if (x==0)
return initBG;
}
// get the buttons into an array
var buttons = [].slice.call(document.getElementsByClassName('button'));
// add event listener to the #navbar element
document.getElementById('navbar').addEventListener('mouseover', function(e){
// target is an element being hovered
var target = e.target;
// check if the target is in the array of buttons
var index = buttons.indexOf( e.target );
if( index > -1 ){
document.body.style.backgroundColor = whichButton(index + 1)
}
else {
document.body.style.backgroundColor = whichButton(0);
}
});

Ajax loaded page refreshing when clicking on button

I load a page in a div through AJAX. This works great.
On this ajax loaded page there are some buttons (generally created with javascript). When I click on one of these buttons the page refreshes. Weird thing is; no where I stated the page SHOULD refresh. Afterall; that's why I use ajax.
This is the javascript that's executed on the AJAX loaded page:
function buttonClicked(id){
var page = id;
photoPage = page*10;
if(cur_button < id)
{
minCount += 10;
maxCount += 10;
}
else
{
minCount -= 10;
maxCount -= 10;
}
cur_button = id;
jQuery("#imagesDiv").html("");
$( "#imagesDiv" ).append( " <br/>");
executePage();
}
function createButtons() {
var i = 1;
var button = "";
while(i <= photoCount)
{
var button = document.createElement("BUTTON");
var buttonName = document.createTextNode(i);
button.appendChild(buttonName);
button.id = i;
jQuery(button).bind('click', { id: i}, function(event) {
var data = event.data;
buttonClicked(data.id);
});
imagesDivJS.appendChild(button);
i++;
}
}
function executePage()
{
setImagesDivID();
createButtons();
$( ids ).append( " <br/>");
populateDiv();
}
function populateDiv() {
for(var i = minCount;i < maxCount; i++)
{
if(i < total_count)
{
create_image("../"+photos[i],photoAlts[i]);
$("#"+ids).append( "<p style=\"display:inline; padding-left:10px;\">" + photoTags[i] + "</p><br/>" );
}
}
}
Help will be appreciated. I've been breaking my neck around this thing!
The button is refreshing the page because it is a submit button. You need to add an attribute of type="button" to the button. For example:
function createButtons() {
var i = 1;
var button = "";
while(i <= photoCount)
{
var button = document.createElement("BUTTON");
var buttonName = document.createTextNode(i);
button.appendChild(buttonName);
button.id = i;
// Add type="button"
button.setAttribute("type", "button");
jQuery(button).bind('click', { id: i}, function(event) {
var data = event.data;
buttonClicked(data.id);
});
imagesDivJS.appendChild(button);
i++;
}
}

Categories