Feature: Room Search and Filtering
Relevant source files
The following files were used as context for generating this wiki page:The Room Search and Filtering feature is the core functionality of the Campuspal Room Finder application. It allows users to find available rooms on campus by providing a visual timeline of room schedules. Users can search for all rooms in a specific building or across all buildings for a given day.
The feature also supports a more specific time-based search, where users can input a desired start time and duration. The system then categorizes rooms into "Available" and "Unavailable" lists based on whether they are free for the entire specified period. The results are presented in a modern, intuitive interface that uses AJAX for dynamic updates and includes a detailed modal for viewing individual room schedules.
Sources: README.md:1-4, finder/views.py:16-21
System Architecture and Components
The search feature is implemented using a standard Django Model-View-Template (MVT) architecture, enhanced with client-side JavaScript for a dynamic user experience.
| Component | File | Description |
|---|---|---|
| Model | finder/models.py | Defines the Room and ClassSchedule database tables, which store all room and booking information. |
| View | finder/views.py | Contains the search_rooms function, which handles form submission, processes search logic, generates timelines, and renders the response. |
| Form | finder/forms.py | Defines the RoomSearchForm class used to validate user input for building, day, time, and duration. |
| Template | finder/templates/finder/search.html | The main HTML page that renders the search form and the results container. It includes a partial template for dynamic updates. |
| Frontend Script | finder/static/finder/js/scripts.js | Manages AJAX form submission, handles tab switching between "Available" and "Unavailable" results, and populates the room details modal. |
Sources: finder/views.py, finder/forms.py, finder/models.py, finder/templates/finder/search.html, finder/static/finder/js/scripts.js
Data Models
The search functionality relies on two primary data models: Room and ClassSchedule. A Room can have many ClassSchedule entries associated with it.
This ER diagram shows the relationship between the Room and ClassSchedule models.
Room Model
Stores static information about each room.
| Field | Type | Description |
|---|---|---|
name | CharField(100) | The name or number of the room (e.g., "A101"). |
building | CharField(100) | The building where the room is located. |
capacity | PositiveIntegerField | The maximum occupancy of the room. |
amenities | JSONField | A list of amenities available in the room (e.g., ["Projector"]). |
photo_url | URLField | A URL to an image of the room. |
A UniqueConstraint ensures that the combination of name and building is unique.
Sources: finder/models.py:6-26
ClassSchedule Model
Stores individual booking or class entries for rooms.
| Field | Type | Description |
|---|---|---|
course | CharField(50) | The course code (e.g., "CS101"). |
day | CharField(3) | The day of the week (e.g., "Mon", "Tue"). |
start_time | TimeField | The start time of the class. |
end_time | TimeField | The end time of the class. |
room | ForeignKey to Room | A reference to the Room where the class is held. |
is_cancelled | BooleanField | A flag to indicate if the class is cancelled. |
Sources: finder/models.py:29-57
Backend Logic: search_rooms View
The search_rooms view in finder/views.py is the engine of the search feature. It handles both initial page loads (GET) and form submissions (POST).
Sources: finder/views.py:16-110
Search and Filtering Flow
The following flowchart illustrates the logic executed within the search_rooms view upon a POST request.
Sources: finder/views.py:22-97
Timeline Generation
For each room, the backend constructs a timeline list that represents the entire day from 7:00 AM to 11:00 PM. It iterates through the room's sorted ClassSchedule entries and fills in the gaps with "free" blocks.
- Booked Block: Created for each
ClassScheduleentry. Containstype: "booked", start/end times, and course details. - Free Block: Created for any time between
last_end_timeand the nextschedule.start_time.
For frontend rendering, two crucial values are calculated for each block:
start_percentage: The block's start position on the timeline, as a percentage of the total day duration (7 AM - 11 PM).width_percentage: The block's width, representing its duration, as a percentage of the total day duration.
These percentages allow the CSS to accurately and dynamically draw the visual timeline.
Sources: finder/views.py:42-56, finder/views.py:99-105
Availability Check
If the user provides a time and duration in the search form, the system performs an availability check.
search_start_timeandsearch_end_timeare calculated.- For each room, the system iterates through its generated timeline.
- A room is marked as "available" if and only if the entire search window (
search_start_timetosearch_end_time) fits completely within a single "free" block. - Rooms are then partitioned into
available_roomsandunavailable_roomslists. If no time is specified, all rooms are placed in theunavailable_roomslist for general browsing.
Sources: finder/views.py:72-88
Frontend and User Interaction
The frontend is built to be responsive and dynamic, minimizing full page reloads for a smoother user experience.
Sources: finder/templates/finder/search.html, finder/static/finder/js/scripts.js
Search Form
The search form is defined in finder/forms.py and rendered in finder/templates/finder/search.html.
| Field | Widget | required | Description |
|---|---|---|---|
building | ChoiceField | True | A dropdown to select a building or "ALL". |
day | ChoiceField | True | A dropdown to select the day of the week. |
time | TimeField | False | An optional time input for specific searches. |
duration | ChoiceField | False | An optional duration for specific searches. |
Sources: finder/forms.py, finder/templates/finder/search.html:31-52
AJAX-Powered Search
User interaction with the search form is handled by finder/static/finder/js/scripts.js, which uses an AJAX POST request to update the results without a page refresh.
The sequence diagram below shows the flow of an AJAX search request.
Results Display
- Initial State: The page shows an empty state message prompting the user to start a search.
- After Search: The results are loaded into the
#results-container. If the search included a specific time, a tabbed interface appears. - Tabs: The "Available Rooms" and "Unavailable Rooms" tabs allow the user to toggle between the two categories. This is handled client-side in
scripts.jsby togglingactiveclasses on the tab content. - Visual Timeline: Each room is displayed as a row with its name and a visual timeline bar. The
freeandbookedblocks are rendered using thestart_percentageandwidth_percentagevalues calculated by the backend.
Sources: finder/templates/finder/search.html:55-64, finder/static/finder/js/scripts.js:80-94, finder/static/finder/css/styles.css:235-300
Summary
The Room Search and Filtering feature is a well-integrated system that combines a robust Django backend with a dynamic JavaScript-powered frontend. The backend efficiently processes room schedules to generate comprehensive daily timelines and perform precise availability checks. The frontend presents this data in a highly visual and interactive format, using AJAX to provide a seamless user experience. The clear separation of concerns between the backend data processing and frontend rendering makes the feature both powerful and maintainable.