ThermalTodos/application/static/scripts.js

602 lines
21 KiB
JavaScript
Raw Normal View History

2023-08-22 23:51:39 +00:00
// <script type="text/javascript">
/*
<li class="task-row p-2 m-1 shadow-md border bg-white rounded-lg flex items-center space-x-1" data-editor-shown="false">
<!-- <a class="handle pr-2 text-2xl justify-center items-center content-center"></a> -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 handle mr-2 cursor-grab shrink-0">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
<span id="timeslot" class="font-semibold shrink-0">11:00-12:30 </span>
<span id="task" class="flex grow shrink">Row 4</span>
</li>
*/
function singleClickListener(e) {
// console.log(e)
// e.target.style.height += 100;
// e.target.classList.remove("h-11")
// e.target.classList.add("h-24")
console.log(e.target.tagName)
console.log(e.target.parentElement.tagName)
if (e.target.tagName !== "LI" && e.target.parentElement.tagName !== "LI" && e.target.parentElement.parentElement.tagName !== "LI") return;
if (e.target.tagName === "SPAN" && e.target.contentEditable === "true") return;
let activeEle = e.target
if (e.target.parentElement.tagName === "LI") {
activeEle = e.target.parentElement
}
if (e.target.parentElement.parentElement.tagName == "LI") {
activeEle = e.target.parentElement.parentElement
}
// var height = activeEle.offsetHeight;
if (activeEle.dataset.expandedView === 'true') {
// var newHeight = height - 75;
activeEle.style.height = null;
activeEle.dataset.expandedView = false
activeEle.querySelector("#task").contentEditable = "false"
activeEle.querySelector("#expanded-info").classList.add("hidden")
// activeEle.querySelector("#task").blur()
// activeEle.classList.add("h-44")
// activeEle.classList.remove("h-44")
} else {
// var newHeight = height + 75;
activeEle.style.height = (activeEle.offsetHeight + 75) + 'px';
activeEle.dataset.expandedView = true
activeEle.querySelector("#task").contentEditable = "true"
activeEle.querySelector("#task").focus()
selectText(activeEle.querySelector("#task"))
activeEle.querySelector("#expanded-info").classList.remove("hidden")
}
// console.log(newHeight)
// activeEle.style.height = newHeight + 'px';
}
// let focOutFired = false
let triggerFocOutEvent = true
function onClickListener(e) {
// if (!focOutFired) return;
// focOutFired = false
triggerFocOutEvent = false
console.log(e)
}
function blurOrKeypress(e) {
// split up largely for readability
console.log(e)
// console.log(document.activeElement)
if (!triggerFocOutEvent) {
triggerFocOutEvent = true
return
}
if (e.target.tagName !== "SPAN" && e.target.id !== "task") return false;
if ((e.type === 'keypress' && e.code != 'Enter' && !e.ctrlKey) || e.target.parentElement.parentElement.dataset.expandedView !== "true") return false;
// if (e.type === "focusout") focOutFired = true;
// if () {}
// if (e.target.parentElement.parentElement.dataset.expandedView === "true") {
// e.target.contentEditable = "false"
// e.target.parentElement.parentElement.style.height = null;
// e.target.parentElement.parentElement.dataset.expandedView = false
// e.target.parentElement.parentElement.querySelector("#expanded-info").classList.add("hidden")
// return
// }
// if (e.type === 'keypress' && (e.code == 'Enter' || e.ctrlKey)) {
e.target.contentEditable = "false"
e.target.blur()
e.target.parentElement.parentElement.style.height = null;
e.target.parentElement.parentElement.dataset.expandedView = false
e.target.parentElement.parentElement.querySelector("#expanded-info").classList.add("hidden")
if (e.target.innerHTML === "") {
e.target.parentElement.parentElement.parentElement.removeChild(e.target.parentElement.parentElement)
// return
}
// }
// if (e.target.tagName !== 'INPUT') return false;
// if (e.type === 'keypress' && e.code != 'Enter' && !e.ctrlKey) return false;
// // a parent, a row, and a newly minted text node walk into a bar...
// const parent = e.target.parentElement;
// const row = parent.parentElement;
// const text = document.createTextNode(e.target.value || e.target.placeholder);
// /* .isConnected refers to it's state in the DOM. this was some work to try and stop an error that was
// ocurring due to this being simultaneously the 'blur' 'keypress' event handler. Alas, it didn't.
// If the error is really an issue, then wrapping the parent.replaceChild in a try/catch block should solve it for you.*/
// if (e.target.isConnected) {
// // use the dataset key + the textarea's value to update the definitions.
// // definitions[row.dataset.key] = e.target.value;
// // write those to the local storage
// // localStorage.setItem('definitions', JSON.stringify(definitions));
// // Or, if you are using a database, you would use some variety of AJAX/XHR call here.
// // get rid of our text element
// parent.replaceChild(text, e.target);
// // reset the editorshown value in case we need to update this again
// row.dataset.editorShown = false;
// }
}
// <li class="task-row p-2 m-1 shadow-md border bg-white min-h-11 rounded-lg flex space-x-2 flex-col" data-editor-shown="false">
// <!-- <a class="handle pr-2 text-2xl justify-center items-center content-center">☰</a> -->
// <div class="flex grow space-x-2 h-full">
// <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 handle cursor-grab shrink-0">
// <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
// </svg>
// <span id="timeslot" class="font-semibold text-sm shrink-0 grow-0 h-fit bg-slate-200 text-slate-600 rounded-md p-0.5 pl-1.5 pr-1.5">1pm</span>
// <span id="task" class="flex grow">Walk to school while jumping on one leg and scratching your head.</span>
// </div>
// <div id="expanded-info" class="flex flex-row space-x-1 items-center hidden mt-6">
// <div class="timePickerWindowButton hover:bg-slate-200 cursor-pointer rounded-md flex flex-row space-x-1 items-center pr-1">
// <span class="w-8 h-8 flex space-x-2 space-y-2 items-center justify-center">
// <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
// <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z" />
// </svg>
// </span>
// <span id="timeButtonDisplay" class="text-sm font-semibold">12:15pm to 1:15pm</span>
// </div>
// </div>
// </li>
function selectText(node) {
/* Helper function slightly modified from: https://stackoverflow.com/a/987376 */
// const node = document.getElementById(nodeId);
if (document.body.createTextRange) {
const range = document.body.createTextRange();
range.moveToElementText(node);
range.select();
} else if (window.getSelection) {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(node);
selection.removeAllRanges();
selection.addRange(range);
} else {
console.warn("Could not select text in node: Unsupported browser.");
}
}
function addTask(defaultTimeRange="", defaultTaskText="New Task", editable=true) {
/* defaultTimeRange must be in format h:mma to h:mma (e.g: 1:15pm to 2:15pm) */
let rows = document.getElementById("table")
const row = document.createElement("li")
row.dataset.editorShown = false
row.dataset.recurring = false
row.className = "task-row p-2 m-1 shadow-md border bg-white min-h-11 rounded-lg flex space-x-2 flex-col"
let firstContainer = document.createElement("div")
firstContainer.className = "flex grow space-x-2 h-full"
firstContainer.innerHTML += "<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' class='w-6 h-6 handle cursor-grab shrink-0'><path stroke-linecap='round' stroke-linejoin='round' d='M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5' /></svg>"
let timeslotSpan = document.createElement("span")
timeslotSpan.id = "timeslot"
timeslotSpan.className = "font-semibold text-sm shrink-0 grow-0 h-fit bg-slate-200 text-slate-600 rounded-md p-0.5 pl-1.5 pr-1.5 hidden"
if (defaultTimeRange !== "") {
timeslotSpan.classList.remove("hidden")
let parsedTime = dayjs(defaultTimeRange.split(' to ')[0], 'h:mma')
timeslotSpan.innerHTML = parsedTime.format("h:mma")
if (parsedTime.minute() == 0) {
timeslotSpan.innerHTML = parsedTime.format("ha")
}
}
firstContainer.appendChild(timeslotSpan)
let taskSpan = document.createElement("span")
taskSpan.id = "task"
taskSpan.className = "flex grow"
taskSpan.innerHTML = defaultTaskText
taskSpan.contentEditable = editable
firstContainer.appendChild(taskSpan)
row.appendChild(firstContainer)
let secondContainer = document.createElement("div")
secondContainer.id = "expanded-info"
secondContainer.className = "flex flex-row space-x-1 items-center mt-6 hidden"
let timePickerWindowButton = document.createElement("div")
timePickerWindowButton.className = "timePickerWindowButton hover:bg-slate-200 cursor-pointer rounded-md flex flex-row space-x-1 items-center pr-1"
secondContainer.appendChild(timePickerWindowButton)
let clockSpan = document.createElement("span")
clockSpan.className = "w-8 h-8 flex space-x-2 space-y-2 items-center justify-center"
clockSpan.innerHTML += "<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' class='w-6 h-6'><path stroke-linecap='round' stroke-linejoin='round' d='M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z' /></svg>"
timePickerWindowButton.appendChild(clockSpan)
let timeButtonDisplay = document.createElement("span")
timeButtonDisplay.id = "timeButtonDisplay"
timeButtonDisplay.className = "text-sm font-semibold"
timeButtonDisplay.innerHTML = defaultTimeRange
timePickerWindowButton.appendChild(timeButtonDisplay)
row.appendChild(secondContainer)
// row.innerHTML += "<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' class='w-6 h-6 handle mr-2 cursor-grab shrink-0'><path stroke-linecap='round' stroke-linejoin='round' d='M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5'/></svg>"
// const t = document.createElement("span")
// t.id = "timeslot"
// t.className = "font-semibold shrink-0"
// t.innerHTML = "xx:xx-xx:xx • "
// const ed = document.createElement("span")
// ed.id = "task"
// ed.className = "flex grow shrink"
// ed.innerHTML = "New Task"
// row.appendChild(t)
// row.appendChild(ed)
// const ta = document.createElement('input')
// ta.classList.add('grow')
// ta.placeholder = ed.innerHTML
// ed.replaceChild(ta, ed.firstChild)
rows.insertBefore(row, rows.lastElementChild)
if (editable) {
row.style.height = (row.offsetHeight + 75) + 'px';
row.dataset.expandedView = true
// row.querySelector("#task").contentEditable = "true"
// row.querySelector("#task").focus()
taskSpan.focus()
selectText(taskSpan)
secondContainer.classList.remove("hidden")
// row.querySelector("#expanded-info").classList.remove("hidden")
}
row.addEventListener('keypress', blurOrKeypress);
row.addEventListener('focusout', blurOrKeypress);
secondContainer.addEventListener('mousedown', onClickListener)
timePickerWindowButton.addEventListener("click", showTimePickerWindow)
timeslotSpan.addEventListener("mousedown", timeSlotShowTimePickerButton)
row.addEventListener('click', singleClickListener);
// ed.firstChild.focus()
}
function dblListener(e) {
let tarEle = e.target
const parent = tarEle.parentElement;
if (tarEle.tagName === "LI" && tarEle.dataset.editorShown !== 'true') {
const ed = tarEle.querySelector('span:last-child')
const ta = document.createElement('input')
ta.classList.add('grow')
ta.placeholder = ed.innerHTML
ed.replaceChild(ta, ed.firstChild)
ed.firstChild.focus()
tarEle.dataset.editorShown = true
return
}
if (parent.tagName !== 'LI' || parent.dataset.editorShown === 'true' || tarEle.dataset.editorShown === 'true') return;
const ed = parent.querySelector('span:last-child')
const ta = document.createElement('input')
ta.classList.add('grow')
// ta.classList.add('w-1/2')
ta.placeholder = ed.innerHTML
ed.replaceChild(ta, ed.firstChild)
ed.firstChild.focus()
parent.dataset.editorShown = true
}
function timeListener(e) {
console.log(e.target.value)
let parsedDate = dayjs(e.target.value, 'HH:mm')
let activeZone = "startTimeLabel"
if (document.getElementById("rad2").checked) {
activeZone = "endTimeLabel"
}
document.getElementById(activeZone).innerHTML = parsedDate.format('h:mm a')
// document.getElementById("endTimeLabel").innerHTML = parsedDate.add().format('h:mm a')
// console.log(dayjs(e.target.value, 'HH:mm').add(1, 'h').format("HH:mm"))
}
function endTimeListener(e) {
if (!e.target.checked) return;
document.getElementById("quickSelectButtons").classList.add("hidden")
document.getElementById("timeInput").value = dayjs(document.getElementById("endTimeLabel").innerHTML, 'h:mm a').format('HH:mm')
}
function startTimeListener(e, triggeredFromCode=false) {
if (!triggeredFromCode) {
if (!e.target.checked) return;
}
document.getElementById("quickSelectButtons").classList.remove("hidden")
document.getElementById("timeInput").value = dayjs(document.getElementById("startTimeLabel").innerHTML, 'h:mm a').format('HH:mm')
let startTime = dayjs(document.getElementById("startTimeLabel").innerHTML, 'h:mm a')
let endTime = dayjs(document.getElementById("endTimeLabel").innerHTML, 'h:mm a')
let idToAmount = {
"t15": 15,
"t30": 30,
"t60": 60,
"t120": 120
}
for (let button of document.getElementsByClassName("quickButton")) {
if (endTime.isSame(startTime.add(idToAmount[button.id], 'm'))) {
button.checked = 'checked'
return
}
button.checked = null
}
}
function quickButtonListener(e) {
if (!e.target.checked) return;
let idToAmount = {
"t15": 15,
"t30": 30,
"t60": 60,
"t120": 120
}
console.log(e.target.id)
console.log(document.getElementById("startTimeLabel").innerHTML)
console.log(dayjs(document.getElementById("startTimeLabel").innerHTML, "h:mm a"))
document.getElementById("endTimeLabel").innerHTML = dayjs(document.getElementById("startTimeLabel").innerHTML, "h:mm a").add(idToAmount[e.target.id], 'm').format('h:mm a')
}
function saveButtonListener(e) {
let startTime = dayjs(document.getElementById("startTimeLabel").innerHTML, 'h:mm a')
let endTime = dayjs(document.getElementById("endTimeLabel").innerHTML, 'h:mm a')
console.log('??')
console.log(document.getElementsByClassName("timePickerWindowButton"))
startTimeListener("", triggeredFromCode=true)
document.getElementById("rad1").checked = "clicked"
document.getElementById("rad2").checked = null
document
for (let b of document.getElementsByClassName("timePickerWindowButton")) {
// let b = bu.querySelector("#timeButtonDisplay")
console.log('==')
console.log(b)
console.log(b.dataset.timepickershown)
console.log('===')
if (b.dataset.timepickershown === 'true') {
b.dataset.timepickershown = false
b.querySelector("#timeButtonDisplay").innerHTML = startTime.format('h:mma') + " to " + endTime.format('h:mma')
b.parentElement.parentElement.querySelector("#timeslot").innerHTML = startTime.format('ha')
console.log(startTime.minute())
if (startTime.minute() != 0) {
b.parentElement.parentElement.querySelector("#timeslot").innerHTML = startTime.format('h:mma')
}
b.parentElement.parentElement.querySelector("#timeslot").classList.remove("hidden")
document.getElementById("timePickerWindow").classList.add("hidden")
b.parentElement.parentElement.querySelector("#task").contentEditable = "false"
b.parentElement.parentElement.querySelector("#task").blur()
b.parentElement.parentElement.style.height = null;
b.parentElement.parentElement.dataset.expandedView = false
b.parentElement.parentElement.querySelector("#expanded-info").classList.add("hidden")
return
}
// b.addEventListener("click", showTimePickerWindow)
}
// console.log(startTime.format('ha'))
// console.log(startTime.format('h:mma') + " to " + endTime.format('h:mma'))
}
// document.getElementById("timePickerWindowButton")
function showTimePickerWindow(e) {
// console.log(e.target)
// console.log(e.target.dataset.timepickershown)
// if (e.target.dataset.timepickershown === 'true') return;
// e.target.dataset.timepickershown = true
console.log(e.target)
console.log(e.target.dataset.timepickershown)
if (this.dataset.timepickershown === 'true') return;
this.dataset.timepickershown = true
// document.getElementById("")
let times = this.querySelector("#timeButtonDisplay").innerHTML.split(" to ")
if (times[0] == "") {
times[0] = dayjs().format("h:mma")
times[1] = dayjs().add(1, 'h').format("h:mma")
}
console.log(times)
// console.log(startTime)
// console.log(endTime)
document.getElementById("startTimeLabel").innerHTML = dayjs(times[0], 'h:mma').format("h:mm a")
document.getElementById("endTimeLabel").innerHTML = dayjs(times[1], 'h:mma').format("h:mm a")
document.getElementById("timeInput").value = dayjs(times[0], 'h:mma').format("HH:mm")
document.getElementById("timePickerWindow").classList.remove("hidden")
}
function timeSlotShowTimePickerButton(e) {
console.log('yay!')
if (this.parentElement.parentElement.querySelector(".timePickerWindowButton").dataset.timepickershown === 'true') return;
console.log('woohoo')
this.parentElement.parentElement.querySelector(".timePickerWindowButton").dataset.timepickershown = true
let times = this.parentElement.parentElement.querySelector(".timePickerWindowButton").querySelector("#timeButtonDisplay").innerHTML.split(" to ")
if (times[0] == "") {
times[0] = dayjs().format("h:mma")
times[1] = dayjs().add(1, 'h').format("h:mma")
}
console.log(times)
// console.log(startTime)
// console.log(endTime)
document.getElementById("startTimeLabel").innerHTML = dayjs(times[0], 'h:mma').format("h:mm a")
document.getElementById("endTimeLabel").innerHTML = dayjs(times[1], 'h:mma').format("h:mm a")
document.getElementById("timeInput").value = dayjs(times[0], 'h:mma').format("HH:mm")
document.getElementById("timePickerWindow").classList.remove("hidden")
}
function recurringButtonListener(e) {
// TODO: change colour to green
//
if (this.parentElement.parentElement.dataset.recurring === "true") {
this.querySelector("svg").classList.add("text-black")
this.querySelector("svg").classList.remove("text-lime-600")
this.parentElement.parentElement.dataset.recurring = false
return
}
this.querySelector("svg").classList.remove("text-black")
this.querySelector("svg").classList.add("text-lime-600")
this.parentElement.parentElement.dataset.recurring = true
return
}
for (let rb of document.getElementsByClassName("recurringButton")) {
rb.addEventListener("click", recurringButtonListener)
}
let rows = document.getElementsByClassName("task-row");
console.log('hmm');
for (let row of rows) {
console.log(row.querySelector("#timeslot"))
row.querySelector("#timeslot").addEventListener("mousedown", timeSlotShowTimePickerButton)
row.addEventListener('keypress', blurOrKeypress);
row.addEventListener('focusout', blurOrKeypress);
// row.addEventListener('dblclick', dblListener)
// row.addEventListener('mousedown', onClickListener)
let ei = row.querySelector("#expanded-info")
if (ei != null) {
ei.addEventListener('mousedown', onClickListener)
}
row.addEventListener('click', singleClickListener);
}
for (let button of document.getElementsByClassName("quickButton")) {
button.addEventListener("change", quickButtonListener)
}
for (let b of document.getElementsByClassName("timePickerWindowButton")) {
b.addEventListener("click", showTimePickerWindow)
}
document.getElementById("timeInput").addEventListener("blur", timeListener)
document.getElementById("rad1").addEventListener("change", startTimeListener)
document.getElementById("rad2").addEventListener("change", endTimeListener)
document.getElementById("date-view").innerHTML = dayjs().format("ddd MMM D, YYYY")
// document.getElementById("rad1").addEventListener("click", )
// document.getElementById("timeInput").showPicker()
// hourInput
// minuteInput
// amPmInput
// let hIn = document.getElementById("hourInput")
// let mIn = document.getElementById("minuteInput")
// let apIn = document.getElementById("amPmInput")
// hIn.addEventListener("keydown", timeInputListener);
// mIn.addEventListener("keydown", timeInputListener);
// apIn.addEventListener("keydown", timeInputListener);
// function timeInputListener(e) {
// let tarEle = e.target
// if (tarEle.id === "hourInput") {
// if (parseInt(tarEle.value) > 12) {
// }
// }
// if (tarEle.id === "minuteInput") {
// }
// if (tarEle.id === "amPmInput") {
// }
// }