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

更新於 2024/02/17閱讀時間約 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
14會員
20內容數
從藝術領域轉職到前端工程師,喜歡書寫學習歷程和技術文件,掌握經驗與隨時提取的感覺很好。
留言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
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
序列化(serialization)是將資料結構或對象轉換為一個格式,可以被儲存到文件或記憶體中,或者可以透過網路傳輸到另一個系統環境。這使得資料可以在不同的系統之間進行交換,並在需要時重新建構回原始的資料結構。本文將介紹兩個好用的Python套件-JSON與Pickle,並比較兩者的不同。
Thumbnail
最近遇到了一個思考有點久的問題,如何將數值不同的樣品進行分組,同時每組的總和不能超越固定的上限值,且某些樣品不能被分在同一組。雖然規則並不困難,但是人工進行分組卻頗花時間,是不是有可能自動化處理這個步驟?如果有可能的話想要產出多個不同的分組方法,最後由人工選擇最佳的分組方式。
Thumbnail
上一篇文章說明了Pillow套件的基礎操作,這篇文章則會透過四個範例來示範如何利用Pillow製作簡單的GIF動畫。
Thumbnail
一早看著IThome的新聞發現到這個標題「📢 PyPI新帳號現需要啟用雙因素驗證才能執行管理操作」, 而近期幾乎都在接觸Python語言, 在Python的生態圈裡相信對於「pip install…」應該相當熟悉了吧! 但對於背後的平台相信我們不曾仔細去了解一番, 這好藉著這次的觀點也順便來介紹一
Thumbnail
本篇適合: > 剛開始學習 HTML / CSS ,對基本語法有了解的人 > 想要快速建立一個一頁式網站,但對 CSS 仍無法很活用的人 初始設定與 Bootstrap 中文版網頁使用 在過去在大學期間擔任助教的過程,常常有人問「Bootstrap」是什麼?一來我也不是什麼前端工程師,我一時也不太知
如有需要可以不用浪費效能重新將整個頁面重新載入,可以使用非同步的JS,使用動態載入資料
Thumbnail
ANKH原意為生命之鑰,是古埃及藝術用來代表生命的符號。Ankh Numpad延續Aaru的浮雕風格,摘錄了羅塞塔石碑的聖碑體倒數4~5排的部份文字,讓原本單純的Numpad鍵盤賦予更深一層的意涵,若再搭配TKL的Aaru,能讓按鍵功能更加完整,自然不能錯過啦~
Thumbnail
MotoGP油箱上長出翅膀背後的意義是?這都跟最新的空氣動力學提供更多的抓地力有關。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
序列化(serialization)是將資料結構或對象轉換為一個格式,可以被儲存到文件或記憶體中,或者可以透過網路傳輸到另一個系統環境。這使得資料可以在不同的系統之間進行交換,並在需要時重新建構回原始的資料結構。本文將介紹兩個好用的Python套件-JSON與Pickle,並比較兩者的不同。
Thumbnail
最近遇到了一個思考有點久的問題,如何將數值不同的樣品進行分組,同時每組的總和不能超越固定的上限值,且某些樣品不能被分在同一組。雖然規則並不困難,但是人工進行分組卻頗花時間,是不是有可能自動化處理這個步驟?如果有可能的話想要產出多個不同的分組方法,最後由人工選擇最佳的分組方式。
Thumbnail
上一篇文章說明了Pillow套件的基礎操作,這篇文章則會透過四個範例來示範如何利用Pillow製作簡單的GIF動畫。
Thumbnail
一早看著IThome的新聞發現到這個標題「📢 PyPI新帳號現需要啟用雙因素驗證才能執行管理操作」, 而近期幾乎都在接觸Python語言, 在Python的生態圈裡相信對於「pip install…」應該相當熟悉了吧! 但對於背後的平台相信我們不曾仔細去了解一番, 這好藉著這次的觀點也順便來介紹一
Thumbnail
本篇適合: > 剛開始學習 HTML / CSS ,對基本語法有了解的人 > 想要快速建立一個一頁式網站,但對 CSS 仍無法很活用的人 初始設定與 Bootstrap 中文版網頁使用 在過去在大學期間擔任助教的過程,常常有人問「Bootstrap」是什麼?一來我也不是什麼前端工程師,我一時也不太知
如有需要可以不用浪費效能重新將整個頁面重新載入,可以使用非同步的JS,使用動態載入資料
Thumbnail
ANKH原意為生命之鑰,是古埃及藝術用來代表生命的符號。Ankh Numpad延續Aaru的浮雕風格,摘錄了羅塞塔石碑的聖碑體倒數4~5排的部份文字,讓原本單純的Numpad鍵盤賦予更深一層的意涵,若再搭配TKL的Aaru,能讓按鍵功能更加完整,自然不能錯過啦~
Thumbnail
MotoGP油箱上長出翅膀背後的意義是?這都跟最新的空氣動力學提供更多的抓地力有關。