Issue
I've been working on an assignment where I am creating a website using JS, HTML and CSS to search for a movie and order tickets for it. The basics work, but I'm running into issues when validating the form.
The site basically works as follows:
- User searches for movie title and poser, which gets fetched by the omdb API
- User enters his information in a form (name, email, amount of tickets)
- Users clicks "order tickets", sees a thank you message. The order history shows up
When a user does not enter his name, email or amount of tickets, the order should NOT get added to the order history. 4. When the page reloads for some reason, the order history still exists.
To force the user to enter the needed information I added the required
attribute to each of the fields, like this:
<section id="Order-Form" style="display: none;">
<h2>Order your tickets</h2>
<ul>
<li>
<label for="User">Please enter your name:</label>
<input type="text" id="User" value="" required>
</li>
<li>
<label for="Email">Please enter your E-mail address:</label>
<input type="email" id="Email" value="" required>
</li>
<li>
<label for="Ticket-Amount">Amount of tickets: (You can order a maximum of 8 tickets</label>
<input type="number" id="Ticket-Amount" value="" min="1" max="8" required>
</li>
Here is the code for my page
"use strict";
const orderHistory = [];
//const orderHistory = JSON.parse(localStorage.getItem("Order-History")) || [];
document.addEventListener("DOMContentLoaded", init);
function init() {
hookupEventHandlers();
showOrderHistory();
}
function hookupEventHandlers() {
document.getElementById("Find-Movie").addEventListener("click", fetchMoviePoster);
document.getElementById("Place-Order").addEventListener("click", processForm);
document.getElementById("Place-Order").addEventListener("click", displayThankYouMessage);
document.getElementById("Place-Order").addEventListener("click", showOrderHistory);
}
function processForm(e) {
e.preventDefault();
const User = document.querySelector("#User");
const MovieTitle = document.querySelector("#Movie-Title");
const amountOfTickets = document.querySelector("#Ticket-Amount");
const email = document.querySelector("#Email");
addOrderToHistory(User, email, MovieTitle, amountOfTickets);
// Perform any necessary validation or processing of the user's input
}
function addOrderToHistory(userinput, emailinput, movieTitleinput, amountOfTicketsinput) {
const user = userinput.value;
const movieTitle = movieTitleinput.value;
const amountOfTickets = amountOfTicketsinput.value;
const email = emailinput.value;
const order = {
user,
email,
movieTitle,
amountOfTickets,
};
orderHistory.push(order);
//localStorage.setItem("Order-History", JSON.stringify(orderHistory));
}
function fetchMoviePoster() {
const movieTitle = document.querySelector("#Movie-Title").value;
const apiKey = "c3b11b36";
const apiUrl = `http://www.omdbapi.com/?t=${movieTitle}&apikey=${apiKey}`;
fetch(apiUrl)
.then(response => response.json())
.then(data => {
const posterElement = document.querySelector("#Movie-Poster");
const posterSection = document.querySelector("#Poster-Section");
const orderformSection = document.querySelector("#Order-Form");
const movieTitleItself = document.querySelector(".Movie-Title");
if (movieTitle =="") {
alert("Please enter a movie title!");
return false;
}
posterElement.src = data.Poster;
posterSection.style.display = "block";
orderformSection.style.display= "block";
movieTitleItself.textContent = data.Title;
})
}
function displayThankYouMessage() {
const thankYouSection = document.querySelector("#Thank-You");
thankYouSection.style.display = "block";
}
function showOrderHistory() {
const orderhistory = document.querySelector("#Order-History");
const ul = document.querySelector("#orderList");
ul.innerHTML = ""; // Clear the list before populating
orderHistory.forEach((order, index) => {
const listItem = document.createElement("li");
listItem.innerHTML =`<li>${order.movieTitle}<br> <a href="mailto:${order.email}">${order.user}</a> (${order.amountOfTickets} ticket(s))`;
ul.appendChild(listItem);
const lineBreak = document.createElement("br");
ul.appendChild(lineBreak);
});
// Show the order history section
orderhistory.style.display = "block";
}
body {
font-family: Verdana, Geneva, Tahoma, sans-serif;
background-color: black;
}
header {
background-color: #6a5acd;
text-align: center;
color: white;
padding-top: 16px;
padding-bottom: 16px;
}
header img {
width: 250px;
height: auto;
}
main {
width: 70%;
margin: auto;
}
footer {
color: white;
background-color: #6a5acd;
font-size: 12px;
margin-top: 32px;
padding-top: 16px;
padding-bottom: 16px;
text-align: center;
}
h1 {
font-size: 48px;
color: white;
}
h2 {
font-size: 32px ;
color: white;
}
h3 {
font-size: 24px;
color: white;
}
li {
list-style: none;
display: inline;
padding: 16px;
color: white;
}
a {
color: white;
color: blue;
}
label, input {
display: block;
margin-bottom: 10px;
}
input[type='submit'] {
width: auto;
}
img {
max-width: 100%;
}
<header>
<h1>Welcome to Howest cinema!</h1>
<h2>We'll make you an offer you can't refuse...</h2>
<img src="/images/god.png" alt="THE GODFATHER">
</header>
<main>
<h3>Find your favorite movie and order your tickets</h3>
<form>
<fieldset>
<ul>
<li>
<label for ="Movie-Title">Enter (a part) of the movie name:</label>
<input type="text" id="Movie-Title" required>
<button type="button" id="Find-Movie" >Find movie</button>
</li>
</ul>
<section id="Poster-Section" style="display: none;">
<h2>Best matching result</h2>
<h3 class="Movie-Title">movie-title</h3>
<figure id="Poster-Container">
<img id="Movie-Poster" src="/" alt="Movie Poster">
</figure>
</section>
<section id="Order-Form" style="display: none;">
<h2>Order your tickets</h2>
<ul>
<li>
<label for="User">Please enter your name:</label>
<input type="text" id="User" value="" required>
</li>
<li>
<label for="Email">Please enter your E-mail address:</label>
<input type="email" id="Email" value="" required>
</li>
<li>
<label for="Ticket-Amount">Amount of tickets: (You can order a maximum of 8 tickets</label>
<input type="number" id="Ticket-Amount" value="" min="1" max="8" required>
</li>
<li>
<button type="button" id="Place-Order">Place Order</button>
</li>
</ul>
</section>
<section id="Thank-You" style="display: none;">
<h3>Thank you for your order!</h3>
</section>
<section id="Order-History" style="display: none;">
<h3>Existing Orders</h3>
<ul id="orderList">
</ul>
</section>
</fieldset>
</form>
</main>
<footer>
<p>© 2023 Howest Cinema</p>
</footer>
So want I would like is that the fields "user, email and ticket amount" are filled in. Also the user should not be able to order more than 8 tickets.
I believe the issue is caused by function hookupEventHandlers() {
which adds the the information to the order history, without executing the form validation. Can anyone help me put more logic into it please?
Solution
I think you have a few problems here.
Multiple Click Events
You are adding 3 click events on the same button
document.getElementById("Place-Order").addEventListener("click", processForm);
document.getElementById("Place-Order").addEventListener("click", displayThankYouMessage);
document.getElementById("Place-Order").addEventListener("click", showOrderHistory);
In general, don't do this. It seems wrong to need to call 3 functions at the exact same time. Instead you should probably call one function like processForm
and that function should then decide what to do next. Like this
function processForm(){
// logic goes here...
if(isValid){
displayThankYouMessage();
showOrderHistory();
}
}
If for some reason you truly do need to have a button click call 3 functions at once, a better way to handle that would be to do it with a single click event handler like this:
document.getElementById("Place-Order").addEventListener("click", ()=>{
processForm();
displayThankYouMessage();
showOrderHistory()
});
Real Forms
You have a <form>
element, but you really aren't using it as intended. When a form submit event happens that's when it will do the checks for the field validity you set up. This is built into the browser, all you have to do is use a button of type="submit"
to trigger that, no JS needed for the basics!
<form>
<input type="text" required>
<button type="submit">Submit that form!</button>
</form>
So, all you need to do is add an event listener for the form submit
event instead of the button click
event. The event will only be triggered once the form is completely valid.
document.getElementById("My-Form").addEventListener("submit", (submitEvent)=>{
console.log(submitEvent)
});
<form id="My-Form">
<h2>Order your tickets</h2>
<ul>
<li>
<label for="User">Please enter your name:</label>
<input type="text" id="User" value="" required>
</li>
<li>
<label for="Email">Please enter your E-mail address:</label>
<input type="email" id="Email" value="" required>
</li>
<li>
<label for="Ticket-Amount">Amount of tickets: (You can order a maximum of 8 tickets</label>
<input type="number" id="Ticket-Amount" value="" min="1" max="8" required>
</li>
</ul>
<button type="submit">Submit that form!</button>
</form>
The built in validation will take care of the fields being required, validating the email, and the min/max values of a number field. You can of course customize this and use your own instead of what's built into the browser, but that might be better suited for a different question.
Answered By - Chris Barr
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.