Skip to content

Instantly share code, notes, and snippets.

@thinkphp
Created May 10, 2025 10:40
Show Gist options
  • Save thinkphp/36b79acc2dab6b90dd7fb97eda5bf0ec to your computer and use it in GitHub Desktop.
Save thinkphp/36b79acc2dab6b90dd7fb97eda5bf0ec to your computer and use it in GitHub Desktop.
RentACar script
<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