Hello everyone! I hope you all are doing well. I am developing a real estate website, there is a property page. In this page the requirement is that there will be a multi filtering system. User can filter properties by category, price range, parking spots, and BHK(Bedroom, Hall and Kitchen). Suppose user first will select apartment category, according to that category every property will show, after that suppose user will select 3 BHK, then 3 BHK apartment properties will show, after that suppose user will select a price range between 2000 and 3000 USD, then 3 BHK apartment properties which has a price range between 2000 and 3000 USD will show. Right now Category filter is working but other filters are not working accordingly.
Here is the property.blade.php :-
@extends('frontend.layouts.main')
@section('main-container')
<div class="page-heading header-text">
<div class="container">
<div class="row">
<div class="col-lg-12">
<span class="breadcrumb"><a href="#">Home</a> / Properties</span>
<h3>Properties</h3>
</div>
</div>
</div>
</div>
<div class="section properties">
<div class="container">
<ul class="properties-filter">
<li><a class="is_active" href="#!" data-filter="*">Show All</a></li>
<li><a href="#!" data-filter=".apartment">Apartment</a></li>
<li><a href="#!" data-filter=".luxury-villa">Luxury Villa</a></li>
<li><a href="#!" data-filter=".penthouse">Penthouse</a></li>
<li><a href="#!" data-filter=".modern-condo">Modern Condo</a></li>
</ul>
<div class="filters">
<!-- Price Filter -->
<div class="filter-item">
<label for="priceRange">Price Range:</label>
<input type="range" id="priceRange" min="500" max="3000" value="500" class="slider">
<span id="priceValue">0</span>
</div>
<!-- Parking Lots Filter -->
<div class="filter-item">
<label>Parking Spots:</label>
<div>
@foreach([3, 6, 8, 10] as $spots)
<input type="radio" id="parking{{ $spots }}" name="parkingSpots" value="{{ $spots }}">
<label for="parking{{ $spots }}">{{ $spots }} spots</label>
@endforeach
</div>
</div>
<!-- BHK Filter -->
<div class="filter-item">
<label for="bhk">BHK:</label>
<select id="bhk" class="form-select">
<option value="*">All</option>
@foreach([2, 3, 4] as $bhk)
<option value="{{ $bhk }}">{{ $bhk }} BHK</option>
@endforeach
</select>
</div>
</div>
<div class="row properties-box">
@foreach ($properties as $property)
<div class="col-lg-4 col-md-6 align-self-center mb-30 properties-items {{ strtolower(str_replace(' ', '-', $property->category_name)) }}"
data-price="{{ $property->price }}"
data-bhk="{{ $property->bhk }}"
data-parking="{{ $property->parking }}">
<div class="item">
<a href="{{ route('property-details', $property->id) }}"><img src="{{ asset('storage/' . $property->property_image) }}" alt=""></a>
<span class="category">{{ $property->category_name }}</span>
<h6>{{ $property->price }}</h6>
<h4><a href="{{ route('property-details', $property->id) }}">{{$property->property_name}}</a></h4>
<ul>
<li>Address: <span><a href="{{ route('property-details', $property->id) }}">{{ $property->address }}</a></span></li>
<li><span>{{ $property->bhk }} BHK</span></li>
<li>Area: <span>{{ $property->area }}</span></li>
@if (in_array($property->category_name, ["Apartment", "Penthouse", "Modern Condo"]))
<li>Floor: <span>{{ $property->floor }}th</span></li>
@else
<li>Floor: <span>{{ $property->floor }}</span></li>
@endif
<li>Parking: <span>{{ $property->parking }}</span></li>
</ul>
<div class="main-button">
<a href="{{ route('property-details', $property->id) }}">Schedule a visit</a>
</div>
</div>
</div>
@endforeach
</div>
</div>
<!-- Pagination -->
<div class="row">
<div class="col-lg-12">
{{ $properties->links() }}
</div>
</div>
</div>
</div>
@endsection
@section('title')
Property
@endsection
property-fliter-script.js :-
document.addEventListener("DOMContentLoaded", function() {
const filters = {
category: document.querySelectorAll('.properties-filter a'),
priceRange: document.getElementById('priceRange'),
parkingSpots: document.querySelectorAll('input[name="parkingSpots"]'),
bhk: document.getElementById('bhk')
};
const priceValueDisplay = document.getElementById('priceValue');
// Function to initially show all properties when the page loads
function showAllProperties() {
document.querySelectorAll('.properties-items').forEach(item => {
item.style.display = "block";
});
}
// Initial function call to show all properties
showAllProperties();
// Update price display
filters.priceRange.oninput = function() {
priceValueDisplay.textContent = `$${this.value}`;
applyFilters();
}
function applyFilters() {
const selectedPrice = parseInt(filters.priceRange.value, 10);
let selectedParking = null;
filters.parkingSpots.forEach(radio => {
if (radio.checked) selectedParking = parseInt(radio.value, 10);
});
const selectedBhk = parseInt(filters.bhk.value, 10);
document.querySelectorAll('.properties-items').forEach(item => {
const price = parseInt(item.dataset.price, 10);
const parking = parseInt(item.dataset.parking, 10);
const bhk = parseInt(item.dataset.bhk, 10);
const priceMatch = !selectedPrice || (price <= selectedPrice);
const parkingMatch = !selectedParking || (parking === selectedParking);
const bhkMatch = !selectedBhk || (bhk === selectedBhk);
item.style.display = (priceMatch && parkingMatch && bhkMatch) ? "block" : "none";
});
}
// Event listeners for BHK and Parking changes
filters.bhk.addEventListener('change', applyFilters);
filters.parkingSpots.forEach(radio => radio.addEventListener('change', applyFilters));
// Apply category filters independently from the other filters
filters.category.forEach(filter => {
filter.addEventListener('click', function(e) {
e.preventDefault();
const category = this.getAttribute('data-filter');
document.querySelectorAll('.properties-items').forEach(item => {
if (category === "*" || item.classList.contains(category.substring(1))) {
item.style.display = "block";
} else {
item.style.display = "none";
}
});
filters.category.forEach(f => f.classList.remove('is_active'));
this.classList.add('is_active');
});
});
});
PropertyController.php :-
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\PropertyDetail;
class PropertyController extends Controller
{
public function index(){
// Fetch 6 properties from the database
$properties = PropertyDetail::paginate(6);
// Pass the properties to the view
return view('frontend.property', compact('properties'));
}
/**
* Show the details for a specific property.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function showPropertyDetails($id)
{
// Fetch the property detail by ID
$property = PropertyDetail::findOrFail($id);
// Pass the property detail to the view
return view('frontend.property-details', compact('property'));
}
}
Please help me. Is there a way to resolve this ? are there any libraries or any other way to fix this issue.