Undefined input value in table - javascript

I am having a problem with a table I'm making with Javascript. The table itself and its functions are working quite nice, but the one thing I am struggling with is submitting the value, and making it be not "undefined".
Provided code is below(values and functions are named in Norwegian, but I hope it is understandable nevertheless).
let skjema = document.getElementById("skjema");
let inpAar = document.getElementById("inpAar");
let inpPromille = document.getElementById("inpPromille");
let inpFart = document.getElementById("inpFart");
let tabell = document.getElementById("tabell");
let lovbruddene = new Map();
lovbruddene.set("2008" , { promille: 9631, fart: 9863});
lovbruddene.set("2009" , { promille: 8593, fart: 12217});
lovbruddene.set("2010" , { promille: 8363, fart: 14920});
lovbruddene.set("2011" , { promille: 8128, fart: 14929});
lovbruddene.set("2012" , { promille: 8514, fart: 15425});
function lagreData(evt){
evt.preventDefault();
if (!lovbruddene.has(inpAar.value)) {
lovbruddene.set(inpAar.value, {})
}
let lovbrudd = lovbruddene.get(inpAar.value);
lovbrudd.promille = Number(inpPromille.value);
lovbrudd.fart = Number(inpFart.value);
lagTabell();
}
function finnAar(){
if (lovbruddene.has(inpAar.value)) {
let lovbrudd = lovbruddene.get(inpAar.value);
inpPromille.value = lovbrudd.promille;
inpFart.value = lovbrudd.fart;
} else {
inpPromille = "";
inpFart = "";
}
}
function slett(key){
lovbruddene.delete(key);
lagTabell();
}
function lagTabell() {
tabell.innerHTML = "";
for ( let [key, lovbrudd] of lovbruddene) {
tabell.innerHTML += `
<tr>
<td>${key}</td>
<td>${lovbrudd.promille}</td>
<td>${lovbrudd.fart}</td>
<td>${lovbrudd.fart + lovbrudd.promille}</td>
<td>
<button onclick="slett('${key}')"class="button tiny">X</button>
</td>
</tr>
`;
}
}
lagTabell();
inpAar.addEventListener("input", finnAar);
skjema.addEventListener("submit", lagreData);

Related

Async/await function to show, wait, hide overlay not working in javascript

I'm having a problem with showing an overlay div element and then hiding it again after the runSearch() function has completed. In short, the overlay does not appear at all.
What the overlay should look like if it worked:
If I had to guess, I believe it could relate to a misunderstanding about how to implement async/await correctly in javascript.
Since I am limited for space here, the full Github project is accessible as a fully deployed page here, if you need more context. However, the most relevant excerpts are below:
The overlay div element in index.html:
<div class="overlay d-flex justify-content-center align-items-center">
<h5>Please wait...</h5>
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
The overlay in CSS:
.overlay {
background-color:#EFEFEF;
position: fixed;
width: 100%;
height: 100%;
z-index: 1000;
left: 0px;
display: none!important;
/* without !important, the overlay would immediately kick into effect */
}
The JS functions which show and hide the overlay when called upon:
function loadingOverlayOn() {
document
.getElementsByClassName("overlay")[0]
.style.display = 'block'
}
function loadingOverlayOff() {
document
.getElementsByClassName("overlay")[0]
.style.display = 'none'
}
JS with respect to button #1:
cityInstanceBtn.addEventListener('click',async function(e){
// for use in headings inside runSearch
// reset
globalCityName === null;
globalCityState === null;
globalCityCountry === null;
globalCityName = e.target.dataset.city
globalCityState = e.target.dataset.state
globalCityCountry = e.target.dataset.country
loadingOverlayOn();
await runSearch(cityName, cityState, cityCountry, cityLat, cityLng, units)
loadingOverlayOff();
})
JS with respect to button #2, which occurs inside of a temporarily displayed Bootstrap modal:
cityInstanceBtn.addEventListener('click', async function(){
myModal.hide()
globalCityName = document.getElementById(id).dataset.city
globalCityState = document.getElementById(id).dataset.state
globalCityCountry = document.getElementById(id).dataset.country
loadingOverlayOn();
await runSearch(cityName, cityState, cityCountry, cityLat, cityLng, units)
loadingOverlayOff();
})
The JS function during which the overlay should be shown, and hidden once its execution is complete:
async function runSearch(
cityName,
cityState,
country,
cityLat,
cityLng,
detectedUnits
) {
console.log("check cityState: " + cityState);
console.log("check globalCityState: " + globalCityState);
var h2Today = document.getElementById("today-title");
var h2Next5Days = document.getElementById("next-5-days-title");
if (globalCityState != "undefined" && globalCityName && globalCityCountry) {
h2Today.innerHTML = `<span class="orange">Today's</span> forecast for <span class="cornflowerblue">${globalCityName}, ${globalCityState}, ${globalCityCountry}</span>`;
h2Next5Days.innerHTML = `<span class="orange">4-day</span> outlook for <span class="cornflowerblue">${globalCityName}, ${globalCityState}, ${globalCityCountry}</span>`;
} else if (
(globalCityState = "undefined" && globalCityName && globalCityCountry)
) {
h2Today.innerHTML = `<span class="orange">Today's</span> forecast for <span class="cornflowerblue">${globalCityName},${globalCityCountry}</span>`;
h2Next5Days.innerHTML = `<span class="orange">4-day</span> outlook for <span class="cornflowerblue">${globalCityName}, ${globalCityCountry}</span>`;
}
var newSearchObject = {
cityName: cityName,
cityState: cityState,
cityCountry: country,
cityLat: cityLat,
cityLng: cityLng,
detectedUnits: detectedUnits,
};
var retrievedLocalStorage = localStorage.getItem("savedCities");
retrievedLocalStorage = JSON.parse(retrievedLocalStorage);
// const arr = retrievedLocalStorage.map(a => {a.cityLat, a.cityLng})
if (retrievedLocalStorage === null) {
localStorage.setItem("savedCities", JSON.stringify([newSearchObject]));
generatePrevCitiesList();
} else if (
retrievedLocalStorage.length > 0 &&
retrievedLocalStorage.length < 5
) {
retrievedLocalStorage.reverse();
if (
!retrievedLocalStorage.some((s) => {
return (
s.cityLat == newSearchObject.cityLat &&
s.cityLng == newSearchObject.cityLng
);
})
) {
// Check if an array of objects contains another object: https://stackoverflow.com/a/63336477/9095603
// this solution which converts objects to string first isn't entirely reliable if you can't guarantee the same order is preserved, for example: https://stackoverflow.com/a/201305/9095603
retrievedLocalStorage.push(newSearchObject);
retrievedLocalStorage.reverse();
console.log("existingSearchObject2: " + retrievedLocalStorage);
localStorage.setItem(
"savedCities",
JSON.stringify(retrievedLocalStorage)
);
}
generatePrevCitiesList();
} else if (retrievedLocalStorage.length >= 5) {
retrievedLocalStorage.reverse();
if (
!retrievedLocalStorage.some((s) => {
return (
s.cityLat == newSearchObject.cityLat &&
s.cityLng == newSearchObject.cityLng
);
})
) {
retrievedLocalStorage.push(newSearchObject);
}
while (retrievedLocalStorage.length > 5) {
retrievedLocalStorage.shift();
}
retrievedLocalStorage.reverse();
localStorage.setItem("savedCities", JSON.stringify(retrievedLocalStorage));
generatePrevCitiesList();
}
fetch(
`https://api.openweathermap.org/data/2.5/forecast?lat=${cityLat}&lon=${cityLng}&units=${detectedUnits}&appid=${apiKey}`
)
.then((response) => response.json())
.then((data) => {
console.log(data);
console.table(data.list);
console.log(JSON.stringify(data));
var timezone = data.city.timezone;
console.log({ timezone });
var country = data.city.country;
console.log({ country });
var cityName = data.city.name;
console.log({ cityName });
var datesArray = [];
console.log({ datesArray });
const days = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
// var h2Today = document.getElementById('today-title')
// h2Today.innerHTML = `<span class="orange">Today's</span> forecast for <span class="cornflowerblue">${globalCityName}, ${globalCityState}, ${globalCityCountry}</span>`
// }
// h2Today.innerHTML = `<span class="orange">Today's</span> forecast for <span class="cornflowerblue">${globalCityName},${globalCityCountry}</span>`
// }
for (let i = 0; i < data.list.length; i++) {
var unixTimestamp = data.list[i].dt;
console.log(data.list[i].dt);
// you don't need it for dt_txt but if you want to use the unix timestamp in the data, you can do this conversion:
var jsTimestamp = unixTimestamp * 1000;
var date = new Date(jsTimestamp);
var basicDateLocalAU = date.toLocaleDateString("en-AU");
var basicDateLocalUS = date.toLocaleDateString("en-US");
var basicDateLocalUser = date.toLocaleDateString(`en-${country}`);
console.log(basicDateLocalAU); // Prints: 5/6/2022
console.log(basicDateLocalUS); // Prints: 6/5/2022
console.log(basicDateLocalUser); // Prints: 6/5/2022
var timeLocalAU = date.toLocaleTimeString("en-AU", {
hour: "2-digit",
minute: "2-digit",
}); // Prints: 13:10:34
// https://stackoverflow.com/a/20430558/9095603
// https://bobbyhadz.com/blog/javascript-typeerror-date-getday-is-not-a-function#:~:text=getDay%20is%20not%20a%20function%22%20error%20occurs%20when%20the%20getDay,method%20on%20valid%20date%20objects.
data.list[i].basicDateLocalAU = basicDateLocalAU;
data.list[i].basicDateLocalUS = basicDateLocalUS;
data.list[i].basicDateLocalUser = basicDateLocalUser;
data.list[i].dayOfWeekIndex = date.getDay();
data.list[i].dayOfWeekValue = days[date.getDay()];
data.list[i].basicTime = timeLocalAU;
// https://bobbyhadz.com/blog/javascript-array-push-if-not-exist
if (!datesArray.includes(basicDateLocalUser)) {
datesArray.push(basicDateLocalUser);
var dayOfWeek = days[date.getDay()];
console.log(dayOfWeek);
}
}
console.log({ date });
console.log({ data });
var datalist = data.list;
console.log({ datalist });
var obj = groupBy(datalist, "basicDateLocalAU");
console.log({ obj });
// const result = data.list.group(({ basicCalendarDateAU }) => basicCalendarDateAU);
for (let i = 0; i < obj.length; i++) {
var dayTableEle = document.querySelector(`#day${i} table`);
// var textNode = document.createTextNode(`${dayOfWeekValue}`);
dayTableEle.innerHTML = `<row><th>Time</th><th>Temp</th><th></th><th>Conditions</th><th>Humidity</th><th>Wind speed</th></row>`;
for (let j = 0; j < obj[i].length; j++) {
console.log(obj[i].length);
if (!document.querySelector(`#day${i} h5`).innerText) {
document.querySelector(
`#day${i} h5`
).innerText = `${obj[i][j].dayOfWeekValue}`;
}
if (
!document.querySelector(`#day${i} span#usercountry-dateformat`)
.innerText
) {
document.querySelector(
`#day${i} span#usercountry-dateformat`
).innerText = `${obj[i][j].basicDateLocalUser}`;
}
if (
!document.querySelector(`#day${i} span#AU-dateformat`).innerText
) {
document.querySelector(
`#day${i} span#AU-dateformat`
).innerText = `${obj[i][j].basicDateLocalAU}`;
document
.querySelector(`#day${i} span#AU-dateformat`)
.style.setProperty("display", "none");
}
if (
!document.querySelector(`#day${i} span#US-dateformat`).innerText
) {
document.querySelector(
`#day${i} span#US-dateformat`
).innerText = `${obj[i][j].basicDateLocalUS}`;
document
.querySelector(`#day${i} span#US-dateformat`)
.style.setProperty("display", "none");
}
// var kelvinToCelcius = obj[i][j].main.temp - 273.15;
var tempMetric;
var tempImperial;
var windSpeedImperial;
var windSpeedMetric;
if (units == "metric") {
var tempMetric = obj[i][j].main.temp;
tempMetric = roundedToFixed(tempMetric, 1);
var tempImperial = tempMetric * 1.8 + 32;
tempImperial = roundedToFixed(tempImperial, 1);
var windSpeedMetric = obj[i][j].wind.speed;
windSpeedMetric = roundedToFixed(windSpeedMetric, 1);
var windSpeedImperial = windSpeedMetric * 2.23694;
windSpeedImperial = roundedToFixed(windSpeedImperial, 1);
var metricDisplay = "inline";
var imperialDisplay = "none";
} else if (units == "imperial") {
var tempImperial = obj[i][j].main.temp;
tempImperial = roundedToFixed(tempImperial, 1);
var tempMetric = (tempImperial - 32) / 1.8;
tempMetric = roundedToFixed(tempMetric, 1);
var windSpeedImperial = obj[i][j].wind.speed;
windSpeedImperial = roundedToFixed(windSpeedImperial, 1);
var windSpeedMetric = windSpeedImperial / 2.23694;
windSpeedMetric = roundedToFixed(windSpeedMetric, 1);
var metricDisplay = "none";
var imperialDisplay = "inline";
}
dayTableEle.innerHTML += `
<row>
<td id="tdTime">${obj[i][j].basicTime}</td>
<td id="tdTemp">
<span class="temp-metric metric" style="display:${metricDisplay};">${tempMetric} ${tempUnitsMetric}</span>
<span class="temp-imperial imperial" style="display:${imperialDisplay};">${tempImperial} ${tempUnitsImperial}</span>
</td>
<td><img src="https://openweathermap.org/img/wn/${obj[i][j].weather[0].icon}.png" alt="weather icon"></td>
<td id="tdConditions">${obj[i][j].weather[0].description}</td>
<td id="tdHumidity">${obj[i][j].main.humidity} %</td>
<td id="tdWindSpeed">
<span class="windspeed-metric metric" style="display:${metricDisplay};">${windSpeedMetric} ${windSpeedUnitsMetric}</span>
<span class="windspeed-imperial imperial" style="display:${imperialDisplay};">${windSpeedImperial} ${windSpeedUnitsImperial}</span>
</td>
<td id="tdWindDir"><i style="transform: rotate(${obj[i][j].wind.deg}deg)" class="fa-solid fa-arrow-up"></i></td>
</row>
`;
}
}
});
}
We can see here that the event listener is properly attached - this is true of both buttons but I'll show one here just to be representative:
Full Github project is accessible as a fully deployed page here.
To reiterate, the problem is that the overlay does not appear at all during this sequence of events and I'm seeing page elements prematurely before the page is built:
loadingOverlayOn();
await runSearch(cityName, cityState, cityCountry, cityLat, cityLng, units)
loadingOverlayOff();
You are not awaiting fetch, you are using then instead.
You have to await fetch
See below example
const response = await fetch(url);
const jsonData = await response.json()

Interact between values

I'm wondering how to stop counting money (iloscPieniedzy) when HP (iloscZycia) is 0 in this code:
let iloscZycia = 20;
const sumaZycia = document.getElementById("suma-zycia");
const dodajZycie = document.getElementById('dodaj-zycie');
const odejmijZycie = document.getElementById('odejmij-zycie');
dodajZycie.addEventListener("click", function() {
iloscZycia++;
sumaZycia.textContent = iloscZycia;
});
odejmijZycie.addEventListener("click", function() {
iloscZycia = iloscZycia - 5;
if (iloscZycia <= 0) {
iloscZycia = 0
};
sumaZycia.textContent = iloscZycia;
});
let iloscPieniedzy = 0;
const sumaPieniedzy = document.getElementById("suma-pieniedzy");
const dodajPieniadze = document.getElementById('dodaj-pieniadze');
const odejmijPieniadze = document.getElementById('odejmij-pieniadze');
dodajPieniadze.addEventListener("click", function() {
iloscPieniedzy = iloscPieniedzy + 10;
sumaPieniedzy.textContent = iloscPieniedzy;
});
odejmijPieniadze.addEventListener("click", function() {
iloscPieniedzy = iloscPieniedzy - 1;
if (iloscPieniedzy <= 0) {
iloscPieniedzy = 0
};
sumaPieniedzy.textContent = iloscPieniedzy;
});
I tried something like this:
if (sumaZycia=0){
sumaPieniedzy=0
};
but even this doesn't work like it's not connected.
the = operator is used to assign values to variables what you're looking for is the equality operator ===.
so try it like this:
if (iloscZycia === 0){
iloscPieniedzy = 0
};
Because Stack Overflow is an English language site, I've renamed your variables and created a map of the new names to previous names in comments at the top of the JavaScript below.
If you create a functional closure for updating your numeric variables, you can encapsulate the necessary logic for only updating money when hp is not equal to 0.
Here's a working example in a code snippet:
// hp: iloscZycia
// element1: sumaZycia
// element2: dodajZycie
// element3: odejmijZycie
// money: iloscPieniedzy
// element4: sumaPieniedzy
// element5: dodajPieniadze
// element6: odejmijPieniadze
let hp = 20;
const adjustHp = (amount) => {
hp += amount;
if (hp < 0) hp = 0;
element1.textContent = hp;
};
const element1 = document.getElementById("suma-zycia");
const element2 = document.getElementById("dodaj-zycie");
const element3 = document.getElementById("odejmij-zycie");
element1.textContent = hp;
element2.addEventListener("click", () => adjustHp(1));
element3.addEventListener("click", () => adjustHp(-5));
let money = 0;
const adjustMoney = (amount) => {
// Update money, but ONLY if hp is not 0:
if (hp !== 0) {
money += amount;
if (money < 0) money = 0;
}
element4.textContent = money;
};
const element4 = document.getElementById("suma-pieniedzy");
const element5 = document.getElementById("dodaj-pieniadze");
const element6 = document.getElementById("odejmij-pieniadze");
element4.textContent = money;
element5.addEventListener("click", () => adjustMoney(10));
element6.addEventListener("click", () => adjustMoney(-1));
.group { display: flex; gap: 0.5rem; }
<h2>HP</h2>
<div class="group">
<button id="odejmij-zycie">-</button>
<div id="suma-zycia">0</div>
<button id="dodaj-zycie">+</button>
</div>
<h2>Money</h2>
<div class="group">
<button id="odejmij-pieniadze">-</button>
<div id="suma-pieniedzy">0</div>
<button id="dodaj-pieniadze">+</button>
</div>

How can I decrease loading time of scripts in vue.js?

Issues
I am building a card builder app and the builder is split into three sections; the create (user enters details), the builder (using vue.draggable user can drag stamps on to card) and the preview (card is displayed to user).
I use jQuery to fade each section in and out and I want to increase the speed of the loading time - my issues is that when the build section is first loaded in, it takes a long time, but then it works as expected.
Failed Solutions
I first thought that is was the png stamp images that were increasing the loading time and so I uploaded them to compress.io and this decreased the image sizes from 406KB to 82KB
I then research some solutions and tried compressing the jQuery the original file looks like this:
$(document).ready(function () {
let btn1 = $('#btn-1')
let btn2 = $('#btn-2')
let btn3 = $('#btn-3')
let btn1Txt = $('#btn-1-txt')
let btn2Txt = $('#btn-2-txt')
let btn3Txt = $('#btn-3-txt')
let create = $('.create-container')
let build = $('.build-container')
let preview = $('.preview-container')
let cardTitle
let cardDescription
let logoAlign
let logoShape
let cardSlots
let cardColour
btn1.addClass('active-btn')
btn1Txt.addClass('active-txt')
create.fadeIn(250)
btn1.click(function () {
btn1.addClass('active-btn')
btn1Txt.addClass('active-txt')
btn2.removeClass('active-btn')
btn2Txt.removeClass('active-txt')
btn3.removeClass('active-btn')
btn3Txt.removeClass('active-txt')
build.fadeOut(100)
preview.fadeOut(100)
create.delay(250).fadeIn(100)
});
btn2.click(function () {
btn2.addClass('active-btn')
btn2Txt.addClass('active-txt')
btn1.removeClass('active-btn')
btn1Txt.removeClass('active-txt')
btn3.removeClass('active-btn')
btn3Txt.removeClass('active-txt')
create.fadeOut(100)
preview.fadeOut(100)
build.delay(250).fadeIn(100)
});
btn3.click(function () {
btn3.addClass('active-btn')
btn3Txt.addClass('active-txt')
btn1.removeClass('active-btn')
btn1Txt.removeClass('active-txt')
btn2.removeClass('active-btn')
btn2Txt.removeClass('active-txt')
create.fadeOut(100)
build.fadeOut(100)
preview.delay(250).fadeIn(100)
});
let titleHelper = $('#title-helper')
let titleHelpShow = $('#title-helper-show')
let titleHelpHide = $('#title-helper-close')
let titleInput = $('#title-input')
let descHelper = $('#desc-helper')
let descHelpShow = $('#desc-helper-show')
let descHelpHide = $('#desc-helper-close')
let descInput = $('#desc-input')
let logoHelper = $('#logo-helper')
let logoHelpShow = $('#logo-helper-show')
let logoHelpHide = $('#logo-helper-close')
let logoShapeHelper = $('#logo-shape-helper')
let logoShapeHelpShow = $('#logo-shape-helper-show')
let logoShapeHelpHide = $('#logo-shape-helper-close')
let colourHelper = $('#colour-helper')
let colourHelpShow = $('#colour-helper-show')
let colourHelpHide = $('#colour-helper-close')
let colourInput = $('#colour-input')
let numHelper = $('#num-helper')
let numHelpShow = $('#num-helper-show')
let numHelpHide = $('#num-helper-close')
let numInput = $('#num-input')
let alignLeft = $('#align-left-opt')
let alignCenter = $('#align-center-opt')
let alignRight = $('#align-right-opt')
let circleLogo = $('#circle-logo')
let squareLogo = $('#square-logo')
let stamp5 = $('#stamps-5')
let stamp10 = $('#stamps-10')
let stamp15 = $('#stamps-15')
let colourPicker = $('#colour-input')
titleHelpShow.click(function() {titleHelper.fadeIn(200)});
titleHelpHide.click(function() {titleHelper.fadeOut(200)});
titleInput.click(function() {titleHelper.fadeOut(200)});
descHelpShow.click(function() {descHelper.fadeIn(200)});
descHelpHide.click(function() {descHelper.fadeOut(200)});
descInput.click(function() {descHelper.fadeOut(200)});
logoHelpShow.click(function() {logoHelper.fadeIn(200)});
logoHelpHide.click(function() {logoHelper.fadeOut(200)});
alignLeft.click(function() {logoHelper.fadeOut(200)});
alignCenter.click(function() {logoHelper.fadeOut(200)});
alignRight.click(function() {logoHelper.fadeOut(200)});
logoShapeHelpShow.click(function() {logoShapeHelper.fadeIn(200)});
logoShapeHelpHide.click(function() {logoShapeHelper.fadeOut(200)});
circleLogo.click(function() {logoShapeHelper.fadeOut(200)});
squareLogo.click(function() {logoShapeHelper.fadeOut(200)});
numHelpShow.click(function() {numHelper.fadeIn(200)});
numHelpHide.click(function() {numHelper.fadeOut(200)});
numInput.click(function() {numHelper.fadeOut(200)});
stamp5.click(function() {numHelper.fadeOut(200)});
stamp10.click(function() {numHelper.fadeOut(200)});
stamp15.click(function() {numHelper.fadeOut(200)});
colourHelpShow.click(function() {colourHelper.fadeIn(200)});
colourHelpHide.click(function() {colourHelper.fadeOut(200)});
colourInput.click(function() {colourHelper.fadeOut(200)});
alignLeft.click(function() {
alignRight.removeClass('active-btn')
alignCenter.removeClass('active-btn')
alignLeft.addClass('active-btn')
});
alignCenter.click(function () {
alignRight.removeClass('active-btn')
alignLeft.removeClass('active-btn')
alignCenter.addClass('active-btn')
});
alignRight.click(function () {
alignLeft.removeClass('active-btn')
alignCenter.removeClass('active-btn')
alignRight.addClass('active-btn')
});
circleLogo.click(function () {
squareLogo.removeClass('active-btn')
circleLogo.addClass('active-btn')
});
squareLogo.click(function () {
circleLogo.removeClass('active-btn')
squareLogo.addClass('active-btn')
});
stamp5.click(function () {
stamp10.removeClass('active-btn')
stamp15.removeClass('active-btn')
stamp5.addClass('active-btn')
});
stamp10.click(function () {
stamp5.removeClass('active-btn')
stamp15.removeClass('active-btn')
stamp10.addClass('active-btn')
});
stamp15.click(function () {
stamp10.removeClass('active-btn')
stamp5.removeClass('active-btn')
stamp15.addClass('active-btn')
});
cardTitle = "Untitled Card"
cardDescription = "This is the card Description"
logoAlign = "Left"
logoShape = "Square"
cardSlots = 5
cardColour = colourPicker.val()
titleInput.change(function() {cardTitle = titleInput.val()});
descInput.change(function() {cardDescription = descInput.val()});
alignLeft.click(function() {logoAlign = "Left"});
alignCenter.click(function() {logoAlign = "Center"});
alignRight.click(function() {logoAlign = "Right"});
circleLogo.click(function() {logoShape = "Circle"});
squareLogo.click(function() {logoShape = "Square"});
stamp5.click(function () {cardSlots = 5});
stamp10.click(function () {cardSlots = 10});
stamp15.click(function () {cardSlots = 15});
colourPicker.change(function() {cardColour = colourPicker.val()});
let logo = $('.sample-logo-container')
let logoPosition = $('.logo-align-container')
let cardHolder = $('.builder-card')
let stampRow1 = $('#stamp-row-1')
let stampRow2 = $('#stamp-row-2')
let stampRow3 = $('#stamp-row-3')
btn2.click(function () {
console.log("Title: " + cardTitle)
console.log("Description: " + cardDescription)
console.log("Logo Alignment: " + logoAlign)
console.log("Logo Shape: " + logoShape)
console.log("Num of stamps: " + cardSlots)
console.log("Background Colour: " + cardColour)
if (logoShape === "Square") {
logo.removeClass('circle-logo')
logo.addClass('square-logo')
}
if (logoShape === "Circle") {
logo.removeClass('square-logo')
logo.addClass('circle-logo')
}
if (logoAlign === "Left") {
logoPosition.removeClass('logo-align-middle')
logoPosition.removeClass('logo-align-right')
logo.removeClass('logo-align-middle')
logo.removeClass('m-inline-e')
logoPosition.addClass('logo-align-left')
logo.addClass('m-inline-s')
}
if (logoAlign === "Center") {
logoPosition.removeClass('logo-align-left')
logoPosition.removeClass('logo-align-right')
logo.removeClass('m-inline-s')
logo.removeClass('m-inline-e')
logoPosition.addClass('logo-align-middle')
logo.addClass('logo-align-middle')
}
if (logoAlign === "Right") {
logoPosition.removeClass('logo-align-left')
logoPosition.removeClass('logo-align-middle')
logo.removeClass('m-inline-s')
logo.removeClass('logo-align-middle')
logoPosition.addClass('logo-align-right')
logo.addClass('m-inline-e')
}
if (cardSlots === 5) {
stampRow1.show()
stampRow2.hide()
stampRow3.hide()
cardHolder.removeClass('two-stamp-row-height')
cardHolder.removeClass('three-stamp-row-height')
cardHolder.addClass('one-stamp-row-height')
}
if (cardSlots === 10) {
stampRow1.show()
stampRow2.show()
stampRow3.hide()
cardHolder.removeClass('one-stamp-row-height')
cardHolder.removeClass('three-stamp-row-height')
cardHolder.addClass('two-stamp-row-height')
}
if (cardSlots === 15) {
stampRow1.show()
stampRow2.show()
stampRow3.show()
cardHolder.removeClass('one-stamp-row-height')
cardHolder.removeClass('two-stamp-row-height')
cardHolder.addClass('three-stamp-row-height')
}
cardHolder.css("background-color", cardColour)
});
});
And the compressed file looks like this:
$(document).ready(function(){let e=$("#btn-1"),t=$("#btn-2"),l=$("#btn-3"),a=$("#btn-1-txt"),o=$("#btn-2-txt"),c=$("#btn-3-txt"),i=$(".create-container"),n=$(".build-container"),s=$(".preview-container"),d,r,u,v,f,m;e.addClass("active-btn"),a.addClass("active-txt"),i.fadeIn(250),e.click(function(){e.addClass("active-btn"),a.addClass("active-txt"),t.removeClass("active-btn"),o.removeClass("active-txt"),l.removeClass("active-btn"),c.removeClass("active-txt"),n.fadeOut(100),s.fadeOut(100),i.delay(250).fadeIn(100)}),t.click(function(){t.addClass("active-btn"),o.addClass("active-txt"),e.removeClass("active-btn"),a.removeClass("active-txt"),l.removeClass("active-btn"),c.removeClass("active-txt"),i.fadeOut(100),s.fadeOut(100),n.delay(250).fadeIn(100)}),l.click(function(){l.addClass("active-btn"),c.addClass("active-txt"),e.removeClass("active-btn"),a.removeClass("active-txt"),t.removeClass("active-btn"),o.removeClass("active-txt"),i.fadeOut(100),n.fadeOut(100),s.delay(250).fadeIn(100)});let C=$("#title-helper"),g=$("#title-helper-show"),h=$("#title-helper-close"),p=$("#title-input"),k=$("#desc-helper"),b=$("#desc-helper-show"),w=$("#desc-helper-close"),O=$("#desc-input"),x=$("#logo-helper"),I=$("#logo-helper-show"),q=$("#logo-helper-close"),L=$("#logo-shape-helper"),y=$("#logo-shape-helper-show"),S=$("#logo-shape-helper-close"),D=$("#colour-helper"),R=$("#colour-helper-show"),T=$("#colour-helper-close"),A=$("#colour-input"),B=$("#num-helper"),N=$("#num-helper-show"),U=$("#num-helper-close"),j=$("#num-input"),z=$("#align-left-opt"),E=$("#align-center-opt"),F=$("#align-right-opt"),G=$("#circle-logo"),H=$("#square-logo"),J=$("#stamps-5"),K=$("#stamps-10"),M=$("#stamps-15"),P=$("#colour-input");g.click(function(){C.fadeIn(200)}),h.click(function(){C.fadeOut(200)}),p.click(function(){C.fadeOut(200)}),b.click(function(){k.fadeIn(200)}),w.click(function(){k.fadeOut(200)}),O.click(function(){k.fadeOut(200)}),I.click(function(){x.fadeIn(200)}),q.click(function(){x.fadeOut(200)}),z.click(function(){x.fadeOut(200)}),E.click(function(){x.fadeOut(200)}),F.click(function(){x.fadeOut(200)}),y.click(function(){L.fadeIn(200)}),S.click(function(){L.fadeOut(200)}),G.click(function(){L.fadeOut(200)}),H.click(function(){L.fadeOut(200)}),N.click(function(){B.fadeIn(200)}),U.click(function(){B.fadeOut(200)}),j.click(function(){B.fadeOut(200)}),J.click(function(){B.fadeOut(200)}),K.click(function(){B.fadeOut(200)}),M.click(function(){B.fadeOut(200)}),R.click(function(){D.fadeIn(200)}),T.click(function(){D.fadeOut(200)}),A.click(function(){D.fadeOut(200)}),z.click(function(){F.removeClass("active-btn"),E.removeClass("active-btn"),z.addClass("active-btn")}),E.click(function(){F.removeClass("active-btn"),z.removeClass("active-btn"),E.addClass("active-btn")}),F.click(function(){z.removeClass("active-btn"),E.removeClass("active-btn"),F.addClass("active-btn")}),G.click(function(){H.removeClass("active-btn"),G.addClass("active-btn")}),H.click(function(){G.removeClass("active-btn"),H.addClass("active-btn")}),J.click(function(){K.removeClass("active-btn"),M.removeClass("active-btn"),J.addClass("active-btn")}),K.click(function(){J.removeClass("active-btn"),M.removeClass("active-btn"),K.addClass("active-btn")}),M.click(function(){K.removeClass("active-btn"),J.removeClass("active-btn"),M.addClass("active-btn")}),d="Untitled Card",r="This is the card Description",u="Left",v="Square",f=5,m=P.val(),p.change(function(){d=p.val()}),O.change(function(){r=O.val()}),z.click(function(){u="Left"}),E.click(function(){u="Center"}),F.click(function(){u="Right"}),G.click(function(){v="Circle"}),H.click(function(){v="Square"}),J.click(function(){f=5}),K.click(function(){f=10}),M.click(function(){f=15}),P.change(function(){m=P.val()});let Q=$(".sample-logo-container"),V=$(".logo-align-container"),W=$(".builder-card"),X=$("#stamp-row-1"),Y=$("#stamp-row-2"),Z=$("#stamp-row-3");t.click(function(){console.log("Title: "+d),console.log("Description: "+r),console.log("Logo Alignment: "+u),console.log("Logo Shape: "+v),console.log("Num of stamps: "+f),console.log("Background Colour: "+m),"Square"===v&&(Q.removeClass("circle-logo"),Q.addClass("square-logo")),"Circle"===v&&(Q.removeClass("square-logo"),Q.addClass("circle-logo")),"Left"===u&&(V.removeClass("logo-align-middle"),V.removeClass("logo-align-right"),Q.removeClass("logo-align-middle"),Q.removeClass("m-inline-e"),V.addClass("logo-align-left"),Q.addClass("m-inline-s")),"Center"===u&&(V.removeClass("logo-align-left"),V.removeClass("logo-align-right"),Q.removeClass("m-inline-s"),Q.removeClass("m-inline-e"),V.addClass("logo-align-middle"),Q.addClass("logo-align-middle")),"Right"===u&&(V.removeClass("logo-align-left"),V.removeClass("logo-align-middle"),Q.removeClass("m-inline-s"),Q.removeClass("logo-align-middle"),V.addClass("logo-align-right"),Q.addClass("m-inline-e")),5===f&&(X.show(),Y.hide(),Z.hide(),W.removeClass("two-stamp-row-height"),W.removeClass("three-stamp-row-height"),W.addClass("one-stamp-row-height")),10===f&&(X.show(),Y.show(),Z.hide(),W.removeClass("one-stamp-row-height"),W.removeClass("three-stamp-row-height"),W.addClass("two-stamp-row-height")),15===f&&(X.show(),Y.show(),Z.show(),W.removeClass("one-stamp-row-height"),W.removeClass("two-stamp-row-height"),W.addClass("three-stamp-row-height")),W.css("background-color",m)})});
Video of problem
Loading time is slow because of screen recording
https://imgur.com/a/XcFXXKJ

How to update created elements?

I have this simple function that will create a paragraph.
function appendElements() {
const input = document.getElementById("myInput");
const createDiv = document.createElement("div");
createDiv.classList.add("myDiv");
const createP = document.createElement("P");
createP.classList.add("myParagraph");
createP.innerHTML = input.value;
createDiv.appendChild(createP);
const div = document.getElementById("examplediv");
div.appendChild(createDiv);
}
And another function that will sum the innerHTML of the divs, and create a div element for the result.
function calculateSum() {
let div = document.getElementsByClassName("myParagraph");
let array = new Array;
for (var i = 0; i <div.length; i++) {
array.push(div[i].innerHTML);
}
let numberedArray = array.map((i) => Number(i));
const sumArray = numberedArray.reduce(function(a, b){
return a + b;
}, 0);
const createElement = document.createElement("div");
createElement.innerHTML = sumArray;
document.getElementById("divForAvg").appendChild(createElement);
}
And the last function that will change the innerHTML of the paragraph element when clicked.
function editELement() {
const input2 = document.getElementById("myInput2")
let items = document.getElementsByClassName("myParagraph");
for(var i = 0; i < items.length; i++){
items[i].onclick = function(){
items[i].innerHTML = input2.value;
}
}
}
So basically when I create some paragraphs and execute the second function, the second function will calculate the sum of the paragraphs and create a div with the sum inside.
What I want is when I remove one of the paragraph elements or edit them, I want the previously created divs to update(recalculate the sum), I have literally no idea on how to do this.
Let's try this using event delegation. I have interpreted what I think you are looking for (note: it's exemplary, but it may give you an idea for your code) and reduced your code a bit for the example. Note the 2 different ways to create new elements (insertAdjacentHTML and Object.assign).
You can play with the code #Stackblitz.com.
document.addEventListener("click", handle);
function handle(evt) {
if (evt.target.id === "create") {
return appendInputValueElement();
}
if (evt.target.classList.contains("remove")) {
return removeThis(evt.target);
}
if (evt.target.id === "clear") {
document.querySelector("#accumulated ul").innerHTML = "";
return true;
}
}
function appendInputValueElement() {
const input = document.querySelector(".myInput");
const div = document.querySelector("#exampleDiv");
exampleDiv.insertAdjacentHTML("beforeEnd", `
<div class="myDiv">
<button class="remove">remove</button>
<span class="myParagraph">${input.value || 0}</span>
</div>
`);
calculateSum();
}
function removeThis(elem) {
elem.closest(".myDiv").remove();
calculateSum();
}
function calculateSum() {
const allParas = [...document.querySelectorAll(".myParagraph")];
const sum = allParas.reduce( (acc, val) => acc + +val.textContent, 0);
document.querySelector("#accumulated ul")
.append(Object.assign(document.createElement("li"), {textContent: sum}));
document.querySelector(".currentSum").dataset.currentSum = sum;
if (sum < 1) {
document.querySelector("#accumulated ul").innerHTML = "";
}
}
.currentSum::after {
content: ' 'attr(data-current-sum);
color: green;
font-weight: bold;
}
.myParagraph {
color: red;
}
.accSums, .currentSum, .myDiv {
margin-top: 0.3rem;
}
<div>
A number please: <input class="myInput" type="number" value="12">
<button id="create">create value</button>
</div>
<div class="currentSum" data-current-sum="0">*Current sum</div>
<p id="exampleDiv"></p>
<div id="accumulated">
<div class="accSums">*Accumulated sums</div>
<ul></ul>
<button id="clear">Clear accumulated</button>
</div>
i've changed calculateSum you can call it when you edited paragraph. If summParagraph doesn't exists then we create it.
function calculateSum() {
let div = document.getElementsByClassName("myParagraph");
let array = new Array;
for (var i = 0; i <div.length; i++) {
array.push(div[i].innerHTML);
}
let numberedArray = array.map((i) => Number(i));
const sumArray = numberedArray.reduce(function(a, b){
return a + b;
}, 0);
if (!document.getElementById("summParagraph")) {
const createElement = document.createElement("div");
createElement.setAttribute("id", "summParagraph");
document.getElementById("divForAvg").appendChild(createElement);
}
document.getElementById("summParagraph").innerHTML = summArray;
}

JavaScript arrays adding last element instead of recently added input

Good evening. I am new to JavaScript and I need help with my mini-project and I have only one issue here and it is in the this.Add = function ().
It works properly when I enter a duplicate value from my list therefore it displays an alert that no dupes are allowed. But... when I enter a unique value, it only adds up the last element present (Wash the dishes) from myTasks list. instead of the one I recently entered and the list goes on adding the same ones. Did I just misplace something?
This is my final activity yet and I want to finish it to move to the next function. Thank you in advance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tasks CRUD</title>
<style>
#tasks{
display: none;
}
</style>
</head>
<body>
<center>
<form action="javascript:void(0);" method="POST" onsubmit="app.Add()">
<input type="text" id="add-task" placeholder="Add another card">
<input type="submit" value="Add">
</form>
<div id="tasks" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-task">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
<table>
<tr>
<th>Name</th>
</tr>
<tbody id="myTasks">
</tbody>
</table>
</center>
<script>
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
if (task ) {
for(task of this.myTasks)
{
var ctr = 0;
if(document.getElementById("add-task").value == task){
ctr = 1;
break;
}
}
if(ctr == 1)
{
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task.trim());
// Reset input value
el.value = '';
// Dislay the new list
this.FetchAll();
}
}
};
this.Edit = function (item) {
var el = document.getElementById('edit-task');
// Display value in the field
el.value = this.myTasks[item];
// Display fields
document.getElementById('tasks').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
// Get value
var task = el.value;
if (task) {
// Edit value
self.myTasks.splice(item, 1, task.trim());
// Display the new list
self.FetchAll();
// Hide fields
CloseInput();
}
}
};
this.Delete = function (item) {
// Delete the current row
this.myTasks.splice(item, 1);
// Display the new list
this.FetchAll();
};
}
app.FetchAll();
function CloseInput() {
document.getElementById('tasks').style.display = 'none';
}
</script>
</body>
</html>
In your for loop:
for (task of this.myTask) {
}
You are not declaring a new task variable, but instead assigning to the outer task variable, hence the repeated addition of tasks already in your list.
You can declare a new variable in the for scope like so:
for (const task of this.myTask) {
}
Your HTML as it is.
And your Javascript goes like below. You have a bug while checking if the task already exists in the array. As you're comparing string value either use simple for loop with triple equals or do as i have attached below.
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
console.log(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
console.log(task);
if (task ){
var arrayContainsTask = (this.myTasks.indexOf(task) > -1);
if(arrayContainsTask == true){
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task);
// Reset input value
el.value = '';
}
// Dislay the new list
this.FetchAll();
}
}
}

Categories

Resources