See this codepen
or the code snippet below
How can I get the button to log to the console when it is clicked? I am trying to learn how to use this in JavaScript. Thanks
const button = document.getElementById("leet");
function LeetSpeaker (elem) {
return {
listenClick () {
const self = this
elem.addEventListener('click', function () {
self.speakLeet()
})
},
speakLeet() { console.log(`1337 15 4W350M3`) }
}
}
button {
background-color: #b666d2;
border: none;
width: 100px;
height: 30px;
font-size: 1em;
border-radius: 10px;
font-family: Verdana;
}
button:hover {
background-color: rebeccapurple;
}
<button id="leet" onclick="LeetSpeaker(button)">Click</button>
The problem isn't this in your code. Get rid of the inline javascript, execute LeetSpeaker(button).listenClick() in your js code and it works. To do it better, use an arrow function and then just this.speakLeet()
const button = document.getElementById("leet");
LeetSpeaker(button).listenClick();
function LeetSpeaker(elem) {
return {
listenClick() {
const self = this
elem.addEventListener('click', function() {
self.speakLeet()
})
},
speakLeet() {
console.log(`1337 15 4W350M3`)
}
}
}
button {
background-color: #b666d2;
border: none;
width: 100px;
height: 30px;
font-size: 1em;
border-radius: 10px;
font-family: Verdana;
}
button:hover {
background-color: rebeccapurple;
}
<button id="leet">Click</button>
Or nicer, with an arrow function
const button = document.getElementById("leet");
LeetSpeaker(button).listenClick();
function LeetSpeaker(elem) {
return {
listenClick() {
elem.addEventListener('click', () => {
this.speakLeet()
})
},
speakLeet() {
console.log(`1337 15 4W350M3`)
}
}
}
button {
background-color: #b666d2;
border: none;
width: 100px;
height: 30px;
font-size: 1em;
border-radius: 10px;
font-family: Verdana;
}
button:hover {
background-color: rebeccapurple;
}
<button id="leet">Click</button>
Related
I have a function that turns an array into modal window links as a template literal.
The code that creates the links works fine outside of the function
But once it gets rendered in the function it no longer works. I can't find any errors, but it does NOT work.
However, if I copy the HTML that the function renders and save that as actual HTML, that works fine on its own.
A good chunk of the JavaScript portion of the code is posted below. A full version is on Codepen.
There are two sections in the example on Codepen:
The first section has the code as it's rendered by the function.
The second section is copied from the Elements tab in Developer Tools and saved as actual HTML.
"use strict";
const modalBtns = document.querySelectorAll(".modal-button");
const modalWin = document.querySelector(".modal-window");
const closeBtn = document.querySelector(".close-modal");
const modal_iframe = document.getElementById("modal_iframe");
modalBtns.forEach((item) => {
item.addEventListener("click", function (e) {
let modal = e.currentTarget;
if (modal.dataset.target) {
let modalID = modal.dataset.target;
document.getElementById(modalID).style.display = "block";
}
if (modal.dataset.iframe) {
modal_iframe.src = modal.dataset.iframe;
document
.querySelector(".button-footer")
.addEventListener("click", function () {
window.open(modal.dataset.iframe, "_blank");
});
}
if (modal.dataset.header) {
document.querySelector(
".modal-header"
).innerHTML = `<h1>${modal.dataset.header}</h1>`;
}
if (modal.dataset.dimensions) {
document
.querySelector(".modal-window")
.setAttribute("style", modal.dataset.dimensions);
}
function loadIframe() {
let frame = document.getElementById("modal_window");
frame.style.height =
frame.contentWindow.document.body.scrollHeight + "px";
}
if (document.querySelector("#modal_window")) {
setTimeout(function () {
loadIframe;
}, 2000);
}
if (modal.dataset.reload && modal.dataset.reload === "1") {
document
.querySelector(".close-modal")
.addEventListener("click", function (e) {
console.log("parent.location.reload() pending...");
parent.location.reload();
});
}
/*======= All EventListeners Below Close Modal ================*/
closeBtn.addEventListener("click", function (e) {
document.querySelector(".modal-background").style.display = "none";
});
window.addEventListener("click", function (e) {
if (e.currentTarget === document.querySelector(".modal-background")) {
document.querySelector(".modal-background").style.display = "none";
}
});
document.body.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
document.querySelector(".modal-background").style.display = "none";
}
});
});
});
const main = document.querySelector("main");
const modal_links = [
{
link: "https://notation.netcentrx.net/staff/",
header: "Musical Staff",
thb: "notation",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
},
{
link: "https://wsl.netcentrx.net/",
header: "WSL Commands",
thb: "wsl",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
}
];
let modalLink = "";
function createModalLinks(
link,
modalID,
header,
img,
w_h = "width:90vw;height:600px",
reload = "0"
) {
modalLink = `
<a href="javascript:void(0)" class="modal-button" onclick="console.log('onclick handler:${link}');" data-header="${header}" data-target="${modalID}" data-iframe="${link}" data-dimensions="${w_h};margin-top:20px" data-reload="${reload}">
<img src="https://resume.netcentrx.net/examples/${img}.jpg" title="${img}" width="50">
</a>
`;
return modalLink;
}
let theLinks = "";
modal_links.forEach((item) => {
theLinks += createModalLinks(
item.link,
"modal_window",
item.header,
item.thb,
item.w_h,
item.reload
);
});
main.innerHTML = theLinks;
My apologies in advance for it not being stripped down to just the bare minimum. But in order to replicate the problem, it required more code than it probably should have had. I've been reworking this for the better part of a day without any insight as to what the real problem is. I've been creating functions using template literals just like this for years now, usually with a high success rate. Whatever the problem is, I need to know so I can get past it. The only anomaly that I spotted is that–in the version on Codepen–the only thing that doesn't work in that version is once the modal is displayed clicking on the background does not dismiss the modal like it does elsewhere. If that's significant as to what the problem may be, I'm not sure what the connection is.
Usually when I take the time to painstakingly write everything out like this I typically either spot the problem or figure out an alternative solution so there's no need to actually post a question, but this does not appear to be one of those times. As always, your help is very much appreciated!
The issue appears to just be timing. Your code is executed in order, and the first part gets all of the modal buttons on the page and sets the appropriate event listeners. Then the second part of your code adds 2 modal buttons, which were not present earlier.
By simply wrapping the first part of your code in a function and calling it later (or swapping the order of those two parts of code), everything works as expected.
"use strict";
const _InitModal = () => {
const modalBtns = document.querySelectorAll(".modal-button");
const modalWin = document.querySelector(".modal-window");
const closeBtn = document.querySelector(".close-modal");
const modal_iframe = document.getElementById("modal_iframe");
modalBtns.forEach((item) => {
item.addEventListener("click", function (e) {
console.log("e.currentTarget = " + e.currentTarget);
let modal = e.currentTarget;
console.log("modal = " + modal);
if (modal.dataset.target) {
let modalID = modal.dataset.target;
console.log("modal.dataset.target = " + modal.dataset.target);
document.getElementById(modalID).style.display = "block";
}
if (modal.dataset.iframe) {
modal_iframe.src = modal.dataset.iframe;
document
.querySelector(".button-footer")
.addEventListener("click", function () {
window.open(modal.dataset.iframe, "_blank");
});
}
if (modal.dataset.header) {
document.querySelector(
".modal-header"
).innerHTML = `<h1>${modal.dataset.header}</h1>`;
console.log(`modal.dataset.header = ${modal.dataset.header}`);
}
if (modal.dataset.dimensions) {
document
.querySelector(".modal-window")
.setAttribute("style", modal.dataset.dimensions);
}
function loadIframe() {
let frame = document.getElementById("modal_window");
frame.style.height =
frame.contentWindow.document.body.scrollHeight + "px";
}
if (document.querySelector("#modal_window")) {
setTimeout(function () {
loadIframe;
}, 2000);
}
// e.preventDefault();
if (modal.dataset.reload && modal.dataset.reload === "1") {
document
.querySelector(".close-modal")
.addEventListener("click", function (e) {
console.log("parent.location.reload() pending...");
parent.location.reload();
});
}
/*======= All EventListeners Below Close Modal ================*/
closeBtn.addEventListener("click", function (e) {
document.querySelector(".modal-background").style.display = "none";
});
window.addEventListener("click", function (e) {
console.log("e.currentTarget = " + e.currentTarget);
if (e.currentTarget === document.querySelector(".modal-background")) {
document.querySelector(".modal-background").style.display = "none";
}
});
document.body.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
console.log("e=" + e);
document.querySelector(".modal-background").style.display = "none";
}
});
});
});
}
const main = document.querySelector("main");
const modal_links = [
{
link: "https://notation.netcentrx.net/staff/",
header: "Musical Staff",
thb: "notation",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
},
{
link: "https://wsl.netcentrx.net/",
header: "WSL Commands",
thb: "wsl",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
}
];
function createModalLinks(
link,
modalID,
header,
img,
w_h = "width:90vw;height:600px",
reload = "0"
) {
let modalLink = "";
modalLink = `
<a href="javascript:void(0)" class="modal-button" onclick="console.log('onclick handler:${link}');" data-header="${header}" data-target="${modalID}" data-iframe="${link}" data-dimensions="${w_h};margin-top:20px" data-reload="${reload}">
<img src="https://resume.netcentrx.net/examples/${img}.jpg" title="${img}" width="50">
</a>`;
return modalLink;
}
let theLinks = "";
modal_links.forEach((item) => {
theLinks += createModalLinks(
item.link,
"modal_window",
item.header,
item.thb,
item.w_h,
item.reload
);
});
main.innerHTML = theLinks;
_InitModal();
.modal-background {
font-family: sans-serif;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: none;
overflow: auto;
background-color: rgba(0, 0, 0, 0.9);
z-index: 9999;
background: rgba(55, 55, 55, 0.6);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.modal-window {
position: relative;
background-color: #ffffff;
width: 50%;
margin: 10% auto;
border-radius: 0.5rem;
padding: 0.75rem;
border: 1px groove #ccc;
/* box-shadow: 1px 1px 1px #999, 2px 2px 2px #000; */
}
.close-modal:hover,
.close-modal:focus {
color: rgba(255, 255, 255, 1);
cursor: pointer;
background: red;
transition: 1s;
text-shadow: 1px 1px 1px #999, 2px 2px 2px #000;
}
button.close-modal {
position: absolute;
top: -0.75rem;
right: -0.75rem;
padding: 0.05rem 0.75rem;
background: #999;
color: #ccc;
border-radius: 50%;
border: none;
outline: none;
-webkit-transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 1.5s;
animation-name: animatebottom;
animation-duration: 1.5s;
}
button.close-modal::before {
content: "\D7";
font-size: 2rem;
}
.modal-window {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
-webkit-animation-name: animatetop;
-webkit-animation-duration: 0.5s;
animation-name: animatetop;
animation-duration: 0.5s;
}
.modal-header {
height: 30px;
text-align: center;
width: 100%;
background: #fff;
padding: 0.2rem;
}
.modal-header h1 {
font-size: 1.1rem;
}
.modal-footer {
height: 20px;
text-align: center;
width: 100%;
background: #fff;
padding: 0.2rem;
}
.modal-content {
background-color: #fff;
height: calc(100% - 70px);
border-radius: 0.5rem;
border: 0.1rem groove #ddd;
overflow: hidden;
}
.button-footer {
background: #fff;
border-radius: 0.5rem;
border: 1px outset #aaa;
padding: 0.2rem;
color: #999;
transition: 1s;
cursor: pointer;
}
.button-footer:hover {
background: #fdfdfd;
color: #555;
border: 1px inset #ddd;
text-shadow: 0.05rem 0.05rem 0.05rem #ccc, 0.055rem 0.055rem 0.055rem #999,
0.06rem 0.06rem 0.06rem #333;
transition: 1s;
}
.close-btn:hover {
color: white;
background: #f00;
cursor: pointer;
}
#modal_iframe {
width: 100%;
height: 100%;
}
button.modal-button {
border-radius: 0.5rem;
border: 0px solid #aaa;
padding: 0;
cursor: pointer;
}
.modal-button-img {
border-radius: 0.5rem;
border: 0.1rem groove #444;
cursor: pointer;
}
.sepia:hover {
filter: sepia(150%);
}
/*
.none {
display: none;
}
*/
#-webkit-keyframes animatetop {
from {
top: -300px;
opacity: 0;
}
to {
top: 0;
opacity: 1;
}
}
#keyframes animatetop {
from {
top: -300px;
opacity: 0;
}
to {
top: 0;
opacity: 1;
}
}
#-webkit-keyframes animatebottom {
from {
top: 0;
opacity: 1;
}
to {
bottom: -300px;
opacity: 0;
}
}
#keyframes animatebottom {
from {
top: 0;
opacity: 1;
}
to {
bottom: -300px;
opacity: 0;
}
}
.container {
border-radius: 0.5rem;
border: 1px solid #aaa;
max-width: 800px;
width: 500px;
margin: 0 auto;
text-align: center;
font-family: sans-serif;
}
main,
aside {
font-family: sans-serif;
max-width: 800px;
width: 500px;
margin: 0 auto;
text-align: center;
}
h2 {
text-align: center;
font-family: sans-serif;
font-weight: normal;
font-size: 1.2rem;
}
span {
font-size: 75%;
background: #ffff0055;
}
<div id="modal_window" class="modal-background">
<div class="modal-window">
<button class="close-modal" data-dismiss="modal"></button>
<div class="modal-header"></div>
<div class="modal-content">
<iframe src="#" id="modal_iframe" frameborder="0">If you'd have had a real browser, I wouldn't be boring you with this now...</iframe>
</div>
<div class="modal-footer"><button class="button-footer">Open In New Tab</button></div>
</div>
</div>
<div class="container">
<h2><code>main</code> Content Rendered By JavaScript</h2>
<main>
Main
</main>
<span>working now</span>
</div>
I'm looking for advice/tips on how to fix a function that is supposed to remove items from localStorage. I'm following a tutorial by John Smilga that I found on Youtube. Although I've modeled my code on his, apparently, I have missed something.
This function works perfectly well if I run it manually from the console and pass in the id of the item that I want to remove from localStorage.
function removeFromLocalStorage(id) {
console.log(id);
let storageItems = getLocalStorage();
console.log(storageItems);
storageItems = storageItems.filter(function(singleItem) {
if (singleItem.id !== id) {
return singleItem;
}
})
console.log(storageItems);
localStorage.setItem("list", JSON.stringify(storageItems));
}
However, when this function is triggered by the deleteItem() function, it refuses to remove the item from localStorage. It still works, there are a bunch of console.logs in it that track its execution, and I can check that it receives the correct item id as the argument, but for some reason it doesn't filter out the item that needs to be removed. I am completely lost and have no idea how to identify the problem. I can't debug it with console.logs as I usually do. I will be very grateful if you help me find the problem. Any advice will be appreciated.
In case the entire code is needed, please find it below.
const form = document.querySelector(".app__form");
const alert = document.querySelector(".app__alert");
const input = document.querySelector(".app__input");
const submitBtn = document.querySelector(".app__submit-btn");
const itemsContainer = document.querySelector(".app__items-container");
const itemsList = document.querySelector(".app__items-list");
const clearBtn = document.querySelector(".app__clear-btn");
let editElement;
let editFlag = false;
let editId = "";
form.addEventListener("submit", addItem);
clearBtn.addEventListener("click", clearItems);
function addItem(e) {
e.preventDefault();
const id = Math.floor(Math.random() * 9999999999);
if (input.value && !editFlag) {
const item = document.createElement("div");
item.classList.add("app__item");
const attr = document.createAttribute("data-id");
attr.value = id;
item.setAttributeNode(attr);
item.innerHTML = `<p class='app__item-text'>${input.value}</p>
<div class='app__item-btn-cont'>
<button class='app__item-btn app__item-btn--edit'>edit</button>
<button class='app__item-btn app__item-btn--delete'>delete</button>
</div>`
const editBtn = item.querySelector(".app__item-btn--edit");
const deleteBtn = item.querySelector(".app__item-btn--delete");
editBtn.addEventListener("click", editItem);
deleteBtn.addEventListener("click", deleteItem);
itemsList.appendChild(item);
displayAlert("item added", "success");
addToLocalStorage(id, input.value);
setBackToDefault();
itemsContainer.classList.add("app__items-container--visible");
} else if (input.value && editFlag) {
editElement.textContent = input.value;
// edit local storage
editLocalStorage(editId, input.value);
setBackToDefault();
displayAlert("item edited", "success");
} else {
displayAlert("empty field", "warning");
}
}
function setBackToDefault() {
input.value = "";
editFlag = false;
editId = "";
submitBtn.textContent = "Submit";
submitBtn.className = "app__submit-btn";
}
function displayAlert(text, action) {
alert.textContent = text;
alert.classList.add(`app__alert--${action}`);
setTimeout(function() {
alert.textContent = "";
alert.classList.remove(`app__alert--${action}`);
}, 700)
}
function clearItems() {
const items = document.querySelectorAll(".app__item");
if (items.length > 0) {
items.forEach(function(singleItem) {
itemsList.removeChild(singleItem);
})
itemsContainer.classList.remove("app__items-container--visible");
displayAlert("items cleared", "cleared");
setBackToDefault();
}
}
function editItem(e) {
const item = e.currentTarget.parentElement.parentElement;
editElement = e.currentTarget.parentElement.previousElementSibling;
editId = item.dataset.id;
editFlag = true;
input.value = editElement.textContent;
submitBtn.textContent = "Edit";
submitBtn.classList.add("app__submit-btn--edit");
input.focus();
}
function deleteItem(e) {
const item = e.currentTarget.parentElement.parentElement;
const itemId = item.dataset.id;
removeFromLocalStorage(itemId);
displayAlert("item removed", "cleared");
setBackToDefault();
itemsList.removeChild(item);
if (itemsList.children.length === 0) {
itemsContainer.classList.remove("app__items-container--visible");
}
}
function addToLocalStorage(id, value) {
const itemsObj = {id: id, value: input.value};
let storageItems = getLocalStorage();
storageItems.push(itemsObj);
localStorage.setItem("list", JSON.stringify(storageItems));
}
function removeFromLocalStorage(id) {
console.log(id);
let storageItems = getLocalStorage();
console.log(storageItems);
storageItems = storageItems.filter(function(singleItem) {
if (singleItem.id !== id) {
return singleItem;
}
})
console.log(storageItems);
localStorage.setItem("list", JSON.stringify(storageItems));
}
function editLocalStorage(id, value) {
}
function getLocalStorage() {
return localStorage.getItem("list") ? JSON.parse(localStorage.getItem("list")) : [];
}
* {
margin: 0;
padding: 0;
}
.app {
width: 70%;
max-width: 600px;
margin: 75px auto 0;
}
.app__title {
text-align: center;
/* color: #1B5D81; */
margin-top: 20px;
color: #377FB4;
}
.app__alert {
width: 60%;
margin: 0 auto;
text-align: center;
font-size: 20px;
color: #215884;
border-radius: 7px;
height: 23px;
transition: 0.4s;
text-transform: capitalize;
}
.app__alert--warning {
background-color: rgba(243, 117, 66, 0.2);
color: #006699;
}
.app__alert--success {
background-color: rgba(165, 237, 92, 0.4);
color: #3333ff;
}
.app__alert--cleared {
background-color: #a978da;
color: white;
}
.app__input-btn-cont {
display: flex;
margin-top: 30px;
}
.app__input {
width: 80%;
box-sizing: border-box;
font-size: 20px;
padding: 3px 0 3px 10px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
border-right: none;
border: 1px solid #67B5E2;
background-color: #EDF9FF;
}
.app__input:focus {
outline: transparent;
}
.app__submit-btn {
display: block;
width: 20%;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
border-left: none;
background-color: #67B5E2;
border: 1px solid #67B5E2;
cursor: pointer;
font-size: 20px;
color: white;
transition: background-color 0.7s;
padding: 3px 0;
}
.app__submit-btn--edit {
background-color: #95CB5D;
}
.app__submit-btn:active {
width: 19.9%;
padding: 0 0;
}
.app__submit-btn:hover {
background-color: #377FB4;
}
.app__submit-btn--edit:hover {
background-color: #81AF51;
}
.app__items-container {
visibility: hidden;
/* transition: 0.7s; */
}
.app__items-container--visible {
visibility: visible;
}
.app__item {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.app__item:hover {
background-color: #b9e2fa;
border-radius: 10px;
}
.app__item-text {
padding-left: 10px;
font-size: 20px;
color: #1B5D81;
}
.app__item-btn-cont {
display: flex;
}
.app__item-btn-img {
width: 20px;
height: 20px;
}
.app__item-btn {
border: none;
background-color: transparent;
cursor: pointer;
display: block;
font-size: 18px;
}
.app__item-btn--edit {
margin-right: 45px;
color: #2c800f;
}
.app__item-btn--delete {
margin-right: 15px;
color: rgb(243, 117, 66);
}
.app__clear-btn {
display: block;
width: 150px;
margin: 20px auto;
border: none;
background-color: transparent;
font-size: 20px;
color: rgb(243, 117, 66);
letter-spacing: 2px;
cursor: pointer;
transition: border 0.3s;
border: 1px solid transparent;
}
.app__clear-btn:hover {
border: 1px solid rgb(243, 117, 66);
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" name="viewport" content="width=device-width,
initial-scale=1">
<link rel="stylesheet" href="list.css">
<title>To Do List App</title>
</head>
<body>
<section class="app">
<form class="app__form">
<p class="app__alert"></p>
<h2 class="app__title">To Do List</h2>
<div class="app__input-btn-cont">
<input class="app__input" type="text" id="todo" placeholder="do stuff">
<button class="app__submit-btn">Submit</button>
</div>
</form>
<div class="app__items-container">
<div class="app__items-list">
</div>
<button class="app__clear-btn">Clear Items</button>
</div>
</section>
<script src="list.js"></script>
</body>
</html>
Your code is fine you just used the wrong comparison operator.
In your case you are comparing 2 IDs (operands) to see if they match up, so you should use normal operators such as (==, !=), but instead in your case, you have used strict operators which are used to compare the operand type and the operand itself.
You can learn more about Comparison Operators here.
Ultimatly,
In your function removeFromLocalStorage(id), you have an extra equal sign in your if function.
Instead of:
if (singleItem.id !== id) {
return singleItem;}
It should be:
if (singleItem.id != id) {
return singleItem;}
Hope this helps.
I am trying to change button text and style when clicking on button. Code is working when changing Generate to Reset button however it doesn't work from reset to generate. It seems that code is working just in first click. How can I fix this?
// Change Generate Button to Reset#
let generateBtn = document.getElementById("generateBtn");
generateBtn.addEventListener("click", () => {
if ((generateBtn.innerHTML = "GENERATE")) {
generateBtn.innerHTML = "RESET";
generateBtn.classList.add("resetBtn-shown");
} else {
generateBtn.innerHTML = "GENERATE";
generateBtn.classList.remove("resetBtn-shown");
}
});
.generateBtn-shown {
background-color: red;
color: #eba341;
font-size: 1.5rem;
font-weight: 500;
border-radius: 0.5rem;
width: 10rem;
height: 3rem;
border: none;
}
.resetBtn-shown {
background-color: #21b884;
color: white;
}
<button id="generateBtn" class="generateBtn-shown">GENERATE</button>
In if statements, you need to have == instead of equals. So in your case it needs to be:
if ((generateBtn.innerHTML == "GENERATE")) {
This article explains it pretty well.
// Change Generate Button to Reset#
let generateBtn = document.getElementById("generateBtn");
generateBtn.addEventListener("click", () => {
if ((generateBtn.innerHTML == "GENERATE")) {
generateBtn.innerHTML = "RESET";
generateBtn.classList.add("resetBtn-shown");
} else {
generateBtn.innerHTML = "GENERATE";
generateBtn.classList.remove("resetBtn-shown");
}
});
.generateBtn-shown {
background-color: red;
color: #eba341;
font-size: 1.5rem;
font-weight: 500;
border-radius: 0.5rem;
width: 10rem;
height: 3rem;
border: none;
}
.resetBtn-shown {
background-color: #21b884;
color: white;
}
<button id="generateBtn" class="generateBtn-shown">GENERATE</button>
// Change Generate Button to Reset#
let generateBtn = document.getElementById("generateBtn");
generateBtn.addEventListener("click", () => {
if ((generateBtn.innerHTML === "GENERATE")) { //=== instead of =
generateBtn.innerHTML = "RESET";
generateBtn.classList.add("resetBtn-shown");
} else {
generateBtn.innerHTML = "GENERATE";
generateBtn.classList.remove("resetBtn-shown");
}
});
.generateBtn-shown {
background-color: red;
color: #eba341;
font-size: 1.5rem;
font-weight: 500;
border-radius: 0.5rem;
width: 10rem;
height: 3rem;
border: none;
}
.resetBtn-shown {
background-color: #21b884;
color: white;
}
<button id="generateBtn" class="generateBtn-shown">GENERATE</button>
try this..
you should use textContent instead of innerHtml .. it will give you text from html tag .. use includes method to compare text ..
Search it on google : innertext vs innerhtml vs textcontent ..
let generateBtn = document.getElementById("generateBtn");
generateBtn.addEventListener("click", (e) => {
if (e.target.textContent.includes("GENERATE")) {
e.target.innerText = "RESET";
e.target.classList.add("resetBtn-shown");
} else {
e.target.innerText = "GENERATE";
e.target.classList.remove("resetBtn-shown");
}
});
.generateBtn-shown {
background-color: red;
color: #eba341;
font-size: 1.5rem;
font-weight: 500;
border-radius: 0.5rem;
width: 10rem;
height: 3rem;
border: none;
}
.resetBtn-shown {
background-color: #21b884;
color: white;
}
<button id="generateBtn" class="generateBtn-shown">GENERATE</button>
I have a bunch of buttons, some shown some hidden. When the shown buttons are clicked, they should get hidden and a select few of the hidden buttons should get shown. Unfortunately, only the shown buttons are becoming hidden. The hidden buttons don't appear.
I have tried different display types for the buttons, but I actually no nothing of html, CSS, or Javascript to know what I am doing or if what I am doing changes anything.
html:
hideGenres();
function proudCondfidentResults() {
hideFeelings();
showIndustrialGothicButton();
showMetalButton();
}
function powerfulPumpedResults() {
hideFeelings();
}
function showIndustrialGothicButton() {
document.getElementById("industrialGothic").style.display = "block";
}
function showMetalButton() {
document.getElementById("metal").style.display = "block";
}
function hideFeelings() {
document.getElementById("feelingButtons").style.display = "none";
}
function hideGenres() {
document.getElementById("genreButtons").style.display = "none";
}
button {
font-family: 'Work Sans', sans-serif;
font-size: 24px;
background-color: #279;
color: #fff;
border: 0;
border-radius: 3px;
cursor: pointer;
margin-right: 0.5%;
margin-bottom: 0.5%;
display: block;
height: 20%;
width: 49%;
float: left;
}
button:hover {
background-color: #38a;
}
<div id="feelingButtons">
<button id="proudConfident" onclick="proudCondfidentResults()">Proud/Confident</button>
<button id="powerfulPumped" onclick="powerfulPumpedResults()">Powerful/Pumped</button>
</div>
<div id="genreButtons">
<button id="industrialGothic" onclick="industrialGothicLink()">Industrial/Gothic</button>
<button id="metal" onclick="metalLink()">Metal</button>
</div>
When the Proud/Confident button is clicked I expect to have the Proud/Confident and Powerful/Pumped buttons disappear and for the Industrial/Gothic and Metal buttons to appear. What happens currently is the Proud/Confident and Powerful/Pumped buttons disappears, but the Industrial/Gothic and Metal buttons stay hidden. How do you make it so that the Industrial/Gothic and Metal buttons are shown?
You need to change the display style of genreButtons div
hideGenres();
function proudCondfidentResults() {
hideFeelings();
industrialGothicLink();
showMetalButton();
}
function powerfulPumpedResults() {
hideFeelings();
}
function industrialGothicLink() {
document.getElementById("industrialGothic").style.display = "block";
}
function showMetalButton() {
document.getElementById("metal").style.display = "block";
}
function hideFeelings() {
document.getElementById("feelingButtons").style.display = "none";
//changed here
document.getElementById("genreButtons").style.display = "block";
}
function hideGenres() {
document.getElementById("genreButtons").style.display = "none";
}
button {
font-family: 'Work Sans', sans-serif;
font-size: 24px;
background-color: #279;
color: #fff;
border: 0;
border-radius: 3px;
cursor: pointer;
margin-right: 0.5%;
margin-bottom: 0.5%;
display: block;
height: 20%;
width: 49%;
float: left;
}
button:hover {
background-color: #38a;
}
<div id="feelingButtons">
<button id="proudConfident" onclick="proudCondfidentResults()">Proud/Confident</button>
<button id="powerfulPumped" onclick="powerfulPumpedResults()">Powerful/Pumped</button>
</div>
<div id="genreButtons">
<button id="industrialGothic" onclick="industrialGothicLink()">Industrial/Gothic</button>
<button id="metal" onclick="metalLink()">Metal</button>
Try hiding the Genre Buttons div by default via CSS (display:none). Once Proud/Confident are clicked, the genreButtons div will show as desired. This way, all the elements within the genre's div will toggle together.
<html><body>
<style>
button {
font-family: 'Work Sans', sans-serif;
font-size: 24px;
background-color: #279;
color: #fff;
border: 0;
border-radius: 3px;
cursor: pointer;
margin-right: 0.5%;
margin-bottom: 0.5%;
display: block;
height: 20%;
width: 49%;
float: left;
}
button:hover {
background-color: #38a;
}
#genreButtons {
display: none;
}
</style>
<script>
hideGenres();
function proudCondfidentResults() {
hideFeelings();
showIndustrialGothicButton();
showMetalButton();
}
function powerfulPumpedResults() {
hideFeelings();
}
function showIndustrialGothicButton() {
document.getElementById("industrialGothic").style.display = "block";
}
function showMetalButton() {
document.getElementById("genreButtons").style.display = "block";
}
function hideFeelings() {
document.getElementById("feelingButtons").style.display = "none";
}
function hideGenres() {
document.getElementById("genreButtons").style.display = "none";
}
</script>
<div id="feelingButtons">
<button id="proudConfident" onclick="proudCondfidentResults()">Proud/Confident</button>
<button id="powerfulPumped" onclick="powerfulPumpedResults()">Powerful/Pumped</button>
</div>
<div id="genreButtons">
<button id="industrialGothic" onclick="industrialGothicLink()">Industrial/Gothic</button>
<button id="metal" onclick="metalLink()">Metal</button>
</div></body></html>
I have these elements created inside a "querySelector('ul'). It's working property.
I want the "blue-Save" button to have the same function as the "yellow-Save".
But the Blue-save button was created in the HTML file, and the Yellow-Save button was created in JavaScript to listen to an event from the "querySelector('ul').
Is there anyway I can just link the Blue-Save to react as if I was clicking in the Yellow-Save?
(I'm sorry if I didn't explain it property or If it seems too confused, this is my first application, It doesn't seems too organized but I'm focused in making things work before dive in 'well developed apps').
Thank You Everyone!
var todoList = {
todos: [],
addTodo: function (todoText) {
this.todos.push({
todoText: todoText,
/*the name of the property (even if it is the same name as the parameter) never change. Only the value, which follows in this case is following the parameter*/
completed: false
});
},
changeTodo: function (position, todoText) {
this.todos[position].todoText = todoText;
},
deleteTodo: function (position) {
this.todos.splice(position, 1);
},
toggleCompleted: function (position) {
var todo = this.todos[position];
todo.completed = !todo.completed;
/*Here we flip the boolean to his oposite value. if todo.completed is equal false, so changes it to true, and so on. */
},
toggleAll: function () {
// recording the number of todos and completed todos
var totalTodos = this.todos.length;
var completedTodos = 0;
// get the number of completed todos.
this.todos.forEach(function (todo) {
if (todo.completed === true) {
completedTodos++;
}
});
this.todos.forEach(function (todo) {
// Case 1: If everything is true, make everything.
if (completedTodos === totalTodos) {
todo.completed = false;
// Case 2: Otherwise, make everything true.
} else {
todo.completed = true;
}
});
}
};
var handlers = {
addTodo: function () {
var addTodoTextInput = document.getElementById('add-todo-text-input');
todoList.addTodo(addTodoTextInput.value);
addTodoTextInput.value = '';
view.displayTodos();
},
changeTodo: function (position) {
var changeTodoTextInput = document.getElementById('change-todo-text-input');
todoList.changeTodo(position, changeTodoTextInput.value);
changeTodoTextInput.value = '';
view.displayTodos();
},
deleteTodo: function (position) {
todoList.deleteTodo(position);
view.displayTodos();
},
toggleCompleted: function (position) {
todoList.toggleCompleted(position);
view.displayTodos();
},
toggleAllButton: function () {
todoList.toggleAll();
view.displayTodos();
}
};
var view = {
displayTodos: function () {
var todosUl = document.querySelector('ul');
todosUl.innerHTML = '';
todoList.todos.forEach(function (todo, position) {
var todoLi = document.createElement('li');
var todoTextWithCompletion = '';
if (todo.completed === true) {
todoTextWithCompletion = todo.todoText;
todoLi.classList.add('item-completed');
} else {
todoTextWithCompletion = todo.todoText;
}
todoLi.id = position;
todoLi.textContent = todoTextWithCompletion;
todoLi.appendChild(this.createEditButton());
todoLi.appendChild(this.createToggleButton());
todoLi.appendChild(this.createDeleteButton());
todoLi.appendChild(this.createSaveButton());
todosUl.appendChild(todoLi);
}, this);
},
createDeleteButton: function () {
var deleteButton = document.createElement('button');
deleteButton.textContent = '\u2715';
deleteButton.className = 'delete-button';
return deleteButton;
},
createToggleButton: function () {
var toggleButton = document.createElement('button');
toggleButton.textContent = '\u2713';
toggleButton.className = 'toggle-button';
return toggleButton;
},
createSaveButton: function () {
var saveButton = document.createElement('button');
saveButton.textContent = 'Save';
saveButton.className = 'save-button';
return saveButton;
},
createEditButton: function () {
var editButton = document.createElement('button');
editButton.textContent = '\u270E';
editButton.className = 'edit-button';
return editButton;
},
setUpEventListeners: function () {
var todosUl = document.querySelector('ul');
todosUl.addEventListener('click', function (event) {
// Get the element that was clicked on.
var elementClicked = event.target;
// Check if elementClicked is a delete button.
if (elementClicked.className === 'delete-button') {
handlers.deleteTodo(parseInt(elementClicked.parentNode.id));
} else if (elementClicked.className === 'toggle-button') {
handlers.toggleCompleted(parseInt(elementClicked.parentNode.id));
} else if (elementClicked.className === 'save-button') {
handlers.changeTodo(parseInt(elementClicked.parentNode.id));
} else if (elementClicked.className === 'edit-button') {
}
});
}
};
view.setUpEventListeners();
body {
font-family: Helvetica, sans-serif;
font-size: 25px;
background: rgb(236, 236, 236);
}
h1 {
color: rgb(255, 255, 255);
text-align: center;
font-family: Helvetica, sans-serif;
font-size: 50px;
text-transform: uppercase;
background: rgb(48, 48, 48);
position: relative;
}
.container {
margin: auto;
width: 50%;
}
ul {
list-style: none;
padding:0px;
margin: 10px;
}
.add-button {
background-color: rgb(68, 165, 230); /* Blue */
border: none;
color: white;
margin:auto;
padding: 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 5px;
width:20%;
}
.add-button:hover {
background-color :rgb(53, 127, 177); /* Green */
color: white;
}
.save-change-button {
background-color: rgb(68, 165, 230); /* Blue */
border: none;
color: white;
margin:auto;
padding: 15px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 5px;
width:20%;
}
.save-change-button:hover {
background-color :rgb(53, 127, 177); /* Green */
color: white;
}
.toggle-all-button {
background-color: rgb(38, 156, 38); /* Green */
border: none;
color: white;
margin: 10px 0;
padding: 15px 32px;
text-align: center;
text-decoration: none;
font-size: 16px;
border-radius: 5px;
width: 100%;
}
.toggle-all-button:hover {
background-color : rgb(36, 114, 36); /* Green */
color: white;
}
.edit-button {
background-color: rgb(219, 208, 50); /* Green */
border: none;
color: white;
padding: 0;
text-align: center;
text-decoration: none;
font-size: 18px;
border-radius: 5px;
width: 25px;
height: 25px;
margin: 0 0 0 10px;
}
.edit-button:hover {
background-color: rgb(185, 175, 26); /* Green */
color: white;
}
.toggle-button {
background-color: rgb(38, 156, 38); /* Green */
border: none;
color: white;
padding: 0;
text-align: center;
text-decoration: none;
font-size: 18px;
border-radius: 5px;
width: 25px;
height: 25px;
margin: 0 0 0 10px;
}
.toggle-button:hover {
background-color: rgb(36, 114, 36); /* Green */
color: white;
}
.delete-button {
background-color: rgb(168, 44, 44); /* Green */
border: none;
color: white;
margin: 0 0 0 10px;
padding: 0;
text-align: center;
text-decoration: none;
font-size: 18px;
border-radius: 5px;
width: 25px;
height: 25px;
}
.delete-button:hover {
background-color :rgb(128, 31, 31); /* Green */
color: white;
}
.save-button {
background-color: rgb(219, 208, 50); /* Green */
border: none;
color: white;
padding: 0;
text-align: center;
text-decoration: none;
font-size: 18px;
border-radius: 5px;
width: 55px;
height: 25px;
margin: 0 10px;
}
.save-button:hover {
background-color :rgb(185, 175, 26); /* Green */
color: white;
}
.add-input {
margin: 10px 0;
padding: 6px 0;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
width: 78%;
}
.edit-input {
margin: 10px 0;
padding: 6px 0;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
font-size: 18px;
width: 78%;
}
.item-completed {
text-decoration: line-through;
}
::placeholder { /* Chrome, Firefox, Opera, Safari 10.1+ */
color: rgba(209, 209, 209, 0.555);
font-family: 'Times New Roman', Times, serif;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Todo List</title>
<link href="index.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="container">
<h1>Todo List</h1>
<div>
<input id="add-todo-text-input" class="add-input" placeholder="Add a New Todo to Your List" type="text">
<button class="add-button" onclick="handlers.addTodo()">Add</button>
</div>
<ul>
</ul>
<div id="edit-todo"">
<input id="change-todo-text-input" class="edit-input" placeholder="Add the Changes Your Want to Make" type="text">
<button class="save-change-button">Save</button>
</div>
<div id="toggle-all"">
<button class="toggle-all-button" onclick="handlers.toggleAllButton()">Toggle All</button>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
You can add a common class to both blue and yellow buttons, and attach a click event by the class name like below
$(".custom_save_button").on("click", function() {
//your code
});
Since you are creating that button, sharing the same class won't just work as expected, instead use delegated events which allow you to attach events on new elements added to the DOM
Add a common class for both and then add an event listener for that class using event delegation.
For this example Let's suppose you chose the class name: stack_class
//I added this function for you to be able to know if an element has a class
function hasClass( target, className ) {
return new RegExp('(\\s|^)' + className + '(\\s|$)').test(target.className);
}
//you could change body to the closest parent's selector both buttons share
document.querySelector('body').addEventListener('click', function(event) {
var clickedElement = event.target;
if(hasClass(clickedElement, "stack_class")) {
//create your functionality for both buttons here
}
});
If you assign a common class to both buttons, then you can add the same event listener to all buttons that have that class. Here is a simple example:
var saveButton = document.createElement('button');
saveButton.textContent = 'Save';
saveButton.className = 'save-button yellow-button';
body = document.querySelector('body');
body.appendChild(saveButton);
buttons = document.getElementsByClassName('save-button');
for (var i = 0; i < buttons.length; i += 1) {
buttons[i].addEventListener('click', function (event) {
alert('Hello!');
});
}
.yellow-button {
background: #ffff00;
}
.blue-button {
background: #0000ff;
}
<button class="save-button blue-button">Save</button>