JavaScript: Close Modal on correct Values - javascript

Good Day,
I am currently nearly done creating a Modal with Vanilla JS, at present, my "Age Gate" does check if the age of the user is less than 18 and displays a error of 'Invalid Credentials',
I have tried to go further by trying to close the modal on the correct value and then the modal to close,
Please see my code below for the JS:
const modal = document.getElementById("myModal");
const form = document.querySelector('form');
const loading = document.getElementById("loading");
const btnSubmit = document.getElementById('btnSubmit');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
};
// Functions
function onlyNumbers(e) {
const ageGate = document.querySelectorAll('.ageGate');
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
const errMsgDiv = document.getElementById('errorMsg');
let containsNumber = false
ageGate.forEach(input => {
if(numbers.some(num => input.value.includes(num))) containsNumber = true;
})
if (containsNumber || ageGate.value !== numbers && ageGate.value == '' || ageGate[2].value < 2004) {
let paragraph = document.createElement('p');
paragraph.innerHTML = 'Invalid Credentials';
errMsgDiv.append(paragraph);
e.preventDefault()
} else if (containsNumber = true) {
btnSubmit.remove()
loading.classList.remove('hide')
}
};
and now the Modal html:
<div id="modal">
<div class="modal-content">
<div class="flex-container">
<div>
<img
src="{% static 'imgs/Fireball_logo.png' %}"
class="logo"
alt="fireball logo"
/>
<h1>WOAH THERE!</h1>
<p class="info-text">We just need to see something</p>
</div>
<form action="">
{% csrf_token %}
<div class="form-flex">
<input
class="ageGate"
type="text"
max-length="2"
placeholder="DD"
/>
<input
class="ageGate"
type="text"
max-length="2"
placeholder="MM"
/>
<input
class="ageGate"
type="text"
max-length="4"
placeholder="YYYY"
/>
</div>
<p class="cookie-policy">
<small>
This site uses cookies. Cookie Policy. I agree
to the terms of use, and the privacy policy.
This information will not be used for marketing
purposes
</small>
</p>
<div class="text-center">
<button id="btnSubmit" class="btn" type="submit">
<p class="btn-text">Enter</p>
</button>
<img
src="{% static 'imgs/spinner.gif' %}"
alt="spinner"
id="loading"
class="loading close">
</div>
<span id="errorMsg"></span>
</form>
<div>
<img
src="{% static 'imgs/Drinkaware_logo.png' %}"
alt="Drinkaware Logo"
/>
</div>
</div>
</div>
</div>
Please as usual, I am sort of new with it all and I am definitely trying, so in your help, please could I ask for a brief explanation on your solution so that I may see how to think as a dev as that kind of information does help me
Thanks!

function onlyNumbers(e) {
e.preventDefault()
const ageGate = document.querySelectorAll('.ageGate');
const errMsgDiv = document.getElementById('errorMsg');
const year = ageGate[2].value;
const month = ageGate[1].value;
const day = ageGate[0].value;
const userBirthday = new Date(year, month - 1, day);
// Date Right Now
const today = new Date();
// Users age in years
const acceptingYear = today.getFullYear() - userBirthday.getFullYear()
if (acceptingYear < 18 ||
acceptingYear == 18 &&
today.getMonth() < userBirthday.getMonth() ||
today.getMonth() == userBirthday.getMonth() &&
today.getDate() < userBirthday.getDate()
) {
let paragraph = document.createElement('p');
paragraph.innerHTML = 'Invalid Credentials';
errMsgDiv.append(paragraph);
} else {
btnSubmit.remove()
loading.classList.remove('hide')
modal.classList.add('close');
}
};
I needed to target the modal and make sure that it was closing on execution of my function

Related

How to Enable check-in when clicked and at the same time checkout will be enabled and vice versa using JavaScript?

I am working on a project where I need to develop the attendance part using Django and JS (as main languages) and I'm stuck with an issue that after clicking check-in button it does not get disabled and the user can check-in multiple time that will cause error when checking out because of the Database.
This is what I tried using Javascript but failed..
<script>
const button1 = document.querySelector('.checkin');
const button2 = document.querySelector('.checkout');
button1.onlclick = function () {
document.cookie = "button1=disabled; button2=enabled; expires=Fri, 31 Dec 9999 23:59:59 GMT";
};
button2.onclick= function () {
document.cookie = "button1=enabled; button2=disabled; expires=Fri, 31 Dec 9999 23:59:59 GMT";
};
window.onload = function () {
const cookies = document.cookie.split("; ");
cookies.forEach(function (cookie) {
const [key, value] = cookie.split("=");
if (key === "button1" && value === "disabled") {
button1.disabled = true;
button2.disabled = false;
} else if (key === "button1" && value === "enabled") {
button1.disabled = false;
button2.disabled = true;
}
});
};
</script>
This is what I tried using Django Template language but failed.
{% if items.check_in is none %}
<script type="text/javascript">
const button1 = document.querySelector('.checkin');
const button2 = document.querySelector('.checkout');
button1.disabled = false;
button2.disabled = true;
</script>
{% else %}
<script type="text/javascript">
const button1 = document.querySelector('.checkin');
const button2 = document.querySelector('.checkout');
button1.disabled = true;
button2.disabled = false;
</script>
{% endif %}
Below is how my HTML looks like
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-sm-12 text-center">
<input type="submit" id="submit" name="Check" class="btn btn-primary checkin" value="Check-In">
<input type="submit" id="submit" name="Check" class="btn btn-primary checkout" value="Check-Out">
</div><!--end col-->
</div><!--end row-->
</form><!--end form-->
I tried to search many internet resources but I am unable to figure it out.
I am kind of new to JavaScript so please do explain the solution in a layman language.

Multi-step form won't go to next section JS/HTML

So I wrote this multi-step form and it worked with the current code I have listed below until I changed it to send/receive data from php. The only thing that works is updating the progress bar but other then that it doesn't work. I have an idea why its not working cause of the actual button event isn't targeting the correct $(this).parent(); when I changed it from nextSection() to onSubmit(). I would possibly like to write it where it just selects the div class from an object then remove the current section but I wanna keep it the way I have for now.
$(".btn").on("click", nextSection);
function nextSection() {
if (typeof sections[current] !== "undefined") {
if(valid) {
current_section = $(this).parent();
next_section = $(this).parent().next();
console.log(current_section)
next_section.fadeIn();
current_section.remove();
current++;
updateProgressbar();
if (current === 1) {
let username = $(".username").val();
updatePenguinObj("username", username);
} else if (current === 2) {
let password = $(".password").val();
let email = $(".email").val();
updatePenguinObj("password", password);
updatePenguinObj("email", email);
} else if (current === 3) {
let name = $(".done");
name.text(name.text().replace(/%.+?%/, userData.username));
}
}
}
}
Then I changed it to the onSubmit() function w/ the validation responses.
$(".btn").on("click", onSubmit);
function onSubmit(event) {
event.preventDefault()
let request = new XMLHttpRequest()
request.onreadystatechange = () => handleResponse(request)
let formData = new FormData()
formData.append('username', userData.username);
formData.append('color', userData.colorId);
formData.append('password', userData.password);
formData.append('email', userData.email);
request.open('POST', 'scripts/php/create.php')
request.send(formData)
}
function handleResponse(request) {
if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) {
return
}
let response = JSON.parse(request.responseText);
if (!response) {
return
}
sectionValidation(response);
}
function sectionValidation(response) {
valid = true;
let section = $(sections[current]);
let input = section.find("input");
input.each(function() {
let inputs = $(this).attr('type') === "checkbox" ? !$(this).is(':checked') : input;
if(inputs) {
if (!response.valid) {
showError(response.message);
return valid = response.valid;
}
}
});
if(valid) {
nextSection(); //This is where nextSection is excuted to go to next page but doesnt.
}
}
I pastebin the entire code for each file type that way im not spamming this thread with just code. Overall i'm just trying to figure out how to fix it where I can go to the next section.
HTML - https://pastebin.com/eF8eXBfN
JS - https://pastebin.com/LuvYtYFc
PHP -
Basically just returns a JSON Object {message: "Test", valid: false} for the message responses and validation for it to go to next section.
if this isn't helpful I apologise in advance ....
because nextSection(); uses $(this) it won't have refrance to the button as it would have done when you used $(".btn").on("click", nextSection);
so you could add a reference of $(this) though to that function from the onSubmit
I create an example using your code, I dummy the response from the php but the rest is the same: https://jsfiddle.net/PatrickHume/8x6rodpn/
I don't know if this is better but it's another approach, I hope its helpful
let valid = true;
let sections = {
0: ".rules-section",
1: ".color-section",
2: ".info-section",
3: ".done-section"
};
let userData;
let current = 0,
current_section, next_section;
let currPalleteId = 0;
let penguinColors = {
"Blue": "003366",
"Green": "009900",
"Pink": "FF3399",
"Black": "333333",
"Red": "CC0000",
"Orange": "FF6600",
"Yellow": "FFCC00",
"Purple": "660099",
"Brown": "996600",
"Peach": "FF6666",
"Dark Green": "006600",
"Light Blue": "0099CC",
"Lime Green": "8AE302",
"Sensei Gray": "93A0A4",
"Aqua": "02A797",
"Arctic White": "F0F0D8",
};
window.onload = function() {
initalizeCreate();
};
function initalizeCreate() {
loadPalletes();
createPenguinObj();
$(".btn").on("click", onSubmit);
$(".show-password").on("click", togglePassword);
$("#startAgain").on("click", resetForm);
$(".random-username").on("click", randomUsername);
$(".username").keyup(function() {
let username = this.value;
updateDollName(username);
});
}
async function randomUsername() {
let url = "https://randomuser.me/api/";
let obj = await (await fetch(url)).json();
obj = obj.results[0];
let randuser = obj.login.username
$(".username").val(randuser);
updateDollName(randuser);
}
function updateDollName(username) {
username === "" ? $(".penguinName").text("Penguin Name") : $(".penguinName").text(username);
}
function togglePassword() {
$(this).toggleClass("fa-eye fa-eye-slash");
let input = $(this).prev('.info-section input');
input.attr('type', input.attr('type') === 'password' ? 'text' : 'password');
}
function resetForm() {
location.reload()
}
function nextSection($this) {
if (typeof sections[current] !== "undefined") {
if (valid) {
current_section = $($this).parent();
next_section = $($this).parent().next();
// console.log(current_section)
next_section.fadeIn();
current_section.remove();
current++;
updateProgressbar();
if (current === 1) {
let username = $(".username").val();
updatePenguinObj("username", username);
} else if (current === 2) {
let password = $(".password").val();
let email = $(".email").val();
updatePenguinObj("password", password);
updatePenguinObj("email", email);
} else if (current === 3) {
let name = $(".done");
name.text(name.text().replace(/%.+?%/, userData.username));
}
}
}
}
function onSubmit(event) {
event.preventDefault()
let request = new XMLHttpRequest()
request.onreadystatechange = () => handleResponse(request, $(this))
let formData = new FormData()
formData.append('username', userData.username);
formData.append('color', userData.colorId);
formData.append('password', userData.password);
formData.append('email', userData.email);
request.open('POST', 'https://reqbin.com/sample/post/json')
request.send(formData)
}
function handleResponse(request, $this) {
if (request.readyState !== XMLHttpRequest.DONE || request.status !== 200) {
return
}
var resp = `{
"message": "Test",
"valid": true
}`
let response = JSON.parse(resp);
if (!response) {
return
}
sectionValidation(response, $this);
}
function sectionValidation(response, $this) {
valid = true;
let section = $(sections[current]);
let input = section.find("input");
input.each(function() {
let inputs = $(this).attr('type') === "checkbox" ? !$(this).is(':checked') : input;
if (inputs) {
if (!response.valid) {
showError(response.message);
return valid = response.valid;
}
}
});
if (valid) {
nextSection($this);
}
}
function showError(text) {
$("#c_container").append(`<div class="error-block-container"><div class="error-container"><div id="error-content"><div id="error-msg-txt"> %text% </div><div id="error-btn"><div id="error-txt">Ok</div></div></div></div></div>`);
$("#error-btn").on("click", () => {
closeError();
});
let message = $("#error-msg-txt").html(text);
message.text(message.text().replace(/%.+?%/, message));
$(".error-block-container").fadeIn();
}
function closeError() {
$(".error-block-container").remove();
}
function updateProgressbar() {
let progressSteps = document.querySelectorAll(".progress-step");
progressSteps.forEach((progressStep, id) => {
if (id < current + 1) {
progressStep.classList.add("progress-step-active");
progressStep.classList.add("step");
} else {
progressStep.classList.remove("progress-step-active");
progressStep.classList.remove("step");
}
});
progressSteps.forEach((progressStep, id) => {
if (id < current) {
progressStep.classList.add("progress-step-check");
progressStep.classList.remove("progress-step-active");
} else {
progressStep.classList.remove("progress-step-check");
}
});
let progressActive = document.querySelectorAll(".step");
$(".progress").css("width", ((progressActive.length - 1) / (progressSteps.length - 1)) * 100 + "%");
}
function loadPalletes() {
let colorIndexNum = 0;
for (let palletes in penguinColors) {
let colorHex = penguinColors[palletes],
colorIndex = palletes,
colorIndexCurrNum = ++colorIndexNum;
$("#palletes").append(`<div data-id="${colorIndexCurrNum}" class="tinyPallete" style="background: #${colorHex}"></div> `);
}
$("#palletes").on("click", function(e) {
currPalleteId = $(e.target).attr("data-id");
e.currentTarget.querySelector(".active").classList.remove("active");
if (e.target.classList.contains("tinyPallete")) {
e.target.classList.add("active");
}
$(".doll").css("background-color", "#" + penguinColorByIndex(currPalleteId, false));
});
}
function penguinColorByIndex(index, keys) {
if (keys) {
return Object.keys(penguinColors)[--index];
}
return Object.values(penguinColors)[--index];
}
function updatePenguinObj(key, value) {
userData[key] = value;
return userData;
}
function createPenguinObj() {
userData = new Object();
userData.username = "";
userData.colorId = Number(currPalleteId);
userData.password = "";
userData.email = "";
return userData;
}
<html>
<head>
<title>Create Account</title>
<link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" />
<link type="text/css" rel="stylesheet" href="styles/fonts.css" />
<link type="text/css" rel="stylesheet" href="styles/create.css" />
<script type="text/javascript" src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
</head>
<body>
<div id="c_header">
<h2>Create a Free Account</h2>
<div id="startAgain">Start Again</div>
<div class="c_progressBar">
<div class="progress" id="progress"></div>
<div class="progress-step progress-step-active"></div>
<div class="progress-step"></div>
<div class="progress-step"></div>
<div class="progress-step"></div>
</div>
</div>
<div id="c_container">
<div id="c_content">
<img id="logo" src="images/logo.png" /><img id="safety" src="images/safety.png" />
<form method="POST">
<div class="rules-section">
<div class="grid-rules">
<div class="item">
<div>
<div id="rule-title">Respect other penguins</div>
Club Penguin does not tolerate any swearing, bullying or mean behavior toward other penguins. Disciplinary action will be taken should any one of these occur while playing.
</div>
<img id="rule-image" src="images/respect.png" />
</div>
<div class="item">
<div>
<div id="rule-title">No inappropriate talk</div>
References to drugs and alcohol related activities, and sexual, racial or otherwise inappropriate talk are not permitted.
</div>
<img id="rule-image" src="images/inapp.png" />
</div>
<div class="item">
<div>
<div id="rule-title">Never reveal personal information</div>
The best way to stay safe online is to NEVER share your real name, phone number, address, email or passwords.
</div>
<img id="rule-image" src="images/personal.png" />
</div>
<div class="item">
<div>
<div id="rule-title">No cheating</div>
Use of third party programs to cheat is prohibited. Players who use any third party programs while playing risk being permanently banned.
</div>
<img id="rule-image" src="images/cheating.png" />
</div>
</div>
<hr />
<div id="agree"> <span class="toggle">
<input type="checkbox" id="agree" name="agree" /><label>I agree to the Club Penguin Rules.</label>
</span>
</div>
<div id="terms"> <span class="toggle">
<input type="checkbox" id="terms" name="terms" /><label>I agree to the <a id="hyper" href="#">Terms of Use</a></label>
</span>
</div>
<button class="btn" name="submit">Continue</button>
</div>
<div class="color-section">
<div id="color-form">
<p id="epname">Enter Your Penguin Name:</p>
<!--<span class="bubble">
<div id="bubble-msg"></div>
</span>-->
<input type="text" name="username" class="username" id="inputaligncenter" maxlength="16" /> <span toggle="#random_username" class="fa fa-fw fa-refresh random-username" title="Random Username"></span>
<div id="cpsmall">Minimum 4 characters: use only numbers, letters and spaces.</div>
<p id="cpname">Click on a Color:</p>
<div id="palletes"></div>
<img id="paintbucket" src="images/paintbucket.png" />
</div>
<div class="doll-container"> <img class="doll" src="images/doll.png" /> <span class="penguinName">Penguin Name</span> </div>
<button class="btn" name="submit">Continue</button>
</div>
<div class="info-section">
<div id="info-form">
<div id="ppname-wrapper">
Penguin Password:
<div id="ppsmall">This is the password you will use to login to Club Penguin. </div>
<input type="password" name="password" class="password" placeholder="Password"><span toggle="#password" class="fa fa-fw fa-eye field_icon show-password"></span>
<input type="password" name="cpassword" class="cpassword" placeholder="Confirm Password"><span toggle="#c_password" class="fa fa-fw fa-eye field_icon show-password"></span>
<p id="activatedTxt">your penguin must be activated before you will be able to play at club penguin</p>
Parent's Email Address:
<div id="ppsmall">Please enter your parent's valid email address. Club Penguin will send your parent an e-mail with an activation code.</div>
<div class="env"> <img src="images/envelope.png">
<input type="text" class="email" name="email">
</div>
</div>
<div class="doll-container fixed"> <img class="doll" src="images/doll.png" /> <span class="penguinName">Penguin Name</span> </div>
</div>
<button type="submit" class="btn" name="submit">Continue</button>
</div>
<div class="done-section">
<h2 class="done">%username%, your Account Has Been Successfully Created!</h2>
</div>
</form>
</div>
</div>
</body>
</html>
Solved my problem lol. I just wrote another function that just selects the classes from a div, removes the current, then adds 1 to the current section to show the next. If anyone has a better method feel free to correct me.
function gotoNextSection() {
current_section = $(sections[current]);
current_section.remove();
current++;
next_section = $(sections[current]);
next_section.fadeIn();
updateProgressbar();
}

How do I get my text input field to remember previously entered data by using local storage?

So I'm currently working on a traveling website-> Link to Deployed Website The website basically allows users to fill out a form with three inputs:
The city they plan on traveling to
The start date of their time in the city
The end date of their time in the city
When the user fills out all the input fields in the form and submits it, the page loads and spits out a list of events happening in the city and a list of breweries close by, all by use of two different APIs.
The page works perfectly fine, but right now I'm trying to figure out how to use local storage to get it to save the last text input. I want the user to see their last city text input in case they accidently refresh the page or close the window. I know this might be a dumb question, but I've been stuck on this for a few hours and feel like an idiot for not knowing how to fix it. I would appreciate it if anyone could help me out. Please don't leave snarky comments, I already feel stupid.
This is the code I'm working stuck on at the moment:
//Input History for the City that the user types
let rememberCity=document.querySelector('.city-text').value
console.log(rememberCity);
//When form is submitted, storage will save the city
form.addEventListener("click", () => {
localStorage.setItem("name",rememberCity);
cityNameDisplay();
});
function cityNameDisplay () {
localStorage.getItem("name");
}
document.body.onload = cityNameDisplay;
Below are the full Javascript + HTML code
const modalClose = document.querySelector(".modal-close");
const modalOpen = document.querySelector(".modal-open");
const form = document.querySelector(".travel-form");
const modalContainer = document.querySelector(".modal");
const modal = document.querySelector(".modal-content");
const cityInput = document.querySelector(".city-text");
const startDate = document.querySelector(".start-date");
const endDate = document.querySelector(".end-date");
const cityError = document.querySelector(".city-error");
const startError = document.querySelector(".start-error");
const endError = document.querySelector(".end-error");
const weatherKey = "c3092c2d4eb3d6f6f64456f5fc464ffa";
// creating an array of all the datepickers in DOM
const datePickers = Array.from(document.querySelectorAll(".date"));
// finding local date
function dateToString(date) {
let year = date.year;
let month = date.month.toString();
let day = date.day.toString();
// padding day and month if necessary for final string
if (day.length === 1) {
day = day.padStart(2, "0");
}
if (month.length === 1) {
month = month.padStart(2, "0");
}
const minDate = `${year}-${month}-${day}`;
return minDate;
}
function datePickerSetUp() {
const minDate = dateToString(luxon.DateTime.now().toObject());
// setting min attribute of datepickers to disable dates in the past
datePickers.forEach((date) => {
date.setAttribute("min", minDate);
});
}
function getCoords(city, start, end) {
const queryCity = city;
fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${queryCity}&appid=${weatherKey}&units=imperial`
)
.then((response) => {
if (response.ok === false) {
cityInput.classList.add("is-danger");
cityError.textContent = "Not a city!";
throw Error("Not a city!");
} else {
response.json().then((data) => {
modalContainer.classList.remove("is-active");
console.log(data.name, data.coord.lat, data.coord.lon);
getEvents(data.coord.lat, data.coord.lon, start, end);
listBreweries(city);
});
}
})
.catch((err) => {
console.log(err.message);
});
}
function handleSubmit() {
const city = cityInput.value.trim().toLowerCase();
let start = luxon.DateTime.fromFormat(startDate.value, "yyyy-MM-dd");
let end = luxon.DateTime.fromFormat(endDate.value, "yyyy-MM-dd");
// if no text in city
if (!city) {
cityInput.classList.add("is-danger");
cityError.textContent = "Choose a city!";
}
if (!startDate.value) {
startDate.classList.add("is-danger");
startError.textContent = "Choose a start date!";
}
if (!endDate.value) {
endDate.classList.add("is-danger");
endError.textContent = "Choose an end date!";
}
if (!city || !startDate.value || !endDate.value) {
modal.classList.add("shake");
var shakeRemove = setTimeout(() => {
modal.classList.remove("shake");
}, 1000);
}
// if all fields are filled
if (city && startDate.value && endDate.value) {
// if the end date is before the start date
if (start > end) {
startDate.classList.add("is-danger");
startError.textContent = "Start date must be after end date!";
endDate.classList.add("is-danger");
endError.textContent = "End date must be before start date!";
return;
}
// convert start and end objects to strings
start = dateToString(start);
end = dateToString(end);
// clear timeout
clearTimeout(shakeRemove);
// send to fetch functions
getCoords(city, start, end);
}
}
// submit listener for form
form.addEventListener("submit", (event) => {
event.preventDefault();
handleSubmit();
});
// If elements have errors and are focused again the error is hidden
cityInput.addEventListener("focus", () => {
if (cityInput.classList.contains("is-danger")) {
cityError.textContent = "";
cityInput.classList.remove("is-danger");
}
});
startDate.addEventListener("focus", () => {
if (startDate.classList.contains("is-danger")) {
startDate.classList.remove("is-danger");
startError.textContent = "";
}
});
endDate.addEventListener("focus", () => {
if (endDate.classList.contains("is-danger")) {
endDate.classList.remove("is-danger");
endError.textContent = "";
}
});
modalClose.addEventListener("click", () => {
modalContainer.classList.remove("is-active");
});
modalOpen.addEventListener("click", () => {
modalContainer.classList.add("is-active");
});
//Input History for the City that the user types
let rememberCity=document.querySelector('.city-text').value
console.log(rememberCity);
//When form is submitted, storage will save the city
form.addEventListener("click", () => {
localStorage.setItem("name",rememberCity);
cityNameDisplay();
});
//City
function cityNameDisplay () {
localStorage.getItem("name");
}
document.body.onload = cityNameDisplay;
datePickerSetUp();
<!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">
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.3.1/luxon.min.js"
integrity="sha512-Nw0Abk+Ywwk5FzYTxtB70/xJRiCI0S2ORbXI3VBlFpKJ44LM6cW2WxIIolyKEOxOuMI90GIfXdlZRJepu7cczA=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css"
integrity="sha512-IgmDkwzs96t4SrChW29No3NXBIBv8baW490zk5aXvhCD8vuZM3yUSkbyTBcXohkySecyzIrUwiF/qV0cuPcL3Q=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="assets/css/styles.css">
<title>City Explorer</title>
</head>
<body class="is-fullheight is-clipped">
<div class="container is-justify-content-center">
<!-- MODAL START-->
<div class="modal is-active">
<!-- REMOVE IS ACTIVE CLASS TO WORK ON SITE -->
<div class="modal-background"></div>
<div
class="modal-content column box p-4 is-three-quarters-mobile is-half-tablet is-5-desktop has-background-info-light">
<form class="travel-form is-flex is-flex-direction-column is-align-items-left">
<div class="field">
<label class="label mb-2" for="city">What city are you visiting?</label>
<input class="city-text input" type="text" name="" id="city" autocomplete="off">
<span class="city-error help is-danger"></span>
</div>
<div class="field">
<label class="label mb-2" for="start-date">Start date:</label>
<input class="input date start-date" type="date">
<span class="start-error help is-danger"></span>
</div>
<div class="field">
<label class=" label mb-2" for="end-date">End date:</label>
<input class="date input end-date" type="date">
<span class="end-error help is-danger"></span>
</div>
<button class="modal-button button is-info mt-2" type="submit">Let's Go!</button>
</form>
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
<!-- MODAL END-->
<section class="hero is-medium is-link">
<div class="hero-body">
<p class="title has-text-centered">
City Name
</p>
</div>
</div>
</section>
<section class="section pt-6 pb-0 is-medium is-link">
<div class="is-flex is-justify-content-center">
<!--<button class="modal-open button is-centered mb-4 is-info">Chose a new city</button>-->
<button class="modal-open button is-centered mb-4 is-info"><span><img src="assets/images/Map.png" /></span> Chose a new city</button>
</div>
<div class="container">
<div class="columns">
<div class="column">
<div class="notification">
<h1 class="title event-title is-size-4 has-text-centered">Events</h1>
<ul class="event-list">
</ul>
</div>
</div>
<div class="column">
<div class="notification">
<h1 class="title brewery-name is-size-4 has-text-centered">Breweries</h1>
<img src= "assets/images/Beer.png" class="icon" alt="Beer">
<ul class="brewery-list">
</ul>
</div>
</div>
</div>
</div>
</section>
<footer class="is-flex">
<img src="assets/images/skyline.png" alt="skyline">
<img src="assets/images/skyline.png" alt="skyline">
</footer>
<script src="./assets/javascript/modal.js"></script>
<script src="./assets/javascript/Breweries.js"></script>
<script src="./assets/javascript/events.js"></script>
</body>
</html>
Well its sort of simple. You want to pull from local storage and place that data into the default value of the input on page refresh/load. So what you'll want to do is just that.
First you'll need to put the input into local storage. I am just assuming you know about getting input values.
function setLocalInput(input){
localStorage.setItem('savedInput', input);
}
In this case localstorage.setItem takes two parameters, the name you want to set as well as the data you want to set. The input value being passed is the value from your input field that you want saved.
From there you can run a function on page load/refresh that checks the local storage API to see if there is any data, and if so set it as the input default value.
function setInputDefault(){
const storedInput = localStorage.getItem('savedInput');
}
From there you can set storedInput equal to the input default value.
An Edit to my original as I did not fully work through your problem.
So I took your code and went through to refactor a bit. Hopefully my changes aren't too intrusive. I started by taking your ending form.addEventListener("click") funtion and added it into your previously created form.addEventListener("submit") function.
// submit listener for form
form.addEventListener("submit", (event) => {
event.preventDefault();
let rememberCity = document.querySelector(".city-text").value;
localStorage.setItem("name", rememberCity);
handleSubmit();
});
Having rememberCity inside the function allows you to get the form input on submit. Then you store that value locally. From there I created a function which checks to see if you have a saved variable under the name name.
function checkForSaved() {
const savedInput = localStorage.getItem("name");
if (savedInput !== null) {
document.querySelector(".city-text").defaultValue = savedInput;
}
}
After checking local storage it sets the defaultValue of the .city-text element to the contents in local storage. Running your code you also have the longitude and latitude being saved in localstorage as well. I added checkForSaved() just at the bottom of your javascript file, above datePickerSetUp().
Hopefully this helps.
The problem is that you are getting the value of the input at the beginning.
At that point it hasn't got anything in it.
You need to get the value of the input when the user has clicked.
//When form is submitted, storage will save the city
form.addEventListener("click", () => {
//Input History for the City that the user types
let rememberCity=document.querySelector('.city-text').value
console.log(rememberCity);
localStorage.setItem("name",rememberCity);
cityNameDisplay();
});
function cityNameDisplay () {
localStorage.getItem("name");
}
document.body.onload = cityNameDisplay;

Put Login in Popup window

I'm creating a login where you click on a button and it shows the login via $("#loginbox").show();, I want to show the contents in loginbox/<div class="loginContainer"> in a popup window. I've been trying to use window.open() but I don't think it'll work for what I want.
my code:
const $document = $(document);
const $login = $("#login");
const $loginBox = $("#loginbox");
const $formElement = $(`
<div class="loginContainer">
<label for="userNameBox"><b>Username: </b></label>
<input type="text" class="userName"id="userNameBox" placeholder="Enter Username"required="required">
<input type="button" class="loginButton" id="loginButton" value="Login"/>
</div>
`);
$document.on("click", "#loginButton", function() {
const $userNameBox = $("#userNameBox");
if ($userNameBox.val() !== "") {
location.href = "mylink.com";
} else {
alert("Please Enter a Username.");
location.reload();
}
});
$('.login').click(function(e) {
if ($loginBox.children().length === 0) {
$loginBox.append($formElement);
}
$("#loginbox").show();
event.preventDefault();
return false;
});

Updating LocalStorage Objects Based on Edit Form with JavaScript/jQuery?

I asked a question earlier with answers which didn't help, I still haven't been able to figure out where my issue is. Originally I thought it was because I had two IDs named the same but this was not the issue.. The form submits and there are no errors but it does not update the values in localStorage?
Edit: After changing const idx to const i the value at position [2] (or final value) would update for every booking (regardless of index). I thought of maybe changing the i value to below but it gives error i is defined before it is initialised?
bookings.findIndex(booking => bookings[i].fname == fname && bookings[i].lname == lname);
Here's what I have (updated code):
// ~~~ add bookings to localStorage
var bookings = JSON.parse(localStorage.getItem("bookings")) || [];
window.onload = showBooking();
$("#submit").click(function() {
var newBookings = {
fname: $('#fname').val(),
lname: $('#lname').val()
}
bookings.push(newBookings);
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
showBooking();
});
// ~~~ edit bookings in localStorage
$(document).on('click','#edit',function (e) {
e.preventDefault();
var parent_form = $(this.form);
var fname = parent_form.find('.input:eq(0)').val();
var lname = parent_form.find('.input:eq(1)').val();
const i = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);
deleteBooking(i);
bookings.push({
fname,
lname
});
var json = JSON.stringify(bookings);
window.localStorage.setItem("bookings", json);
// showBooking();
});
// ~~~ display bookings in browser
function showBooking() {
var bookingResult = document.getElementById("result");
var ul = document.createElement("ul");
// var bookingItems = JSON.parse(localStorage.getItem("bookings")) || [];
bookingResult.innerHTML = "";
for (let i = 0; i < bookings.length; i++) {
bookingResult.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname}
<button onclick="deleteBooking(${i})" class="btn btn-danger text-light ">Delete</button>
<button onclick="editBooking(${i})" class="btn btn-danger text-light ">Edit</button>
</h3>
</div>`;
}
}
// ~~~ edit bookings in browser
function editBooking(i) {
// $('#regForm').hide();
$('#result').hide();
var currentItem = document.getElementById("currentItem");
var editBooking = document.getElementById("editAppt");
currentItem.innerHTML += `<div class="card card-body bg-light m-4">
<h3>${bookings[i].fname + " " + bookings[i].lname} </h3>
</div>`;
editBooking.innerHTML = `<input type="text" class="input" id="fname_${i}" placeholder="${bookings[i].fname}" name="${bookings[i].fname}" value="${bookings[i].fname}" required>
<input type="text" class="input" id="lname_${i}" placeholder="${bookings[i].lname}" name="${bookings[i].lname}" value="${bookings[i].lname}" required>
<input id="edit" type="submit" value="Edit">`;
}
// ~~~ delete bookings from localStorage
function deleteBooking(i) {
bookings.splice(i, 1);
localStorage.setItem("bookings", JSON.stringify(bookings));
showBooking();
}
My HTML form:
<form id="regForm" name="regForm" action="" class="col-sm-6">
<div class="row">
<input type="text" class="input" id="fname" placeholder="First Name" name="fname" required>
<input type="text" class="input" id="lname"placeholder="Last Name" name="lname" required>
<input id="submit" type="submit" value="Submit">
</div>
</form>
<div id="result" class="row"></div>
<div id="currentItem" class="row"></div>
<div id="editAppt" class="row"></div>
There are several changes you need to consider
You have bookings AND bookingItems
You do some changes (I assume there will be some destination change) but do not save them
You parse the localStorage far too often. Not needed. Only read once and write when modified
You cannot have duplicate IDs so you need to delegate and use class names
Be consistent and use jQuery to create elements and to add events- for example the delete button should be d er legates and remove its closest form element
Here is how to find the booking based on names
const idx = bookings.findIndex(booking => bookings.fname == fname && bookings.lname == lname);

Categories