summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorMark Powers <mark@marks.kitchen>2023-01-30 22:26:19 -0600
committerMark Powers <mark@marks.kitchen>2023-01-30 22:27:26 -0600
commitad11ec7f93dca356748cb6c8bc49313a7ee7c3d7 (patch)
tree72418f494cd4b405cecdd5e6fbd539781e0c30e0 /static
parentb6c0e7dbc3b618ecca2449c4395ce857649521cf (diff)
Add form for new form
Diffstat (limited to 'static')
-rw-r--r--static/index.html247
-rw-r--r--static/new_form.html74
2 files changed, 321 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>
diff --git a/static/new_form.html b/static/new_form.html
new file mode 100644
index 0000000..7022d5a
--- /dev/null
+++ b/static/new_form.html
@@ -0,0 +1,74 @@
+<html>
+ <head>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ </head>
+ <body>
+ <nav></nav>
+ <div class="main">
+
+ <div>
+ <label for="type">Type:</label>
+ <select name="type" onchange="update_select()">
+ <option value="multiple_select">multiple_select</option>
+ <option value="number">number</option>
+ <option value="range">range</option>
+ <option value="textarea">textarea</option>
+ <option value="text">text</option>
+ </select>
+ </div>
+
+ <div>
+ <label for="prompt">prompt</label>
+ <input name="prompt" type="text"></input>
+ </div>
+ <div>
+ <label for="prompt_id">prompt_id</label>
+ <input name="prompt_id" type="text"></input>
+ </div>
+
+ <div class="range">
+ <div>
+ <label for="min">min</label>
+ <input name="min" type="text"></input>
+ </div>
+ <div>
+ <label for="max">max</label>
+ <input name="max" type="text"></input>
+ </div>
+ </div>
+
+ <div><button onclick="on_submit()">Submit</button></div>
+ <script>
+ async function enqueue_data(path, payload, do_alert=false, timestamp=true){
+ if(timestamp){
+ payload["timestamp"] = Date.now()
+ }
+ await fetch(path, {method: "POST", body: JSON.stringify(payload)})
+ if(do_alert){
+ alert("saved!")
+ }
+ }
+ function update_select(){
+ let v = document.querySelectorAll("select")[0].value
+ document.querySelectorAll(".range").forEach(el => {
+ el.style.display = v == "range" ? "block" : "none"
+ })
+ }
+ function on_submit(){
+ let payload = {
+ "type": document.querySelectorAll("select")[0].value,
+ }
+ document.querySelectorAll("input").forEach(el => {
+ if(el.value.length > 0){
+ payload[el.name] = el.value
+ }
+ })
+ enqueue_data("/submit_new_form", payload, do_alert=true, timestamp=false)
+ }
+ window.onload = function(){
+ update_select()
+ }
+ </script>
+ </div>
+ </body>
+</html>