JavaScript DOM Tutorial: Build a Searchable Course List
- Get link
- X
- Other Apps
Web Development Learning Series — Part 3 of 10 · Intermediate
JavaScript becomes easier to learn when each interaction has a clear job. This project filters a course list as the reader types. It teaches events, arrays, and DOM updates without a framework.
The finished feature should handle three situations: a matching query, an empty query that shows everything, and a query with no matches. Decide those behaviors before writing the event handler.
Add the search interface
Save this markup inside the body of a standalone page. Load app.js as a module, which also lets you split the project into files later.
<label for="course-search">Search courses</label>
<input id="course-search" type="search" autocomplete="off">
<p id="result-count" role="status"></p>
<ul id="course-results"></ul>
<script type="module" src="app.js"></script>Write app.js
const courses = [
{ id: 'html', title: 'HTML Foundations' },
{ id: 'css', title: 'Responsive CSS' },
{ id: 'js', title: 'JavaScript Practice' }
];
const input = document.querySelector('#course-search');
const list = document.querySelector('#course-results');
const count = document.querySelector('#result-count');
function render(query) {
const term = query.trim().toLowerCase();
const matches = courses.filter(course =>
course.title.toLowerCase().includes(term)
);
const items = matches.map(course => {
const item = document.createElement('li');
item.textContent = course.title;
return item;
});
list.replaceChildren(...items);
count.textContent = matches.length === 0
? 'No courses found. Try another search.'
: matches.length + ' courses found.';
}
input.addEventListener('input', event => render(event.target.value));
render('');Serve module-based examples through a local development server; directly opening files can encounter browser restrictions. Check the console if the script fails to load, and verify that the file path matches the actual filename.
Separate calculation from display
Filtering calculates which records match. Rendering creates the visible list. As the project grows, extract the filtering function so it can be checked without a browser. For example, give it the courses and a query, and have it return matching records. Keep DOM queries outside that function.
Use textContent when inserting a course title as text. If data later comes from a user or API, treating it as HTML would change both behavior and risk. You do not need HTML parsing to display a title.
Design useful empty states
“No courses found” is different from “the data could not load.” This local example never requests remote data, so there is no network failure state yet. When you add an API, keep those states separate. A learner should know whether changing their search can help.
The input has a visible label rather than depending on a placeholder. The status region reports the changing count. Test the experience with a keyboard and assistive technology; a rapidly changing announcement may need adjustment if a larger search feature becomes noisy.
Debug deliberately
- Search for HTML, html, and a query with spaces around it.
- Search for a word that does not exist.
- Clear the field and confirm that all courses return.
- Add a title containing an ampersand or angle brackets and confirm it displays as text.
- Confirm that there is only one event listener, even after repeated searches.
Practice task
Add a difficulty level to each course and a second filter. Decide whether the two filters combine with “and” or “or,” then explain that rule beside the interface. A clear filter model is more useful than a collection of unexplained buttons.
Continue your learning
Previous lesson: Responsive CSS Grid: Build Course Cards That Fit Any Screen. Explore our web development series and the HTML multimedia project.
Reference: Official documentation for this lesson. Examples are learning exercises; adapt and test them for your own application.
- Get link
- X
- Other Apps
Comments
Post a Comment