diff options
Diffstat (limited to 'static/index.html')
-rw-r--r-- | static/index.html | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..83136dc --- /dev/null +++ b/static/index.html @@ -0,0 +1,247 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <style> + p { + #margin-top: 0; + #margin-bottom: 0; + } + label.number, label.text { + margin-right: 1rem; + } + label.multi-label { + padding: 1rem; + border: 1px solid #3366ff; + } + input[type="checkbox"].multi-checkbox { + display: none; + } + input[type="checkbox"] { + height: 2rem; + width: 2rem; + } + input:checked + label{ + background-color: #99ccff; + } + input[type="number"] { + height: 3rem; + } + input[type="range"] { + width: 60%; + } + input[type="text"] { + height: 3rem; + } + .prompt { + margin-bottom: 2rem; + } + textarea { + width: 80ch; + height: 5rem; + } + button { + padding: 1rem; + border: 1px solid #3366ff; + } + </style> + </head> + <body> + <nav></nav> + <div class="main"> + <div id="books"></div> + <div id="prompts"></div> + <div><button onclick="on_submit()">Submit</button></div> + <script> + function insert_multiple_select(prompt, prompt_id, items){ + let root_el = document.getElementById("prompts") + let wrapper_el = document.createElement("div") + wrapper_el.setAttribute("class", "prompt multiple_select") + + let prompt_text_el = document.createElement("p") + prompt_text_el.innerHTML = prompt + wrapper_el.appendChild(prompt_text_el) + items.forEach(item => { + let checkbox_el = document.createElement("input") + checkbox_el.setAttribute("id", prompt_id+"__"+item["id"]) + checkbox_el.setAttribute("type", "checkbox") + checkbox_el.setAttribute("class", "multi-checkbox") + wrapper_el.appendChild(checkbox_el) + + let item_label = document.createElement("label") + item_label.setAttribute("for", prompt_id+"__"+item["id"]) + item_label.setAttribute("class", "multi-label") + item_label.innerHTML = item["display"] + wrapper_el.appendChild(item_label) + }) + root_el.appendChild(wrapper_el) + } + function insert_input(prompt, prompt_id, class_name, type){ + let root_el = document.getElementById("prompts") + let wrapper_el = document.createElement("div") + wrapper_el.setAttribute("class", "prompt") + + let item_label = document.createElement("label") + item_label.setAttribute("for", prompt_id) + item_label.setAttribute("class", class_name) + item_label.innerHTML = prompt + + let input_el = document.createElement("input") + input_el.setAttribute("id", prompt_id) + input_el.setAttribute("type", type) + wrapper_el.appendChild(item_label) + wrapper_el.appendChild(input_el) + root_el.appendChild(wrapper_el) + + return input_el + } + function insert_number(prompt, prompt_id){ + insert_input(prompt, prompt_id, "number", "number") + } + function insert_text(prompt, prompt_id){ + insert_input(prompt, prompt_id, "text", "text") + } + function insert_range(prompt, prompt_id, min, max){ + let input_el = insert_input(prompt, prompt_id, "number", "range") + input_el.setAttribute("min", min) + input_el.setAttribute("max", max) + input_el.setAttribute("value", Math.floor((max+min)/2)) + + let checkbox_el = document.createElement("input") + checkbox_el.setAttribute("id", prompt_id+"_checkbox") + checkbox_el.setAttribute("type", "checkbox") + input_el.parentElement.insertBefore(checkbox_el, input_el) + } + function insert_textarea(prompt, prompt_id){ + let root_el = document.getElementById("prompts") + let wrapper_el = document.createElement("div") + wrapper_el.setAttribute("class", "prompt") + + let item_label = document.createElement("label") + item_label.setAttribute("for", prompt_id) + item_label.setAttribute("class", "number") + item_label.innerHTML = prompt + + let input_el = document.createElement("textarea") + input_el.setAttribute("id", prompt_id) + + let label_wrapper = document.createElement("div") + label_wrapper.appendChild(item_label) + wrapper_el.appendChild(label_wrapper) + wrapper_el.appendChild(input_el) + root_el.appendChild(wrapper_el) + } + function insert_book(title){ + let safe_id = title.replace(/\s/g, ''); + + let item_label = document.createElement("label") + item_label.setAttribute("for", safe_id) + item_label.setAttribute("class", "number") + item_label.innerHTML = title + + let input_el = document.createElement("input") + input_el.setAttribute("id", safe_id) + input_el.setAttribute("type", "number") + input_el.setAttribute("placeholder", "pages") + + let item_complete_label = document.createElement("label") + item_complete_label.setAttribute("for", safe_id+"_complete") + item_complete_label.innerHTML = "Completed?" + + let input_complete_el = document.createElement("input") + input_complete_el.setAttribute("id", safe_id+"_complete") + input_complete_el.setAttribute("type", "checkbox") + + let wrapper_el = document.createElement("div") + wrapper_el.setAttribute("class", "prompt") + wrapper_el.appendChild(item_label) + wrapper_el.appendChild(input_el) + wrapper_el.appendChild(item_complete_label) + wrapper_el.appendChild(input_complete_el) + + let root_el = document.getElementById("books") + root_el.appendChild(wrapper_el) + } + function item(i){ + return {"id": i, "display": i} + } + async function enqueue_data(path, payload, do_alert=false){ + payload["timestamp"] = Date.now() + await fetch(path, {method: "POST", body: JSON.stringify(payload)}) + if(do_alert){ + alert("saved!") + } + } + function submit_geolocation(){ + navigator.geolocation.getCurrentPosition(function(pos){ + enqueue_data("/submit_payload", { + "geoposition": { + "latitude": pos.coords.latitude, + "longitude": pos.coords.longitude + } + }) + }); + } + function on_submit(){ + let payload = {} + document.querySelectorAll("#prompts input[type=checkbox].multi-checkbox").forEach(el => { + let p = el.id.split("__", 2) + if(!(p[0] in payload)){ + payload[p[0]] = {} + } + payload[p[0]][p[1]] = el.checked + }) + document.querySelectorAll("#prompts input[type=number]").forEach(el => { + payload[el.id] = el.value + }) + document.querySelectorAll("#prompts input[type=checkbox]:checked + input[type=range]").forEach(el => { + payload[el.id] = el.value + }) + document.querySelectorAll("#prompts textarea").forEach(el => { + payload[el.id] = el.value + }) + payload["books"] = [] + document.querySelectorAll("#books .prompt").forEach(el => { + if(el.childNodes[1].value){ + book = { + "title": el.childNodes[0].innerHTML, + "pages": el.childNodes[1].value, + "complete": el.childNodes[3].checked + } + payload["books"].push(book) + } + }) + console.log(payload["books"]) + enqueue_data("/submit_payload", payload, do_alert=true) + submit_geolocation() + } + window.onload = function(){ + fetch("/forms").then(res => res.json()).then(data => { + data.forEach(form => { + switch(form["type"]) { + case "multiple_select": + insert_multiple_select(form["prompt"], form["prompt_id"], form["extra"]) + break; + case "number": + insert_number(form["prompt"], form["prompt_id"]) + break; + case "range": + insert_range( + form["prompt"], form["prompt_id"], form["extra"]["min"], form["extra"]["max"]) + break; + case "textarea": + insert_textarea(form["prompt"], form["prompt_id"]) + break; + case "text": + insert_text(form["prompt"], form["prompt_id"]) + break; + } + }) + }) + fetch("/books").then(res => res.json()).then(data => { + data.forEach(book => insert_book(book)) + }) + } + </script> + </div> + </body> +</html> |