webdevpuneet.com

FullCalendar Agenda List with Filters — Free HTML CSS JS Snippet

FullCalendar Agenda List with Filters · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

Requires
<div class="al-wrap">
  <div class="al-filters" id="alFilters">
    <button type="button" class="al-chip active" data-cat="all">All</button>
    <button type="button" class="al-chip" data-cat="meeting">Meetings</button>
    <button type="button" class="al-chip" data-cat="deadline">Deadlines</button>
    <button type="button" class="al-chip" data-cat="social">Social</button>
  </div>
  <div id="alCal"></div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Automatic day grouping
listWeek groups events under day headers with no manual code.
Source-swap filtering
Removes and re-adds events so grouping recomputes correctly.
Correct empty-state per filter
noEventsContent shows cleanly whenever a filter matches nothing.
Custom category via extendedProps
Filtering data lives alongside the event, not in a separate map.
Persistent filter across navigation
The active category stays applied when changing weeks.
Single active-filter chip state
Simple, clear toggle logic for one filter dimension.

About this UI Snippet

FullCalendar Agenda List with Filters — Swapping the Source, Not Hiding Rows

Screenshot of the FullCalendar Agenda List with Filters snippet rendered live

An agenda/list view groups events by day automatically — useful for a scannable upcoming-events feed, but it means filtering by category can't just hide and show individual <li>-style rows, because hiding rows would leave stale day headers behind for days whose only events just got filtered out. This snippet filters by replacing FullCalendar's entire event source instead, letting the library recompute everything correctly from scratch.

initialView: 'listWeek' groups by day automatically

FullCalendar's list view renders a day-header row for each date that has at least one event, followed by that day's events — this grouping-by-day behavior is built into the view type itself, not something this snippet's code constructs.

Filtering removes and re-adds the whole event source

Each filter chip's click handler calls calendar.removeAllEvents() followed by calendar.addEventSource(filtered) with a freshly-filtered array — rather than trying to individually hide DOM rows for non-matching events. That matters specifically for a grouped list view: if "Deadlines" filters out every event on a given day, that day's header row needs to disappear too, and recomputing the whole rendered list from a smaller dataset is what makes that happen correctly and automatically.

noEventsContent handles the all-filtered-out case natively

When a filter matches zero events, FullCalendar's list view has a documented behavior for showing a customizable empty-state message (noEventsContent) rather than rendering a blank white box — this snippet sets that message once at initialization, and it applies correctly no matter which filter produces zero results.

category lives in extendedProps, same pattern as the month-view modal

Like the month-view event-modal snippet elsewhere in this collection, the category used for filtering isn't one of FullCalendar's built-in event fields — it's a custom value stored in extendedProps at event-creation time, read back out by the filter's .filter() call on the original array.

The chip's active state is simple because there's only one filter dimension

With a single active category at a time, toggling .active is just "remove from all, add to the clicked one" — a multi-select filter (several categories active simultaneously) would need the filter predicate to check membership in a set rather than equality against one value, but the swap-the-event-source approach itself would still apply unchanged.

Reusing it

Swap the category filter for any other event attribute — priority, assignee, location — stored the same way in extendedProps, and the remove/re-add filtering pattern keeps working since it never depends on what the filter predicate actually checks.

Step by step

How to Use

  1. 1
    Add the FullCalendar CDNLoad the FullCalendar global bundle before the snippet's JS runs.
  2. 2
    Paste HTML, CSS, and JSA week agenda list renders, grouped by day, with filter chips above it.
  3. 3
    Click "Meetings"Only meeting events show, days with none disappear entirely.
  4. 4
    Click a filter with zero matches on some daysThose day headers vanish along with their events.
  5. 5
    Click "All"The full unfiltered agenda returns.
  6. 6
    Navigate weeksThe active filter stays applied across navigation.

Real-world uses

Common Use Cases

Personal agenda feeds
Present upcoming events as a scannable list grouped by day automatically, with no manual code writing day headers.
Conference programme filtering
Let attendees filter a schedule by track using category chips that swap the whole event source, so day grouping always recomputes correctly.
Deadline and task lists
Pair with the month view event modal so people can switch between a calendar overview and a focused, filterable list.
Reminder and notification feeds
Show category-filtered upcoming items, with a clean noEventsContent empty state appearing whenever a filter matches nothing at all.
Club and community boards
Let visitors narrow events to the one category they care about, since filter data lives in extendedProps right beside each event.

Got questions?

Frequently Asked Questions

The list view automatically groups events under a day-header row for each date that has at least one event. If a filter hid individual event rows with CSS but left the underlying event data in place, a day whose only events got filtered out would still show its now-empty day header. Removing all events and adding back only the filtered set lets FullCalendar recompute the day grouping from scratch, so headers for days with zero matching events correctly disappear too.

FullCalendar's list view has a built-in noEventsContent option, set once when the calendar is initialized, that displays a custom message whenever there are no events to show in the current view. Because filtering works by fully replacing the event source, an empty filtered array correctly triggers this built-in empty state automatically — there's no separate empty-state check needed in the filter logic itself.

Category is stored in each event's extendedProps object at the point the sample events are defined — extendedProps is FullCalendar's designated place for any custom data beyond its built-in fields like title, start, and color. The filter's .filter() call reads e.extendedProps.category directly off the original array to decide which events belong in the current filtered set.

No — removeAllEvents() only clears the event data, not the calendar's current date range or view. Calling addEventSource() with the newly filtered events re-renders the list for whatever week is currently being viewed, so switching a filter while browsing a future week keeps that same week in view with the new filter applied.

Change the filter chips to toggle independently (each one adding or removing itself from a set of active categories) instead of only one being active at a time, and update the filter predicate to check whether an event's category is included in that set rather than strictly equal to one value. The underlying removeAllEvents/addEventSource swap pattern would apply completely unchanged.