Created
May 10, 2025 10:40
-
-
Save thinkphp/36b79acc2dab6b90dd7fb97eda5bf0ec to your computer and use it in GitHub Desktop.
RentACar script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
// Car data (in a real app, this would come from a database) | |
const cars = [ | |
{ | |
id: 1, | |
name: "Toyota Corolla", | |
category: "Economy", | |
image: "/api/placeholder/300/200", | |
features: { | |
seats: 5, | |
luggage: 2, | |
transmission: "Automatic" | |
}, | |
pricePerDay: 45, | |
location: "new-york" | |
}, | |
{ | |
id: 2, | |
name: "Honda Civic", | |
category: "Compact", | |
image: "/api/placeholder/300/200", | |
features: { | |
seats: 5, | |
luggage: 2, | |
transmission: "Automatic" | |
}, | |
pricePerDay: 52, | |
location: "los-angeles" | |
}, | |
{ | |
id: 3, | |
name: "Toyota Camry", | |
category: "Mid-size", | |
image: "/api/placeholder/300/200", | |
features: { | |
seats: 5, | |
luggage: 3, | |
transmission: "Automatic" | |
}, | |
pricePerDay: 65, | |
location: "chicago" | |
}, | |
{ | |
id: 4, | |
name: "Ford Explorer", | |
category: "SUV", | |
image: "/api/placeholder/300/200", | |
features: { | |
seats: 7, | |
luggage: 4, | |
transmission: "Automatic" | |
}, | |
pricePerDay: 85, | |
location: "miami" | |
}, | |
{ | |
id: 5, | |
name: "BMW 5 Series", | |
category: "Luxury", | |
image: "/api/placeholder/300/200", | |
features: { | |
seats: 5, | |
luggage: 3, | |
transmission: "Automatic" | |
}, | |
pricePerDay: 120, | |
location: "san-francisco" | |
}, | |
{ | |
id: 6, | |
name: "Nissan Versa", | |
category: "Economy", | |
image: "/api/placeholder/300/200", | |
features: { | |
seats: 5, | |
luggage: 2, | |
transmission: "Manual" | |
}, | |
pricePerDay: 40, | |
location: "new-york" | |
} | |
]; | |
// DOM Elements | |
const carsContainer = document.getElementById('cars-container'); | |
const searchForm = document.getElementById('search-form'); | |
const bookingModal = document.getElementById('booking-modal'); | |
const closeModal = document.getElementById('close-modal'); | |
const bookingDetails = document.getElementById('booking-details'); | |
const bookingForm = document.getElementById('booking-form'); | |
const pickupDateInput = document.getElementById('pickup-date'); | |
const returnDateInput = document.getElementById('return-date'); | |
const rentalDurationElement = document.getElementById('rental-duration'); | |
// Date picker setup | |
const today = new Date(); | |
const tomorrow = new Date(today); | |
tomorrow.setDate(tomorrow.getDate() + 1); | |
// Set minimum date for pickup and return dates | |
const formatDate = (date) => { | |
return date.toISOString().split('T')[0]; | |
}; | |
pickupDateInput.min = formatDate(today); | |
returnDateInput.min = formatDate(tomorrow); | |
// Initialize with default values | |
pickupDateInput.value = formatDate(today); | |
returnDateInput.value = formatDate(tomorrow); | |
// Update rental duration | |
function updateRentalDuration() { | |
const pickupDate = new Date(pickupDateInput.value); | |
const returnDate = new Date(returnDateInput.value); | |
// Calculate the difference in days | |
const diffTime = returnDate.getTime() - pickupDate.getTime(); | |
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); | |
if (diffDays < 1) { | |
rentalDurationElement.textContent = "Return date must be after pickup date"; | |
rentalDurationElement.style.color = "red"; | |
returnDateInput.setCustomValidity("Return date must be after pickup date"); | |
} else { | |
rentalDurationElement.textContent = `Rental Duration: ${diffDays} day${diffDays > 1 ? 's' : ''}`; | |
rentalDurationElement.style.color = "#1a73e8"; | |
returnDateInput.setCustomValidity(""); | |
} | |
} | |
// Add event listeners for date changes | |
pickupDateInput.addEventListener('change', function() { | |
// Set minimum return date to be the same as pickup date | |
const nextDay = new Date(this.value); | |
nextDay.setDate(nextDay.getDate() + 1); | |
returnDateInput.min = formatDate(nextDay); | |
// If return date is before new pickup date, update it | |
const returnDate = new Date(returnDateInput.value); | |
if (returnDate <= new Date(this.value)) { | |
returnDateInput.value = formatDate(nextDay); | |
} | |
updateRentalDuration(); | |
}); | |
returnDateInput.addEventListener('change', function() { | |
updateRentalDuration(); | |
}); | |
// Initialize rental duration | |
updateRentalDuration(); | |
// Display all cars initially | |
displayCars(cars); | |
// Filter cars based on search criteria | |
searchForm.addEventListener('submit', function(e) { | |
e.preventDefault(); | |
const location = document.getElementById('pickup-location').value; | |
const carType = document.getElementById('car-type').value; | |
let filteredCars = cars; | |
if (location) { | |
filteredCars = filteredCars.filter(car => car.location === location); | |
} | |
if (carType) { | |
filteredCars = filteredCars.filter(car => car.category.toLowerCase() === carType); | |
} | |
displayCars(filteredCars); | |
}); | |
// Display cars in the container | |
function displayCars(carsToDisplay) { | |
carsContainer.innerHTML = ''; | |
if (carsToDisplay.length === 0) { | |
carsContainer.innerHTML = '<p class="no-results">No cars available matching your criteria. Please try different search options.</p>'; | |
return; | |
} | |
carsToDisplay.forEach(car => { | |
const carCard = document.createElement('div'); | |
carCard.className = 'car-card'; | |
carCard.innerHTML = ` | |
<img src="${car.image}" alt="${car.name}" class="car-image"> | |
<div class="car-details"> | |
<h3 class="car-name">${car.name}</h3> | |
<p class="car-category">${car.category}</p> | |
<div class="car-features"> | |
<span class="feature"> | |
<span>${car.features.seats} Seats</span> | |
</span> | |
<span class="feature"> | |
<span>${car.features.luggage} Luggage</span> | |
</span> | |
<span class="feature"> | |
<span>${car.features.transmission}</span> | |
</span> | |
</div> | |
<p class="car-price">$${car.pricePerDay}/day</p> | |
<div class="car-actions"> | |
<button class="btn book-now-btn" data-car-id="${car.id}">Book Now</button> | |
</div> | |
</div> | |
`; | |
carsContainer.appendChild(carCard); | |
}); | |
// Add event listeners to book now buttons | |
document.querySelectorAll('.book-now-btn').forEach(btn => { | |
btn.addEventListener('click', function() { | |
const carId = this.getAttribute('data-car-id'); | |
openBookingModal(carId); | |
}); | |
}); | |
} | |
// Open booking modal | |
function openBookingModal(carId) { | |
const car = cars.find(car => car.id === parseInt(carId)); | |
const pickupDate = new Date(pickupDateInput.value); | |
const returnDate = new Date(returnDateInput.value); | |
// Calculate days and total price | |
const diffTime = returnDate.getTime() - pickupDate.getTime(); | |
const days = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); | |
const totalPrice = (car.pricePerDay * days).toFixed(2); | |
// Format dates for display | |
const formatDisplayDate = (date) => { | |
return date.toLocaleDateString('en-US', { | |
weekday: 'short', | |
month: 'short', | |
day: 'numeric', | |
year: 'numeric' | |
}); | |
}; | |
bookingDetails.innerHTML = ` | |
<div class="detail-row"> | |
<span>Car:</span> | |
<span>${car.name}</span> | |
</div> | |
<div class="detail-row"> | |
<span>Category:</span> | |
<span>${car.category}</span> | |
</div> | |
<div class="detail-row"> | |
<span>Pickup Date:</span> | |
<span>${formatDisplayDate(pickupDate)}</span> | |
</div> | |
<div class="detail-row"> | |
<span>Return Date:</span> | |
<span>${formatDisplayDate(returnDate)}</span> | |
</div> | |
<div class="detail-row"> | |
<span>Duration:</span> | |
<span>${days} day${days > 1 ? 's' : ''}</span> | |
</div> | |
<div class="detail-row"> | |
<span>Price per Day:</span> | |
<span>$${car.pricePerDay}</span> | |
</div> | |
<div class="detail-row summary-total"> | |
<span>Total Price:</span> | |
<span>$${totalPrice}</span> | |
</div> | |
`; | |
bookingModal.style.display = 'flex'; | |
} | |
// Close modal | |
closeModal.addEventListener('click', function() { | |
bookingModal.style.display = 'none'; | |
}); | |
// Close modal if clicked outside | |
window.addEventListener('click', function(e) { | |
if (e.target === bookingModal) { | |
bookingModal.style.display = 'none'; | |
} | |
}); | |
// Handle booking form submission | |
bookingForm.addEventListener('submit', function(e) { | |
e.preventDefault(); | |
// In a real application, this would send the data to a server | |
alert('Booking successful! You will receive a confirmation email shortly.'); | |
bookingModal.style.display = 'none'; | |
// Reset the form | |
this.reset(); | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment