let { pages, view, firstDayOfWeek, globalTaskFilter, dailyNoteFolder, dailyNoteFormat, startPosition, upcomingDays, css, options, } = input; // Error Handling if (!pages && pages != "") { dv.span( '> [!ERROR] Missing pages parameter\n> \n> Please set the pages parameter like\n> \n> `pages: ""`' ); return false; } if (!options.includes("style")) { dv.span( '> [!ERROR] Missing style parameter\n> \n> Please set a style inside options parameter like\n> \n> `options: "style1"`' ); return false; } if (!view) { dv.span( '> [!ERROR] Missing view parameter\n> \n> Please set a default view inside view parameter like\n> \n> `view: "month"`' ); return false; } if (firstDayOfWeek) { if (firstDayOfWeek.match(/[|\\0123456]/g) == null) { dv.span( "> [!ERROR] Wrong value inside firstDayOfWeek parameter\n> \n> Please choose a number between 0 and 6" ); return false; } } else { dv.span( '> [!ERROR] Missing firstDayOfWeek parameter\n> \n> Please set the first day of the week inside firstDayOfWeek parameter like\n> \n> `firstDayOfWeek: "1"`' ); return false; } if (startPosition) { if (!startPosition.match(/\d{4}\-\d{1,2}/gm)) { dv.span( "> [!ERROR] Wrong startPosition format\n> \n> Please set a startPosition with the following format\n> \n> Month: `YYYY-MM` | Week: `YYYY-ww`" ); return false; } } if (dailyNoteFormat) { if ( dailyNoteFormat.match(/[|\\YMDWwd.,-: \[\]]/g).length != dailyNoteFormat.length ) { dv.span("> [!ERROR] The `dailyNoteFormat` contains invalid characters"); return false; } } // Get, Set, Eval Pages if (pages == "") { var tasks = dv.pages().file.tasks; } else if (typeof pages === "string" && pages.startsWith("dv.pages")) { var tasks = eval(pages); } else if (typeof pages && pages.every((p) => p.task)) { var tasks = pages; } else { var tasks = dv.pages(pages).file.tasks; } // Variables var done, doneWithoutCompletionDate, due, recurrence, overdue, start, scheduled, process, progress, cancelled, dailyNote, dailyNoteRegEx; if (!dailyNoteFormat) { dailyNoteFormat = "YYYY-MM-DD"; } var dailyNoteRegEx = momentToRegex(dailyNoteFormat); var tToday = moment().format("YYYY-MM-DD"); var tMonth = moment().format("M"); var tDay = moment().format("d"); var tYear = moment().format("YYYY"); var tid = new Date().getTime(); if (startPosition) { var selectedMonth = moment(startPosition, "YYYY-MM").date(1); var selectedList = moment(startPosition, "YYYY-MM").date(1); var selectedWeek = moment(startPosition, "YYYY-ww").startOf("week"); } else { var selectedMonth = moment(startPosition).date(1); var selectedWeek = moment(startPosition).startOf("week"); var selectedList = moment(startPosition).date(1); } var selectedDate = eval("selected" + capitalize(view)); var arrowLeftIcon = ''; var arrowRightIcon = ''; var filterIcon = ''; var monthIcon = ''; var weekIcon = ''; var listIcon = ''; var calendarClockIcon = ''; var calendarCheckIcon = ''; var calendarHeartIcon = ''; var cellTemplate = "
{{cellName}}
{{cellContent}}
"; var taskTemplate = "
{{note}}
{{icon}}
{{taskContent}}
"; const rootNode = dv.el("div", "", { cls: "tasksCalendar " + options, attr: { id: "tasksCalendar" + tid, view: view, style: "position:relative;-webkit-user-select:none!important", }, }); if (css) { var style = document.createElement("style"); style.innerHTML = css; rootNode.append(style); } var taskDoneIcon = "βœ…"; var taskDueIcon = "πŸ“…"; var taskScheduledIcon = "⏳"; var taskRecurrenceIcon = "πŸ”"; var taskOverdueIcon = "⚠️"; var taskProcessIcon = "⏺️"; var taskProgressIcon = "⏯️"; var taskCancelledIcon = "🚫"; var taskStartIcon = "πŸ›«"; var taskDailyNoteIcon = "πŸ“„"; // Initialze getMeta(tasks); setButtons(); setStatisticPopUp(); setWeekViewContext(); eval("get" + capitalize(view))(tasks, selectedDate); function getMeta(tasks) { for (i = 0; i < tasks.length; i++) { var taskText = tasks[i].text; var taskFile = getFilename(tasks[i].path); var dailyNoteMatch = taskFile.match(eval(dailyNoteRegEx)); var dailyTaskMatch = taskText.match(/(\d{4}\-\d{2}\-\d{2})/); if (dailyNoteMatch) { if (!dailyTaskMatch) { tasks[i].dailyNote = moment(dailyNoteMatch[1], dailyNoteFormat).format( "YYYY-MM-DD" ); } } var dueMatch = taskText.match(/\πŸ“…\W(\d{4}\-\d{2}\-\d{2})/); if (dueMatch) { tasks[i].due = dueMatch[1]; tasks[i].text = tasks[i].text.replace(dueMatch[0], ""); } var startMatch = taskText.match(/\πŸ›«\W(\d{4}\-\d{2}\-\d{2})/); if (startMatch) { tasks[i].start = startMatch[1]; tasks[i].text = tasks[i].text.replace(startMatch[0], ""); } var scheduledMatch = taskText.match(/\⏳\W(\d{4}\-\d{2}\-\d{2})/); if (scheduledMatch) { tasks[i].scheduled = scheduledMatch[1]; tasks[i].text = tasks[i].text.replace(scheduledMatch[0], ""); } var completionMatch = taskText.match(/\βœ…\W(\d{4}\-\d{2}\-\d{2})/); if (completionMatch) { tasks[i].completion = completionMatch[1]; tasks[i].text = tasks[i].text.replace(completionMatch[0], ""); } var repeatMatch = taskText.includes("πŸ”"); if (repeatMatch) { tasks[i].recurrence = true; tasks[i].text = tasks[i].text.substring(0, taskText.indexOf("πŸ”")); } var lowMatch = taskText.includes("πŸ”½"); if (lowMatch) { tasks[i].priority = "D"; } var mediumMatch = taskText.includes("πŸ”Ό"); if (mediumMatch) { tasks[i].priority = "B"; } var highMatch = taskText.includes("⏫"); if (highMatch) { tasks[i].priority = "A"; } if (!lowMatch && !mediumMatch && !highMatch) { tasks[i].priority = "C"; } if (globalTaskFilter) { tasks[i].text = tasks[i].text.replaceAll(globalTaskFilter, ""); } else { tasks[i].text = tasks[i].text.replaceAll("#task", ""); } tasks[i].text = tasks[i].text.replaceAll("[[", ""); tasks[i].text = tasks[i].text.replaceAll("]]", ""); tasks[i].text = tasks[i].text.replace(/\[.*?\]/gm, ""); } } function getFilename(path) { var filename = path.match(/^(?:.*\/)?([^\/]+?|)(?=(?:\.[^\/.]*)?$)/)[1]; return filename; } function capitalize(str) { return str[0].toUpperCase() + str.slice(1); } function getMetaFromNote(task, metaName) { var meta = dv.pages('"' + task.link.path + '"')[metaName][0]; if (meta) { return meta; } else { return ""; } } function transColor(color, percent) { var num = parseInt(color.replace("#", ""), 16), amt = Math.round(2.55 * percent), R = (num >> 16) + amt, B = ((num >> 8) & 0x00ff) + amt, G = (num & 0x0000ff) + amt; return ( "#" + ( 0x1000000 + (R < 255 ? (R < 1 ? 0 : R) : 255) * 0x10000 + (B < 255 ? (B < 1 ? 0 : B) : 255) * 0x100 + (G < 255 ? (G < 1 ? 0 : G) : 255) ) .toString(16) .slice(1) ); } function momentToRegex(momentFormat) { momentFormat = momentFormat.replaceAll(".", "\\."); momentFormat = momentFormat.replaceAll(",", "\\,"); momentFormat = momentFormat.replaceAll("-", "\\-"); momentFormat = momentFormat.replaceAll(":", "\\:"); momentFormat = momentFormat.replaceAll(" ", "\\s"); momentFormat = momentFormat.replace("dddd", "\\w{1,}"); momentFormat = momentFormat.replace("ddd", "\\w{1,3}"); momentFormat = momentFormat.replace("dd", "\\w{2}"); momentFormat = momentFormat.replace("d", "\\d{1}"); momentFormat = momentFormat.replace("YYYY", "\\d{4}"); momentFormat = momentFormat.replace("YY", "\\d{2}"); momentFormat = momentFormat.replace("MMMM", "\\w{1,}"); momentFormat = momentFormat.replace("MMM", "\\w{3}"); momentFormat = momentFormat.replace("MM", "\\d{2}"); momentFormat = momentFormat.replace("DDDD", "\\d{3}"); momentFormat = momentFormat.replace("DDD", "\\d{1,3}"); momentFormat = momentFormat.replace("DD", "\\d{2}"); momentFormat = momentFormat.replace("D", "\\d{1,2}"); momentFormat = momentFormat.replace("ww", "\\d{1,2}"); regEx = "/^(" + momentFormat + ")$/"; return regEx; } function getTasks(date) { done = tasks .filter( (t) => t.completed && t.checked && t.completion && moment(t.completion.toString()).isSame(date) ) .sort((t) => t.completion); doneWithoutCompletionDate = tasks .filter( (t) => t.completed && t.checked && !t.completion && t.due && moment(t.due.toString()).isSame(date) ) .sort((t) => t.due); done = done.concat(doneWithoutCompletionDate); due = tasks .filter( (t) => !t.completed && !t.checked && !t.recurrence && t.due && moment(t.due.toString()).isSame(date) ) .sort((t) => t.due); recurrence = tasks .filter( (t) => !t.completed && !t.checked && t.recurrence && t.due && moment(t.due.toString()).isSame(date) ) .sort((t) => t.due); overdue = tasks .filter( (t) => !t.completed && t.due && t.status != "-" && moment(t.due.toString()).isBefore(date) ) .sort((t) => t.due); start = tasks .filter( (t) => !t.completed && !t.checked && t.start && moment(t.start.toString()).isSame(date) ) .sort((t) => t.start); scheduled = tasks .filter( (t) => !t.completed && !t.checked && t.scheduled && moment(t.scheduled.toString()).isSame(date) ) .sort((t) => t.scheduled); process = tasks.filter( (t) => !t.completed && !t.checked && t.due && t.start && moment(t.due.toString()).isAfter(date) && moment(t.start.toString()).isBefore(date) ); progress = tasks .filter( (t) => !t.completed && t.checked && t.status == "/" && ((t.due && moment(t.due.toString()).isSame(date)) || (t.scheduled && moment(t.scheduled.toString()).isSame(date)) || (t.start && moment(t.start.toString()).isSame(date))) ) .sort((t) => t.due); cancelled = tasks .filter( (t) => !t.completed && t.checked && t.status == "-" && t.due && moment(t.due.toString()).isSame(date) ) .sort((t) => t.due); dailyNote = tasks .filter( (t) => !t.completed && !t.checked && t.dailyNote && moment(t.dailyNote.toString()).isSame(date) ) .sort((t) => t.dailyNote); } function setTask(obj, cls) { var lighter = 25; var darker = -40; var noteColor = getMetaFromNote(obj, "color"); var textColor = getMetaFromNote(obj, "textColor"); var noteIcon = getMetaFromNote(obj, "icon"); var taskText = obj.text.replace("'", "'"); var taskPath = obj.link.path.replace("'", "'"); var taskIcon = eval("task" + capitalize(cls) + "Icon"); if (obj.due) { var relative = moment(obj.due).fromNow(); } else { var relative = ""; } var noteFilename = getFilename(taskPath); if (noteIcon) { noteFilename = noteIcon + " " + noteFilename; } else { noteFilename = taskIcon + " " + noteFilename; cls += " noNoteIcon"; } var taskSubpath = obj.header.subpath; var taskLine = taskSubpath ? taskPath + "#" + taskSubpath : taskPath; if (noteColor && textColor) { var style = "--task-background:" + noteColor + "33;--task-color:" + noteColor + ";--dark-task-text-color:" + textColor + ";--light-task-text-color:" + textColor; } else if (noteColor && !textColor) { var style = "--task-background:" + noteColor + "33;--task-color:" + noteColor + ";--dark-task-text-color:" + transColor(noteColor, darker) + ";--light-task-text-color:" + transColor(noteColor, lighter); var style = "--task-background:" + noteColor + "33;--task-color:" + noteColor + ";--dark-task-text-color:" + transColor(noteColor, darker) + ";--light-task-text-color:" + transColor(noteColor, lighter); } else if (!noteColor && textColor) { var style = "--task-background:#7D7D7D33;--task-color:#7D7D7D;--dark-task-text-color:" + transColor(textColor, darker) + ";--light-task-text-color:" + transColor(textColor, lighter); } else { var style = "--task-background:#7D7D7D33;--task-color:#7D7D7D;--dark-task-text-color:" + transColor("#7D7D7D", darker) + ";--light-task-text-color:" + transColor("#7D7D7D", lighter); } var newTask = taskTemplate .replace("{{taskContent}}", taskText) .replace("{{class}}", cls) .replace("{{taskPath}}", taskLine) .replace("{{due}}", "done") .replaceAll("{{style}}", style) .replace("{{title}}", noteFilename + ": " + taskText) .replace("{{note}}", noteFilename) .replace("{{icon}}", taskIcon) .replace("{{relative}}", relative); return newTask; } function setTaskContentContainer(currentDate) { var cellContent = ""; function compareFn(a, b) { if (a.priority.toUpperCase() < b.priority.toUpperCase()) { return -1; } if (a.priority.toUpperCase() > b.priority.toUpperCase()) { return 1; } if (a.priority == b.priority) { if (a.text.toUpperCase() < b.text.toUpperCase()) { return -1; } if (a.text.toUpperCase() > b.text.toUpperCase()) { return 1; } return 0; } } function showTasks(tasksToShow, type) { const sorted = [...tasksToShow].sort(compareFn); for (var t = 0; t < sorted.length; t++) { cellContent += setTask(sorted[t], type); } } if (tToday == currentDate) { showTasks(overdue, "overdue"); } showTasks(due, "due"); showTasks(scheduled, "scheduled"); showTasks(start, "start"); showTasks(process, "process"); showTasks(progress, "progress"); showTasks(dailyNote, "dailyNote"); showTasks(recurrence, "recurrence"); showTasks(done, "done"); showTasks(cancelled, "cancelled"); return cellContent; } function setButtons() { var buttons = ""; rootNode .querySelector("span") .appendChild(dv.el("div", buttons, { cls: "buttons", attr: {} })); setButtonEvents(); } function setButtonEvents() { rootNode.querySelectorAll("button").forEach((btn) => btn.addEventListener("click", () => { var activeView = rootNode.getAttribute("view"); if (btn.className == "previous") { if (activeView == "month") { selectedDate = moment(selectedDate).subtract(1, "months"); getMonth(tasks, selectedDate); } else if (activeView == "week") { selectedDate = moment(selectedDate) .subtract(7, "days") .startOf("week"); getWeek(tasks, selectedDate); } else if (activeView == "list") { selectedDate = moment(selectedDate).subtract(1, "months"); getList(tasks, selectedDate); } } else if (btn.className == "current") { if (activeView == "month") { selectedDate = moment().date(1); getMonth(tasks, selectedDate); } else if (activeView == "week") { selectedDate = moment().startOf("week"); getWeek(tasks, selectedDate); } else if (activeView == "list") { selectedDate = moment().date(1); getList(tasks, selectedDate); } } else if (btn.className == "next") { if (activeView == "month") { selectedDate = moment(selectedDate).add(1, "months"); getMonth(tasks, selectedDate); } else if (activeView == "week") { selectedDate = moment(selectedDate).add(7, "days").startOf("week"); getWeek(tasks, selectedDate); } else if (activeView == "list") { selectedDate = moment(selectedDate).add(1, "months"); getList(tasks, selectedDate); } } else if (btn.className == "filter") { rootNode.classList.toggle("filter"); rootNode.querySelector("#statisticDone").classList.remove("active"); rootNode.classList.remove("focusDone"); } else if (btn.className == "monthView") { if ( moment().format("ww-YYYY") == moment(selectedDate).format("ww-YYYY") ) { selectedDate = moment().date(1); } else { selectedDate = moment(selectedDate).date(1); } getMonth(tasks, selectedDate); } else if (btn.className == "listView") { if ( moment().format("ww-YYYY") == moment(selectedDate).format("ww-YYYY") ) { selectedDate = moment().date(1); } else { selectedDate = moment(selectedDate).date(1); } getList(tasks, selectedDate); } else if (btn.className == "weekView") { if (rootNode.getAttribute("view") == "week") { var leftPos = rootNode.querySelector("button.weekView").offsetLeft; rootNode.querySelector(".weekViewContext").style.left = leftPos + "px"; rootNode.querySelector(".weekViewContext").classList.toggle("active"); if ( rootNode .querySelector(".weekViewContext") .classList.contains("active") ) { var closeContextListener = function () { rootNode .querySelector(".weekViewContext") .classList.remove("active"); rootNode.removeEventListener( "click", closeContextListener, false ); }; setTimeout(function () { rootNode.addEventListener("click", closeContextListener, false); }, 100); } } else { if ( moment().format("MM-YYYY") != moment(selectedDate).format("MM-YYYY") ) { selectedDate = moment(selectedDate) .startOf("month") .startOf("week"); } else { selectedDate = moment().startOf("week"); } getWeek(tasks, selectedDate); } } else if (btn.className == "statistic") { rootNode.querySelector(".statisticPopup").classList.toggle("active"); } btn.blur(); }) ); rootNode.addEventListener("contextmenu", function (event) { event.preventDefault(); }); } function setWrapperEvents() { rootNode.querySelectorAll(".wrapperButton").forEach((wBtn) => wBtn.addEventListener("click", () => { var week = wBtn.getAttribute("data-week"); var year = wBtn.getAttribute("data-year"); selectedDate = moment(moment(year).add(week, "weeks")).startOf("week"); rootNode.querySelector(`#tasksCalendar${tid} .grid`).remove(); getWeek(tasks, selectedDate); }) ); } function setStatisticPopUpEvents() { rootNode.querySelectorAll(".statisticPopup li").forEach((li) => li.addEventListener("click", () => { var group = li.getAttribute("data-group"); const liElements = rootNode.querySelectorAll(".statisticPopup li"); if (li.classList.contains("active")) { const liElements = rootNode.querySelectorAll(".statisticPopup li"); for (const liElement of liElements) { liElement.classList.remove("active"); } rootNode.classList.remove("focus" + capitalize(group)); } else { for (const liElement of liElements) { liElement.classList.remove("active"); } li.classList.add("active"); rootNode.classList.remove.apply( rootNode.classList, Array.from(rootNode.classList).filter((v) => v.startsWith("focus")) ); rootNode.classList.add("focus" + capitalize(group)); } }) ); } function setStatisticPopUp() { var statistic = "
  • "; statistic += "
  • "; statistic += "
  • "; statistic += "
  • "; statistic += "
  • "; statistic += "
  • "; statistic += "
  • "; statistic += "
  • "; statistic += "
  • "; rootNode .querySelector("span") .appendChild(dv.el("ul", statistic, { cls: "statisticPopup" })); setStatisticPopUpEvents(); } function setWeekViewContextEvents() { rootNode.querySelectorAll(".weekViewContext li").forEach((li) => li.addEventListener("click", () => { var selectedStyle = li.getAttribute("data-style"); const liElements = rootNode.querySelectorAll(".weekViewContext li"); if (!li.classList.contains("active")) { for (const liElement of liElements) { liElement.classList.remove("active"); } li.classList.add("active"); rootNode.classList.remove.apply( rootNode.classList, Array.from(rootNode.classList).filter((v) => v.startsWith("style")) ); rootNode.classList.add(selectedStyle); } rootNode.querySelector(".weekViewContext").classList.toggle("active"); }) ); } function setWeekViewContext() { var activeStyle = Array.from(rootNode.classList).filter((v) => v.startsWith("style") ); var liElements = ""; var styles = 11; for (i = 1; i < styles + 1; i++) { var liIcon = "
    "; liElements += "
  • " + liIcon + "Style " + i + "
  • "; } rootNode .querySelector("span") .appendChild(dv.el("ul", liElements, { cls: "weekViewContext" })); rootNode .querySelector(".weekViewContext li[data-style=" + activeStyle + "]") .classList.add("active"); setWeekViewContextEvents(); } function setStatisticValues( dueCounter, doneCounter, overdueCounter, startCounter, scheduledCounter, recurrenceCounter, dailyNoteCounter ) { var taskCounter = parseInt(dueCounter + doneCounter + overdueCounter); var tasksRemaining = taskCounter - doneCounter; var percentage = Math.round( (100 / (dueCounter + doneCounter + overdueCounter)) * doneCounter ); percentage = isNaN(percentage) ? 100 : percentage; if (dueCounter == 0 && doneCounter == 0) { rootNode.querySelector("button.statistic").innerHTML = calendarHeartIcon; } else if (tasksRemaining > 0) { rootNode.querySelector("button.statistic").innerHTML = calendarClockIcon; } else if (dueCounter == 0 && doneCounter != 0) { rootNode.querySelector("button.statistic").innerHTML = calendarCheckIcon; } if (tasksRemaining > 99) { tasksRemaining = "⚠️"; } rootNode .querySelector("button.statistic") .setAttribute("data-percentage", percentage); rootNode .querySelector("button.statistic") .setAttribute("data-remaining", tasksRemaining); rootNode.querySelector("#statisticDone").innerText = "βœ… Done: " + doneCounter + "/" + taskCounter; rootNode.querySelector("#statisticDue").innerText = "πŸ“… Due: " + dueCounter; rootNode.querySelector("#statisticOverdue").innerText = "⚠️ Overdue: " + overdueCounter; rootNode.querySelector("#statisticStart").innerText = "πŸ›« Start: " + startCounter; rootNode.querySelector("#statisticScheduled").innerText = "⏳ Scheduled: " + scheduledCounter; rootNode.querySelector("#statisticRecurrence").innerText = "πŸ” Recurrence: " + recurrenceCounter; rootNode.querySelector("#statisticDailyNote").innerText = "πŸ“„ Daily Notes: " + dailyNoteCounter; } function removeExistingView() { if (rootNode.querySelector(`#tasksCalendar${tid} .grid`)) { rootNode.querySelector(`#tasksCalendar${tid} .grid`).remove(); } else if (rootNode.querySelector(`#tasksCalendar${tid} .list`)) { rootNode.querySelector(`#tasksCalendar${tid} .list`).remove(); } } function getMonth(tasks, month) { removeExistingView(); var currentTitle = "" + moment(month).format("MMMM") + " " + moment(month).format("YYYY") + ""; rootNode.querySelector("button.current").innerHTML = currentTitle; var gridContent = ""; var firstDayOfMonth = moment(month).format("d"); var firstDateOfMonth = moment(month).startOf("month").format("D"); var lastDateOfMonth = moment(month).endOf("month").format("D"); var dueCounter = 0; var doneCounter = 0; var overdueCounter = 0; var startCounter = 0; var scheduledCounter = 0; var recurrenceCounter = 0; var dailyNoteCounter = 0; // Move First Week Of Month To Second Week In Month View if (firstDayOfMonth == 0) { firstDayOfMonth = 7; } // Set Grid Heads var gridHeads = ""; for ( h = 0 - firstDayOfMonth + parseInt(firstDayOfWeek); h < 7 - firstDayOfMonth + parseInt(firstDayOfWeek); h++ ) { var weekDayNr = moment(month).add(h, "days").format("d"); var weekDayName = moment(month).add(h, "days").format("ddd"); if ( tDay == weekDayNr && tMonth == moment(month).format("M") && tYear == moment(month).format("YYYY") ) { gridHeads += "
    " + weekDayName + "
    "; } else { gridHeads += "
    " + weekDayName + "
    "; } } // Set Wrappers var wrappers = ""; var starts = 0 - firstDayOfMonth + parseInt(firstDayOfWeek); for (w = 1; w < 7; w++) { var wrapper = ""; var weekNr = ""; var yearNr = ""; var monthName = moment(month) .format("MMM") .replace(".", "") .substring(0, 3); for (i = starts; i < starts + 7; i++) { if (i == starts) { weekNr = moment(month).add(i, "days").format("w"); yearNr = moment(month).add(i, "days").format("YYYY"); } var currentDate = moment(month).add(i, "days").format("YYYY-MM-DD"); if (!dailyNoteFolder) { var dailyNotePath = currentDate; } else { var dailyNotePath = dailyNoteFolder + "/" + currentDate; } var weekDay = moment(month).add(i, "days").format("d"); var shortDayName = moment(month).add(i, "days").format("D"); var longDayName = moment(month).add(i, "days").format("D. MMM"); var shortWeekday = moment(month).add(i, "days").format("ddd"); // Filter Tasks getTasks(currentDate); // Count Events Only From Selected Month if ( moment(month).format("MM") == moment(month).add(i, "days").format("MM") ) { dueCounter += due.length; dueCounter += recurrence.length; dueCounter += scheduled.length; dueCounter += dailyNote.length; doneCounter += done.length; startCounter += start.length; scheduledCounter += scheduled.length; recurrenceCounter += recurrence.length; dailyNoteCounter += dailyNote.length; // Get Overdue Count From Today if ( moment().format("YYYY-MM-DD") == moment(month).add(i, "days").format("YYYY-MM-DD") ) { overdueCounter = overdue.length; } } // Set New Content Container var cellContent = setTaskContentContainer(currentDate); // Set Cell Name And Weekday if (moment(month).add(i, "days").format("D") == 1) { var cell = cellTemplate .replace("{{date}}", currentDate) .replace("{{cellName}}", longDayName) .replace("{{cellContent}}", cellContent) .replace("{{weekday}}", weekDay) .replace("{{dailyNote}}", dailyNotePath); cell = cell.replace("{{class}}", "{{class}} newMonth"); } else { var cell = cellTemplate .replace("{{date}}", currentDate) .replace("{{cellName}}", shortDayName) .replace("{{cellContent}}", cellContent) .replace("{{weekday}}", weekDay) .replace("{{dailyNote}}", dailyNotePath); } // Set prevMonth, currentMonth, nextMonth if (i < 0) { cell = cell.replace("{{class}}", "prevMonth"); } else if (i >= 0 && i < lastDateOfMonth && tToday !== currentDate) { cell = cell.replace("{{class}}", "currentMonth"); } else if (i >= 0 && i < lastDateOfMonth && tToday == currentDate) { cell = cell.replace("{{class}}", "currentMonth today"); } else if (i >= lastDateOfMonth) { cell = cell.replace("{{class}}", "nextMonth"); } wrapper += cell; } wrappers += "
    W" + weekNr + "
    " + wrapper + "
    "; starts += 7; } gridContent += "
    " + gridHeads + "
    "; gridContent += "
    " + wrappers + "
    "; rootNode .querySelector("span") .appendChild(dv.el("div", gridContent, { cls: "grid" })); setWrapperEvents(); setStatisticValues( dueCounter, doneCounter, overdueCounter, startCounter, scheduledCounter, recurrenceCounter, dailyNoteCounter ); rootNode.setAttribute("view", "month"); } function getWeek(tasks, week) { removeExistingView(); var currentTitle = "" + moment(week).format("YYYY") + " " + moment(week).format("[W]w") + ""; rootNode.querySelector("button.current").innerHTML = currentTitle; var gridContent = ""; var currentWeekday = moment(week).format("d"); var weekNr = moment(week).format("[W]w"); var dueCounter = 0; var doneCounter = 0; var overdueCounter = 0; var startCounter = 0; var scheduledCounter = 0; var recurrenceCounter = 0; var dailyNoteCounter = 0; for ( i = 0 - currentWeekday + parseInt(firstDayOfWeek); i < 7 - currentWeekday + parseInt(firstDayOfWeek); i++ ) { var currentDate = moment(week).add(i, "days").format("YYYY-MM-DD"); if (!dailyNoteFolder) { var dailyNotePath = currentDate; } else { var dailyNotePath = dailyNoteFolder + "/" + currentDate; } var weekDay = moment(week).add(i, "days").format("d"); var dayName = moment(currentDate).format("ddd D."); var longDayName = moment(currentDate).format("ddd, D. MMM"); // Filter Tasks getTasks(currentDate); // Count Events From Selected Week dueCounter += due.length; dueCounter += recurrence.length; dueCounter += scheduled.length; dueCounter += dailyNote.length; doneCounter += done.length; startCounter += start.length; scheduledCounter += scheduled.length; recurrenceCounter += recurrence.length; dailyNoteCounter += dailyNote.length; if ( moment().format("YYYY-MM-DD") == moment(week).add(i, "days").format("YYYY-MM-DD") ) { overdueCounter = overdue.length; } // Set New Content Container var cellContent = setTaskContentContainer(currentDate); // Set Cell Name And Weekday var cell = cellTemplate .replace("{{date}}", currentDate) .replace("{{cellName}}", longDayName) .replace("{{cellContent}}", cellContent) .replace("{{weekday}}", weekDay) .replace("{{dailyNote}}", dailyNotePath); // Set Cell Name And Weekday if (moment(week).add(i, "days").format("D") == 1) { var cell = cellTemplate .replace("{{date}}", currentDate) .replace("{{cellName}}", longDayName) .replace("{{cellContent}}", cellContent) .replace("{{weekday}}", weekDay) .replace("{{dailyNote}}", dailyNotePath); } else { var cell = cellTemplate .replace("{{date}}", currentDate) .replace("{{cellName}}", dayName) .replace("{{cellContent}}", cellContent) .replace("{{weekday}}", weekDay) .replace("{{dailyNote}}", dailyNotePath); } // Set Today, Before Today, After Today if (currentDate < tToday) { cell = cell.replace("{{class}}", "beforeToday"); } else if (currentDate == tToday) { cell = cell.replace("{{class}}", "today"); } else if (currentDate > tToday) { cell = cell.replace("{{class}}", "afterToday"); } gridContent += cell; } rootNode .querySelector("span") .appendChild( dv.el("div", gridContent, { cls: "grid", attr: { "data-week": weekNr } }) ); setStatisticValues( dueCounter, doneCounter, overdueCounter, startCounter, scheduledCounter, recurrenceCounter, dailyNoteCounter ); rootNode.setAttribute("view", "week"); } function getList(tasks, month) { removeExistingView(); var currentTitle = "" + moment(month).format("MMMM") + " " + moment(month).format("YYYY") + ""; rootNode.querySelector("button.current").innerHTML = currentTitle; var listContent = ""; var dueCounter = 0; var doneCounter = 0; var overdueCounter = 0; var startCounter = 0; var scheduledCounter = 0; var recurrenceCounter = 0; var dailyNoteCounter = 0; // Loop Days From Current Month for (i = 0; i < moment(month).endOf("month").format("D"); i++) { var currentDate = moment(month) .startOf("month") .add(i, "days") .format("YYYY-MM-DD"); var monthName = moment(month) .format("MMM") .replace(".", "") .substring(0, 3); // Filter Tasks getTasks(currentDate); // Count Events dueCounter += due.length; dueCounter += recurrence.length; dueCounter += scheduled.length; dueCounter += dailyNote.length; doneCounter += done.length; startCounter += start.length; scheduledCounter += scheduled.length; recurrenceCounter += recurrence.length; dailyNoteCounter += dailyNote.length; if (moment().format("YYYY-MM-DD") == currentDate) { overdueCounter = overdue.length; var overdueDetails = "
    Overdue" + setTaskContentContainer(currentDate) + "
    "; var todayDetails = "
    Today" + setTaskContentContainer(currentDate) + "
    "; // Upcoming if (!upcomingDays) { upcomingDays = "7"; } var upcomingContent = ""; for (t = 1; t < parseInt(upcomingDays) + 1; t++) { var next = moment(currentDate).add(t, "days").format("YYYY-MM-DD"); getTasks(next); upcomingContent += setTaskContentContainer(next); } var upcomingDetails = "
    Upcoming" + upcomingContent + "
    "; listContent += "
    " + moment(currentDate).format("dddd, D") + " " + moment(currentDate).format("[W]w") + "
    " + overdueDetails + todayDetails + upcomingDetails + "
    "; } else { listContent += "
    " + moment(currentDate).format("dddd, D") + " " + moment(currentDate).format("[W]w") + "
    " + setTaskContentContainer(currentDate) + "
    "; } } rootNode.querySelector("span").appendChild( dv.el("div", listContent, { cls: "list", attr: { "data-month": monthName }, }) ); setStatisticValues( dueCounter, doneCounter, overdueCounter, startCounter, scheduledCounter, recurrenceCounter, dailyNoteCounter ); rootNode.setAttribute("view", "list"); // Scroll To Today If Selected Month Is Current Month if (moment().format("YYYY-MM") == moment(month).format("YYYY-MM")) { var listElement = rootNode.querySelector(".list"); var todayElement = rootNode.querySelector(".today"); var scrollPos = todayElement.offsetTop - todayElement.offsetHeight + 85; listElement.scrollTo(0, scrollPos); } }