Tip calculator javascript - javascript

I am creating a tip calculator which calculates tip amount based on bill amount, tip percentage, and the number of people (which are all inputs by the user). I have created a script using Javascript but it's not working and I am not sure why. Am I calling the function in the wrong way? Did I make any mistakes in the function or in the for loop? I apologize for the messed-up layout of the calculator in the snippet, I am going with a mobile-first approach and still working on the desktop layout.
let allButtons = document.getElementsByClassName('btn');
let noOfButtons = allButtons.length;
let i;
function tipCalculate(e) {
let billAmount = parseFloat(document.getElementById('bill__amount').value);
let tipPercent = e.target.value;
let noOfPeople = document.getElementById('people-no').value;
let tipAmountPerPerson = billAmount / 100 * tipPercent / noOfPeople;
let totalAmountPerPerson = (billAmount + (billAmount / 100 * tipPercent)) / noOfPeople;
document.getElementByClassName('tip-amount-display').innerHTML = tipAmountPerPerson;
document.getElementByClassName('total-amount-display').innerHTML = totalAmountPerPerson;
}
// append event listeners to each button
for (i = 0; i < noOfButtons; i++) {
allButtons[i].addEventListener('click', tipCalculate);
}
#import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght#400;700&display=swap');
:root {
--clr-primary: hsl(172, 67%, 45%);
--clr-neutral-100: hsl(0, 0%, 100%);
--clr-neutral-200: hsl(189, 41%, 97%);
--clr-neutral-300: hsl(185, 41%, 84%);
--clr-neutral-400: hsl(184, 14%, 56%);
--clr-neutral-500: hsl(186, 14%, 43%);
--clr-neutral-600: hsl(183, 100%, 15%);
}
*,
*::after,
*::before {
box-sizing: border-box;
}
h2 {
margin: 0;
font-size: 1rem;
}
body {
margin: 0;
font-family: 'Space Mono', monospace;
background: var(--clr-neutral-300);
font-size: 1rem;
font-weight: 400;
}
button {
font-family: 'Space Mono', monospace;
text-transform: uppercase;
border: none;
padding: 0.3em 0.6em;
border-radius: 0.45rem;
font-size: 1.4rem;
font-weight: 700;
}
.btn-main {
background-color: var(--clr-neutral-600);
color: var(--clr-neutral-100);
}
.btn-main:hover,
.btn-main:focus {
background-color: var(--clr-primary);
color: var(--clr-neutral-600);
}
.btn-inverse {
background-color: var(--clr-primary);
color: var(--clr-neutral-600);
}
.title {
color: var(--clr-neutral-500);
text-align: center;
letter-spacing: .35em;
padding: 1em 0;
}
form {
background: var(--clr-neutral-100);
border-radius: 1.8rem 1.8rem 0 0;
}
.accent-title {
color: var(--clr-neutral-500);
}
.accent-title-light {
color: var(--clr-neutral-400);
font-size: .8rem;
}
.tip-amount {
background: var(--clr-neutral-600);
border-radius: 1rem;
padding: 1.6rem;
display: flex;
/* flex-direction: column; */
flex-wrap: wrap;
justify-content: space-between;
}
.neutral-title {
color: var(--clr-neutral-100);
}
input {
border: none;
background-color: var(--clr-neutral-200);
width: 100%;
border-radius: .25rem;
}
.bill__amount,
.people-no {
height: 40px;
text-align: right;
font-family: 'Space Mono', monospace;
font-size: 24px;
font-weight: 700;
color: var(--clr-neutral-600);
padding-right: .8rem;
}
.bill__amount {
background-image: url(../images/icon-dollar.svg);
background-repeat: no-repeat;
background-position: left center;
background-origin: content-box;
padding-left: .8rem;
}
.people-no {
background-image: url(../images/icon-person.svg);
background-repeat: no-repeat;
background-position: left center;
background-origin: content-box;
padding-left: .8rem;
}
div+div {
margin-top: 2em;
}
.calculator {
padding: 2rem;
}
.tip__btns {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.accent-title-light {
margin-top: 0%;
}
.reset {
width: 100%;
margin-top: 1rem;
}
.tip__heading {
margin-bottom: .9rem;
}
.tip__custom {
font-family: 'Space Mono', monospace;
font-size: 1.3rem;
font-weight: 700;
letter-spacing: .1rem;
text-align: right;
padding-right: .8rem;
}
.bill__heading,
.no-of-people__heading {
margin-bottom: .6rem;
}
.tip-amount-display,
.total-amount-display {
/* text-align: right; */
color: var(--clr-primary);
font-size: 24px;
}
.total-amount-display {
margin-top: 1.25rem;
}
.tip-amount-display {
align-self: start;
margin-top: .4rem;
}
.col+.col {
margin-top: 0;
}
#media (min-width: 768px) {
form {
display: flex;
flex-direction: row;
justify-content: space-between;
align-content: stretch;
width: 50%;
margin: 0 auto;
border-radius: 1.8rem 1.8rem 1.8rem 1.8rem;
}
form>* {
flex: 1 1 50%;
}
.attribution {
align-self: flex-end;
}
div+div {
margin-top: 0;
}
}
.attribution {
font-size: 11px;
text-align: center;
}
.attribution a {
color: hsl(228, 45%, 44%);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- displays site properly based on user's device -->
<link rel="stylesheet" href="css/style.css">
<link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
<script src="js/tip.js"></script>
<title>Frontend Mentor | Tip calculator app</title>
</head>
<body>
<h1 class="title">SPLI<br>TTER</h1>
<form class="calculator">
<div class="main-cols">
<div class="bill">
<h2 class="bill__heading"><label for="bill__amount" class="accent-title">Bill</label></h2>
<input type="text" name="bill__amount" id="bill__amount" class="bill__amount" placeholder="0">
</div>
<div class="tip">
<h2 class="tip__heading"><label for="" class="accent-title">Select Tip %</label></h2>
<div class="tip__btns">
<button type="button" class="btn btn-main">5%</button>
<button type="button" class="btn btn-main">10%</button>
<button type="button" class="btn btn-main">15%</button>
<button type="button" class="btn btn-main">25%</button>
<button type="button" class="btn btn-main">50%</button>
<input type="text" name="tip__custom" class="tip__custom" id="tip__custom" placeholder="Custom">
</div>
</div>
<div class="no-of-people">
<h2 class="no-of-people__heading"><label for="people-no" class="accent-title">Number of People</label></h2>
<input type="text" name="people-no" id="people-no" class="people-no" placeholder="0">
</div>
</div>
<div class="main-cols">
<div class="tip-amount">
<div class="col">
<h2 class="neutral-title">Tip Amount</h2>
<h3 class="accent-title-light ">/ person</h3>
<h2 class="neutral-title">Total</h2>
<h3 class="accent-title-light">/ person</h3>
</div>
<div class="col">
<h2 class="tip-amount-display">$0.00</h2>
<h2 class="total-amount-display">$0.00</h2>
</div>
<button class="btn-inverse reset">Reset</button>
</div>
</div>
<div class="attribution">
Challenge by Frontend Mentor. Coded by Sachin Jadhav.
</div>
</form>
</body>
</html>

Issue 1
It's getElementsByClassName not getElementByClassName (you are missing the 's').
Here is how to use it: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName
Specifically document.getElementsByClassName('test')[0] will be of interest for you, to get the first element with that class.
Your code will look like this:
document.getElementsByClassName('tip-amount-display')[0].innerHTML = tipAmountPerPerson;
// ^ ^
Alternatively you can use querySelector to find an element in the DOM using css selectors.
Issue 2.1
e.target.value is always an empty string (doing math with it will result in NaN).
This is because the HTML Element that was clicked did not have a value property on it. To fix it add value="5" to the Buttons in your HTML like this:
<button type="button" value="5" class="btn btn-main">5%</button>
<button type="button" value="10" class="btn btn-main">10%</button>
<!-- ... -->
Issue 2.2
document.getElementById('people-no').value is also an empty string when no value was entered. To fix it you can check for it's truthiness as the empty string and 0 will be falsy you can replace them with 1.
Long version:
let noOfPeople = document.getElementById('people-no').value;
if (!noOfPeople) {
noOfPeople = 1;
}
Short version using short circuit evaluation:
let noOfPeople = document.getElementById('people-no').value || 1;
Here is a working fiddle: https://jsfiddle.net/zg6t4o1a/

let button = document.querySelector("button");
let fun = () => { let totalamount = +document.getElementById("amount").value let select = +document.getElementById("select").value; let totalpeople = +document.getElementById("peo").value; let finale =document.getElementById("h3");let absolute = (totalamount * select) / totalpeople; finale.textContent = absolute;if (totalamount <= 0) { alert("Your entered value is invalid"); }};button.addEventListener("click", fun);

Related

How to .appendChild() to all elements with the same class

The blue F turns into an actual amount of weight when you enter a number into the input field above.
The Two Functions Kg() and Lbs() are changing the class .dynamic which is where Kg or Lbs is being appended to the 8 divs that have the .dynamic class. Now that's exactly what isn't happening. When I select the divs with the .dynamic class, It adds Kg or Lbs (whatever button I press) to the first element with the .dynamic class.
How do I make it so that it appends that to all of the elements with the .dynamic class?
//Variables
const mercury = document.getElementById("mercury");
const venus = document.getElementById("venus");
const earth = document.getElementById("earth");
const mars = document.getElementById("mars");
const jupiter = document.getElementById("jupiter");
const saturn = document.getElementById("saturn");
const uranus = document.getElementById("uranus");
const neptune = document.getElementById("neptune");
const weight = document.getElementById("weight");
weight.addEventListener("input", Calc);
function Calc() {
if (weight.value > 99999) {
alert("Max Amount Of Numbers is 99999");
weight.value = "";
} else {
var val = weight.value;
console.log(val);
var calculate = val * 0.38;
calculate = Math.round(calculate);
mercury.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.9;
calculate = Math.round(calculate);
venus.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 1;
calculate = Math.round(calculate);
earth.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.38;
calculate = Math.round(calculate);
mars.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 2.36;
calculate = Math.round(calculate);
jupiter.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.92;
calculate = Math.round(calculate);
saturn.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.89;
calculate = Math.round(calculate);
uranus.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 1.12;
calculate = Math.round(calculate);
neptune.innerHTML = calculate;
console.log(calculate);
}
}
function lbs() {
let unit = document.getElementById("unit");
if (unit == null) {
let newElement = document.createElement("h3");
newElement.setAttribute("class", "value");
newElement.setAttribute("id", "unit");
newElement.textContent = "Lbs";
document.querySelector(".dynamic").appendChild(newElement);
} else {
if (unit.innerHTML == "Kg") {
unit.innerHTML = "Lbs";
}
}
}
function kg() {
let unit = document.getElementById("unit");
if (unit == null) {
let newElement = document.createElement("h3");
newElement.setAttribute("class", "value");
newElement.setAttribute("id", "unit");
newElement.textContent = "Kg";
document.querySelector(".dynamic").appendChild(newElement);
} else {
if (unit.innerHTML == "Lbs") {
unit.innerHTML = "Kg";
}
}
}
#import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
#font-face {
font-family: SpaceQuest;
src: url(https://raw.githubusercontent.com/Lemirq/WODP/master/Fonts/SpaceQuest-yOY3.woff);
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
}
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: url(./dario-bronnimann-hNQwIirOseE-unsplash.jpg);
}
/* Handle */
::-webkit-scrollbar-thumb {
background: rgba(59, 59, 59, 0.741);
border-radius: 200px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: rgb(255, 255, 255);
}
* {
--c-light: #f4f4f4;
--c-dark: #141414;
--c-blue: rgb(10, 132, 255);
--f-body: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
--trans-ease-in-out: all 0.2s ease-in-out;
color: var(--c-light);
}
body {
background-image: url(https://raw.githubusercontent.com/Lemirq/WODP/master/images/dario-bronnimann-hNQwIirOseE-unsplash.jpg);
margin: 0;
inset: 50px;
font-family: var(--f-body);
}
a {
color: var(--c-light);
text-decoration: none;
}
/***** NAVBAR *****/
.nav-item {
transition: var(--trans-ease-in-out);
}
.ext-link {
cursor: alias;
}
.nav-item:hover {
color: var(--c-dark);
background-color: var(--c-light);
}
.nav-item:hover li {
color: var(--c-dark);
}
.nav-item.icon-link:hover i {
color: var(--c-dark);
}
.nav-item:not(:last-child) {
margin-right: 20px;
}
navbar {
display: flex;
flex-direction: row;
justify-content: end;
align-items: center;
padding: 20px;
}
.nav-item-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
}
.nav-item {
display: inline-block;
list-style: none;
padding: 10px;
font-size: 20px;
border-radius: 10px;
}
.gh-icon {
font-size: 30px;
}
/***** End NAVBAR *****/
/***** Main *****/
#wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
h1 {
font-family: SpaceQuest, sans-serif;
font-size: 3.5rem;
}
.input-group {
border: 2px var(--c-light) solid;
border-radius: 10px;
/* max-width: 400px; */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-top: 50px;
}
[type="number"]:focus {
outline: none;
}
[type="number"] {
font-size: 20px;
padding: 5px;
background-color: rgba(217, 217, 217, 0.2);
border: none;
font-family: var(--f-body);
min-width: 280px;
}
.btn-form {
font-size: 20px;
padding: 5px;
background-color: rgba(217, 217, 217, 0.2);
border: none;
transition: var(--trans-ease-in-out);
cursor: pointer;
font-family: var(--f-body);
}
.btn-form:hover {
background-color: rgba(217, 217, 217, 0.4);
}
.btn-form:first {
border-right: var(--c-light) 1px solid;
}
.input-group-text {
background-color: rgba(217, 217, 217, 0.2);
font-size: 17px;
padding: 7px;
}
/***** End Main *****/
/***** CARDS *****/
.card-container {
margin: 50px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
align-items: center;
grid-gap: 10px;
width: calc(100vw - 200px);
}
.card {
background-color: #141414;
width: auto;
height: auto;
border-radius: 10px;
padding: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175);
}
.planet-info {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.planet {
font-size: 50px;
margin: 0;
text-transform: capitalize;
}
.planet-img {
width: 80px;
height: auto;
margin-right: 30px;
}
[src="./images/planets/Saturn.png"] {
height: 79.25px;
width: auto;
}
.weight {
margin-top: 10px;
text-transform: capitalize;
font-size: 20px;
}
.weight::after {
content: ":";
}
.divider {
height: 1px;
width: 100%;
margin: 20px 0;
background-color: var(--c-light);
}
.value {
font-size: 60px;
color: var(--c-blue);
}
.dynamic>.value:nth-child(2) {
margin-left: 10px;
}
.dynamic {
display: flex;
flex-direction: row;
justify-content: space-between;
}
/***** End CARDS *****/
.input-error {
outline: 1px solid red;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.8.3/font/bootstrap-icons.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<navbar>
<ul class="nav-item-container">
<a target="_blank" class="nav-item ext-link" href="https://lemirq.github.io">
<li>Website</li>
</a>
<a target="_blank" class="nav-item icon-link ext-link" href="https://github.com/Lemirq">
<li><i class="bi bi-github gh-icon"></i></li>
</a>
</ul>
</navbar>
<div id="wrapper">
<h1 id="vs-h1">Your Weight On Different Planets</h1>
<div class="input-group">
<input id="weight" placeholder="Enter your Weight" type="number">
<button id="kg" onclick="kg()" class="btn-form" type="button">Kg</button>
<button id="lbs" onclick="lbs()" class="btn-form" type="button">Lbs</button>
</div>
<div class="card-container">
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Mercury.png" alt="EARTH">
<h3 class="planet">mercury</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="mercury" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Venus.png" alt="EARTH">
<h3 class="planet">venus</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="venus" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Earth.png" alt="EARTH">
<h3 class="planet">earth</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="earth" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Mars.png" alt="EARTH">
<h3 class="planet">mars</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="mars" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Jupiter.png" alt="EARTH">
<h3 class="planet">jupiter</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="jupiter" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Saturn.png" alt="EARTH">
<h3 class="planet">saturn</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="saturn" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Uranus.png" alt="EARTH">
<h3 class="planet">uranus</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="uranus" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Neptune.png" alt="EARTH">
<h3 class="planet">neptune</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="neptune" class="value">F</h3>
</div>
</div>
</div>
</div>
Select all elements with the .dynamic class by using querySelectorAll
Iterate through the NodeList and append desired child to each node
let dynamics = document.querySelectorAll(".dynamic")
dynamics.forEach((ele) => {
let newElement = document.createElement("h3");
ele.appendChild(newElement);
}
Minor Problems
There's no such HTML element <navbar>, there's <nav>.
There's a block code hard-coded 8 times with the only difference between them is a number. Whenever code needs to repeat itself, we use some sort of iteration such as a for loop or an array method and the numbers would be passed as a single variable passed with every iteration.
const gforce = [0.38, 0.9, 1, 0.38, 2.36, 0.92, 0.89, 1.12];
for (let i=0; i < 8; i++) {
var val = weight.value;
console.log(val);
var calculate = val * gforce[i];//<== that should be a variable
calculate = Math.round(calculate);
venus.innerHTML = calculate;
console.log(calculate);
}
Also, the <input> that's supposed to calculate lbs and kg doesn't appear to convert kg to lbs or vice-versa.
Details are commented in example
// An array of objects - each object represents a planet
const data = [{
planet: 'Mercury',
gforce: 0.38,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Mercury_in_true_color.jpg/440px-Mercury_in_true_color.jpg`
},
{
planet: 'Venus',
gforce: 0.9,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/0/08/Venus_from_Mariner_10.jpg/440px-Venus_from_Mariner_10.jpg`
},
{
planet: 'Earth',
gforce: 1,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/The_Blue_Marble_%28remastered%29.jpg/440px-The_Blue_Marble_%28remastered%29.jpg`
},
{
planet: 'Mars',
gforce: 0.38,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/OSIRIS_Mars_true_color.jpg/440px-OSIRIS_Mars_true_color.jpg`
},
{
planet: 'Jupiter',
gforce: 2.36,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/2/2b/Jupiter_and_its_shrunken_Great_Red_Spot.jpg/440px-Jupiter_and_its_shrunken_Great_Red_Spot.jpg`
},
{
planet: 'Saturn',
gforce: 0.92,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Saturn_during_Equinox.jpg/600px-Saturn_during_Equinox.jpg`
},
{
planet: 'Uranus',
gforce: 0.89,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png/440px-Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png`
},
{
planet: 'Neptune',
gforce: 1.12,
img: `https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Neptune_-_Voyager_2_%2829347980845%29_flatten_crop.jpg/440px-Neptune_-_Voyager_2_%2829347980845%29_flatten_crop.jpg`
}
];
// Reference <form> and all form controls
const conv = document.forms.converter;
const IO = conv.elements;
/*
Collect all tags with [name='planet'] and convert it into an array...
...iterate through array and define a htmlString and interpolate planet
name and <img> url...
...render htmlString into current <output>
*/
[...IO.planet].forEach((output, index) => {
const html = `
<h3>${data[index].planet}</h3>
<img src='${data[index].img}'>
<h4></h4>`;
output.insertAdjacentHTML('beforeend', html)
});
// Bind the "input" event to <form>
conv.oninput = IWC;
/*
Event handler passes Event Object by default
Reference all form controls
Reference the tag the user interacted with
If the user typed into [name='weight']...
...if that tag was also #lbs...
...#kg value is the value of >origin< times 0.45359237...
...otherwise #lbs value is the value of >origin< times 2.20462...
*/
/*
Collect all [name='planet'] into an array and iterate with .forEach()...
...clear out the last tag of current <output> (<h4>)...
...display the calculated totals for lbs. and kg of each planet
*/
function IWC(e) {
const IO = this.elements;
const origin = e.target;
if (origin.name === 'weight') {
if (origin.id === 'lbs') {
IO.kg.value = +origin.value * 0.45359237;
} else {
IO.lbs.value = +origin.value * 2.20462;
}
[...IO.planet].forEach((output, index) => {
output.lastElementChild.innerHTML = '';
output.lastElementChild.insertAdjacentHTML('beforeend',
`lbs. ${Math.round(data[index].gforce * IO.lbs.value)}<br>
kg ${Math.round(data[index].gforce * IO.kg.value)}`);
});
}
}
#import url('https://fonts.googleapis.com/css2?family=Oswald:wght#300&family=Raleway:wght#300&display=swap');
html {
font: 300 2ch/1 Oswald;
}
body {
width: 100%;
overflow-x: hidden;
background: #aaa
}
h1 {
color: gold
}
h1,
h2,
h3,
h4 {
margin: 0;
font-family: Raleway;
}
h3,
h4 {
position: absolute;
z-index: 1;
}
h3 {
margin: 0 auto;
}
h4 {
bottom: 0
}
form {
margin: 0 0 0 -15px;
}
fieldset {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: center;
max-width: 90%;
margin: 15px
}
fieldset+fieldset {
background: #222
}
fieldset+fieldset legend {
color: gold
}
output {
position: relative;
display: inline-flex;
width: 24%;
min-height: 8rem;
margin-top: 15px;
padding: 2px;
background: black;
color: cyan
}
input {
font: inherit;
width: 10rem;
margin: 10px;
text-align: center;
}
img {
width: 100%;
}
<form id='converter'>
<fieldset>
<legend>
<h1>Interplanetary<br>Weight Converter</h1>
</legend>
<input id="lbs" name='weight' placeholder=" Weight in lbs." type="number" min='0' max='99999'><label for='lbs'>lbs.</label>
<input id="kg" name='weight' placeholder="Weight in kg." type="number" min='0' max='99999'><label for='kg'>kg</label>
</fieldset>
<fieldset>
<legend>
<h2>The Solar System</h2>
</legend>
<output name='planet'></output>
<output name='planet'></output>
<output name='planet'></output>
<output name='planet'></output>
<output name='planet'></output>
<output name='planet'></output>
<output name='planet'></output>
<output name='planet'></output>
</fieldset>
</form>
The script must look something like this:
<script>
let elements = document.querySelectorAll(".dynamic")
elements.forEach(el=>{
let child = document.createElement('div')
el.appendChild(child)
})
</script>
This can be simplified quite a bit, the buttons' innerHTML values match what you want in the new unit elements.
<button id="kg" class="btn-form" type="button">Kg</button>
<button id="lbs" class="btn-form" type="button">Lbs</button>
Use JavaScript to add an event listener to both unit buttons that call the same function which will update the innerHTML of the unit headings to match the clicked button. When initializing the unit heading elements you should not give them all the same id but rather a common class and you must also append a cloned copy of the element or it will just move the element form one spot to the next:
document.querySelectorAll('#kg, #lbs').forEach(ub => ub.addEventListener('click', units));
function units(e) {
let units = document.querySelectorAll(".value.unit");
if (units.length == 0) {
let newElement = document.createElement("h3");
newElement.setAttribute("class", "value unit");
document.querySelectorAll(".dynamic").forEach((dyn) => {
// append a cloned copy to each, not the same newElement
dyn.appendChild(newElement.cloneNode())
});
// re-run the query to find the newly added nodes
units = document.querySelectorAll(".value.unit");
}
// set the content
units.forEach(unit => unit.innerHTML = e.target.innerHTML);
}
//Variables
const mercury = document.getElementById("mercury");
const venus = document.getElementById("venus");
const earth = document.getElementById("earth");
const mars = document.getElementById("mars");
const jupiter = document.getElementById("jupiter");
const saturn = document.getElementById("saturn");
const uranus = document.getElementById("uranus");
const neptune = document.getElementById("neptune");
const weight = document.getElementById("weight");
weight.addEventListener("input", Calc);
function Calc() {
if (weight.value > 99999) {
alert("Max Amount Of Numbers is 99999");
weight.value = "";
} else {
var val = weight.value;
console.log(val);
var calculate = val * 0.38;
calculate = Math.round(calculate);
mercury.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.9;
calculate = Math.round(calculate);
venus.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 1;
calculate = Math.round(calculate);
earth.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.38;
calculate = Math.round(calculate);
mars.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 2.36;
calculate = Math.round(calculate);
jupiter.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.92;
calculate = Math.round(calculate);
saturn.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 0.89;
calculate = Math.round(calculate);
uranus.innerHTML = calculate;
console.log(calculate);
var val = weight.value;
console.log(val);
var calculate = val * 1.12;
calculate = Math.round(calculate);
neptune.innerHTML = calculate;
console.log(calculate);
}
}
document.querySelectorAll('#kg, #lbs').forEach(ub => ub.addEventListener('click', units));
function units(e) {
let units = document.querySelectorAll(".value.unit");
if (units.length == 0) {
let newElement = document.createElement("h3");
newElement.setAttribute("class", "value unit");
document.querySelectorAll(".dynamic").forEach((dyn) => {
// append a cloned copy to each, not the same newElement
dyn.appendChild(newElement.cloneNode())
});
// re-run the query to find the newly added nodes
units = document.querySelectorAll(".value.unit");
}
// set the content
units.forEach(unit => unit.innerHTML = e.target.innerHTML);
}
#import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");
#font-face {
font-family: SpaceQuest;
src: url(https://raw.githubusercontent.com/Lemirq/WODP/master/Fonts/SpaceQuest-yOY3.woff);
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
}
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: url(./dario-bronnimann-hNQwIirOseE-unsplash.jpg);
}
/* Handle */
::-webkit-scrollbar-thumb {
background: rgba(59, 59, 59, 0.741);
border-radius: 200px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: rgb(255, 255, 255);
}
* {
--c-light: #f4f4f4;
--c-dark: #141414;
--c-blue: rgb(10, 132, 255);
--f-body: "Montserrat", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
--trans-ease-in-out: all 0.2s ease-in-out;
color: var(--c-light);
}
body {
background-image: url(https://raw.githubusercontent.com/Lemirq/WODP/master/images/dario-bronnimann-hNQwIirOseE-unsplash.jpg);
margin: 0;
inset: 50px;
font-family: var(--f-body);
}
a {
color: var(--c-light);
text-decoration: none;
}
/***** NAVBAR *****/
.nav-item {
transition: var(--trans-ease-in-out);
}
.ext-link {
cursor: alias;
}
.nav-item:hover {
color: var(--c-dark);
background-color: var(--c-light);
}
.nav-item:hover li {
color: var(--c-dark);
}
.nav-item.icon-link:hover i {
color: var(--c-dark);
}
.nav-item:not(:last-child) {
margin-right: 20px;
}
navbar {
display: flex;
flex-direction: row;
justify-content: end;
align-items: center;
padding: 20px;
}
.nav-item-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin: 0;
padding: 0;
}
.nav-item {
display: inline-block;
list-style: none;
padding: 10px;
font-size: 20px;
border-radius: 10px;
}
.gh-icon {
font-size: 30px;
}
/***** End NAVBAR *****/
/***** Main *****/
#wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
h1 {
font-family: SpaceQuest, sans-serif;
font-size: 3.5rem;
}
.input-group {
border: 2px var(--c-light) solid;
border-radius: 10px;
/* max-width: 400px; */
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-top: 50px;
}
[type="number"]:focus {
outline: none;
}
[type="number"] {
font-size: 20px;
padding: 5px;
background-color: rgba(217, 217, 217, 0.2);
border: none;
font-family: var(--f-body);
min-width: 280px;
}
.btn-form {
font-size: 20px;
padding: 5px;
background-color: rgba(217, 217, 217, 0.2);
border: none;
transition: var(--trans-ease-in-out);
cursor: pointer;
font-family: var(--f-body);
}
.btn-form:hover {
background-color: rgba(217, 217, 217, 0.4);
}
.btn-form:first {
border-right: var(--c-light) 1px solid;
}
.input-group-text {
background-color: rgba(217, 217, 217, 0.2);
font-size: 17px;
padding: 7px;
}
/***** End Main *****/
/***** CARDS *****/
.card-container {
margin: 50px;
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
align-items: center;
grid-gap: 10px;
width: calc(100vw - 200px);
}
.card {
background-color: #141414;
width: auto;
height: auto;
border-radius: 10px;
padding: 30px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175);
}
.planet-info {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.planet {
font-size: 50px;
margin: 0;
text-transform: capitalize;
}
.planet-img {
width: 80px;
height: auto;
margin-right: 30px;
}
[src="./images/planets/Saturn.png"] {
height: 79.25px;
width: auto;
}
.weight {
margin-top: 10px;
text-transform: capitalize;
font-size: 20px;
}
.weight::after {
content: ":";
}
.divider {
height: 1px;
width: 100%;
margin: 20px 0;
background-color: var(--c-light);
}
.value {
font-size: 60px;
color: var(--c-blue);
}
.dynamic>.value:nth-child(2) {
margin-left: 10px;
}
.dynamic {
display: flex;
flex-direction: row;
justify-content: space-between;
}
/***** End CARDS *****/
.input-error {
outline: 1px solid red;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.8.3/font/bootstrap-icons.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<navbar>
<ul class="nav-item-container">
<a target="_blank" class="nav-item ext-link" href="https://lemirq.github.io">
<li>Website</li>
</a>
<a target="_blank" class="nav-item icon-link ext-link" href="https://github.com/Lemirq">
<li><i class="bi bi-github gh-icon"></i></li>
</a>
</ul>
</navbar>
<div id="wrapper">
<h1 id="vs-h1">Your Weight On Different Planets</h1>
<div class="input-group">
<input id="weight" placeholder="Enter your Weight" type="number">
<button id="kg" class="btn-form" type="button">Kg</button>
<button id="lbs" class="btn-form" type="button">Lbs</button>
</div>
<div class="card-container">
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Mercury.png" alt="EARTH">
<h3 class="planet">mercury</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="mercury" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Venus.png" alt="EARTH">
<h3 class="planet">venus</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="venus" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Earth.png" alt="EARTH">
<h3 class="planet">earth</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="earth" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Mars.png" alt="EARTH">
<h3 class="planet">mars</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="mars" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Jupiter.png" alt="EARTH">
<h3 class="planet">jupiter</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="jupiter" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Saturn.png" alt="EARTH">
<h3 class="planet">saturn</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="saturn" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Uranus.png" alt="EARTH">
<h3 class="planet">uranus</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="uranus" class="value">F</h3>
</div>
</div>
<div class="card">
<div class="planet-info">
<img class="planet-img" src="./images/planets/Neptune.png" alt="EARTH">
<h3 class="planet">neptune</h3>
</div>
<div class="divider"></div>
<h4 class="weight">weight</h4>
<div class="dynamic">
<h3 id="neptune" class="value">F</h3>
</div>
</div>
</div>
</div>

Change a button onclick href based on multiple IDs

I have an order summary. The order summary is a collection of 5 different HTML IDs based on user selection. I'm trying to get the "checkout button" to link to different URLs based on different configurations corresponding to different HTML IDs.
For example, if the user selects "BRAZIL", "2 BAGS", "WHOLE BEAN", "EVERY 4 WEEKS", "ALL ROAST TYPES" the checkout button would take them to a specific URL and so on specific for that selection. If they make a different selection, they should be taken to a different URL.
I'm assuming a for loop and if... else statement would do the trick but I can't seem to figure it out. I feel like I'm close but maybe I'm way off.
What I currently have:
// CHECKOUT BUTTON CONDITIONALS
function checkoutButton() {
let checkoutBtnClick = document.querySelectorAll("#change-coffee, #change-bag, #change-grind-type, #change-delivery, #change-roast-type").innerHTML;
if (checkoutBtnClick === "BRAZIL", "2 BAGS", "WHOLE BEAN", "EVERY 4 WEEKS", "ALL ROAST TYPES") {
document.getElementById("box-summary-checkout-button").setAttribute('onclick', 'window.location.href="https://www.google.com/"');
} else if (checkoutBtnClick === "BRAZIL", "2 BAGS", "GROUND", "EVERY 4 WEEKS", "ALL ROAST TYPES") {
document.getElementById("box-summary-checkout-button").setAttribute('onclick', 'window.location.href="https://www.facebook.com/"');
}
}
/* ORDER SUMMARY */
.container-summary {
display: flex;
border: 3px solid none;
justify-content: center;
margin-bottom: 50px;
font-family: 'lato', sans-serif;
}
.box-summary {
height: 20.5rem;
width: 30rem;
background: #eee;
border-radius: 6px;
}
.box-summary-title {
display: flex;
justify-content: center;
font-size: 20px;
font-weight: 600;
letter-spacing: .03rem;
margin-top: 25px;
color: #433d3d;
line-height: .95em;
}
.box-summary-block {
display: flex;
justify-content: space-around;
margin: 1rem 3rem;
font-size: 13px;
font-weight: 600;
letter-spacing: .03rem;
line-height: 1.9em;
color: #393939;
}
.box-summary-block-coffee {
display: flex;
justify-content: center;
margin: 1rem 4rem;
font-size: 13px;
font-weight: 600;
letter-spacing: .03rem;
line-height: 1.9em;
color: #393939;
}
.box-summary-option-coffee {
margin-left: .75rem;
}
.box-summary-block-right {
text-align: end;
}
.box-summary-category2-left,
.box-summary-category2-right {
margin-top: .6em;
}
.box-summary-option-bags,
.box-summary-option-grind,
.box-summary-option-delivery,
.box-summary-option-roast,
.box-summary-option-coffee {
color: #3e718a;
}
.box-summary-shipment-plus-price {
display: flex;
justify-content: space-evenly;
margin-left: 60px;
margin-right: 60px;
margin-bottom: 10px;
margin-top: 20px;
font-size: 15px;
font-weight: 600;
letter-spacing: .03rem;
line-height: .95em;
color: #433d3d;
}
.box-summary-order-button-container {
display: flex;
justify-content: center;
}
.box-summary-order-button {
padding: 15px 30px 15px 30px;
font-size: 15px
}
<!--ORDER SUMMARY CONTAINER-->
<div class="container-summary">
<div class="box-summary">
<div class="box-summary-title">
ORDER SUMMARY
</div>
<div class="box-summary-block-coffee">
COFFEE SELECTION: <span class="box-summary-option-coffee" id="change-coffee">BRAZIL</span>
</div>
<div class="box-summary-block">
<div class="box-summary-block-left">
<div class="box-summary-category1-left">
# OF BAGS
</div>
<div class="box-summary-option-bags" id="change-bag">
2 BAGS
</div>
<div class="box-summary-category2-left">
GRIND TYPE
</div>
<div class="box-summary-option-grind" id="change-grind-type">
WHOLE BEAN
</div>
</div>
<div class="box-summary-block-right">
<div class="box-summary-category1-right">
DELIVERY
</div>
<div class="box-summary-option-delivery" id="change-delivery">
EVERY 4 WEEKS
</div>
<div class="box-summary-category2-right">
ROAST TYPE
</div>
<div class="box-summary-option-roast" id="change-roast-type">
ALL ROAST TYPES
</div>
</div>
</div>
<div class="box-summary-order-summary">
<div class="box-summary-shipment-plus-price">
<span class="box-summary-price-per-shipment">
PRICE PER SHIPMENT:
</span>
<span class="box-summary-order-price" id="box-summary-total-price">
$90
</span>
</div>
<div class="box-summary-order-button-container">
<button class="box-summary-order-button" id="box-summary-checkout-button" onclick="checkoutButton()">
CONTINUE TO CHECKOUT
</button>
I think what you're looking for, is something like this :
// List Shopify codes for all possible variations as a hierarchical object
let variations = {
// coffee
"BRAZIL" : {
// bag
"2 BAGS" : {
// delivery
"EVERY 4 WEEKS" : {
// roast type
"ALL ROAST TYPES" : {
// grind type
"WHOLE BEAN" :"42755456106732:1",
"GROUND" :"42755456106500:1",
...
},
...
},
...
},
...
},
...
};
// CHECKOUT BUTTON CONDITIONALS
function checkoutButton() {
// Select each node you want to process
let coffee = document.getElementById("change-coffee").innerHTML.trim().toUpperCase();
let bag = document.getElementById("change-bag").innerHTML.trim().toUpperCase();
let delivery = document.getElementById("change-delivery").innerHTML.trim().toUpperCase();
let roastType = document.getElementById("change-roast-type").innerHTML.trim().toUpperCase();
let grindType = document.getElementById("change-grind-type").innerHTML.trim().toUpperCase();
try {
// Go find the Shopify code
// If only grindType is not known, this returns 'undefined'
// If any of the other values are not known, this triggers an error
// The order of the variables should match the order in your hierarchical object
let shopifyCode = variations[coffee][bag][delivery][roastType][grindType];
if(typeof shopifyCode === 'undefined') {
// Now you also throw an error if just grindType is not known
throw "shopifyCode can't be undefined";
}
// Build your URL
const URL = `https://www.server.com/thepartthatstaysthesame/${shopifyCode}`;
// Display URL in console (useful for testing purposes)
console.log(URL);
// Visit the URL you just created
window.location.href = URL;
} catch (error) {
// Do your error handling here
console.error('Variation unknown');
}
}
You can use a map.
Also recommended to use addEventListener
Note the spread operator [...] to make an array of the node list to map
I also assume the IDs we are looking for all start with change
// CHECKOUT BUTTON CONDITIONALS
document.getElementById("box-summary-checkout-button").addEventListener("click", () => {
const parms = [...document.querySelectorAll("[id^=change]")]
.map(div => `${div.id}=${div.textContent.trim().replace(/ /g,"+")}`);
const url = `https://www.server.com/someprocesses?${parms.join("&")}`;
console.log(url);
//window.location.href = url;
})
/* ORDER SUMMARY */
.container-summary {
display: flex;
border: 3px solid none;
justify-content: center;
margin-bottom: 50px;
font-family: 'lato', sans-serif;
}
.box-summary {
height: 20.5rem;
width: 30rem;
background: #eee;
border-radius: 6px;
}
.box-summary-title {
display: flex;
justify-content: center;
font-size: 20px;
font-weight: 600;
letter-spacing: .03rem;
margin-top: 25px;
color: #433d3d;
line-height: .95em;
}
.box-summary-block {
display: flex;
justify-content: space-around;
margin: 1rem 3rem;
font-size: 13px;
font-weight: 600;
letter-spacing: .03rem;
line-height: 1.9em;
color: #393939;
}
.box-summary-block-coffee {
display: flex;
justify-content: center;
margin: 1rem 4rem;
font-size: 13px;
font-weight: 600;
letter-spacing: .03rem;
line-height: 1.9em;
color: #393939;
}
.box-summary-option-coffee {
margin-left: .75rem;
}
.box-summary-block-right {
text-align: end;
}
.box-summary-category2-left,
.box-summary-category2-right {
margin-top: .6em;
}
.box-summary-option-bags,
.box-summary-option-grind,
.box-summary-option-delivery,
.box-summary-option-roast,
.box-summary-option-coffee {
color: #3e718a;
}
.box-summary-shipment-plus-price {
display: flex;
justify-content: space-evenly;
margin-left: 60px;
margin-right: 60px;
margin-bottom: 10px;
margin-top: 20px;
font-size: 15px;
font-weight: 600;
letter-spacing: .03rem;
line-height: .95em;
color: #433d3d;
}
.box-summary-order-button-container {
display: flex;
justify-content: center;
}
.box-summary-order-button {
padding: 15px 30px 15px 30px;
font-size: 15px
}
<!--ORDER SUMMARY CONTAINER-->
<div class="container-summary">
<div class="box-summary">
<div class="box-summary-title">
ORDER SUMMARY
</div>
<div class="box-summary-block-coffee">
COFFEE SELECTION: <span class="box-summary-option-coffee" id="change-coffee">BRAZIL</span>
</div>
<div class="box-summary-block">
<div class="box-summary-block-left">
<div class="box-summary-category1-left">
# OF BAGS
</div>
<div class="box-summary-option-bags" id="change-bag">
2 BAGS
</div>
<div class="box-summary-category2-left">
GRIND TYPE
</div>
<div class="box-summary-option-grind" id="change-grind-type">
WHOLE BEAN
</div>
</div>
<div class="box-summary-block-right">
<div class="box-summary-category1-right">
DELIVERY
</div>
<div class="box-summary-option-delivery" id="change-delivery">
EVERY 4 WEEKS
</div>
<div class="box-summary-category2-right">
ROAST TYPE
</div>
<div class="box-summary-option-roast" id="change-roast-type">
ALL ROAST TYPES
</div>
</div>
</div>
<div class="box-summary-order-summary">
<div class="box-summary-shipment-plus-price">
<span class="box-summary-price-per-shipment">
PRICE PER SHIPMENT:
</span>
<span class="box-summary-order-price" id="box-summary-total-price">
$90
</span>
</div>
<div class="box-summary-order-button-container">
<button class="box-summary-order-button" id="box-summary-checkout-button">
CONTINUE TO CHECKOUT
</button>

Problem with deleting object from array of objects

I have a issue where deleting dynamically created dom object from an array of objects. The problem is that when i delete some element from the array the rest of the elements after the spliced element also gets deleted.
To my knowledge this is happening due to the index of the next elements gets updated to the one before it and the function deletes the element having the same index over and over.
How can i fix this?(Code uploaded w HTML and CSS incl.)
Is this the recommended way to implement this function?
function populateBooks(myLib, bookView) {
const bookCards = document.querySelectorAll('.book-card')
bookCards.forEach(bookCard => bookList.removeChild(bookCard));
myLib.forEach((book, index) => {
book.id = index;
const cardContent = `<div class="book-card" data-index=${book.id}>
<div class="card-info-wrapper">
<h2>${book.title}</h2>
<h3>${book.author}</h3>
<h4>${book.pages} Pages</h4>
<p>${book.info()}</p>
</div>
<div class="card-menu">
<div class="button" id="remove-btn">
Remove
</div>
</div>
</div>`
const element = document.createElement('div');
element.innerHTML = cardContent;
// element.dataset.indexx = book.id;
bookView.appendChild(element.firstChild);
const cards = document.querySelectorAll('[data-index]');
cards.forEach(card => {
const removeButton = card.querySelector('.button');
removeButton.addEventListener('click', () => {
removeBook(book.id)
})
})
});
};
function removeBook(id) {
console.log('deleting', id);
myLibrary.splice(id, 1);
console.table(myLibrary);
populateBooks(myLibrary, bookList);
}
Full code
const form = document.getElementById('input-form');
const formButton = document.getElementById('add-form');
const formView = document.querySelector('.form-card')
const bookList = document.querySelector('.books-wrapper');
let myLibrary = [];
let newBook;
function Book(title, author, pages) {
this.title = title;
this.author = author;
this.pages = pages;
this.info = function() {
return `${this.title} is a book by ${this.author}, ${this.pages} pages, not read yet.`
};
};
Book.prototype.read = false;
function addToLibrary(e) {
{
e.preventDefault();
const title = (document.getElementById('title')).value;
const author = (document.getElementById('author')).value;
const pages = (document.getElementById('pages')).value;
newBook = new Book(title, author, pages);
} {
myLibrary.push(newBook);
populateBooks(myLibrary, bookList);
formDisplay();
form.reset();
console.table(myLibrary)
}
};
function populateBooks(myLib, bookView) {
const bookCards = document.querySelectorAll('.book-card')
bookCards.forEach(bookCard => bookList.removeChild(bookCard));
myLib.forEach((book, index) => {
book.id = index;
const cardContent = `<div class="book-card" data-index=${book.id}>
<div class="card-info-wrapper">
<h2>${book.title}</h2>
<h3>${book.author}</h3>
<h4>${book.pages} Pages</h4>
<p>${book.info()}</p>
</div>
<div class="card-menu">
<div class="button" id="remove-btn">
Remove
</div>
</div>
</div>`
const element = document.createElement('div');
element.innerHTML = cardContent;
// element.dataset.indexx = book.id;
bookView.appendChild(element.firstChild);
const cards = document.querySelectorAll('[data-index]');
cards.forEach(card => {
const removeButton = card.querySelector('.button');
removeButton.addEventListener('click', () => {
removeBook(book.id)
})
})
});
};
function removeBook(id) {
console.log('deleting', id);
myLibrary.splice(id, 1);
console.table(myLibrary);
populateBooks(myLibrary, bookList);
}
function formDisplay() {
form.reset();
formView.classList.toggle('toggle-on');
};
const theHobbit = new Book('The Hobbit', 'J.R.R. Tolkien', 295);
myLibrary.push(theHobbit)
const harryPotter = new Book('Harry Potter', 'J.K Rowling', 320);
myLibrary.push(harryPotter)
const sangaf = new Book('The Subtle Art of Not Giving a Fuck', 'Mark Manson', 300)
myLibrary.push(sangaf)
document.addEventListener("DOMContentLoaded", function() {
form.addEventListener("submit", function(e) {
addToLibrary(e)
});
});
formButton.addEventListener('click', formDisplay);
populateBooks(myLibrary, bookList);
#font-face {
font-family: "fanwood";
font-style: normal;
font-weight: normal;
src: url("fonts/Fanwood.otf");
font-display: swap;
}
:root {
--color-primary: #e9e2d7;
--color-primary-alt: #8e6549;
--color-secondary: #d42257;
--color-background: #d2fbf7;
--color-text: #412d86;
--color-light: #fff;
--color-anchor: #3a00ff;
--font-family: "fanwoood";
--font-weight-strong: 500;
--font-size-h1: 4rem;
--font-size-h2: 3rem;
--font-size-h3: 2rem;
--font-size-h4: 1.35rem;
--font-size-text: 1.15rem;
--border-radius: 8px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Remove default margin */
body,
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
}
html {
overflow-x: hidden;
}
/* Set core body defaults */
body {
font-family: 'fanwood';
min-height: 100vh;
font-size: 100%;
line-height: 1.5;
text-rendering: optimizeSpeed;
overflow-x: hidden;
}
/* Make images easier to work with */
img {
display: block;
max-width: 100%;
}
/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}
body {
background-color: var(--color-primary);
}
button {
background-color: var(--color-primary);
border: none;
margin: 0;
}
input {
width: 100%;
margin-bottom: 10px 0;
}
.site-wrapper {
margin: 0 4%;
}
.card-info-wrapper {
margin: 4% 4%;
text-align: left;
}
.card-menu {
align-self: flex-end;
margin: 4% 4%;
}
.header {
color: var(--color-primary);
background-color: var(--color-primary-alt);
height: 84px;
display: flex;
align-items: center;
justify-content: center;
}
.tool-bar {
margin-top: 20px;
}
.tools {
display: flex;
}
.button {
cursor: pointer;
display: inline-flex;
padding: 2px 8px;
color: var(--color-primary-alt);
background-color: var(--color-primary);
}
.button.add {
display: inline-flex;
padding: 2px 8px;
background-color: var(--color-primary-alt);
color: var(--color-primary);
}
.books-wrapper {
margin-top: 20px;
/* border: 1px solid white; */
display: flex;
flex-wrap: wrap;
}
.book-card {
word-wrap: normal;
background-color: var(--color-primary-alt);
color: var(--color-primary);
width: 300px;
height: 350px;
margin-right: 10px;
margin-bottom: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.form-card {
display: none;
word-wrap: normal;
background-color: var(--color-primary-alt);
color: var(--color-primary);
width: 300px;
height: 350px;
margin-right: 10px;
margin-bottom: 10px;
}
.toggle-on {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Book</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="header">
<div class="site-wrapper">
<div class="header-logo-container">
<h1>Library</h1>
</div>
</div>
</div>
<div class="tool-bar">
<div class="site-wrapper">
<div class="tools">
<div class="button add" id="add-form">
Add Book
</div>
</div>
</div>
</div>
<div class="books">
<div class="site-wrapper">
<div class="books-wrapper">
<!-- TEMPLATE FOR BOOK CARD -->
<!-- <div class="book-card">
<div class="card-info-wrapper">
<h2>Title</h2>
<h3>Author</h3>
<h4>Pages</h4>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ipsum fugit officiis animi soluta et, sit aliquid.</p>
</div>
<div class="card-menu">
<div class="button">
Remove
</div>
</div>
</div> -->
<div class="form-card">
<div class="card-info-wrapper">
<form id="input-form">
<label for="title"><h3>Title</h3></label>
<input type="text" id="title" name="title" placeholder="Name of the Book" required>
<label for="author"><h3>Author</h3></label>
<input type="text" id="author" name="author" placeholder="Name of the Author" required>
<label for="pages"><h3>Pages</h3></label>
<input type="number" id="pages" name="pages" placeholder="Number of Pages" required>
<button type="submit" class="button" id="addBook">Add Book</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>
The problem with your code is that for every card aded in populateBook, you loop all the previous cards and add a click event listener, which means the second book gets 2 copies of this handler, the third 3 etc.
Instead of doing that, add a single event handler for clicking and handle appropriately:
document.querySelector(".books-wrapper").addEventListener("click", (e) => {
if(e.target.classList.contains("button")){
const index = e.target.parentElement.parentElement.dataset.index;
removeBook(index);
}
});
Live example:
const form = document.getElementById('input-form');
const formButton = document.getElementById('add-form');
const formView = document.querySelector('.form-card')
const bookList = document.querySelector('.books-wrapper');
let myLibrary = [];
let newBook;
function Book(title, author, pages) {
this.title = title;
this.author = author;
this.pages = pages;
this.info = function() {
return `${this.title} is a book by ${this.author}, ${this.pages} pages, not read yet.`
};
};
Book.prototype.read = false;
function addToLibrary(e) {
{
e.preventDefault();
const title = (document.getElementById('title')).value;
const author = (document.getElementById('author')).value;
const pages = (document.getElementById('pages')).value;
newBook = new Book(title, author, pages);
} {
myLibrary.push(newBook);
populateBooks(myLibrary, bookList);
formDisplay();
form.reset();
console.table(myLibrary)
}
};
function populateBooks(myLib, bookView) {
const bookCards = document.querySelectorAll('.book-card')
bookCards.forEach(bookCard => bookList.removeChild(bookCard));
myLib.forEach((book, index) => {
book.id = index;
const cardContent = `<div class="book-card" data-index=${book.id}>
<div class="card-info-wrapper">
<h2>${book.title}</h2>
<h3>${book.author}</h3>
<h4>${book.pages} Pages</h4>
<p>${book.info()}</p>
</div>
<div class="card-menu">
<div class="button" id="remove-btn">
Remove
</div>
</div>
</div>`
const element = document.createElement('div');
element.innerHTML = cardContent;
// element.dataset.indexx = book.id;
bookView.appendChild(element.firstChild);
});
};
function removeBook(id) {
console.log('deleting', id);
myLibrary.splice(id, 1);
console.table(myLibrary);
populateBooks(myLibrary, bookList);
}
function formDisplay() {
form.reset();
formView.classList.toggle('toggle-on');
};
const theHobbit = new Book('The Hobbit', 'J.R.R. Tolkien', 295);
myLibrary.push(theHobbit)
const harryPotter = new Book('Harry Potter', 'J.K Rowling', 320);
myLibrary.push(harryPotter)
const sangaf = new Book('The Subtle Art of Not Giving a Fuck', 'Mark Manson', 300)
myLibrary.push(sangaf)
document.addEventListener("DOMContentLoaded", function() {
form.addEventListener("submit", function(e) {
addToLibrary(e)
});
document.querySelector(".books-wrapper").addEventListener("click", (e) => {
if(e.target.classList.contains("button")){
const index = e.target.parentElement.parentElement.dataset.index;
removeBook(index);
}
})
});
formButton.addEventListener('click', formDisplay);
populateBooks(myLibrary, bookList);
#font-face {
font-family: "fanwood";
font-style: normal;
font-weight: normal;
src: url("fonts/Fanwood.otf");
font-display: swap;
}
:root {
--color-primary: #e9e2d7;
--color-primary-alt: #8e6549;
--color-secondary: #d42257;
--color-background: #d2fbf7;
--color-text: #412d86;
--color-light: #fff;
--color-anchor: #3a00ff;
--font-family: "fanwoood";
--font-weight-strong: 500;
--font-size-h1: 4rem;
--font-size-h2: 3rem;
--font-size-h3: 2rem;
--font-size-h4: 1.35rem;
--font-size-text: 1.15rem;
--border-radius: 8px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
/* Remove default margin */
body,
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 0;
}
html {
overflow-x: hidden;
}
/* Set core body defaults */
body {
font-family: 'fanwood';
min-height: 100vh;
font-size: 100%;
line-height: 1.5;
text-rendering: optimizeSpeed;
overflow-x: hidden;
}
/* Make images easier to work with */
img {
display: block;
max-width: 100%;
}
/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}
body {
background-color: var(--color-primary);
}
button {
background-color: var(--color-primary);
border: none;
margin: 0;
}
input {
width: 100%;
margin-bottom: 10px 0;
}
.site-wrapper {
margin: 0 4%;
}
.card-info-wrapper {
margin: 4% 4%;
text-align: left;
}
.card-menu {
align-self: flex-end;
margin: 4% 4%;
}
.header {
color: var(--color-primary);
background-color: var(--color-primary-alt);
height: 84px;
display: flex;
align-items: center;
justify-content: center;
}
.tool-bar {
margin-top: 20px;
}
.tools {
display: flex;
}
.button {
cursor: pointer;
display: inline-flex;
padding: 2px 8px;
color: var(--color-primary-alt);
background-color: var(--color-primary);
}
.button.add {
display: inline-flex;
padding: 2px 8px;
background-color: var(--color-primary-alt);
color: var(--color-primary);
}
.books-wrapper {
margin-top: 20px;
/* border: 1px solid white; */
display: flex;
flex-wrap: wrap;
}
.book-card {
word-wrap: normal;
background-color: var(--color-primary-alt);
color: var(--color-primary);
width: 300px;
height: 350px;
margin-right: 10px;
margin-bottom: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.form-card {
display: none;
word-wrap: normal;
background-color: var(--color-primary-alt);
color: var(--color-primary);
width: 300px;
height: 350px;
margin-right: 10px;
margin-bottom: 10px;
}
.toggle-on {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Book</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="header">
<div class="site-wrapper">
<div class="header-logo-container">
<h1>Library</h1>
</div>
</div>
</div>
<div class="tool-bar">
<div class="site-wrapper">
<div class="tools">
<div class="button add" id="add-form">
Add Book
</div>
</div>
</div>
</div>
<div class="books">
<div class="site-wrapper">
<div class="books-wrapper">
<!-- TEMPLATE FOR BOOK CARD -->
<!-- <div class="book-card">
<div class="card-info-wrapper">
<h2>Title</h2>
<h3>Author</h3>
<h4>Pages</h4>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ipsum fugit officiis animi soluta et, sit aliquid.</p>
</div>
<div class="card-menu">
<div class="button">
Remove
</div>
</div>
</div> -->
<div class="form-card">
<div class="card-info-wrapper">
<form id="input-form">
<label for="title"><h3>Title</h3></label>
<input type="text" id="title" name="title" placeholder="Name of the Book" required>
<label for="author"><h3>Author</h3></label>
<input type="text" id="author" name="author" placeholder="Name of the Author" required>
<label for="pages"><h3>Pages</h3></label>
<input type="number" id="pages" name="pages" placeholder="Number of Pages" required>
<button type="submit" class="button" id="addBook">Add Book</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>

why can't I get my jquery to fade in on click of button?

#rock {
display: none;
position: relative;
left: 49.4%
}
#paper {
display: none;
position: relative;
left: 49%;
bottom: 81px;
}
#scissors {
display: none;
position: relative;
left: 48.14%;
bottom: 162px;
}
#shoot {
display: none;
position: relative;
left: 48.7%;
bottom: 243px;
}
I'm trying to get these h2 elements to fade in then out one after the other after the click of one of three buttons, but my JQuery isn't working for the fade in portion (I'm trying to take this in pieces since I'm new to JavaScript and JQuery). Here's my script:
$(document).ready(function(){
$("button").click(function(){
$("#rock").fadeIn();
$("#paper").fadeIn();
$("#scissors").fadeIn("slow");
$("#shoot").fadeIn(3000);
});
});
<div class="selections">
<button class="selection" data-selection="rock">🗻</button>
<button class="selection" data-selection="paper">📜</button>
<button class="selection" data-selection="scissors">✂</button>
</div>
<h2 class="chant" id="rock">Rock</h2>
<h2 class="chant" id="paper">Paper</h2>
<h2 class="chant" id=scissors>Scissors</h2>
<h2 class="chant" id="shoot">Shoot!</h2>
`
To accomplish your initial goal, everything is fine except: You need to hide your h2's initially, which you can do with the hidden attribute.
I'll probably get in trouble for this, but I thought I would show one way to complete this game. The code is commented below.
If you want to only reveal the associate button h2, access the data() of that element
$(document).ready(function() {
let choices = ['rock', 'paper', 'scissors']; // our choices
$("button").click(function() {
$('.chant').hide(); // hide all h2s for the round
$("#" + $(this).data("selection")).fadeIn(); // my selection - $(this).data("selection") grabs the data-selection attribute of the button ( $(this) ) which was clicked
let computer = choices[Math.floor(Math.random() * 3)]; // a random computer choice
$("#computer").html(computer.toUpperCase()).fadeIn("slow"); // new element #computer takes random value as html and fades in
// our chooser logic - we compare the index positions of the 2 choices
let msg, diff = choices.indexOf($(this).data("selection")) - choices.indexOf(computer);
if (diff === 0) msg = "Its a Tie";
else if (diff > 0 || diff === -2) msg = "You Won!";
else msg = "Shoot!";
$("#shoot").html(msg).fadeIn(3000);
// $("#paper").fadeIn();
// $("#scissors").fadeIn("slow");
// $("#shoot").fadeIn(3000);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="selections">
<button class="selection" data-selection="rock">🗻</button>
<button class="selection" data-selection="paper">📜</button>
<button class="selection" data-selection="scissors">✂</button>
</div>
<h2 class="chant" hidden id="rock">Rock</h2>
<h2 class="chant" hidden id="paper">Paper</h2>
<h2 class="chant" hidden id="scissors">Scissors</h2>
<h2 class="chant" hidden id="computer"></h2>
<h2 class="chant" hidden id="shoot">Shoot!</h2>
You don't need to start them display:none. Instead you could just start them without text and then .hide() them and set the .text() right before they .fadeIn().
I kind of went with the other answer and assumed you're trying to make a game. Didn't realize you can make hours of fun in so few lines of code.
$('.selections button').click(function() {
let player = this.getAttribute('data-selection'),
ai = ['rock', 'paper', 'scissors'][Math.round(Math.random() * 2)],
outcome = player === ai ? 'TIE' :
((player === 'rock' && ai === 'scissors') ||
(player === 'paper' && ai === 'rock') ||
(player === 'scissors' && ai === 'paper')) ? 'WIN' :
'LOST';
$('.chant').hide();
$('.chant.player').text(player).fadeIn();
$('.chant.ai').text(ai).fadeIn('slow');
$('.chant.outcome').text(outcome).fadeIn(3000);
});
<div class="selections">
<button data-selection="rock">🗻</button>
<button data-selection="paper">📜</button>
<button data-selection="scissors">✂</button>
</div>
<h2 class="chant player"></h2>
<h2 class="chant ai"></h2>
<h2 class="chant outcome"></h2>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Or if you want to make absolutely sure that they fade in in sequence, .fadeIn() allows for an on complete callback, so you could nest them:
$('.chant.player').text(player).fadeIn(function() {
$('.chant.ai').text(ai).fadeIn('slow', function() {
$('.chant.outcome').text(outcome).fadeIn(3000);
});
});
I went with the document.ready function and used the .fadeIn .fadeOut effects. I hid each h2 element individually in my html and came to this solution. The only issue I'm having now is the screen expands and moves some elements when the script is ran.
//Displays the chant 'Rock Paper Scissors Shoot!' after one of the buttons is clicked
$(document).ready(function(){
$('button').click(function(){
$('#rock').fadeIn(500).delay(1000).fadeOut(500);
$('#paper').delay(2000).fadeIn(500).delay(1000).fadeOut(500);
$('#scissors').delay(4000).fadeIn(500).delay(1000).fadeOut(500);
$('#shoot').delay(6000).fadeIn(500);
});
});
#import
url('https://fonts.googleapis.com/css2?family=Big+Shoulders+Stencil+Display:wght#100&display=swap');
*{
font-family: "Big Shoulders Stencil Display", sans-serif;
}
body {
background-size: contain;
background-color: #A80289;
}
.game {
margin: 40px 0 0 0;
font-size: 55px;
text-align: center;
letter-spacing: 3px;
}
.selections {
display: flex;
justify-content: center;
margin: 20px 0 0 0;
}
button {
padding: 0 20px 0 20px;
}
.selection {
background: none;
border: none;
font-size: 50px;
cursor: pointer;
transition: 100ms;
}
.selection:hover {
transform: scale(1.2);
}
.chant {
border: none;
font-size: 40px;
font-weight: bold;
letter-spacing: 3px;
}
#rock {
position: relative;
left: 49.4%
}
#paper {
position: relative;
left: 49%;
}
#scissors {
position: relative;
left: 48.14%;
}
#shoot {
position: relative;
left: 48.7%;
}
.winner {
margin: 1rem;
display: grid;
justify-content: center;
grid-template-columns: repeat(2, .2fr);
justify-items: center;
align-items: center;
position: relative;
top: 100px;
font-size: 25px;
letter-spacing: 2px;
font-weight: bold;
}
.winner-score {
margin: 0 0 0 8px;
font-size: 75%;
}
.result-selection {
opacity: .5;
font-size: 20px;
}
.result-selection.winner {
opacity: 1;
font-size: 30px;
position: relative;
top: 0;
}
/*Media Queries*/
/*Tablets and smaller*/
#media(max-width: 768px) {
.game {
margin: 40px 0 0 0;
font-size: 45px;
text-align: center;
letter-spacing: 3px;
}
.selection {
font-size: 40px;
}
.chant {
font-size: 40px;
letter-spacing: 3px;
}
#rock {
position: relative;
left: 48%
}
#paper {
position: relative;
left: 47.62%;
}
#scissors {
position: relative;
left: 45.7%;
}
#shoot {
position: relative;
left: 46.5%;
}
.winner {
font-size: 24px;
}
}
/*Mobile*/
#media(max-width: 500px) {
.game {
margin: 40px 0 0 0;
font-size: 40px;
text-align: center;
letter-spacing: 3px;
}
.selection {
font-size: 35px;
}
.chant {
font-size: 40px;
letter-spacing: 3px;
}
#rock {
position: relative;
left: 47.26%
}
#paper {
position: relative;
left: 46.27%;
}
#scissors {
position: relative;
left: 43.19%;
}
#shoot {
position: relative;
left: 45%;
}
.winner {
font-size: 22px;
}
}
<!DOCTYPE html>
<html lang="en" {IF CLASSES}class="classes"{/IF}>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript" src="myscript.js"></script>
<link rel="stylesheet" type="text/css" href="css/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="preconnect" href="https://fonts.gstatic.com">
<title>Rock Paper Scissors</title>
<meta charset="UTF-8">
<meta name="viewpoint" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div class="game">
<h1>Rock Paper Scissors</h1>
</div>
<div class="selections">
<button class="selection" data-selection="rock">🗻</button>
<button class="selection" data-selection="paper">📜</button>
<button class="selection" data-selection="scissors">✂</button>
</div>
<h2 class="chant" hidden id="rock">Rock</h2>
<h2 class="chant" hidden id="paper">Paper</h2>
<h2 class="chant" hidden id=scissors>Scissors</h2>
<h2 class="chant" hidden id="shoot">Shoot!</h2>
<div class="winner">
<div>
Player
<span class="winner-score" data-your-score>0</span>
</div>
<div data-final-column>
Computer
<span class="winner-score" data-computer-score>0</span>
</div>
<!--
<div class="result-selection winner">✂</div>
<div class="result-selection">📜</div>
-->
</div>
</body>
</html>

Dividing a website into 3 sections -> 1 horizontally and 2 vertically below

i have a Sidebar on the left of the Screen. I can toggle it by pressing a button. On the right I have the content.
I want to place the button on a horizontal bar on the top. The sidebar seems to cover this bar so I can not see the button.
This is my current code:
The Html File:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>
</title>
</head>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="MainController.js"></script>
<link rel="stylesheet" type="text/css" href="MainStyle.css">
<body onload="InitDocument()">
<div id="topBar">
<button id="btnNavToggle" type="button" onclick="ToggleNavbar()">Menu</button>
</div>
<div id="container">
<div id="sideNav">
<button type="button" onclick="NewEntry()">+</button>
<p>test</p>
</div>
<div id="mainArea">
<p>Title:</p>
<input id="titleInputField" type="text">
<p>Text:</p>
<textarea id="textArea"> </textarea>
<p></p>
<button type="button" onclick="SaveEntry()">Save</button>
</div>
</div>
</body>
</html>
The Css File:
body{
background-color: #EEEEEE;
color: #000000;
}
* {
margin: 0;
padding: 0;
}
#sideNav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 0;
left: 0;
overflow-x: hidden;
background-color: #333333;
color: #EEEEEE;
}
The Js File:
var navIsOpen = true;
function InitDocument(){ // Initialization
ToggleNavbar();
}
function ToggleNavbar(){ // show - hide the navbar
var sideNavWidth = "0px";
var mainAreaWidth = "0px";
if (navIsOpen)
{
sideNavWidth = "200px";
mainAreaWidth = "200px";
}
$("#sideNav").width(sideNavWidth);
$("#mainArea").css('margin-left',mainAreaWidth);
navIsOpen = !navIsOpen;
}
function SaveEntry(){ // save the entry
var txtTitle = $("#titleInputField").val();
var txtField = $("#textArea").val();
alert(txtTitle + "#" + txtField);
}
function NewEntry() { // create a new entry
alert("neuer Eintrag");
}
This is what I want to archieve
It seems I just have to fix the CSS to get it done.
I added margin-top:0; to your topBar and removed top: 0; from your sideNav.
Try this:
var navIsOpen = true;
function InitDocument(){ // Initialization
ToggleNavbar();
}
function ToggleNavbar(){ // show - hide the navbar
var sideNavWidth = "0px";
var mainAreaWidth = "0px";
if (navIsOpen)
{
sideNavWidth = "200px";
mainAreaWidth = "200px";
}
$("#sideNav").width(sideNavWidth);
$("#mainArea").css('margin-left',mainAreaWidth);
navIsOpen = !navIsOpen;
}
function SaveEntry(){ // save the entry
var txtTitle = $("#titleInputField").val();
var txtField = $("#textArea").val();
alert(txtTitle + "#" + txtField);
}
function NewEntry() { // create a new entry
alert("neuer Eintrag");
}
body{
background-color: #EEEEEE;
color: #000000;
}
*{
margin: 0;
padding: 0;
}
#topBar {
margin-top:0;
background-color: navy;
}
#sideNav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
left: 0;
overflow-x: hidden;
background-color: #333333;
color: #EEEEEE;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>
</title>
</head>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="MainController.js"></script>
<link rel="stylesheet" type="text/css" href="MainStyle.css">
<body onload="InitDocument()">
<div id="topBar">
<button id="btnNavToggle" type="button" onclick="ToggleNavbar()">Menu</button>
</div>
<div id="container">
<div id="sideNav">
<button type="button" onclick="NewEntry()">+</button>
<p>test</p>
</div>
<div id="mainArea">
<p>Title:</p>
<input id="titleInputField" type="text">
<p>Text:</p>
<textarea id="textArea"> </textarea>
<p></p>
<button type="button" onclick="SaveEntry()">Save</button>
</div>
</div>
</body>
</html>
Try this:
var navIsOpen = true;
function InitDocument(){ // Initialization
ToggleNavbar();
}
function ToggleNavbar(){ // show - hide the navbar
var sideNavWidth = "0px";
var mainAreaWidth = "0px";
if (navIsOpen)
{
sideNavWidth = "200px";
mainAreaWidth = "200px";
}
$("#sideNav").width(sideNavWidth);
$("#mainArea").css('margin-left',mainAreaWidth);
navIsOpen = !navIsOpen;
}
function SaveEntry(){ // save the entry
var txtTitle = $("#titleInputField").val();
var txtField = $("#textArea").val();
alert(txtTitle + "#" + txtField);
}
function NewEntry() { // create a new entry
alert("neuer Eintrag");
}
body{
background-color: #EEEEEE;
color: #000000;
}
* {
margin: 0;
padding: 0;
}
#main {
display: flex;
flex-direction: column;
}
#sideNav {
height: 100%;
width: 0;
position: fixed;
z-index: 1;
top: 50px;
left: 0;
overflow-x: hidden;
background-color: #333333;
color: #EEEEEE;
}
#topBar {
position: fixed;
display: inline-block;
width: 100%;
height: 50px;
background-color: red;
}
#container {
display: flex;
padding-top: 50px;
flex: 1;
flex-direction: row;
}
<html>
<head>
<meta charset="utf-8" />
<title>
</title>
</head>
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js"></script>
<script src="MainController.js"></script>
<link rel="stylesheet" type="text/css" href="MainStyle.css">
<body onload="InitDocument()">
<div id="main">
<div id="topBar">
<button id="btnNavToggle" type="button" onclick="ToggleNavbar()">Menu</button>
</div>
<div id="container">
<div id="sideNav">
<button type="button" onclick="NewEntry()">+</button>
<p>test</p>
</div>
<div id="mainArea">
<p>Title:</p>
<input id="titleInputField" type="text">
<p>Text:</p>
<textarea id="textArea"> </textarea>
<p></p>
<button type="button" onclick="SaveEntry()">Save</button>
</div>
</div>
</div>
</body>
</html>
Take a look flex-box concepts
Checkout this example of using the new HTML5 semantic elements.
http://www.w3schools.com/html/html5_semantic_elements.asp
I have taken most of the example elements from the link above and created a simple HTML5 page.
You can add/remove/modify any of the section below by removing the HTML or removing/adding additional CSS properties.
var toggleButton = document.getElementById('toggle-button');
var pageWrapper = document.getElementsByClassName('wrapper')[0];
toggleButton.addEventListener('click', function() {
toggleClass(pageWrapper, 'toggle-hidden')
});
function toggleClass(el, className) {
if (el.classList) {
el.classList.toggle(className);
} else {
var classes = el.className.split(' ');
var existingIndex = classes.indexOf(className);
if (existingIndex >= 0) classes.splice(existingIndex, 1);
else classes.push(className);
el.className = classes.join(' ');
}
}
header, footer {
width: 100%;
text-align: center;
background: #DDD;
padding: 0.25em !important;
}
.title {
font-weight: bold;
font-size: 2.25em;
margin-bottom: 0.5em;
}
.subtitle {
font-size: 1.5em;
font-style: italic;
}
.wrapper {
background: #EEE;
}
nav {
text-align: center;
background: #CCC;
padding: 0.25em !important;
}
aside {
float: left;
top: 0;
width: 12em;
height: 100%;
padding: 0.25em !important;
}
aside a {
display: block;
text-decoration: none;
margin-bottom: 0.5em;
}
aside a:before {
content: '➢ ';
}
article, section {
margin-left: 12em !important;
background: #FFF;
padding: 0.25em !important;
}
/* Default HTML4 typography styles */
h1 { font-size: 2.00em !important; margin: 0.67em 0 !important; }
h2 { font-size: 1.50em !important; margin: 0.75em 0 !important; }
h3 { font-size: 1.17em !important; margin: 0.83em 0 !important; }
h5 { font-size: 0.83em !important; margin: 1.50em 0 !important; }
h6 { font-size: 0.75em !important; margin: 1.67em 0 !important; }
h1, h2, h3, h4, h5, h6 { font-weight: bolder !important; }
p { font-size: 1.00em !important; margin: 1em 0 !important; }
#toggle-button {
display: block;
position: absolute;
width: 5em;
height: 5em;
line-height: 1.5em;
text-align: center;
}
.wrapper.toggle-hidden aside {
display: none;
width: 0;
}
.wrapper.toggle-hidden article, .wrapper.toggle-hidden section {
margin-left: 0 !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet"/>
<header>
<button id="toggle-button">Toggle<br />Sidebar</button>
<div class="title">What Does WWF Do?</div>
<div class="subtitle">WWF's mission:</div>
</header>
<div class="wrapper">
<nav>
HTML |
CSS |
JavaScript |
jQuery
</nav>
<aside>
<h1>Links</h1>
HTML
CSS
JavaScript
jQuery
</aside>
<section>
<h1>WWF</h1>
<p>The World Wide Fund for Nature (WWF) is....</p>
</section>
<article>
<h1>What Does WWF Do?</h1>
<p>WWF's mission is to stop the degradation of our planet's natural environment,
and build a future in which humans live in harmony with nature.</p>
</article>
</div>
<footer>
<p>Posted by: Hege Refsnes</p>
<p>Contact information: someone#example.com.</p>
</footer>

Categories

Resources