webdevpuneet.com

Flatpickr Multi-Date Selection — Free HTML CSS JS Snippet

Flatpickr Multi-Date Selection · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

Copy & paste

Source Code

<div class="md-wrap">
  <div class="md-card">
    <div class="md-title">Recurring Class Dates</div>
    <div class="md-sub">Click multiple dates, or click a selected date again to remove it</div>
    <div id="mdCalendar"></div>
    <div class="md-chips" id="mdChips"></div>
    <div class="md-count" id="mdCount">0 dates selected</div>
  </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

Built-in multi-select toggling
mode: multiple handles add/remove clicks natively.
Chips as a pure reflection of state
The chip list never diverges from Flatpickr's own selection.
Remove-through-the-library
Chip removal updates the real calendar, not just the chip UI.
Chronological chip ordering
Sorted at render time regardless of click order.
Accurate singular/plural count
Correct wording for exactly one date versus several.
Fully re-themed calendar
Custom CSS matches the surrounding card design.

About this UI Snippet

Flatpickr Multi-Date Selection — a Chip List That Reads From the Real Selection

Screenshot of the Flatpickr Multi-Date Selection snippet rendered live

Picking several non-consecutive dates — recurring class sessions, multi-day availability, custom blackout dates — needs a calendar in multiple mode plus some way to review and adjust the full selection, since a small calendar grid alone doesn't show "which 6 dates did I pick" at a glance. This snippet pairs the calendar with a chip list, and the two are kept honest by having exactly one of them (Flatpickr's own selection) be the actual source of truth.

mode: 'multiple' is Flatpickr's built-in toggle behavior

Setting mode: 'multiple' changes click behavior so every date click adds to the selection, and clicking an already-selected date removes it — Flatpickr handles this toggle logic internally; no click-counting or manual selection-array management is needed in application code.

The chip list is a rendering of onChange's output, not independent state

Every time Flatpickr's selection changes — from a calendar click in either direction — its onChange callback fires with the full current selectedDates array, and the render function rebuilds the entire chip list from that array, sorted chronologically. The chips never hold their own separate list; they're a direct reflection of whatever Flatpickr currently considers selected.

Removing a chip goes back through Flatpickr, not around it

The tempting shortcut — just remove that one chip's DOM element — would leave the calendar still showing that date highlighted, since Flatpickr's internal selection would never have been told anything changed. Instead, the remove button filters fp.selectedDates to exclude that one date and calls fp.setDate(remaining, true), updating Flatpickr's real selection (and, via the true flag, re-triggering onChange, which redraws the chips from the now-correct list). The calendar's highlighted dates and the chip list can never show conflicting information, because only one path ever changes the actual selection.

Sorting happens at render time, not at selection time

Flatpickr's selectedDates array reflects click order, not calendar order — clicking September 20th and then September 5th would put the 20th first. Sorting a copy of the array (.slice().sort(...)) inside render is what keeps the chip list always reading left-to-right chronologically, regardless of the order dates were actually clicked in.

Reusing it

This exact pattern — a multi-select calendar with a synced chip/tag list, single source of truth, remove-through-the-library — applies to any multi-date input: recurring events, multi-day trip planning, availability blocks.

Step by step

How to Use

  1. 1
    Add the Flatpickr CDNLoad flatpickr.min.css and flatpickr.min.js before the snippet's JS runs.
  2. 2
    Paste HTML, CSS, and JSAn inline calendar renders with an empty chip list below it.
  3. 3
    Click several datesEach one highlights and adds a chip in chronological order.
  4. 4
    Click a selected date againIt deselects and its chip disappears.
  5. 5
    Click a chip's remove buttonThat date deselects on the calendar too.
  6. 6
    Watch the countIt updates correctly with singular/plural wording.

Real-world uses

Common Use Cases

Recurring class scheduling
Pick every session date for a course, using mode: multiple so clicks toggle dates on and off natively.
Multi-day availability
Mark several specific days as available, with a chronological chip list reviewing the full selection however it was clicked.
Blackout date configuration
Let admins define custom unavailable dates, where removing a chip updates the real calendar selection rather than only the chip display.
Trip planning with gaps
Select non-consecutive travel days, with chips sorted at render time regardless of the order they were picked.
Bulk publishing schedules
Pair with the date range presets approach for content calendars, and use it to learn two-way state sync.

Got questions?

Frequently Asked Questions

Setting mode: 'multiple' changes Flatpickr's internal click handling so that clicking an unselected date adds it to the selection and clicking an already-selected date removes it — this toggle logic is built into multiple mode itself, with no manual selection-array management or click-counting needed in application code.

Flatpickr maintains its own internal record of which dates are selected, entirely independent of whatever chip elements happen to be rendered on the page. Simply removing a chip's DOM element would leave Flatpickr still believing that date is selected, so the calendar would keep showing it highlighted — calling fp.setDate() with the filtered list is what actually updates the real underlying selection that the calendar reads from.

Flatpickr's selectedDates array reflects the order dates were clicked in, not their chronological calendar order — clicking a later date before an earlier one would put them in that same order in the array. Sorting a copy of the array inside the render function every time ensures the chip list is always displayed in left-to-right date order regardless of the order the user actually clicked them in.

No — fp.setDate is called with fireChangeEvent set to true specifically so onChange fires once with the new, correct selection, which re-renders the chip list to match. This is a single, one-directional update (remove one date, recompute the full chip list from the result), not a loop, since removing a chip doesn't itself trigger another removal.

Check the length of selectedDates inside the onChange handler, and if it exceeds your desired maximum, call fp.setDate on a trimmed version of the array (for example dropping the most recently added date) to enforce the limit — the same setDate-based approach the chip removal already uses, just triggered by a length check instead of a button click.