So, I have been trying to connect a database to a booking form for a restaurant with some code i have generated with some AI tools and hard coded, i have no idea why there is a problem, i am new to coding. Any assistance would help. Apparently there is an error on line 311 of the html file.I have also gone through the naming conventions of my database and everything seems to be in line.
HTML for BOOKING
Booking - Your Restaurant Name
<!-- Include the same header as your main page -->
<main>
<section id="booking">
<h2>Book Your Table</h2>
<form id="booking-form" method="POST" action="Booking.php">
<div>
<label for="guests">Number of Guests:</label>
<input type="number" id="guests" name="guests" min="1" max="8" required>
</div>
<div>
<label for="karaoke">Karaoke:</label>
<input type="checkbox" id="karaoke" name="karaoke" value="yes">
<label for="karaoke">Yes</label>
</div>
<p id="karaoke-message" style="display: none;">Please select at least 4 guests if you wish to book the karaoke table.</p>
<div>
<label for="date">Date:</label>
<input type="date" id="date" name="date" min="2024-05-14" required>
</div>
<div>
<label for="time">Time:</label>
<select id="time" name="time">
<!-- Time options will be dynamically added here -->
</select>
</div>
<div>
<label for="table">Table:</label>
<select id="table" name="table">
<option value="">Select a Table</option> <!-- Default empty option -->
<option value="Table S1">Table S1</option>
<option value="Table S2">Table S2</option>
<option value="Table S3">Table S3</option>
<option value="Table S4">Table S4</option>
<option value="Table S5">Table S5</option>
<option value="Table M1">Table M1</option>
<option value="Table M2">Table M2</option>
<option value="Table M3">Table M3</option>
<option value="Table M4">Table M4</option>
<option value="Table M5">Table M5</option>
<option value="Table M6">Table M6</option>
<option value="Table L1">Table L1</option>
<option value="Table L2">Table L2</option>
<option value="Table L3">Table L3</option>
<option value="Table K1">Table K1</option>
</select>
</div>
<div class="Floorplan-image">
<img src="" alt="Floorplan Image">
</div>
<div>
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
</div>
<div>
<label for="surname">Surname:</label>
<input type="text" id="surname" name="surname" required>
</div>
<div>
<label for="phone">Telephone Number:</label>
<input type="tel" id="phone" name="phone" required>
</div>
<div>
<label for="email">Email Address:</label>
<input type="email" id="email" name="email" required>
</div>
<button type="submit">Make Booking</button>
</form>
</section>
</main>
<footer>
<!-- Include the same footer as your main page -->
</footer>
<script>
const bookingForm = document.getElementById('booking-form');
const guestsInput = document.getElementById('guests');
const tableSelect = document.getElementById('table');
const karaokeCheckbox = document.getElementById('karaoke');
const karaokeMessage = document.getElementById('karaoke-message');
const dateInput = document.getElementById('date');
const timeSelect = document.getElementById('time');
// Time slots for 1-hour intervals
const oneHourTimeSlots = [
"11:00",
"12:00",
"13:00",
"14:00",
"15:00",
"16:00",
"17:00",
"18:00",
"19:00",
"20:00",
];
// Time slots for 2-hour intervals
const twoHourTimeSlots = [
"11:00",
"13:00",
"15:00",
"17:00",
"19:00",
`your text`
];
function updateTableOptions() {
const numGuests = parseInt(guestsInput.value);
const tableOptions = tableSelect.options;
const karaokeSelected = karaokeCheckbox.checked;
// Reset options to include all tables initially
for (let i = 0; i < tableOptions.length; i++) {
tableOptions[i].disabled = false;
tableOptions[i].style.display = 'block';
}
// Enable/disable tables based on guest count
if (numGuests >= 1 && numGuests <= 2) {
// Allow S1-S5
for (let i = 0; i < tableOptions.length; i++) {
if (
!tableOptions[i].value.startsWith('Table S') ||
tableOptions[i].value === 'Table S6' ||
tableOptions[i].value === 'Table S7' ||
tableOptions[i].value === 'Table S8'
) {
tableOptions[i].disabled = true;
tableOptions[i].style.display = 'none';
}
}
} else if (numGuests >= 3 && numGuests <= 4) {
// Allow M1-M4
for (let i = 0; i < tableOptions.length; i++) {
if (
!tableOptions[i].value.startsWith('Table M') ||
tableOptions[i].value === 'Table M5' ||
tableOptions[i].value === 'Table M6'
) {
tableOptions[i].disabled = true;
tableOptions[i].style.display = 'none';
}
}
} else if (numGuests >= 5 && numGuests <= 6) {
// Allow M5-M6
for (let i = 0; i < tableOptions.length; i++) {
if (
!tableOptions[i].value.startsWith('Table M') ||
tableOptions[i].value === 'Table M1' ||
tableOptions[i].value === 'Table M2' ||
tableOptions[i].value === 'Table M3' ||
tableOptions[i].value === 'Table M4'
) {
tableOptions[i].disabled = true;
tableOptions[i].style.display = 'none';
}
}
} else if (numGuests >= 7 && numGuests <= 8) {
// Allow L1-L3
for (let i = 0; i < tableOptions.length; i++) {
if (
!tableOptions[i].value.startsWith('Table L') ||
tableOptions[i].value === 'Table L4' ||
tableOptions[i].value === 'Table L5' ||
tableOptions[i].value === 'Table L6'
) {
tableOptions[i].disabled = true;
tableOptions[i].style.display = 'none';
}
}
}
// If karaoke is selected AND at least 4 guests, only allow Table K1
if (karaokeSelected && numGuests >= 4) {
for (let i = 0; i < tableOptions.length; i++) {
if (tableOptions[i].value !== 'Table K1') {
tableOptions[i].disabled = true;
tableOptions[i].style.display = 'none';
}
}
// Make sure Table K1 is visible and enabled
tableSelect.querySelector('option[value="Table K1"]').style.display = 'block';
tableSelect.querySelector('option[value="Table K1"]').disabled = false;
karaokeMessage.style.display = 'none'; // Hide the message
} else if (karaokeSelected && numGuests < 4) {
karaokeMessage.style.display = 'block'; // Show the message
}
}
// Add event listener to the guests input
guestsInput.addEventListener('change', updateTableOptions);
// Add event listener to the karaoke checkbox
karaokeCheckbox.addEventListener('change', updateTableOptions);
// Call the updateTableOptions function initially
updateTableOptions();
// Date Validation
function validateDate() {
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1); // Get tomorrow's date
const tomorrowFormatted = tomorrow.toISOString().split('T')[0]; // Format tomorrow's date
dateInput.min = tomorrowFormatted; // Set minimum date to tomorrow
// Prevent selecting Tuesdays
const date = new Date(dateInput.value);
const day = date.getDay();
if (day === 2) {
// Tuesday is 2 in getDay()
dateInput.value = '';
alert('Bookings are not available on Tuesdays.');
}
}
// Call validateDate initially and whenever the date input changes
validateDate();
dateInput.addEventListener('change', validateDate);
// Update the time options based on the number of guests
function updateTimeOptions() {
const numGuests = parseInt(guestsInput.value);
const timeOptions = timeSelect.options;
// Clear existing options
timeOptions.length = 0;
// Generate new options based on guest count
if (numGuests <= 3) {
oneHourTimeSlots.forEach(time => {
const option = document.createElement('option');
option.value = time;
option.text = time;
timeOptions.add(option);
});
} else {
twoHourTimeSlots.forEach(time => {
const option = document.createElement('option');
option.value = time;
option.text = time;
timeOptions.add(option);
});
}
}
// Call updateTimeOptions initially and when the number of guests changes
updateTimeOptions();
guestsInput.addEventListener('change', updateTimeOptions);
bookingForm.addEventListener('submit', async (event) => {
event.preventDefault();
// Get values from the form
const table = document.getElementById('table').value;
const time = document.getElementById('time').value;
const guests = document.getElementById('guests').value;
const date = document.getElementById('date').value;
const karaoke = document.getElementById('karaoke').checked ? 'yes' : 'no'; // Get karaoke value
const name = document.getElementById('name').value;
const surname = document.getElementById('surname').value;
const phone = document.getElementById('phone').value;
const email = document.getElementById('email').value;
fetch('Booking.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `table=${table}&time=${time}&guests=${guests}&date=${date}&karaoke=${karaoke}&name=${name}&surname=${surname}&phone=${phone}&email=${email}`,}).then((response) => {// Handle server responseif (response.ok) {// If the response is OK (status code 200), parse as JSONreturn response.json();} else {}
})
.then(data => {
if (typeof data === 'object' && data.bookingId) {
// If we successfully parsed JSON data with a bookingId
displayConfirmationModal(data.bookingId, email);
} else {
// Handle errors
alert(data); // Display the error message from the server
}
})
.catch((error) => {
console.error('Error:', error);
alert('An error occurred. Please try again later.');
});});
// Function to display a modal for confirmation
function displayConfirmationModal(bookingId, email) {
const modal = document.createElement('div');
modal.id = 'confirmationModal';
modal.classList.add('modal'); // Add a class for modal styling
modal.innerHTML = `
<div class="modal-content">
<span class="close" onclick="closeModal()">×</span>
<h2>Booking Successful!</h2>
<p>Your Booking ID: ${bookingId}</p>
<p>An email confirmation will be sent to: ${email}</p>
<button onclick="window.location.href='index.html'">Continue</button>
</div>
`;
document.body.appendChild(modal);
}
// Function to close the modal
function closeModal() {
const modal = document.getElementById('confirmationModal');
if (modal) {
document.body.removeChild(modal);
}
}
document.addEventListener('click', function(event) {
if (event.target.classList.contains('close')) {
closeModal();
}
});
</script>
<style>
/* Modal styles */
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Black with opacity */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
padding-top: 60px;
}
.modal-content {
background-color: #fefefe;
margin: 5% auto; /* 5% from the top and centered */
padding: 20px;
border: 1px solid #888;
width: 80%; /* Could be more or less, depending on your design */
}
.close {
color: #aaa;
float: right; /* Add this line to float the close button to the right */
font-size: 28px;
font-weight: bold;
cursor: pointer;
}
.close:hover,
.close:focus {
color: black;
}
</style>
PHP FOR BOOKING
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Database connection details (from login.php)
$host = "localhost";
$dbname = "movedb";
$username = "root";
$password = "";
try {
$dsn = "mysql:host=$host;dbname=$dbname";
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
// Return a JSON error if the database connection fails
header('Content-Type: application/json');
echo json_encode(['error' => 'Database connection failed.']);
exit;
}
// Check if the booking form is submitted
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Get booking details from the form
$bookingDate = $_POST['date'];
$bookingTime = $_POST['time'];
$tableId = $_POST['table'];
$custFname = $_POST['name'];
$custLname = $_POST['surname'];
$custEmail = $_POST['email'];
$custCell = $_POST['phone'];
$noOfGuests = $_POST['guests'];
// Validate inputs (add more validation as needed)
if (empty($bookingDate) || empty($bookingTime) || empty($tableId) || empty($custFname) || empty($custLname) || empty($custEmail) || empty($custCell) || empty($noOfGuests)) {
// Return a JSON error response if any required field is missing
header('Content-Type: application/json');
echo json_encode(['error' => 'Please fill in all required fields.']);
exit;
}
// Retrieve table details
$sqlTable = "SELECT * FROM Table WHERE TableID = :table";
$stmtTable = $pdo->prepare($sqlTable);
$stmtTable->bindParam(':tableId', $tableId);
$stmtTable->execute();
$tableDetails = $stmtTable->fetch(PDO::FETCH_ASSOC);
// Check if table is active
if ($tableDetails['TableStatus'] !== 'Active') {
header('Content-Type: application/json');
echo json_encode(['error' => 'Table is not active.']);
exit;
}
// Insert the customer data
$sqlCustomer = "INSERT INTO Customer (CustFName, CustLName, CustEmail, CustCell)
VALUES (:custFname, :custLname, :custEmail, :custCell)";
$stmtCustomer = $pdo->prepare($sqlCustomer);
$stmtCustomer->bindParam(':custFname', $custFname);
$stmtCustomer->bindParam(':custLname', $custLname);
$stmtCustomer->bindParam(':custEmail', $custEmail);
$stmtCustomer->bindParam(':custCell', $custCell);
try {
$stmtCustomer->execute();
} catch (PDOException $e) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Error inserting customer data: ' . $e->getMessage()]);
exit;
}
// Get the newly created customer ID
$newCustomerId = $pdo->lastInsertId();
// Insert the booking data
$sqlBooking = "INSERT INTO Booking (BookingDate, BookingTime, BookingStatus, Karaoke, NoOfGuests, CustType, CustCell, TableID, ReceptionistID, CustomerID)
VALUES (:date, :time, :bookingStatus, :karaoke, :guests, :customerType, :phone, :table, :receptionistId, :customerId)";
$stmtBooking = $pdo->prepare($sqlBooking);
$stmtBooking->bindParam(':date', $bookingDate);
$stmtBooking->bindParam(':time', $bookingTime);
$stmtBooking->bindParam(':bookingStatus', 'Active');
$stmtBooking->bindParam(':karaoke', isset($_POST['karaoke']) ? 1 : 0);
$stmtBooking->bindParam(':guests', $noOfGuests);
$stmtBooking->bindParam(':customerType', 'Online');
$stmtBooking->bindParam(':phone', $custCell);
$stmtBooking->bindParam(':table', $tableId);
// Get a receptionist ID (you'll need to implement logic to get this from your system)
$receptionistId = 1; // Replace with actual receptionist ID logic
$stmtBooking->bindParam(':receptionistId', $receptionistId);
$stmtBooking->bindParam(':customerId', $newCustomerId); // Bind the new customer ID
try {
$stmtBooking->execute();
} catch (PDOException $e) {
header('Content-Type: application/json');
echo json_encode(['error' => 'Error inserting booking data: ' . $e->getMessage()]);
exit;
}
// Get the new booking ID
$newBookingId = $pdo->lastInsertId();
// Send email confirmation (replace with your actual email logic)
$to = $custEmail;
$subject = "Your Booking Confirmation";
$message = "Your booking (ID: " . $newBookingId . ") has been confirmed. nn" .
"Booking Date: " . $bookingDate . "n" .
"Booking Time: " . $bookingTime . "n" .
"Table: " . $tableDetails['TableNo'] . "n" .
"Number of Guests: " . $noOfGuests . "nn" .
"Thank you for booking with us!";
$headers = 'From: [email protected]' . "rn";
mail($to, $subject, $message, $headers);
// Return JSON response with the booking ID
header('Content-Type: application/json');
echo json_encode(['bookingId' => $newBookingId]);
exit; // Stop further execution
}
?>
I tried changing some of the JSON issues but they just reappear for line 311
booking.html:311 Error:
SyntaxError: Unexpected token ‘<‘, “
“… is not valid JSON
This is the apparent error, but i am sure there might be more wrong.
This is all i really know, help would be awesome.