0

So I am trying to implement one function to a cinema ticket booking javascript app this is what the app looks like where you can select dates like this look and what I want is whenever someone changes the date of when he wants to book the ticket, the data(selected,booked seats) get removed and you have only blank seats to choose from. For that, I have implemented this:

dateSelect.addEventListener('input',updateValue)
function updateValue() {
    
    resetSelection();
    resetSeatGrid();
  }

but from some reason, it doesn' work. Under here I am moving the full code. Thanks so much for any advice.

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.13.0/css/all.css" integrity="sha384-Bfad6CLCknfcloXFOyFnlgtENryhrpZCe29RTifKEixXQZ38WheV+i/6YWSzkz3V" crossorigin="anonymous">
    <link href="https://fonts.googleapis.com/css2?family=Lato:wght@300&display=swap" rel="stylesheet">
    <title>Movie Seat Booking</title>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
 <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
 <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>


 <script>
   $(function() {
   $( "#dtb_yr" ).datepicker({ dateFormat: 'yy-mm-dd' });
 });
 </script>
</head>
<body>
    
    <h1>VanillaJS cinema</h1>

    <div class="wrapper">

        <div class="movie-selection">

            <div class="movie-container">
                <label>Select date</label>
                
                <input type="text" name="dtb_yr" id="dtb_yr" placeholder="Select Date" />
                
                <label>Select the movie</label>
               
                <select id="movie">
                    <option id="selection" value="0">Press to select...</option>
                    <option id="avengers" value="10">Tron: Legacy</option>
                    <option id="joker" value="12">The Internship</option>
                    <option id="toystory" value="8">The Social Network</option>
                    <option id="lionking" value="9">The Matrix</option>
                </select>
            </div>

            <div class="summary-container">
                <div class="items">
                    <p class="text seats-number">Number of seats</p>
                    <p class="text seats-premium-number">Premium seats</p>
                    <p class="text ticket-price">Ticket price</p>
                    <p class="text ticket-premium-price">Ticket premium price</p>
                    <p class="text total-price">Total price</p>
                </div>
                <div class="totals">
                    <p class="number seats-number" id="count">0</p>
                    <p class="number seats-premium-number" id="countpremium">£0</p>
                    <p class="number ticket-price" id="price">£0</p>
                    <p class="number ticket-premium-price" id="premiumprice">£0</p>
                    <p class="number total-price" id="total">£0</p>
                </div>
                
            </div>

            <div class="commands-container">
                <button id="resetselection"><span style="color: tomato;"><i class="fa fa-times-circle"></i></span>
                     Reset</button>
                <button id="confirmselection"><span style="color:limegreen;"><i class="fa fa-pound-sign"></i></span> Pay</button>
            </div>
    
        </div>
        
        <div class="seat-selection">
            <div class="cinema-container">
            
                <div class="screen" id="screen"></div>
        
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>

                <!-- Premium seats central -->
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat premium-seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>

                <!-- Normal seats -->
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>
                <div class="row">
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                    <div class="seat"></div>
                </div>
            </div>
        
            <div class="showcase">
                <ul class="row-showcase">
                    <li>
                        <div class="seat"></div>
                        <small>Free</small>
                    </li>
                    <li>
                        <div class="seat premium-seat"></div>
                        <small>Premium seat</small>
                    </li>
                </ul>
                <ul class="row-showcase">
                    <li>
                        <div class="seat selected"></div>
                        <small>Selected</small>
                    </li>
                    <li>
                        <div class="seat occupied"></div>
                        <small>Occupied</small>
                    </li>
                </ul>
            </div>
            
        </div>
    </div>

    <script src="script.js"></script>
</body>
</html>

script.js

const cinemacontainer = document.querySelector('.cinema-container');
const seats = document.querySelectorAll('.row .seat:not(.occupied)');
const count = document.getElementById('count');
const total = document.getElementById('total');
const movieSelect = document.getElementById('movie');
const dateSelect = document.getElementById('dtb_yr');

let movieList = [];

getMovieList();
checkStorage();


// #########################################################################
// FUNCTIONS
// #########################################################################

// CHECK STORAGE
function checkStorage() {

    const movieIndex = +localStorage.getItem('selectedMovieIndex');

    if (!(movieIndex === 0)) {
        if (localStorage.getItem('selectedSeats_'+movieList[movieIndex][1]) === null) {
            resetSeatGrid();
            localStorage.setItem('selectedSeats_'+movieList[movieIndex][1], '');
            localStorage.setItem('selectedPremiumSeats_'+movieList[movieIndex][1], '');
            localStorage.setItem('occupiedSeats_'+movieList[movieIndex][1], '');
        }
        else {
            resetSeatGrid();
            populateUI();
            updateSelectedCountAndTotal();
        }
    }
    else if (movieIndex === 0) {
        resetSeatGrid();
        document.getElementById('screen').innerHTML = '';
    }
    
}

// ----------------------
// GET MOVIE LIST
function getMovieList() {
    for(i=0;i<movieSelect.options.length;i++) {
        movieList.push([movieSelect.options[i].text, movieSelect.options[i].id]);
    }
}

// ----------------------
// SET MOVIE DATA
// Save selected movie index and price
function setMovieData(movieIndex, moviePrice) {
    localStorage.setItem('selectedMovieIndex', movieIndex);
    localStorage.setItem('selectedMoviePrice', moviePrice);
}

// ----------------------
// POPULATE UI
// Get data from localStorage and populate the UI
function populateUI() {

    if (localStorage.length > 0) {

        const movieIndex = localStorage.getItem('selectedMovieIndex');

        if (movieIndex !== null) {
            movieSelect.selectedIndex = movieIndex;
        }

        if (!(localStorage.getItem('selectedSeats_'+movieList[movieIndex][1]) === null) || localStorage.getItem('selectedSeats_'+movieList[movieIndex][1]).length > 0) {

            const selectedSeats = JSON.parse(localStorage.getItem('selectedSeats_'+movieList[movieIndex][1]));

            if (selectedSeats !== null && selectedSeats.length > 0) {
                seats.forEach((seat, index) => {
                    if(selectedSeats.indexOf(index) > -1) {
                        seat.classList.add('selected');
                    }
                });
            }
        }

        if (!(localStorage.getItem('selectedPremiumSeats_'+movieList[movieIndex][1]) === null) || localStorage.getItem('selectedPremiumSeats_'+movieList[movieIndex][1]).length > 0) {
            
            const selectedPremiumSeats = JSON.parse(localStorage.getItem('selectedPremiumSeats_'+movieList[movieIndex][1]));

            if (selectedPremiumSeats !== null && selectedPremiumSeats.length > 0) {
                seats.forEach((seat, index) => {
                    if(selectedPremiumSeats.indexOf(index) > -1) {
                        seat.classList.add('selected-premium');
                    }
                });
            }
        }

        if (!(localStorage.getItem('occupiedSeats_'+movieList[movieIndex][1]) === null) || localStorage.getItem('occupiedSeats_'+movieList[movieIndex][1]).length > 0) {
            
            const occupiedSeats = JSON.parse(localStorage.getItem('occupiedSeats_'+movieList[movieIndex][1]));
            
            if (occupiedSeats !== null && occupiedSeats.length > 0) {
                seats.forEach((seat, index) => {
                    if(occupiedSeats.indexOf(index) > -1) {
                        seat.classList.add('occupied');
                    }
                });
            }
        }
    }
};

// ----------------------
// UPDATE SELECTED COUNT AND TOTAL
// Update total and count
function updateSelectedCountAndTotal() {

    if (localStorage.length > 0) {

        const selectedSeats = document.querySelectorAll('.row .seat.selected');
        const selectedSeatsPremium = document.querySelectorAll('.row .seat.selected-premium');
        const occupiedSeats = document.querySelectorAll('.row .seat.occupied');

        // Copy selected seats into an array
        // Map through that array
        // Return a new array of indexes
        const seatsIndex = [...selectedSeats].map((seat) => [...seats].indexOf(seat));
        const seatsPremiumIndex = [...selectedSeatsPremium].map((seat) => [...seats].indexOf(seat));
        const occupiedIndex = [...occupiedSeats].map((seat) => [...seats].indexOf(seat));

        const movieIndex = localStorage.getItem('selectedMovieIndex');

        localStorage.setItem('selectedSeats_'+movieList[movieIndex][1], JSON.stringify(seatsIndex));
        localStorage.setItem('selectedPremiumSeats_'+movieList[movieIndex][1], JSON.stringify(seatsPremiumIndex));
        localStorage.setItem('occupiedSeats_'+movieList[movieIndex][1], JSON.stringify(occupiedIndex));

        const selectedSeatsCount = selectedSeats.length;
        const selectedPremiumSeatsCount = selectedSeatsPremium.length;

        count.innerText = selectedSeatsCount;
        countpremium.innerText = selectedPremiumSeatsCount;

        const moviePrice = +localStorage.getItem('selectedMoviePrice');
        price.innerText = "£" + moviePrice.toFixed(2);
        premiumprice.innerText = "£" + (moviePrice * 1.25).toFixed(2);

        total.innerText = "£" + (+(selectedSeatsCount * moviePrice + moviePrice * 1.25 * selectedPremiumSeatsCount)).toFixed(2);

        if (!(movieIndex == 0)) {
            document.getElementById('screen').innerHTML = movieList[movieIndex][0];
        }

    }

};


// #########################################################################
// EVENT LISTENER
// #########################################################################

// ----------------------
// SELECT A MOVIE
// Movie select event
movieSelect.addEventListener('change', (e) => {

    setMovieData(e.target.selectedIndex, e.target.value);
    checkStorage();
    
    ticketPrice = +e.target.value;

    updateSelectedCountAndTotal();
});

dateSelect.addEventListener('input',updateValue)
function updateValue() {
    
    resetSelection();
    resetSeatGrid();
  }
// ----------------------
// SELECT A SEAT
// Seat click event
cinemacontainer.addEventListener('click', (e) => {

    if(e.target.classList.contains('seat') && !e.target.classList.contains('occupied') && !e.target.classList.contains('premium-seat') && !(movieSelect.options[movieSelect.selectedIndex].id === 'selection')) {
        // with toggle it is possible to apply and remove the class quickly
        e.target.classList.toggle('selected');
        updateSelectedCountAndTotal();
    }

    if(e.target.classList.contains('premium-seat') && !e.target.classList.contains('occupied') && !(movieSelect.options[movieSelect.selectedIndex].id === 'selection')) {
        e.target.classList.toggle('selected-premium');
        updateSelectedCountAndTotal();
    }

});

// ----------------------
// RESET SELECTION
// Cancel selected seats
document.getElementById('resetselection').addEventListener('click', function() {
    resetSelection();
    updateSelectedCountAndTotal();
});

// ----------------------
// CONFIRM SELECTION
// Confirms selected seats and block them
document.getElementById('confirmselection').addEventListener('click', function() {
    confirmSelection();
    updateSelectedCountAndTotal();
});


// #########################################################################
// SELECTION FUNCTIONS
// #########################################################################

function resetSelection() {
    seats.forEach(seat => {
        if (seat.classList.contains('selected')) {
            seat.classList.remove('selected');
        }
        if (seat.classList.contains('selected-premium')) {
            seat.classList.remove('selected-premium');
        }
    });
};

function resetSeatGrid() {
    resetSelection();
    seats.forEach(seat => {
        if (seat.classList.contains('occupied')) {
            seat.classList.remove('occupied');
        }
    });
};

function confirmSelection() {
    seats.forEach(seat => {
        if (seat.classList.contains('selected')) {
            seat.classList.add('occupied');
            seat.classList.remove('selected');
        }
        if (seat.classList.contains('selected-premium')) {
            seat.classList.add('occupied');
            seat.classList.remove('selected-premium');
        }
    });
};
jenlee123
  • 133
  • 1
  • 10

1 Answers1

0

In situations like that always check if your event listener is working e.g. by adding console.log.

dateSelect.addEventListener('input',updateValue)
function updateValue() {
  console.log('event fired');
  resetSelection();
  resetSeatGrid();
}

In jquery docs you can find a note: "This widget manipulates its element's value programmatically, therefore a native change event may not be fired when the element's value changes." So 'input' didn't fire either. You can find help with that in another stack post.

RauboLuk
  • 421
  • 1
  • 3
  • 7