【套件筆記 - JS】時間選擇器 flatpickr.js

更新於 發佈於 閱讀時間約 9 分鐘

不喜歡 HTML 原生的時間選擇器外型嗎?試試看 flatpickr 吧!

以下是使用 flatpickr 做簡單的示例,以及 flatpickr 使用注意事項。

Demo

Demo

一、官網資源

flatpickr 官網:https://flatpickr.js.org/


二、CDN 安裝

flatpickr

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>

Bootstrap CSS(建立表單用,非必要)

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">


三、使用範例

https://codepen.io/annchou_illu/pen/oNmZbBX

3-1. 目標功能

  1. 時間輸入格須具備點選 年/月/日/時/分
  2. 時間輸入格採 24 時制
  3. 開始時間不能早於當前本地時間
  4. 結束時間只能選擇當前一個月內的本地時間
  5. 時間輸入格的開始時間不能晚於結束時間

3-2. 示範步驟

  1. 規劃版位
  2. DOM 元素綁定
  3. flatpickr 初始化
  4. 判斷時間先後順序,提示錯誤警告

3-3. 實作

  1. 規劃版位 HTML
    寫入開始與結束日期輸入格,以及錯誤訊息提示,並將錯誤訊息先使用 d-none (Bootstrap 樣式)隱藏。
    input 時間 type 的寫法請參考 MDN,我們在這裡新增一個 dateSelector 的 class 在兩個時間輸入格上,這待會可以用來做 flatpicr 初始化綁定。其實 flatpicr 綁 id 也可以,但因為 id 必須是唯一值,class 可以重複,所以綁 class 比較單純。
    目前已經可以使用 HTML 原生的選擇器了。
<ul class="d-flex flex-column gap-3 p-5 border border-2 w-50 list-unstyled">
<li>
<label for="startDate" class="mb-16 mb-md-12">開始日期</label>
<input type="datetime-local" id="startDate" name="startDate" placeholder="請點選日期" class="dateSelector">
</li>
<li>
<label for="endDate" class="mb-16 mb-md-12">結束日期</label>
<input type="datetime-local" id="endDate" name="endDate" placeholder="請點選日期" class="dateSelector">
<p class="mt-3 text-danger d-none dateAlert">※ 結束日期須晚於開始日期</p>
</li>
</ul>
原生 HTML 選擇器

原生 HTML 選擇器

  1. DOM 元素綁定
    綁定錯誤訊息提示。
const dateAlert = document.querySelector(".dateAlert");

3. 設定 flatpicr 初始化
注意 MDN 說明提到 type="datetime-local" 在部分瀏覽器會自動轉成 type="text",所以建議綁 id 或是 class 比較安全。
更多說明:初始化方式初始化屬性設定

因為這個範例是未使用 moment 的範例,所以我們需要藉由 Date 處理。

const currentTime = new Date()

config = {
enableTime: true, //可選時與分
dateFormat: "Y/m/d H:i", //時間格式
time_24hr: true, //24 時制
minuteIncrement: 15, //分鐘每次選擇間隔單位
allowInput: true, //可輸入控制
minDate: "today", //可選最小時間,可直接接受 'today' 字串
maxDate: currentTime.setMonth(currentTime.getMonth() + 1), //可選最大時間,從今天起一個月
}

flatpickr(".dateSelector", config);
  1. 測試是否能取值
    我們也能利用 flatpickr 做 onChange 監聽,做些執行動作。在 config 中加入以下程式碼,傳入的三個值依序代表
    selectedDate:相當 Date.prototype.toString(),返回的字串 "Sun Dec 24 2023 03:00:00 GMT+0800 (台北標準時間)"
    dateStr:返回字串 "2023/12/24 03:00",格式是剛才我們在 config 中設定的 dateFormat
    instance:flatpickr 實例,如果用 console.dir 展開可以在其中找到 inputinput.id 可用來判斷目前正被點選的 DOM
onChange: function (selectedDates, dateStr, instance) {
console.log(`你現在點選的是 ${instance.input.id},時間為 ${selectedDates} / ${dateStr}`);
}
Demo

Demo

  1. 上面步驟有提到 instance.input.id 可以用作判斷正被點選的 DOM,所以我們改寫 onChange,讓它能將參數傳輸,引發能辨別時間先後的函式執行
onChange: function (selectedDates, dateStr, instance) {
checkDateTime(dateStr, instance.input.id);
}
  1. 辨別兩時間先後
    因為每次 onChange 觸發,checkDateTime 都會跑一次,所以要先把開始日期和結束日期宣告在外面當全域變數。我們即可以使用比較運算子來判斷開始日期是否晚於結束日期。如果開始日期較晚,則移除錯誤訊息的 d-none,讓錯誤訊息顯示。
let startDateValue = null
let endDateValue = null

function checkDateTime(dateStr, id) {
if (id === "startDate"){
startDateValue = dateStr
}

if (id === "endDate"){
endDateValue = dateStr
}

if (startDateValue>endDateValue){
dateAlert.classList.remove("d-none");
}else{
dateAlert.classList.add("d-none");
}

}
  1. 以上即完成所有項目


四、flatpickr 注意事項

  1. 可使用 flatpickr("input[type=datetime-local]", config); 綁定,但 MDN 表示 type="datetime-local" 在少數瀏覽器中會降階為 type="text",所以還是建議使用 class 或 id 綁定會比較好。
  2. 部分設置如限制可選時間、每次可選時間間隔的設定,因為手機會變成使用每個系統原生的選擇器,所以將造成可用手機原生選擇器選擇被限制的時間,但在手機畫面顯示時會產生錯誤。
  3. 如果要將 A input 的時間傳遞至 B input 顯示,需於使用 flatpickr 綁定的 B input 使用 setDate(時間, true),否則在手機版無法顯示。
avatar-img
16會員
23內容數
從藝術領域轉職到前端工程師,喜歡書寫學習歷程和技術文件,掌握經驗與隨時提取的感覺很好。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
Ann Chou的沙龍 的其他內容
我依舊維持著修習 JS 的步伐,但我仍然覺得自己對 JS 的熟悉度不足。在 JS 班開課後,我藉由刷題庫和做 side project 專題,填補了課前的不自信感和知識焦慮。最終我們小組在 2.5 個月內開發了一個訂閱制電商網站的前後台,我也參加了 F2E week1 完賽,獲得銀級徽章
這是我參加為期三個月的六角學院 2023 網頁前端切版直播班中的學習和成長經驗。最初參加直播班時誤以為自己已經具備足夠的前端知識,但後來發現自己的程式碼還有改進的空間。我在參與直播班的過程中,不僅學到了更多切版技術,也在小組協作中體驗到了組織能力和團隊合作的重要性,並從做設計稿與切版中發現個人優勢。
軟工體驗營最後一周,短短一個月的前端程式體驗,真的是非常超值的課程。不論是檢視自己對寫程式的感受,或是透過社群認識自己的新面向、軟實力的培養都是。六角是非常新手友善的程式學校,推薦給每位想學習前端的初心者朋友。
遭受學習挫折的一周,開始發現社群的重要性,最終還是回歸於自己報名體驗營的目的。
軟體工程師體驗營的第三周,對於知識、學習、課程、社群的感想,持續內化中,我不想只有上課,也希望從學習過程獲得更多經驗,所以寫下了這篇記錄。我也意外發現剛學習的 JavaScript,說不定能讓我重拾學習程式互動藝術,這很令人開心,即使我正在考慮轉職,但創作是終生的,希望下次發作品能有些新展現。
在軟體工程師體驗營的第二周,我仿佛置身於精神時光屋,獲得了許多新的樂趣。寫程式依然讓我感到有趣,每天都迫不及待地期待著有新的發現。在這篇文章中,我紀錄了這一周的心得和體會。
我依舊維持著修習 JS 的步伐,但我仍然覺得自己對 JS 的熟悉度不足。在 JS 班開課後,我藉由刷題庫和做 side project 專題,填補了課前的不自信感和知識焦慮。最終我們小組在 2.5 個月內開發了一個訂閱制電商網站的前後台,我也參加了 F2E week1 完賽,獲得銀級徽章
這是我參加為期三個月的六角學院 2023 網頁前端切版直播班中的學習和成長經驗。最初參加直播班時誤以為自己已經具備足夠的前端知識,但後來發現自己的程式碼還有改進的空間。我在參與直播班的過程中,不僅學到了更多切版技術,也在小組協作中體驗到了組織能力和團隊合作的重要性,並從做設計稿與切版中發現個人優勢。
軟工體驗營最後一周,短短一個月的前端程式體驗,真的是非常超值的課程。不論是檢視自己對寫程式的感受,或是透過社群認識自己的新面向、軟實力的培養都是。六角是非常新手友善的程式學校,推薦給每位想學習前端的初心者朋友。
遭受學習挫折的一周,開始發現社群的重要性,最終還是回歸於自己報名體驗營的目的。
軟體工程師體驗營的第三周,對於知識、學習、課程、社群的感想,持續內化中,我不想只有上課,也希望從學習過程獲得更多經驗,所以寫下了這篇記錄。我也意外發現剛學習的 JavaScript,說不定能讓我重拾學習程式互動藝術,這很令人開心,即使我正在考慮轉職,但創作是終生的,希望下次發作品能有些新展現。
在軟體工程師體驗營的第二周,我仿佛置身於精神時光屋,獲得了許多新的樂趣。寫程式依然讓我感到有趣,每天都迫不及待地期待著有新的發現。在這篇文章中,我紀錄了這一周的心得和體會。
你可能也想看
Google News 追蹤
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
前言 今天課程要來學習,在 .css 設計樣式後,怎麼透過選擇器,讓 .html 可以有所配對,經過這一步後,便可以開始學習,如何正式設計 .css 了。 選擇器 介紹 還記得上次課程,我們在 .css 檔案中,撰寫的程式碼嗎?讓我們來複習看看: .highlight { co
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
前言 今天課程要來學習,在 .css 設計樣式後,怎麼透過選擇器,讓 .html 可以有所配對,經過這一步後,便可以開始學習,如何正式設計 .css 了。 選擇器 介紹 還記得上次課程,我們在 .css 檔案中,撰寫的程式碼嗎?讓我們來複習看看: .highlight { co