What I'm trying to do is to get an image from my input type="file" and do a card with this image and other information from inputs type="text".
The problem is that whenever I store an image src data in variable and push it to array of imgArrForPush (that is array for extra pictures that admin wants to see on other page after you click on card) and it works but when I'm trying to add imgArrForPush in object to push all of data to cardArr (cardArr is arr that store all card's information in object and I want to render this data) it doesn't work, what I receive is undefined.
The error:
undefined:1 GET http://127.0.0.1:5500/undefined 404 (Not Found)
I don't think that css of the whole page play a big role in that problem so I created another folder and trying to solve this problem with this styles. But I think that css of a card would be important.
I'm also using fontawesome icons and I don't know is it ok that icons is here in code.
<div class="admin-inputs-container">
<input type="file" class="input">
<button class="admin-buttons" onclick="onGetImg()">submit</button>
<input class="admin-inputs img-name-input" type="text" placeholder="img name(must be number)" />
<input class="admin-inputs district-input" type="text" placeholder="district"/>
<input class="admin-inputs area-input" type="text" placeholder="area"/>
<input class="admin-inputs rooms-input" type="text" placeholder="number of rooms"/>
<input class="admin-inputs floor-input" type="text" placeholder="floor"/>
<input class="admin-inputs number-of-floors-input" type="text" placeholder="floors in building"/>
<input class="admin-inputs price-input" type="text" placeholder="price"/>
<input class="admin-inputs adress-input" type="text" placeholder="adreess"/>
<div class="admin-inputs-container">
<button class="admin-buttons" onclick="onGetDataFromInput()">submit</button>
</div>
<button onclick="redner()">render</button>
<div class="container"></div>
.card {
display: flex;
flex-direction: column;
width: 40%;
align-items: flex-start;
border: 4px solid #0A3D33;
margin: 0 0 30px 0;
}
.card-button {
margin: 0 20px 0 0;
font-size: 16px;
font-weight: 600;
transition: all 0.3s;
cursor: pointer;
background-color: #f4f3f0;
color: #0A3D33;
border: 2px solid #0A3D33;
border-radius: 5px;
height: 60px;
width: 150px;
}
.card-button:hover {
background-color: #0A3D33 ;
color: #f4f3f0;
}
.card-button:active {
background-color: #E7E6E3;
color: #0A3D33;
}
.card-info-container {
width: 100%;
display: flex;
flex-direction: column;
}
.card-info-sign-container {
border-top: 2px solid #0A3D33;
display: flex;
gap: 20px;
padding: 0 0 0 10px;
}
.icon-wrapper {
display: flex;
gap: 20px;
}
.card-info-price-container {
border-top: 2px solid #0A3D33;
gap: 5px;
padding: 0 0 0 10px;
display: flex;
justify-content: space-between;
align-items: center;
height: 70px;
}
.card-info-sign {
font-size: 36px;
}
.card-price {
font-size: 36px;
}
.card-img {
height: 250px;
width: 100%;
cursor: pointer;
}
.card-icon-container {
display: flex;
align-items: center;
justify-content: center;
width: 25px;
}
.fa-arrow-up,
.fa-bed,
.fa-layer-group,
.fa-location-dot {
font-size: 20px;
}
.fa-dollar-sign {
font-size: 35px;
color: #137A63;
}
.fa-location-dot {
color: #c85108;
}
.fa-layer-group {
color: #a20e0e;
}
.fa-arrow-up {
color: #318CE7;
}
.password-input {
width: 500px;
text-align: center;
height: 50px;
background-color: #f4f3f0;
border: 2px solid #0A3D33;
color: #0A3D33;
font-weight: 600;
font-size: 20px;
border-radius: 10px;
}
.wirte-a-password-sign{
font-size: 30px;
font-weight: 600;
color: #0A3D33;
}
.admin-inputs {
width: 320px;
height: 30px;
border: 2px solid #0A3D33;
border-radius: 5px;
padding: 5px;
background-color: #f4f3f0;
color: #0A3D33;
font-size: 20px;
font-weight: 600;
}
.admin-buttons {
font-weight: 600;
transition: all 0.3s;
cursor: pointer;
background-color: #0A3D33;
color: #f4f3f0;
width: 150px;
height: 40px;
border-radius: 5px;
}
.admin-buttons:hover {
border: 2px solid #0A3D33;
background-color: #f4f3f0 ;
color: #0A3D33;}
const adressInput = document.querySelector(".adress-input");
const priceInput = document.querySelector(".price-input");
const numberOfFloorsInput = document.querySelector(".number-of-floors-input");
const floorInput = document.querySelector(".floor-input");
const roomsInput = document.querySelector(".rooms-input");
const areaInput = document.querySelector(".area-input");
const districtInput = document.querySelector(".district-input");
const imgNameInput = document.querySelector(".img-name-input");
const imgInput = document.querySelector('.input');
const containerImg = document.querySelector('.container-img');
const container = document.querySelector('.container');
let uploaded_image = "";
const cardArr = [];
const imgArrForPush = [];
const onGetImg = () => {
const reader = new FileReader();
var file = imgInput.files[0];
reader.addEventListener("load", () => {
uploaded_image = reader.result;
imgArrForPush.push(uploaded_image);
})
reader.readAsDataURL(file);
imgInput.value = "";
}
const onGetDataFromInput = () => {
cardArr.push({
imgNameInput:imgNameInput.value,
inputData : {
districtInput:districtInput.value,
areaInput:areaInput.value,
roomsInput:roomsInput.value,
floorInput:floorInput.value,
numberOfFloorsInput:numberOfFloorsInput.value,
priceInput:priceInput.value,
adressInput:adressInput.value
},
images:imgArrForPush
});
imgNameInput.value = "";
districtInput.value = "";
areaInput.value = "";
roomsInput.value = "";
floorInput.value = "";
numberOfFloorsInput.value = "";
priceInput.value = "";
adressInput.value = "";
imgInput.value = "";
imgArrForPush.splice(0,imgArrForPush.length);
}
const redner = () => {
container.innerHTML = "";
cardArr.forEach(card => {
console.log(card.images);
container.innerHTML += ` <div class="card">
<img src="${card.images[card.images.length - 1]}"/>
<div class="card-info-container">
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-location-dot"></i>
</div>
<p class="card-info-sign">${card.inputData.districtInput}</p>
</div>
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-layer-group"></i>
</div>
<p class="card-info-sign">${card.inputData.areaInput} м²</p>
</div>
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-bed"></i>
</div>
<p class="card-info-sign">${card.inputData.roomsInput}</p>
</div>
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-arrow-up"></i>
</div>
<p class="card-info-sign">${card.inputData.floorInput}</p>
</div>
<div class="card-info-price-container">
<div class="icon-wrapper">
<div class="card-icon-container">
<i class="fa-solid fa-dollar-sign"></i>
</div>
<p class="card-info-sign card-price">${card.inputData.priceInput}$</p>
</div>
<button class="card-button">Перейти</button>
</div>
</div>
</div>`
})
}
What I want to get is this :
For example:
cardArr = [{
imgNameInput:"the_img_name",
districtInput:"the_district",
areaInput:"250",
roomsInput:"3",
floorInput:"5",
numberOfFloorsInput:"10",
priceInput:"30000",
adressInput:"the_adress",
images:["the_img_path_1","the_img_path_2","the_img_path_3"]
}]
Thanks to the #FiddlingAway!!
const adressInput = document.querySelector(".adress-input");
const priceInput = document.querySelector(".price-input");
const numberOfFloorsInput = document.querySelector(".number-of-floors-input");
const floorInput = document.querySelector(".floor-input");
const roomsInput = document.querySelector(".rooms-input");
const areaInput = document.querySelector(".area-input");
const districtInput = document.querySelector(".district-input");
const imgNameInput = document.querySelector(".img-name-input");
const imgInput = document.querySelector('.input');
const containerImg = document.querySelector('.container-img');
const container = document.querySelector('.container');
let uploaded_image = "";
const cardArr = [];
let imgArrForPush = [];
const onGetImg = () => {
const reader = new FileReader();
var file = imgInput.files[0];
reader.addEventListener("load", () => {
uploaded_image = reader.result;
imgArrForPush.push(uploaded_image);
//imgArrForPush.push(uploaded_image);
})
reader.readAsDataURL(file);
imgInput.value = "";
}
const onGetDataFromInput = () => {
cardArr.push({
imgNameInput:imgNameInput.value,
inputData : {
districtInput:districtInput.value,
areaInput:areaInput.value,
roomsInput:roomsInput.value,
floorInput:floorInput.value,
numberOfFloorsInput:numberOfFloorsInput.value,
priceInput:priceInput.value,
adressInput:adressInput.value
},
images:imgArrForPush
});
imgNameInput.value = "";
districtInput.value = "";
areaInput.value = "";
roomsInput.value = "";
floorInput.value = "";
numberOfFloorsInput.value = "";
priceInput.value = "";
adressInput.value = "";
imgInput.value = "";
imgArrForPush = [];
}
const redner = () => {
container.innerHTML = "";
cardArr.forEach(card => {
console.log(card.images);
container.innerHTML += ` <div class="card">
<img src="${card.images[0]}"/>
<div class="card-info-container">
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-location-dot"></i>
</div>
<p class="card-info-sign">${card.inputData.districtInput}</p>
</div>
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-layer-group"></i>
</div>
<p class="card-info-sign">${card.inputData.areaInput} м²</p>
</div>
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-bed"></i>
</div>
<p class="card-info-sign">${card.inputData.roomsInput}</p>
</div>
<div class="card-info-sign-container">
<div class="card-icon-container">
<i class="fa-solid fa-arrow-up"></i>
</div>
<p class="card-info-sign">${card.inputData.floorInput}</p>
</div>
<div class="card-info-price-container">
<div class="icon-wrapper">
<div class="card-icon-container">
<i class="fa-solid fa-dollar-sign"></i>
</div>
<p class="card-info-sign card-price">${card.inputData.priceInput}$</p>
</div>
<button class="card-button">Перейти</button>
</div>
</div>
</div>`
})
}
Related
I've made a budgeting app that has expenses and Income tabs. Every time you add an expense or income, the app pushes the information inside of an array of objects and dynamically renders an <li> component and places it inside of a <ul>. I'm having trouble with the edit and delete features. Each individual <li> comes with a delete and edit button. The <li>, delete button, and edit button all have the same id of Date.now(). Date.now() is used because it produces a number based on milliseconds and won't produce the same id twice unless someone types an expense or income twice within one millisecond I want to click on the delete button inside of the <li> and have my app remove that individual object from my entry_list[] array and also remove the <li> from the DOM.
'use strict'
const balanceElement = document.querySelector(".balance .value");
const totalIncome = document.querySelector(".income-total");
const totalOutcome = document.querySelector(".outcome-total");
const incomeElement = document.querySelector(".income-tab");
const expense = document.querySelector(".expense-tab");
const all = document.querySelector(".all-tab");
const incomeList = document.querySelector(".income-tab .list");
const expenseList = document.querySelector(".expense-tab .list");
const allList = document.querySelector(".all-tab .list");
const expensesButton = document.querySelector(".tab1");
const incomeButton = document.querySelector(".tab2");
const allButton = document.querySelector(".tab3");
const addExpense = document.querySelector(".add-expense")
const expenseTitle = document.querySelector(".expense-title-input")
const expenseAmount = document.querySelector(".expense-amount-input")
const addIncome = document.querySelector(".add-income")
const incomeTitle = document.querySelector(".income-title-input")
const incomeAmount = document.querySelector(".income-amount-input")
const list = document.querySelector('.list')
//SWITCHING BETWEEN TABS
expensesButton.addEventListener('click', () => {
expense.classList.remove('hidden');
incomeElement.classList.add('hidden');
expensesButton.classList.add('clicked');
incomeButton.classList.remove('clicked');
})
incomeButton.addEventListener('click', () => {
incomeElement.classList.remove('hidden');
expense.classList.add('hidden');
expensesButton.classList.remove('clicked');
incomeButton.classList.add('clicked');
})
incomeList.addEventListener('click', deleteOrEdit)
expenseList.addEventListener('click', deleteOrEdit)
let entry_list = []
addExpense.addEventListener('click', () =>{
if(expenseTitle.value == '' || expenseAmount.value == ''){
return;
}
let expense = {
type: 'expense',
title: expenseTitle.value,
amount: expenseAmount.value,
id: Date.now()
}
entry_list.push(expense)
clearExpense()
changeLists()
})
addIncome.addEventListener('click', () =>{
if(incomeTitle.value == '' || incomeAmount.value == ''){
return;
}
let income = {
type: 'income',
title: incomeTitle.value,
amount: incomeAmount.value,
id: Date.now()
}
entry_list.push(income)
clearIncome()
changeLists()
})
const clearExpense = () =>{
expenseTitle.value = '';
expenseAmount.value = '';
}
const clearIncome = () =>{
incomeTitle.value = ''
incomeAmount.value = ''
}
const changeLists = () =>{
expenseList.innerHTML = ''
incomeList.innerHTML = ''
entry_list.map((entry) =>{
if(entry.type == 'expense'){
return expenseList.innerHTML += `<li id = "${entry.id}" class= "${entry.type}">
<div class = "entry">${entry.title}: $${entry.amount}</div>
<div class="icon-container">
<div class = "edit" id="${entry.id}"></div>
<div class ="delete" id="${entry.id}"></div>
</div>
</li>`
}
else if(entry.type == 'income'){
return incomeList.innerHTML += `<li id = "${entry.id}" class= "${entry.type}">
<div class = "entry">${entry.title}: $${entry.amount}</div>
<div class="icon-container">
<div class = "edit" id="${entry.id}"></div>
<div class ="delete" id="${entry.id}"></div>
</div>
</li>`
}
})
addIncomes()
}
const addIncomes = () =>{
let sum = 0;
let income = 0;
let outcome = 0;
balanceElement.innerHTML = 0
totalIncome.innerHTML = 0
totalOutcome.innerHTML = 0
entry_list.forEach(list =>{
if(list.type == 'expense'){
sum -= list.amount
outcome -= list.amount
}else if(list.type == 'income'){
sum += Number(list.amount)
income += Number(list.amount)
}
balanceElement.innerHTML = '$' + sum
totalIncome.innerHTML = '$' + income
totalOutcome.innerHTML = '$' + outcome
})
}
// // DETERMINE IF BUTTON IS EDIT OR DELETE
function deleteOrEdit(e){
const targetButton = e.target;
const entry = targetButton.parentNode.parentNode;
if(targetButton.classList == ('delete')){
deleteEntry(entry)
}else if(targetButton.classList == ('edit')){
editEntry(entry);
}
}
// //DELETE FUNCTION
const deleteEntry = (entry) =>{
console.log(entry.id)
entry_list.splice(entry.id, 1)
// entry.innerHTML = ''
console.log(entry.id)
addIncomes()
}
// EDIT FUNCTION
const editEntry = (entry) =>{
let Entry = entry_list[entry.id]
if(entry.type == "income"){
incomeAmount.value = Entry.amount;
incomeTitle.value = Entry.title;
}else if(entry.type == "expense"){
expenseAmount.value = Entry.amount;
expenseTitle.value = Entry.title;
}
deleteEntry(entry);
}
#import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght#400;700&family=Raleway:wght#400;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Open Sans', sans-serif;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.budget-container{
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100%;
background-color: #4F98CA;
}
.balance-container{
width: 360px;
height: 470px;
background-color: #50D890;
border-radius: 30px;
margin-right: 100px;
}
.app-title{
color: white;
margin-top: 1rem;
margin-left: 1rem;
}
.month{
color: white;
margin-top: 1rem;
text-align: center;
}
.budget-header{
display: flex;
flex-direction:column;
justify-content: center;
}
.balance{
margin-top: 1rem;
margin-left: 1rem;
}
.title{
color: white;
font-size: 1.25rem;
opacity: .75;
}
.value{
font-size: 1.75rem;
color: white;
font-weight: bold;
margin-left: 1rem;
}
.account{
margin-top: 2.5rem;
margin: 2.5rem 1.5rem 2.5rem 1.5rem;
display: flex;
justify-content: space-between
}
.income-total{
color: white;
text-align: center;
font-size: 1.5rem;
}
.outcome-total{
color: #4F98CA;
text-align: center;
font-size: 1.5rem;
}
/* DASHBOARD */
.budget-dashboard{
display: block;
width: 360px;
height: 470px;
position: relative;
border-radius: 30px;
background-color: white;
}
.dash-title{
margin-top: 2rem;
margin-left: 1rem;
font-size: 1.5rem;
}
.toggle{
margin: 1rem;
display: flex;
cursor: pointer;
}
.toggle .tab2, .tab3{
margin-left: 1rem;
cursor: pointer;
}
.clicked{
font-weight: bold !important;
}
.hidden{
display: none !important;
}
/* EXPENSES TAB */
.expense-tab{
display: flex;
justify-content: center;
}
.expense-input-container{
position: absolute;
top: 400px;
border-top: solid 1px gray;
width: 100%;
}
.expense-amount-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.expense-title-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.add-expense{
color: none;
background-color: none;
border: none;
outline: none;
color: inherit;
}
/* INCOME TAB */
.income-tab{
display: flex;
justify-content: center;
}
.income-input-container{
position: absolute;
top: 400px;
border-top: solid 1px gray;
width: 100%;
}
.input{
display: flex;
justify-content: space-between;
align-items: center;
margin: 1rem;
}
.income-amount-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.income-title-input{
width: 125px;
border: none;
outline: none;
font-size: 1.25rem;
}
.add-income{
color: none;
background-color: none;
border: none;
outline: none;
}
.plus-img{
width: 40px;
}
/* li */
ul{
width: 360px;
height: 255px;
list-style: none;
margin-top:20px;
overflow-x: auto;
}
/* BUTTON ICONS */
.edit{
background-image: url('media/Icons/icons8-edit-48.png');
background-size: contain;
width: 25px;
height: 25px;
background-repeat: no-repeat;
margin-right: 10px;
}
.delete{
background-image: url('media/Icons/icons8-trash-can-48 (2).png');
background-size: contain;
width:25px;
height: 25px;
background-repeat: no-repeat;
}
.income{
width:250px;
height: auto;
padding-left: 20px;
margin-bottom: 10px;;
word-wrap: break-word;
color: black
}
.expense{
width:250px;
height: auto;
padding-left: 20px;
margin-bottom: 10px;;
word-wrap: break-word;
font-family: 'Gilroy Bold';
color: #4F98CA;
}
li{
display: flex;
justify-content: space-between;
width: 100% !important;
padding-right: 20px;
}
.icon-container{
display: flex;
}
#media (max-width:900px){
.budget-container{
display: inline-block;
position: relative
}
.balance-container{
position: absolute;
top: 10%;
left: 25%;
}
.budget-dashboard{
position: absolute;
left: 25%;
top: 40%;
}
}
<!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">
<link rel="stylesheet" href="style.css">
<title>Budgetrr</title>
</head>
<body>
<main class="budget-container">
<section class="balance-container">
<div class="app-title">
<p>Budgetrr</p>
</div>
<h1 class="month">OCTOBER</h1>
<section class="budget-header">
<div class="balance">
<div class="title">
Balance
</div>
<div class="value">
<small>$</small>0
</div>
</div>
<div class="account">
<div class="budget-income">
<div class="title">
Income
</div>
<div class="income-total">
<small>$</small>0
</div>
</div>
<div class="chart"></div>
<div class="budgetoutcome">
<div class="title">
Expenses
</div>
<div class="outcome-total">
<small>$</small>0
</div>
</div>
</div>
</section>
</section>
<section class="budget-dashboard">
<div class="dash-title">Dashboard</div>
<div class="toggle">
<div class="tab1 clicked">Expenses</div>
<div class="tab2">Income</div>
<!-- <div class="tab3 clicked">All</div> -->
</div>
<div class="income-tab hidden">
<ul class="list"></ul>
<div class="income-input-container">
<form class="input">
<input type="text" class="income-title-input" name="title" placeholder="Title">
<input type="number" class="income-amount-input" name="amount" placeholder="$0">
<button type = "button" class="add-income"><img class= "plus-img"src="media/Icons/icons8-add-new-48.png" alt=""></button>
</form>
</div>
</div>
<div class = "expense-tab">
<ul class="list"></ul>
<div class="expense-input-container">
<div class="input">
<input type="text" class="expense-title-input" name="title" placeholder="Title">
<input type="number" class="expense-amount-input" name="amount" placeholder="$0">
<button type="button" class="add-expense"><img class= "plus-img" src="media/Icons/icons8-add-new-48.png" alt=""></button>
</div>
</div>
</div>
</section>
</main>
<script src="JavaScript/budget.js"></script>
</body>
</html>
I've tried to use .splice() but I can't seem to get it to work.
Your entry is an object. And entry has an id property with Date type.
Your delete function calls this:
entry_list.splice(entry.id, 1)
Javascript splice function
function takes number as argument(s).
You should find the id of element you want to delete and get its index. After that you can delete the element with splice method.
Here is how to delete:
// Find the index of object at the given list
const index = entry_list.findIndex(x => x.id === entry.id);
// Starting from index of element to delete, remove 1 element.
entry_list.splice(index, 1);
In the snippet below, I have a step-form. While submitting the content in the form and hitting next, the input values are being passed to the confirmation page at the end.
I'm trying to understand if this is the most efficient way to pass the information to the confirmation page?
const previousButton = document.getElementById("previous")
const nextButton = document.getElementById("next")
const submitButton = document.getElementById('validate')
const form = document.getElementById('stepByStepForm')
const dots = document.getElementsByClassName('progress-bar__dot')
const numberOfSteps = 5
let currentStep = 1
for(let i = 0 ; i < dots.length ; ++i){
dots[i].addEventListener('click', ()=>{
goToStep(i+1)
})
}
previousButton.onclick = goPrevious
nextButton.onclick = goNext
function goNext(e) {
e.preventDefault()
currentStep += 1
goToStep(currentStep)
}
function goPrevious(e) {
e.preventDefault()
currentStep -= 1
goToStep(currentStep)
}
function goToStep(stepNumber){
currentStep = stepNumber
let inputsToHide = document.getElementsByClassName('step')
let inputs = document.getElementsByClassName(`step${currentStep}`)
let indicators = document.getElementsByClassName('progress-bar__dot')
for(let i = indicators.length-1; i >= currentStep ; --i){
indicators[i].classList.remove('full')
}
for(let i = 0; i < currentStep; ++i){
indicators[i].classList.add('full')
}
//hide all input
for (let i = 0; i < inputsToHide.length; ++i) {
hide(inputsToHide[i])
}
//only show the right one
for (let i = 0; i < inputs.length; ++i) {
show(inputs[i])
}
//if we reached final step
if(currentStep === numberOfSteps){
enable(previousButton)
disable(nextButton)
show(submitButton)
}
//else if first step
else if(currentStep === 1){
disable(previousButton)
enable(next)
hide(submitButton)
}
else {
enable(previousButton)
enable(next)
hide(submitButton)
}
}
function enable(elem) {
elem.classList.remove("disabled");
elem.disabled = false;
}
function disable(elem) {
elem.classList.add("disabled");
elem.disabled = true;
}
function show(elem){
elem.classList.remove('hidden')
}
function hide(elem){
elem.classList.add('hidden')
}
//collect inputs
next.addEventListener('click', function() {
const fNameInput = document.getElementById('firstname').value;
document.getElementById('fNameOutput').textContent = fNameInput;
const lNameInput = document.getElementById('lastname').value;
document.getElementById('lNameOutput').textContent = lNameInput;
const emailInput = document.getElementById('mail').value;
document.getElementById('emailOutput').textContent = emailInput;
const phoneInput = document.getElementById('phone').value;
document.getElementById('phoneOutput').textContent = phoneInput;
const addressInput = document.getElementById('address').value;
document.getElementById('addressOutput').textContent = addressInput;
const countryInput = document.getElementById('country').value;
document.getElementById('countryOutput').textContent = countryInput;
const colorInput = document.getElementById('color').value;
document.getElementById('colorOutput').textContent = colorInput;
const animalInput = document.getElementById('animal').value;
document.getElementById('animalOutput').textContent = animalInput;
});
submitButton.addEventListener('click', function(e) {
e.preventDefault();
})
html {
background-color: #A2C7E5;
}
.hidden {
display: none;
}
.button {
width: 140px;
cursor: pointer;
padding: 1em;
border-radius: 0.2em;
border: none;
color: white;
font-weight: bold;
font-size: 1em;
transition: all 0.5s ease;
background-color: #ff8552;
}
.button:hover {
background-color: #ff4f06;
}
.button.disabled {
opacity: 0.5;
}
.button.disabled:hover {
background-color: #ff8552;
}
.form {
width: 20em;
margin: auto;
margin-top: 5em;
padding: 5em;
padding-top: 2em;
padding-bottom: 2em;
background-color: white;
font-family: "Raleway", sans-serif;
color: #33312E;
border-radius: 0.2em;
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
}
.form .progress-bar {
width: 100%;
list-style-type: none;
display: flex;
padding: 0;
justify-content: center;
margin-bottom: 3.5em;
}
.form .progress-bar li.progress-bar__dot {
display: block;
width: 0.6em;
border-radius: 50%;
height: 0.6em;
border: 0.1em solid #ff8552;
background-color: white;
cursor: pointer;
transition: all 0.5s ease;
}
.form .progress-bar li.progress-bar__dot.full {
background-color: #ff8552;
}
.form .progress-bar li.progress-bar__connector {
display: block;
width: 5em;
border-radius: 1000em;
height: 0.1em;
background-color: #ff8552;
margin-top: 0.35em;
}
.form label {
font-weight: bold;
font-size: 1.2em;
}
.form input {
width: 100%;
padding: 1.3em;
margin-bottom: 3em;
box-sizing: border-box;
margin-top: 1em;
border: none;
border-radius: 0.5em;
background-color: #e6e6e6;
font-size: 1em;
font-family: "Raleway", sans-serif;
}
.form input:focus {
border: none;
}
.form .button-group {
width: 100%;
display: flex;
justify-content: space-between;
margin-top: 50px;
}
.form button#validate {
margin: auto;
background-color: #1A936F;
width: 12em;
}
.form button#validate:hover {
background-color: #12684e;
}
<form id="stepByStepForm" class="form">
<ul class="progress-bar">
<li class="progress-bar__dot full"></li>
<li class="progress-bar__connector"></li>
<li class="progress-bar__dot"></li>
<li class="progress-bar__connector"></li>
<li class="progress-bar__dot"></li>
<li class="progress-bar__connector"></li>
<li class="progress-bar__dot"></li>
<li class="progress-bar__connector"></li>
<li class="progress-bar__dot"></li>
</ul>
<div class="step step1">
<div class="input-group">
<label for="firstname">First name</label>
<input type="text" value="James" name="firstname" id="firstname">
</div>
<div class="input-group">
<label for="lastname">Last name</label>
<input type="text" value="Smith" name="lastname" id="lastname">
</div>
</div>
<div class="step step2 hidden">
<div class="input-group">
<label for="mail">E-mail</label>
<input type="mail" value="jamessmith#gmail.com" name="mail" id="mail">
</div>
<div class="input-group">
<label for="phone">Phone</label>
<input type="text" value="602-379-1395" name="phone" id="phone">
</div>
</div>
<div class="step step3 hidden">
<div class="input-group">
<label for="address">Address</label>
<input type="text" value="221B Baker Street" name="address" id="address">
</div>
<div class="input-group">
<label for="country">Country</label>
<input type="text" value="United States" name="country" id="country">
</div>
</div>
<div class="step step4 hidden">
<div class="input-group">
<label for="color">Favorite Color</label>
<input type="text" value="Blue" name="color" id="color">
</div>
<div class="input-group">
<label for="animal">Favorite Animal</label>
<input type="text" value="Lion" name="animal" id="animal">
</div>
</div>
<div class="step step5 hidden">
<h4>Name:</h4>
<p><strong>First Name:</strong> <span id="fNameOutput"></span></p>
<p><strong>Last Name:</strong> <span id="lNameOutput"></span></p>
<hr>
<h4>Contact:</h4>
<p><strong>Email:</strong> <span id="emailOutput"></span></p>
<p><strong>Phone:</strong> <span id="phoneOutput"></span></p>
<hr>
<h4>Location:</h4>
<p><strong>Address:</strong> <span id="addressOutput"></span></p>
<p><strong>Country:</strong> <span id="countryOutput"></span></p>
<hr>
<h4>Attributes:</h4>
<p><strong>Favorite Color:</strong> <span id="colorOutput"></span></p>
<p><strong>Favorite Animal:</strong> <span id="animalOutput"></span></p>
</div>
<div class="button-group">
<button id="previous" class="disabled button" disabled>
previous
</button>
<button id="next" class="button">
next
</button>
</div>
<div class="button-group">
<button id="validate" type="submit" class="hidden button">
Submit
</button>
</div>
</form>
There are 3 problems:
In this part next.addEventListener('click', function() {...}, it updates all texts every time the next button is pressed.
document.getElementById(ID_NAME).textContent = VALUE; is written repeatedly; It is not that bad but there are more readable ways.
The confirmation textContents are not updated when the last dot is clicked.
First, make a function to update texts. To avoid writing similar code repeatedly, you can use an Object for ids and for...of to implement updating the text contents.
function updateConfirmText() {
const map = {
firstname: 'fNameOutput',
lastname: 'lNameOutput',
mail: 'emailOutput',
phone: 'phoneOutput',
address: 'addressOutput',
country: 'countryOutput',
color: 'colorOutput',
animal: 'animalOutput'
};
for (const [input, output] of Object.entries(map)) {
document.getElementById(output).textContent = document.getElementById(input).value;
}
}
Second, call the function in the if statement that you have already written.
//if we reached final step
if (currentStep === numberOfSteps) {
enable(previousButton)
disable(nextButton)
show(submitButton)
updateConfirmText(); // Add
}
I hope it works🤞
I tried but can't get it after this so please help me with this.
I want to set the adult price in such a way that if private is selected than with ATV is 100 and without ATV is 10
but if shared is selected than with ATV is 50 and without ATV is 5
for children, if private is selected then with ATV is 50 and without ATV is 5
but if shared is selected then with ATV is 25 and without 3
function calculateTotal() {
const privateAdultPrice = 0;
const sharedAdultPrice = 0;
const privateChildrenPrice = 0;
const sharedChildrenPrice = 0;
const withAtvAdultPrice = 100;
const withAtvChildrenPrice = 80;
const noAtvPrice = 10;
const adults = +document.querySelector('#adults').value;
const children = +document.querySelector('#children').value;
const isPrivate = document.getElementById('private').checked;
const isWithAtv = document.getElementById('withatv').checked;
const adultTripPrice = isPrivate ? privateAdultPrice : sharedAdultPrice;
const childrenTripPrice = isPrivate ? privateChildrenPrice : sharedChildrenPrice;
const adultVehiclePrice = isWithAtv ? withAtvAdultPrice : noAtvPrice;
const childrenVehiclePrice = isWithAtv ? withAtvChildrenPrice : noAtvPrice;
const adultPrice = adults * (adultTripPrice + adultVehiclePrice)
const childrenPrice = children * (childrenTripPrice + childrenVehiclePrice)
return adultPrice + childrenPrice;
}
function updateTotal() {
const total = calculateTotal();
console.log(total);
document.querySelector('#totalPrice').innerHTML = total;
}
function increaseCount(e, el) {
var input = el.previousElementSibling;
var value = parseInt(input.value, 10);
value = isNaN(value) ? 0 : value;
value++;
input.value = value;
updateTotal();
}
function decreaseCount(e, el) {
var input = el.nextElementSibling;
var value = parseInt(input.value, 10);
if (value > 1) {
value = isNaN(value) ? 0 : value;
value--;
input.value = value;
}
updateTotal();
}
function decreaseCount2(e, el) {
var input = el.nextElementSibling;
var value = parseInt(input.value, 10);
if (value > 0) {
value = isNaN(value) ? 0 : value;
value--;
input.value = value;
}
updateTotal();
}
var MainImg = document.getElementById('MainImg');
var smallimg = document.getElementsByClassName('small-img');
smallimg[0].onclick = function () {
MainImg.src = smallimg[0].src;
};
smallimg[1].onclick = function () {
MainImg.src = smallimg[1].src;
};
smallimg[2].onclick = function () {
MainImg.src = smallimg[2].src;
};
smallimg[3].onclick = function () {
MainImg.src = smallimg[3].src;
};
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous"
/>
<style>
.small-img-group {
display: flex;
justify-content: space-between;
}
.small-img-col {
flex-basis: 24%;
cursor: pointer;
}
.counter1 {
float: left;
display: flex;
justify-content: space-between;
overflow-x: hidden;
overflow-y: hidden;
}
.counter2 {
float: left;
display: flex;
justify-content: space-between;
overflow-x: hidden;
overflow-y: hidden;
padding-left: 15px;
}
.up,
.down {
display: inline-block;
color: rgb(0, 0, 0);
font-size: 20px;
margin: 1px 1px;
cursor: pointer;
width: 15px;
line-height: 14px;
height: 16px;
text-align: center;
font-weight: bold;
border: 1px solid #000;
user-select: none;
}
.up:hover,
.down:hover {
color: #fd0b3f;
text-align: center;
}
.adults {
padding-right: 5px;
}
.children {
padding-right: 5px;
}
input {
appearance: none;
height: 21px;
text-align: center;
width: 42px;
line-height: 24px;
font-size: 15px;
border-radius: 5px;
}
.container {
display: flex;
width: 2000px
}
input[type='radio'] {
display: none;
}
label[for='private'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
margin-right: 10px;
}
label[for='shared'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
}
label[for='withatv'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
margin-right: 10px;
}
label[for='withoutatv'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
}
input[type='radio']:checked + label {
background-color: orangered;
color: white;
}
input[type='radio']:checked + label:before {
height: 16px;
width: 16px;
border: 10px solid white;
background-color: orangered;
}
</style>
</head>
<body>
<section class="container sproduct my-5 pt-5">
<div class="row mt-5">
<div class="col-lg-5 col-md-12 col-12">
<img
class="img-fluid w-100 pb-1"
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
alt=""
id="MainImg"
width="450"
/>
<div class="small-img-group">
<div class="small-img-col">
<img
src="https://media.tacdn.com/media/attractions-splice-spp-674x446/09/99/99/87.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
<div class="small-img-col">
<img
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
<div class="small-img-col">
<img
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
<div class="small-img-col">
<img
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
</div>
</div>
<div class="col-lg-6 col-md-12 col-12">
<h6>Home / Morning Safari</h6>
<h3>Morning Safari</h3>
<h2><label> Total:</label><label id="totalPrice"class="total Price"></label></h2>
<div class="counter1">
<label class="Adults">Adults</label>
<div class="down" onclick="decreaseCount(event, this)">-</div>
<input id="adults" type="text" value="1" readonly />
<div class="up" onclick="increaseCount(event, this)">+</div>
</div>
<div class="counter2">
<label class="Children">Children</label>
<div class="down" onclick="decreaseCount2(event, this)">-</div>
<input id="children" type="text" value="0" readonly />
<div class="up" onclick="increaseCount(event, this)">+</div>
</div>
<div class="container" style="padding-left: 0; padding-top: 5px">
<div>
<input
type="radio"
name="occupancy"
id="private"
checked="checked"
onclick="updateTotal()"
/>
<label for="private">Private</label>
<input
type="radio"
name="occupancy"
id="shared"
onclick="updateTotal()"
/>
<label for="shared">Shared</label>
</div>
<div>
<input
type="radio"
name="atv"
id="withatv"
checked="checked"
onclick="updateTotal()"
/>
<label for="withatv">With ATV</label>
<input
type="radio"
name="atv"
id="withoutatv"
onclick="updateTotal()"
/>
<label for="withoutatv">Without ATV</label>
</div>
</div>
</div>
</div>
</section>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"
></script>
<script>
</script>
</body>
</html>
hi
I tried but can't get it after this so please help me with this.
I want to set the adult price in such a way that if private is selected then with ATV is 100 and without ATV is 10
but if shared is selected than with ATV is 50 and without ATV is 5
for children, if private is selected then with ATV is 50 and without ATV is 5
but if shared is selected then with ATV is 25 and without 3
Now, your price is based on conditions.
So, the way to calculate is a little different. Translating your words, in JS code it'd be something like:
const adultTripPrice = isPrivate && isWithAtv ? 100 : isPrivate ? 10 : isWithAtv ? 50 : 5;
const childrenTripPrice = isPrivate && isWithAtv ? 50 : isPrivate ? 5 : isWithAtv ? 25 : 3;
const adultPrice = adults * (adultTripPrice)
const childrenPrice = children * (childrenTripPrice)
It evaluates for adults
isPrivate and isWithATV then 100
isPrivate (but not isWithATV) then 10
isWithATV (but not isPrivate) then 50
Not isPrivate neither isWithATV then 5.
And then multiplies that number for the number of Adults. (the same logic applies to Children)
The updated code would be like:
function calculateTotal() {
const privateAdultPrice = 0;
const sharedAdultPrice = 0;
const privateChildrenPrice = 0;
const sharedChildrenPrice = 0;
const withAtvAdultPrice = 100;
const withAtvChildrenPrice = 80;
const noAtvPrice = 10;
const adults = +document.querySelector('#adults').value;
const children = +document.querySelector('#children').value;
const isPrivate = document.getElementById('private').checked;
const isWithAtv = document.getElementById('withatv').checked;
const adultTripPrice = isPrivate && isWithAtv ? 100 : isPrivate ? 10 : isWithAtv ? 50 : 5;
const childrenTripPrice = isPrivate && isWithAtv ? 50 : isPrivate ? 5 : isWithAtv ? 25 : 3;
const adultPrice = adults * (adultTripPrice)
const childrenPrice = children * (childrenTripPrice)
return adultPrice + childrenPrice;
}
function updateTotal() {
const total = calculateTotal();
console.log(total);
document.querySelector('#totalPrice').innerHTML = total;
}
function increaseCount(e, el) {
var input = el.previousElementSibling;
var value = parseInt(input.value, 10);
value = isNaN(value) ? 0 : value;
value++;
input.value = value;
updateTotal();
}
function decreaseCount(e, el) {
var input = el.nextElementSibling;
var value = parseInt(input.value, 10);
if (value > 1) {
value = isNaN(value) ? 0 : value;
value--;
input.value = value;
}
updateTotal();
}
function decreaseCount2(e, el) {
var input = el.nextElementSibling;
var value = parseInt(input.value, 10);
if (value > 0) {
value = isNaN(value) ? 0 : value;
value--;
input.value = value;
}
updateTotal();
}
var MainImg = document.getElementById('MainImg');
var smallimg = document.getElementsByClassName('small-img');
smallimg[0].onclick = function () {
MainImg.src = smallimg[0].src;
};
smallimg[1].onclick = function () {
MainImg.src = smallimg[1].src;
};
smallimg[2].onclick = function () {
MainImg.src = smallimg[2].src;
};
smallimg[3].onclick = function () {
MainImg.src = smallimg[3].src;
};
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<!-- Bootstrap CSS -->
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
crossorigin="anonymous"
/>
<style>
.small-img-group {
display: flex;
justify-content: space-between;
}
.small-img-col {
flex-basis: 24%;
cursor: pointer;
}
.counter1 {
float: left;
display: flex;
justify-content: space-between;
overflow-x: hidden;
overflow-y: hidden;
}
.counter2 {
float: left;
display: flex;
justify-content: space-between;
overflow-x: hidden;
overflow-y: hidden;
padding-left: 15px;
}
.up,
.down {
display: inline-block;
color: rgb(0, 0, 0);
font-size: 20px;
margin: 1px 1px;
cursor: pointer;
width: 15px;
line-height: 14px;
height: 16px;
text-align: center;
font-weight: bold;
border: 1px solid #000;
user-select: none;
}
.up:hover,
.down:hover {
color: #fd0b3f;
text-align: center;
}
.adults {
padding-right: 5px;
}
.children {
padding-right: 5px;
}
input {
appearance: none;
height: 21px;
text-align: center;
width: 42px;
line-height: 24px;
font-size: 15px;
border-radius: 5px;
}
.container {
display: flex;
width: 2000px
}
input[type='radio'] {
display: none;
}
label[for='private'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
margin-right: 10px;
}
label[for='shared'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
}
label[for='withatv'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
margin-right: 10px;
}
label[for='withoutatv'] {
position: relative;
color: orangered;
font-size: 20px;
border: 2px solid orangered;
border-radius: 5px;
align-items: left;
display: flex;
cursor: pointer;
}
input[type='radio']:checked + label {
background-color: orangered;
color: white;
}
input[type='radio']:checked + label:before {
height: 16px;
width: 16px;
border: 10px solid white;
background-color: orangered;
}
</style>
</head>
<body>
<section class="container sproduct my-5 pt-5">
<div class="row mt-5">
<div class="col-lg-5 col-md-12 col-12">
<img
class="img-fluid w-100 pb-1"
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
alt=""
id="MainImg"
width="450"
/>
<div class="small-img-group">
<div class="small-img-col">
<img
src="https://media.tacdn.com/media/attractions-splice-spp-674x446/09/99/99/87.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
<div class="small-img-col">
<img
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
<div class="small-img-col">
<img
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
<div class="small-img-col">
<img
src="https://skylandtourism.com/wp-content/uploads/2018/03/Morning-Safari.jpg"
width="100%"
class="small-img"
alt=""
/>
</div>
</div>
</div>
<div class="col-lg-6 col-md-12 col-12">
<h6>Home / Morning Safari</h6>
<h3>Morning Safari</h3>
<h2><label> Total:</label><label id="totalPrice"class="total Price"></label></h2>
<div class="counter1">
<label class="Adults">Adults</label>
<div class="down" onclick="decreaseCount(event, this)">-</div>
<input id="adults" type="text" value="1" readonly />
<div class="up" onclick="increaseCount(event, this)">+</div>
</div>
<div class="counter2">
<label class="Children">Children</label>
<div class="down" onclick="decreaseCount2(event, this)">-</div>
<input id="children" type="text" value="0" readonly />
<div class="up" onclick="increaseCount(event, this)">+</div>
</div>
<div class="container" style="padding-left: 0; padding-top: 5px">
<div>
<input
type="radio"
name="occupancy"
id="private"
checked="checked"
onclick="updateTotal()"
/>
<label for="private">Private</label>
<input
type="radio"
name="occupancy"
id="shared"
onclick="updateTotal()"
/>
<label for="shared">Shared</label>
</div>
<div>
<input
type="radio"
name="atv"
id="withatv"
checked="checked"
onclick="updateTotal()"
/>
<label for="withatv">With ATV</label>
<input
type="radio"
name="atv"
id="withoutatv"
onclick="updateTotal()"
/>
<label for="withoutatv">Without ATV</label>
</div>
</div>
</div>
</div>
</section>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script
src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"
></script>
<script
src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"
></script>
<script>
</script>
</body>
</html>
I am trying to build a variable number of keyword boxes (the number of keyword boxes is handeld by php).
For better understanding I made three hardcoded html keyword boxes.
The final result should be multiple keyword boxes which can handle multiple keywords and show them after every ENTER in a seperated inner box. If I click on the BUTTON, all keywords should be alerted.
My current try is nearly working. You are able to type in keywords, store them by pressing enter.
But the inner keyword boxes are only shown, after klicking on the keyword box again.
I would be verry grateful if anybody could help me with this problem. :)
let tags = [];
let tagContainer = document.querySelectorAll('.tag-container');
tagContainer.forEach(function(foo) {
foo.addEventListener('click', (e) => {
//console.log(e.target.tagName);
//if (e.target.tagName === 'I') {
var tagLabel = e.target.getAttribute('data-item');
var index = tags.indexOf(tagLabel);
tags = [...tags.slice(0, index), ...tags.slice(index + 1)];
foo.querySelectorAll('.tag').forEach(tag => {
tag.parentElement.removeChild(tag);
});
tags.slice().reverse().forEach(tag => {
var div = document.createElement('div');
div.setAttribute('class', 'tag');
var span = document.createElement('span');
span.innerHTML = tag;
var closeIcon = document.createElement('i');
closeIcon.innerHTML = 'close';
closeIcon.setAttribute('class', 'material-icons');
closeIcon.setAttribute('data-item', tag);
div.appendChild(span);
div.appendChild(closeIcon);
foo.prepend(div);
});
//}
})
});
let input = document.querySelectorAll('.tag-container input');
input.forEach(function(bar) {
bar.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
e.target.value.split(',').forEach(tag => {
tags.push(tag);
});
bar.querySelectorAll('.tag').forEach(tag => {
tag.parentElement.removeChild(tag);
});
tags.slice().reverse().forEach(tag => {
var div = document.createElement('div');
div.setAttribute('class', 'tag');
var span = document.createElement('span');
span.innerHTML = tag;
var closeIcon = document.createElement('i');
closeIcon.innerHTML = 'close';
closeIcon.setAttribute('class', 'material-icons');
closeIcon.setAttribute('data-item', tag);
div.appendChild(span);
div.appendChild(closeIcon);
bar.prepend(div);
});
bar.value = '';
}
bar.focus();
})
});
function clicked() {
alert(JSON.stringify(tags));
}
.container {
width: 20%;
margin: 40px;
align-self: center;
}
.tag-container {
border: 2px solid #ccc;
padding: 10px;
border-radius: 5px;
display: flex;
}
.tag-container .tag {
padding: 5px;
border: 1px solid #ccc;
display: flex;
align-items: center;
margin: 5px;
border-radius: 3px;
background: #f2f2f2;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2), inset 0 1px 1px #fff;
cursor: default;
}
.tag i {
font-size: 16px;
margin-left: 5px;
}
.tag-container input {
flex: 1;
font-size: 16px;
padding: 5px;
outline: none;
border: 0;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<table>
<td>
<div class="tag-container">
<div id="span_tag">
<span id="span_key" value=""></span>
<i class="material-icons">close</i>
</div>
<input id="input_search" value="" />
</div>
</tr>
</td>
<td><button type="button" id="bt" onclick="clicked()">Button</button>
<td/>
</table>
<table>
<td>
<div class="tag-container">
<div id="span_tag">
<span id="span_key" value=""></span>
<i class="material-icons">close</i>
</div>
<input id="input_search" value="" />
</div>
</tr>
</td>
<td><button type="button" id="bt" onclick="clicked()">Button</button>
<td/>
</table>
<table>
<td>
<div class="tag-container">
<div id="span_tag">
<span id="span_key" value=""></span>
<i class="material-icons">close</i>
</div>
<input id="input_search" value="" />
</div>
</tr>
</td>
<td><button type="button" id="bt" onclick="clicked()">Button</button>
<td/>
</table>
re
const tagContainerNodes = document.querySelectorAll(".tag-container");
tagContainerNodes.forEach((tagContainerNode) => {
const input = tagContainerNode.querySelector("input");
input.addEventListener("keyup", e => {
if (e.key === "Enter") {
createTag(e.target.value, tagContainerNode, input);
e.target.value = "";
}
});
});
function createTag(tagName, parent, before) {
var div = document.createElement("div");
div.setAttribute("class", "tag");
var span = document.createElement("span");
span.innerHTML = tagName;
div.appendChild(span);
parent.insertBefore(div, before)
}
function clicked() {
const allTagText = [];
tagContainerNodes.forEach((tagContainerNode) => {
const tagNodes = tagContainerNode.querySelectorAll(".tag");
tagNodes.forEach((tagNode) => {
allTagText.push(tagNode.textContent);
});
});
console.log(allTagText);
}
.tag-container {
border: 2px solid #ccc;
padding: 10px;
border-radius: 5px;
display: flex;
}
.tag-container .tag {
padding: 5px;
border: 1px solid #ccc;
margin: 5px;
border-radius: 3px;
background: #f2f2f2;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2), inset 0 1px 1px #fff;
}
.tag-container input {
font-size: 16px;
padding: 5px;
outline: none;
border: 0;
}
<div class="tag-container">
<input id="input_search" />
</div>
<button type="button" onclick="clicked()">Button</button>
<div class="tag-container">
<input id="input_search" />
</div>
<button type="button" onclick="clicked()">Button</button>
<div class="tag-container">
<input id="input_search" />
</div>
<button type="button" onclick="clicked()">Button</button>
I would like to create a new row with product name, product cost, product quantity, product sum and a delete button. Exactly as the structure of the two first rows in the example. I believe I can use insertAdjacentHTML, but I cant get it to work.
I have defined name, unitPrice, quantityInput, itemSum and deleteButton. These five html strings I would like to append to rowDiv and after append rowDiv after the last row (last product in the list). What am I doing wrong? I have attached the code below:
function createNewItemRow:
function createNewItemRow() {
const newProductName = document.getElementById("new-product-name");
const newProductCostPerUnit = document.getElementById(
"new-product-cost-per-unit",
);
const name = `<div><span class="product-name">${newProductName.value}</span></div>`;
const unitPrice = `<div>$<span class="cost-per-unit">${newProductCostPerUnit.value}</span></div>`;
const quantityInput =
'<div><span>QTY</span><input type="text" name="quantity" class="quantity"></div>';
const itemSum = '<div>$<span class="item-sum">0.00</span></div>';
const deleteButton =
'<div><button class="btn btn-delete">Delete</button></div>';
const container = document.getElementById("container");
const rowItem = container.lastChild;
const rowDiv = document.createElement("div");
rowDiv.setAttribute("class", "row");
// USE insertAdjacentHTML and add:
const string = name + unitPrice + itemSum + deleteButton;
rowDiv.insertAdjacentHTML("beforeend", string);
// Append the rowDiv with the new data to after last row inside the container.
rowItem.appendChild(rowDiv);
}
function deleteItem(e) {
const del = e.currentTarget.parentElement.parentElement;
const parent = del.parentElement;
parent.removeChild(del);
getTotalPrice();
}
function getTotalPrice() {
const costPerUnit = document.getElementsByClassName("cost-per-unit");
const inputValue = document.getElementsByClassName("quantity");
const itemSum = document.getElementsByClassName("item-sum");
const totalPrice = document.getElementById("total-price");
let total = 0;
for (let i = 0; i < costPerUnit.length; i++) {
const sum = costPerUnit[i].innerHTML * inputValue[i].value;
itemSum[i].innerHTML = sum;
total += sum;
}
totalPrice.innerHTML = total;
}
function createNewItemRow() {
const newProductName = document.getElementById("new-product-name");
const newProductCostPerUnit = document.getElementById(
"new-product-cost-per-unit",
);
const name = `<div><span class="product-name">${newProductName.value}</span></div>`;
const unitPrice = `<div>$<span class="cost-per-unit">${newProductCostPerUnit.value}</span></div>`;
const quantityInput =
'<div><span>QTY</span><input type="text" name="quantity" class="quantity"></div>';
const itemSum = '<div>$<span class="item-sum">0.00</span></div>';
const deleteButton =
'<div><button class="btn btn-delete">Delete</button></div>';
const container = document.getElementById("container");
const rowItem = container.lastChild;
const rowDiv = document.createElement("div");
rowDiv.setAttribute("class", "row");
// USE insertAdjacentHTML and add:
const string = name + unitPrice + itemSum + deleteButton;
rowDiv.insertAdjacentHTML("beforeend", string);
// Append the rowDiv with the new data to after last row inside the container.
rowItem.appendChild(rowDiv);
}
function refreshItems(deleteButtons) {
for (var i = 0; i < deleteButtons.length; i++) {
deleteButtons[i].onclick = deleteItem;
}
}
window.onload = function() {
const calculatePriceButton = document.getElementById("calc-prices-button");
const createItemButton = document.getElementById("new-item-create");
const deleteButtons = document.getElementsByClassName("btn-delete");
refreshItems(deleteButtons);
};
input {
border: solid 1px black;
}
#new-product-name {
width: 130px;
}
#new-product-cost-per-unit {
width: 120px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 20px;
}
.row-new-product {
margin: 20px;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-delete {
color: #fff;
background-color: #cf000f;
border-color: #cf000f;
}
.quantity {
margin: 0 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="./css/style.css">
<script type="text/javascript" src="./js/index.js"></script>
<title>Ironhack cart</title>
</head>
<body>
<div id="container">
<div class="row">
<div>
<span class="product-name">IronBubble-head</span>
</div>
<div>
$
<span class="cost-per-unit">25</span>
</div>
<div>
<span>QTY</span>
<input type="text" name="quantity" class="quantity">
</div>
<div>
$
<span class="item-sum">0.00</span>
</div>
<div>
<button class="btn btn-delete">Delete</button>
</div>
</div>
<div class="row">
<div>
<span class="product-name">IronBubble-foot</span>
</div>
<div>
$
<span class="cost-per-unit">50</span>
</div>
<div>
<span>QTY</span>
<input type="text" name="quantity" class="quantity">
</div>
<div>
$
<span class="item-sum">0.00</span>
</div>
<div>
<button class="btn btn-delete">Delete</button>
</div>
</div>
</div>
<div class="row-new-product">
<div>
Product:
<input type="text" id="new-product-name">
</div>
<div>
Cost:
<input type="text" id="new-product-cost-per-unit">
</div>
<div>
<button class="btn btn-success" onclick="createNewItemRow()">Create</button>
</div>
</div>
<div class="wrapper ">
<button class="btn btn-success" id="calc-prices-button " onclick="getTotalPrice() ">Calculate Prices</button>
Total Price $
<span id="total-price">0.00</span>
</div>
</body>
</html>
You need to make 4 changes and the add row will work.
function createNewItemRow() {
//rowItem is not needed
//const rowItem = container.lastChild;
//added quantityInput
const string = name + unitPrice + quantityInput + itemSum + deleteButton;
//changed rowDiv.insertAdjacentHTML("beforeend", string); to:
rowDiv.innerHTML = string;
// changed rowItem.appendChild(rowDiv); to:
container.appendChild(rowDiv);
}
Here are the changes made in your code:
function deleteItem(e) {
const del = e.currentTarget.parentElement.parentElement;
const parent = del.parentElement;
parent.removeChild(del);
getTotalPrice();
}
function getTotalPrice() {
const costPerUnit = document.getElementsByClassName("cost-per-unit");
const inputValue = document.getElementsByClassName("quantity");
const itemSum = document.getElementsByClassName("item-sum");
const totalPrice = document.getElementById("total-price");
let total = 0;
for (let i = 0; i < costPerUnit.length; i++) {
const sum = costPerUnit[i].innerHTML * inputValue[i].value;
itemSum[i].innerHTML = sum.toFixed(2);
total += sum;
}
totalPrice.innerHTML = total.toFixed(2);
}
function createNewItemRow() {
const deleteButtons = document.getElementsByClassName("btn-delete");
const newProductName = document.getElementById("new-product-name");
const newProductCostPerUnit = document.getElementById(
"new-product-cost-per-unit",
);
const name = `<div><span class="product-name">${newProductName.value}</span></div>`;
const unitPrice = `<div>$<span class="cost-per-unit">${newProductCostPerUnit.value}</span></div>`;
const quantityInput =
'<div><span>QTY</span><input type="number" name="quantity" class="quantity"></div>';
const itemSum = '<div>$<span class="item-sum">0.00</span></div>';
const deleteButton =
'<div><button class="btn btn-delete">Delete</button></div>';
const container = document.getElementById("container");
const rowDiv = document.createElement("div");
rowDiv.setAttribute("class", "row");
const string = name + unitPrice + quantityInput + itemSum + deleteButton;
rowDiv.innerHTML = string;
container.appendChild(rowDiv);
refreshItems(deleteButtons);
}
function refreshItems(deleteButtons) {
for (var i = 0; i < deleteButtons.length; i++) {
deleteButtons[i].onclick = deleteItem;
}
}
window.onload = function() {
const deleteButtons = document.getElementsByClassName("btn-delete");
refreshItems(deleteButtons);
};
input {
border: solid 1px black;
}
#new-product-name {
width: 130px;
}
#new-product-cost-per-unit {
width: 120px;
}
.row {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 20px;
}
.row-new-product {
margin: 20px;
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-delete {
color: #fff;
background-color: #cf000f;
border-color: #cf000f;
}
.quantity {
margin: 0 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<link rel="stylesheet" href="./css/style.css">
<script type="text/javascript" src="./js/index.js"></script>
<title>Ironhack cart</title>
</head>
<body>
<div id="container">
<div class="row">
<div>
<span class="product-name">IronBubble-head</span>
</div>
<div>
$
<span class="cost-per-unit">25.00</span>
</div>
<div>
<span>QTY</span>
<input type="number" name="quantity" class="quantity">
</div>
<div>
$
<span class="item-sum">0.00</span>
</div>
<div>
<button class="btn btn-delete">Delete</button>
</div>
</div>
<div class="row">
<div>
<span class="product-name">IronBubble-foot</span>
</div>
<div>
$
<span class="cost-per-unit">50.00</span>
</div>
<div>
<span>QTY</span>
<input type="number" name="quantity" class="quantity">
</div>
<div>
$
<span class="item-sum">0.00</span>
</div>
<div>
<button class="btn btn-delete">Delete</button>
</div>
</div>
</div>
<div class="row-new-product">
<div>
Product:
<input type="text" id="new-product-name">
</div>
<div>
Cost:
<input type="number" id="new-product-cost-per-unit">
</div>
<div>
<button class="btn btn-success" onclick="createNewItemRow()">Create</button>
</div>
</div>
<div class="wrapper ">
<button class="btn btn-success" id="calc-prices-button " onclick="getTotalPrice() ">Calculate Prices</button>
Total Price $
<span id="total-price">0.00</span>
</div>
</body>
</html>