更新於 2024/03/07閱讀時間約 14 分鐘

【套件筆記 - JS】月曆 evocalendar.js

分享這套功能齊全視覺超級可愛還有響應式變化教學文件又很容易閱讀的套件 Evo Calendar。

當初在製作 JS side project 時,想找一個與 VCalendar 視覺相近的套件,但多半都不合意。六角學院指派的 side project 教練也幫我找了另一個純 JS 的範例,也很接近 VCalendar,但我實在改不動它的 JS,專題完成時間有限,所以最後仍選擇使用套件製作專題。

evocalendar


一、官網資源

evocalendar 官網:https://edlynvillegas.github.io/evo-calendar/


二、CDN 安裝

需搭配 jQuery 使用

<!-- 月曆 evo-calendar -->
<script src="https://www.jsdelivr.com/package/npm/evo-calendar"></script>

<!-- Add jQuery library (required) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>

<!-- Add the evo-calendar.js for.. obviously, functionality! -->
<script src="https://cdn.jsdelivr.net/npm/evo-calendar@1.1.2/evo-calendar/js/evo-calendar.min.js"></script>


三、使用範例

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

3-1. 目標功能

  1. ​建立行事曆,可填寫事件標題
  2. 可填寫開始與結束時間
  3. 分類活動
  4. 登記是否為重複活動
  5. 寫點敘述文字

3-2. 示範步驟

  1. 規劃版位
  2. 準備事件來源資料

3-3. 實作

  1. 規劃版位
<div class="container">
<!-- 表格區 -->
<form class="form">
<div>
<label for="name">活動標題</label>
<input type="text" placeholder="活動標題" class="event-input">
</div>
<div>
<label for="startDate">開始時間</label>
<input type="date" class="event-input">
</div>
<div>
<label for="endDate">結束時間</label>
<input type="date" class="event-input">
</div>
<div>
<label for="type">活動類型</label>
<select name="type" id="type" class="event-input">
<option value="">--Please choose an option--</option>
<option value="event">event</option>
<option value="holiday">holiday</option>
</select>
</div>
<div>
<label for="everyYear">是否每年重覆</label>
<select name="everyYear" id="everyYear" class="event-input">
<option value="">--Please choose an option--</option>
<option value="yes">yes</option>
<option value="no">no</option>
</select>
</div>
<div>
<label for="describe">敘述</label>
<textarea name="describe" id="describe" cols="20" rows="10" class="event-input"></textarea>
</div>
<button type="button" class="addEvent">送出</button>
</form>

<!-- 月曆渲染區 -->
<div id="calendar" style="width:600px"></div>
</div>
  1. 觀察套件所需資料格式
    進入 evocalendar 的 GitHub 閱讀文件,在 event 處可以看到它接受的資料格式。所以我們可得知資料格式為:
    (1)外層陣列包裹多個物件資料
    (2)物件屬性務必要有 id、name、date、type
  1. 準備事件來源資料庫用於渲染月曆
const events = [
{
id: "E001",
name: "看牙醫",
description: "記得先刷牙",
date: "2023/12/05",
type: "event",
everyYear: false
},
...
];
  1. 初始化月曆
    官網已經都幫我們寫好了,直接 copy paste。別忘了注意剛才 HTML 的月曆渲染 element id 要和這裏設定的相同。
$('#calendar').evoCalendar({
settingName: settingValue
})
  1. 月曆設定
    填入自己想顯示的視覺元件和設定。其實能做的選擇不多,它的原始預設是月份選擇、月曆、事件列表都全部打開的,但我們可以在此根據能分配給月曆顯示的區域尺寸,選擇哪些元件預設為隱藏狀態。
$("#calendar")
.evoCalendar({
format: "yyyy/mm/dd", //時間格式
todayHighlight: true, //標註今天
sidebarDisplayDefault: false, //左側月份預設顯示狀態
eventDisplayDefault: false, //右側事件預設顯示狀態
calendarEvents: events //傳入套件的事件來源
})
  1. 完成以上動作,就可以呈現月曆資料了

Demo

  1. 綁定畫面左側,用來增加事件的 DOM 元素們
    這裡小偷懶一點,輸入格的 DOM 綁定在所有輸入格上,但實際上還是一格格使用唯一的 class 或 id 綁定比較好。
// 綁定送出按鈕
const btnAddEvent = document.querySelector(".addEvent");
// 綁定所有輸入格
const eventInput = document.querySelectorAll(".event-input");
// 綁定表單
const form = document.querySelector(".form");
// 當送出按鈕按下,觸發 addEvent 函式
btnAddEvent.addEventListener("click", addEvent);

function addEvent(){}
  1. 撰寫建立事件函式 function addEvent
    在這個函式中,我們需要
    (1)取得輸入格中填入的資料
    (2)在月曆上新增事件:在官網的 methods 中,可以找到 addCalendarEvent 方法
    (3)新增事件後要再次初始化月曆,更新渲染
    (4)新增成功後清除輸入格中的資料
function addEvent() {
// 取得輸入格資料
const data = {
id: new Date().getTime(), // 因為 id 是唯一值,直接用日期當作唯一值
name: eventInput[0].value,
description: eventInput[5].value,
date: [eventInput[1].value, eventInput[2].value],
type: eventInput[3].value,
everyYear: eventInput[4].value === "yes" ? true : false
};

// 測試印出要新增的資料,看是否符合格式
console.log(data);

// 在月曆上新增事件
$("#calendar").evoCalendar("addCalendarEvent", data);

// 執行月曆初始化
$("#calendar").evoCalendar();

// 清除表單,因為我的表格在 HTML 中最外層有使用 form 包裹,才能使用這個辦法
form.reset();
}
  1. 加入必填驗證
    所有輸入格必填,否則無法送出資料。
    新增一個函式 function checkFormError ,它的職責是驗證每個輸入格均有填寫,如果有內容為 "" 空字串,則變更變數 isFilledForm 的狀態,使用 alert 提醒,並返回結果給 function addEvent
    function addEvent 內部最前面則加入執行驗證的程式碼,如果有未填欄位則使用 return 中斷函式執行。
function addEvent() {
// 有未填欄位就跳出
if (!checkFormError()) {
return;
}

const data = ...
}

// 確認表格必填
function checkFormError() {
let isFilledForm = true;

eventInput.forEach((item) => {
if (item.value.trim() === "") {
isFilledForm = false;
}
});

alert("欄位均須填寫");
return isFilledForm;
}
  1. 延伸
$("#calendar")
.evoCalendar({
...
})
.on("selectEvent", function (event, activeEvent) {
// 點擊月曆右側的事件列才會觸發
console.log("你選擇的事件是", event);
})
.on("selectDate", function (event, activeDate) {
// 點擊月曆日期會觸發
console.log(
"你選擇的事件 id 是",
event.target.evoCalendar.$active.events[0].id
);
console.log(`你選擇的日期是:${activeDate}`);
})
.on("selectMonth", function (event, activeMonth) {
// 點擊月曆月份會觸發
console.log(`你選擇的月份是:${activeMonth}`);
});


四、心得

  1. 功能齊全,文件說明清楚,但比較適合顯示範圍整頁時使用。
    a. 顯示範圍過小時,RWD 會跑版,這可以靠客製化解決,但不容易魔改
    b. 因為左右按鈕是換年份,不是換月份,必須叫出左邊的月份側邊欄才能換月,這是他的 UX 比較不好的地方
  2. 視覺可愛,但 CSS 比較不好更動,覆蓋權重較難
  3. 雖然功能齊全又漂亮,但作者似乎沒有再繼續維護,真的很可惜
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.