diff options
Diffstat (limited to 'templates')
-rw-r--r-- | templates/staff/jams/forms/questions_edit.html | 357 | ||||
-rw-r--r-- | templates/staff/jams/forms/questions_view.html | 596 | ||||
-rw-r--r-- | templates/staff/jams/forms/view.html | 757 | ||||
-rw-r--r-- | templates/staff/jams/index.html | 1 |
4 files changed, 1711 insertions, 0 deletions
diff --git a/templates/staff/jams/forms/questions_edit.html b/templates/staff/jams/forms/questions_edit.html new file mode 100644 index 00000000..af143540 --- /dev/null +++ b/templates/staff/jams/forms/questions_edit.html @@ -0,0 +1,357 @@ +{% extends "main/base.html" %} +{% block title %}Staff | Jams | Question Edit{% endblock %} +{% block og_title %}Staff | Jams | Question Edit{% endblock %} +{% block og_description %}Edit a question{% endblock %} +{% block extra_head %} + <script src="{{ static_file('js/jams.js') }}"></script> +{% endblock %} +{% block content %} + <div class="uk-container uk-container-small uk-section"> + <h1>Question Edit: {{ question.id }}</h1> + + <form class="uk-form-horizontal" method="post" action="{{ url_for("staff.jams.forms.questions.edit", question=question.id) }}"> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="title">Title</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="title" name="title" class="uk-input" value="{{ question.title }}"> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="optional">Optional</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="optional" name="optional"> + {% if question.optional %} + <option value="optional" selected>Optional</option> + <option value="required">Required</option> + {% else %} + <option value="optional">Optional</option> + <option value="required" selected>Required</option> + {% endif %} + </select> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="type">Type</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="type" name="type"> + {% if question.type == "checkbox" %} + <option value="checkbox" selected>Checkbox</option> + {% else %} + <option value="checkbox">Checkbox</option> + {% endif %} + + {% if question.type == "email" %} + <option value="email" selected>Email</option> + {% else %} + <option value="email">Email</option> + {% endif %} + + {% if question.type == "number" %} + <option value="number" selected>Number</option> + {% else %} + <option value="number">Number</option> + {% endif %} + + {% if question.type == "radio" %} + <option value="radio" selected>Radio</option> + {% else %} + <option value="radio">Radio</option> + {% endif %} + + {% if question.type == "range" %} + <option value="range" selected>Range</option> + {% else %} + <option value="range">Range</option> + {% endif %} + + {% if question.type == "slider" %} + <option value="slider" selected>Slider</option> + {% else %} + <option value="slider">Slider</option> + {% endif %} + + {% if question.type == "textarea" %} + <option value="textarea" selected>Text (Block)</option> + {% else %} + <option value="textarea">Text (Block)</option> + {% endif %} + + {% if question.type == "text" %} + <option value="text" selected>Text (Line)</option> + {% else %} + <option value="text">Text (Line)</option> + {% endif %} + </select> + </div> + </div> + + {% if question.type == "radio" %} + <div id="radio-section"> + {% else %} + <div id="radio-section" hidden="hidden"> + {% endif %} + <br /> + <div> + <div class="uk-form-label"> + <button type="button" class="uk-button uk-button-primary uk-width-1-1" id="radio-add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add</button> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="radio-add-input" class="uk-input" placeholder="Item"> + </div> + </div> + <div> + <div class="uk-form-label"> + <button type="button" class="uk-button uk-button-danger uk-width-1-1" id="radio-remove-button"><i class="uk-icon fa-fw far fa-minus"></i> Remove</button> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="radio-options"> + <option hidden="hidden" disabled selected value="none"></option> + + {% for option in question.data.options %} + <option value="{{ option }}">{{ option }}</option> + {% endfor %} + </select> + {% if question.data.options %} + <input type="hidden" id="options" name="options" value="{{ "{\"options\": " + question.data.options.__str__() + "}" | safe }}"> + {% else %} + <input type="hidden" id="options" name="options" value="{{ "{\"options\": []}" }}"> + {% endif %} + </div> + </div> + </div> + + {% if question.type in ["number", "range", "slider"] %} + <div id="number-section"> + {% else %} + <div id="number-section" hidden="hidden"> + {% endif %} + <br /> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="min">Min Value</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="min" name="min" class="uk-input" value="{{ question.data.min }}"> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="max">Max Value</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="max" name="max" class="uk-input" value="{{ question.data.max }}"> + </div> + </div> + </div> + + <br /> + + <div> + <input type="hidden" name="csrf_token" id="csrf_token" value="{{ csrf_token() }}"/> + + <a class="uk-button uk-button-danger uk-modal-close" href="{{ url_for("staff.jams.forms.questions") }}"> + <i class="uk-icon fa-fw far fa-times"></i> Cancel + </a> + <button class="uk-button uk-button-primary" type="submit" id="question-submit"> + <i class="uk-icon fa-fw far fa-check"></i> Save + </button> + </div> + </form> + </div> + + <script type="application/javascript"> + "use strict"; + const new_question_title = document.getElementById("title"); + const new_question_optional = document.getElementById("optional"); + const new_question_type = document.getElementById("type"); + + const radio_section = document.getElementById("radio-section"); + + const radio_add_button = document.getElementById("radio-add-button"); + const radio_add_input = document.getElementById("radio-add-input"); + const radio_remove_button = document.getElementById("radio-remove-button"); + const radio_options = document.getElementById("radio-options"); + const hidden_radio_options = document.getElementById("options"); + + const number_section = document.getElementById("number-section"); + + const number_min = document.getElementById("min"); + const number_max = document.getElementById("max"); + + const submit_button = document.getElementById("question-submit"); + + let current_radio_options; + + {% if question.data.options %} + current_radio_options = {{ question.data.options | safe }}; + {% else %} + current_radio_options = Array(); + {% endif %} + + new_question_type.onchange = function() { + if (this.value === "checkbox") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "email") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "number") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "radio") { + radio_section.removeAttribute("hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "range") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "slider") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "textarea") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "text") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } + + checkValid(); + }; + + new_question_title.oninput = checkValid; + new_question_optional.onchange = checkValid; + + radio_add_input.onkeyup = function(event) { + event.preventDefault(); + + if (event.which === 13 || event.keyCode === 13) { + radio_add_button.onclick(undefined); + } + }; + + radio_add_button.onclick = function() { + let value = radio_add_input.value; + + if (value.length < 1) { + radio_add_input.classList.add("uk-form-danger"); + radio_add_input.focus(); + } else { + let index = current_radio_options.indexOf(value); + + if (index > -1 || value === "none") { + radio_add_input.classList.add("uk-form-danger"); + radio_add_input.focus(); + } else { + radio_add_input.classList.remove("uk-form-danger"); + radio_add_input.value = ""; + + let element = document.createElement("option"); + element.value = value; + element.text = value; + + radio_options.appendChild(element); + current_radio_options.push(value); + hidden_radio_options.value = JSON.stringify({"options": current_radio_options}); + } + } + + checkValid(); + }; + + radio_remove_button.onclick = function() { + let value = radio_options.value; + + if (value === "none") { + return; + } + + let index = current_radio_options.indexOf(value); + + if (index < 0) { // We have a problem! + console.log("Unable to remove value from radio values because it doesn't exist: " + value) + } else { + current_radio_options.splice(index, 1); + } + + for (let element of radio_options.getElementsByTagName("option")) { + if (element.value === "none") { + continue; + } + + if (element.value === value) { + radio_options.removeChild(element); + } + } + + hidden_radio_options.value = JSON.stringify({"options": current_radio_options}); + radio_options.value = "none"; + radio_add_input.focus(); + checkValid(); + }; + + number_min.oninput = function() { + if (this.value.length > 0 && isNaN(parseInt(this.value))) { + this.classList.add("uk-form-danger") + } else { + this.classList.remove("uk-form-danger") + } + + checkValid(); + }; + + number_max.oninput = function() { + if (this.value.length > 0 && isNaN(parseInt(this.value))) { + this.classList.add("uk-form-danger") + } else { + this.classList.remove("uk-form-danger") + } + + checkValid(); + }; + + function checkValid() { + if (new_question_title.value.length < 1) { + return setButtonEnabled(false); + } + + let question_type = new_question_type.value; + + if (question_type === "radio") { + if (current_radio_options.length < 1) { + return setButtonEnabled(false); + } + } + + if ( question_type === "number" + || question_type === "range" + || question_type === "slider" + ) { + if (isNaN(parseInt(number_min.value))) { + return setButtonEnabled(false); + } + if (isNaN(parseInt(number_max.value))) { + return setButtonEnabled(false); + } + + if (number_min.value.length < 1 || number_max.value.length < 1) { + return setButtonEnabled(false); + } + } + + return setButtonEnabled(true); + } + + function setButtonEnabled(enabled) { + submit_button.disabled = !enabled; + } + </script> +{% endblock %} diff --git a/templates/staff/jams/forms/questions_view.html b/templates/staff/jams/forms/questions_view.html new file mode 100644 index 00000000..eb545451 --- /dev/null +++ b/templates/staff/jams/forms/questions_view.html @@ -0,0 +1,596 @@ +{% extends "main/base.html" %} +{% block title %}Staff | Jams | Questions{% endblock %} +{% block og_title %}Staff | Jams | Questions{% endblock %} +{% block og_description %}Manage all created questions{% endblock %} +{% block extra_head %} + <script src="{{ static_file('js/jams.js') }}"></script> +{% endblock %} +{% block content %} + <div class="uk-container uk-container-small uk-section"> + <h1>Questions List</h1> + + <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> + <button class="uk-button uk-button-primary" id="add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add Question</button> + {# <a class="uk-button uk-button-secondary" target="_blank" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw far fa-eye"></i> Preview</a> #} + + {% if not questions %} + <p id="no-questions-paragraph">No questions found. Add one above!</p> + <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table" hidden="hidden"> + <thead> + <tr> + <th class="uk-table-shrink"> </th> + <th><strong>ID</strong></th> + <th class="uk-table-shrink">Optional</th> + <th>Title</th> + <th class="uk-table-shrink">Type</th> + <th>Data</th> + </tr> + </thead> + <tbody id="table-body"> + </tbody> + </table> + {% else %} + <p id="no-questions-paragraph" hidden="hidden">No questions found. Add one above!</p> + + <div class="uk-overflow-auto"> + <br /> + <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table"> + <thead> + <tr> + <th class="uk-table-shrink"> </th> + <th><strong>ID</strong></th> + <th class="uk-table-shrink">Optional</th> + <th>Title</th> + <th class="uk-table-shrink">Type</th> + <th>Data</th> + </tr> + </thead> + <tbody id="table-body"> + {% for question in questions %} + <tr id="row-{{ question.id }}"> + <td class="uk-table-shrink"> + <button class="uk-button-small uk-button uk-button-danger delete-question-button" style="padding-left: 5px; padding-right: 5px;" data-question-id="{{ question.id }}"><i class="uk-icon fa-fw far fa-trash"></i></button> + <a href="{{ url_for("staff.jams.forms.questions.edit", question=question.id) }}" class="uk-button-small uk-button uk-button-primary edit-question-button" style="padding-left: 5px; padding-right: 5px;"><i class="uk-icon fa-fw far fa-pencil"></i></a> + </td> + <td class="uk-text-truncate" title="{{ question.id }}">{{ question.id }}</td> + <td class="uk-table-shrink"> + {% if question.optional %} + <i class="uk-icon uk-text-success fa-fw far fa-check"></i> + {% else %} + <i class="uk-icon uk-text-danger fa-fw far fa-times"></i> + {% endif %} + </td> + <td title="{{ question.title }}">{{ question.title }}</td> + <td class="uk-table-shrink" title="{{ question.type.title() }}">{{ question.type.title() }}</td> + <td> + {% if question.type == "text" %} + + {% elif question.type == "number" %} + <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} + <br /> + <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} + {% elif question.type == "checkbox" %} + + {% elif question.type == "email" %} + + {% elif question.type == "textarea" %} + + {% elif question.type == "radio" %} + <ul> + {% for option in question.data.options %} + <li>{{ option }}</li> + {% endfor %} + </ul> + {% elif question.type == "range" %} + <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} + <br /> + <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} + {% elif question.type == "slider" %} + <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} + <br /> + <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} + {% else %} + {{ question.data }} + {% endif %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + {% endif %} + </div> + + <div id="question-modal" class="uk-flex-top" uk-modal> + <div class="uk-modal-dialog"> + <button class="uk-modal-close-default" type="button" uk-close></button> + + <div class="uk-modal-header"> + <h2 class="uk-modal-title">Add Question</h2> + </div> + + <div class="uk-modal-body"> + <form class="uk-form-horizontal"> + <div id="loading-spinner" class="uk-text-center uk-margin-small-top" hidden="hidden"> + <div uk-spinner></div> + </div> + <div id="new-question-section"> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="new-question-title">Title</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="new-question-title" class="uk-input"> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="new-question-optional">Optional</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="new-question-optional"> + <option hidden="hidden" disabled selected value="none"></option> + <option value="optional">Optional</option> + <option value="required">Required</option> + </select> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="new-question-type">Type</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="new-question-type"> + <option hidden="hidden" disabled selected value="none"></option> + <option value="checkbox">Checkbox</option> + <option value="email">Email</option> + <option value="number">Number</option> + <option value="radio">Radio</option> + <option value="range">Range</option> + <option value="slider">Slider</option> + <option value="textarea">Text (Block)</option> + <option value="text">Text (Line)</option> + </select> + </div> + </div> + </div> + + <div id="radio-section" hidden="hidden"> + <br /> + <div> + <div class="uk-form-label"> + <button type="button" class="uk-button uk-button-primary uk-width-1-1" id="radio-add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add</button> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="radio-add-input" class="uk-input" placeholder="Item"> + </div> + </div> + <div> + <div class="uk-form-label"> + <button type="button" class="uk-button uk-button-danger uk-width-1-1" id="radio-remove-button"><i class="uk-icon fa-fw far fa-minus"></i> Remove</button> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="radio-options"> + <option hidden="hidden" disabled selected value="none"></option> + </select> + </div> + </div> + </div> + + <div id="number-section" hidden="hidden"> + <br /> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="number-min">Min Value</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="number-min" class="uk-input"> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="number-max">Max Value</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="number-max" class="uk-input"> + </div> + </div> + </div> + </form> + </div> + + <div class="uk-modal-footer"> + <div class="uk-text-center"> + <button class="uk-button uk-button-danger uk-modal-close" type="button" id="state-cancel"> + <i class="uk-icon fa-fw far fa-times"></i> Cancel + </button> + <button class="uk-button uk-button-primary" type="button" id="question-submit" disabled> + <i class="uk-icon fa-fw far fa-check"></i> Save + </button> + </div> + </div> + </div> + </div> + + <script type="application/javascript"> + "use strict"; + + const actions = new Actions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); + const table_body = document.getElementById("table-body"); + const table = document.getElementById("table"); + const no_questions_paragraph = document.getElementById("no-questions-paragraph"); + + let all_questions = {{ question_ids | safe }}; + const question_edit_url = "{{ url_for("staff.jams.forms.questions.edit", question="{NONE}") }}"; + + const add_button = document.getElementById("add-button"); + const modal = UIkit.modal(document.getElementById("question-modal")); + const loading_spinner = document.getElementById("loading-spinner"); + + const new_question_section = document.getElementById("new-question-section"); + const new_question_title = document.getElementById("new-question-title"); + const new_question_optional = document.getElementById("new-question-optional"); + const new_question_type = document.getElementById("new-question-type"); + + const radio_section = document.getElementById("radio-section"); + + const radio_add_button = document.getElementById("radio-add-button"); + const radio_add_input = document.getElementById("radio-add-input"); + const radio_remove_button = document.getElementById("radio-remove-button"); + const radio_options = document.getElementById("radio-options"); + + const number_section = document.getElementById("number-section"); + + const number_min = document.getElementById("number-min"); + const number_max = document.getElementById("number-max"); + + const submit_button = document.getElementById("question-submit"); + + let current_radio_options = Array(); + + add_button.onclick = function() { + clearModal(); + checkModal(); + modal.show(); + }; + + new_question_type.onchange = function() { + if (this.value === "checkbox") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "email") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "number") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "radio") { + radio_section.removeAttribute("hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "range") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "slider") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "textarea") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "text") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } + + checkModal(); + }; + + new_question_title.oninput = checkModal; + new_question_optional.onchange = checkModal; + + radio_add_input.onkeyup = function(event) { + event.preventDefault(); + + if (event.which === 13 || event.keyCode === 13) { + radio_add_button.onclick(undefined); + } + }; + + radio_add_button.onclick = function() { + let value = radio_add_input.value; + + if (value.length < 1) { + radio_add_input.classList.add("uk-form-danger"); + radio_add_input.focus(); + } else { + let index = current_radio_options.indexOf(value); + + if (index > -1 || value === "none") { + radio_add_input.classList.add("uk-form-danger"); + radio_add_input.focus(); + } else { + radio_add_input.classList.remove("uk-form-danger"); + radio_add_input.value = ""; + + let element = document.createElement("option"); + element.value = value; + element.text = value; + + radio_options.appendChild(element); + current_radio_options.push(value); + } + } + + checkModal(); + }; + + radio_remove_button.onclick = function() { + let value = radio_options.value; + + if (value === "none") { + return; + } + + let index = current_radio_options.indexOf(value); + + if (index < 0) { // We have a problem! + console.log("Unable to remove value from radio values because it doesn't exist: " + value) + } else { + current_radio_options.splice(index, 1); + } + + for (let element of radio_options.getElementsByTagName("option")) { + if (element.value === "none") { + continue; + } + + if (element.value === value) { + radio_options.removeChild(element); + } + } + + radio_options.value = "none"; + radio_add_input.focus(); + checkModal(); + }; + + number_min.oninput = function() { + if (this.value.length > 0 && isNaN(parseInt(this.value))) { + this.classList.add("uk-form-danger") + } else { + this.classList.remove("uk-form-danger") + } + + checkModal(); + }; + + number_max.oninput = function() { + if (this.value.length > 0 && isNaN(parseInt(this.value))) { + this.classList.add("uk-form-danger") + } else { + this.classList.remove("uk-form-danger") + } + + checkModal(); + }; + + submit_button.onclick = function () { + let type = new_question_type.value; + let optional = new_question_optional.value === "optional"; + let title = new_question_title.value; + + let question_data = { + "type": type, + "optional": optional, + "title": title + }; + + if (type === "radio") { + question_data.data = {"options": current_radio_options}; + } else if (type === "number" + || type === "range" + || type === "slider") { + question_data.data = { + "max": parseInt(number_max.value), + "min": parseInt(number_min.value) + }; + } + + number_section.setAttribute("hidden", "hidden"); + new_question_section.setAttribute("hidden", "hidden"); + radio_section.setAttribute("hidden", "hidden"); + loading_spinner.removeAttribute("hidden"); + + actions.create_question(question_data, function(result, data) { + if (result) { + question_data["id"] = data.id; + addToTable(question_data); + modal.hide(); + clearModal(); + + UIkit.notification({ + "message": "Question added", + "status": "success", + "pos": "bottom-center", + "timeout": 5000, + }); + } else { + console.log(data); + UIkit.notification({ + "message": "Failed to create question", + "status": "danger", + "pos": "bottom-center", + "timeout": 5000, + }); + } + }) + }; + + const toTitleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase()); + + function hookUpDeleteButtons() { + for (let element of document.getElementsByClassName("delete-question-button")) { + element.onclick = function() { + let question_id = this.getAttribute("data-question-id"); + let row = document.getElementById("row-" + question_id); + + actions.delete_question(question_id, function(result, data) { + if (result) { + document.getElementById("table-body").removeChild(row); + UIkit.notification({ + "message": "Question deleted", + "status": "success", + "pos": "bottom-center", + "timeout": 5000, + }); + } else { + console.log(data); + UIkit.notification({ + "message": "Failed to delete question", + "status": "danger", + "pos": "bottom-center", + "timeout": 5000, + }); + } + }) + } + } + } + + function clearModal() { + // Existing question section + loading_spinner.setAttribute("hidden", "hidden"); + + new_question_section.removeAttribute("hidden"); + + // New question section + new_question_title.value = ""; + new_question_optional.value = "none"; + new_question_type.value = "none"; + + // Radio question section + radio_section.setAttribute("hidden", "hidden"); + + radio_add_input.value = ""; + radio_options.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; + radio_options.value = "none"; + + current_radio_options = Array(); + + // Number question section + number_section.setAttribute("hidden", "hidden"); + } + + function checkModal() { + if (new_question_title.value.length < 1) { + return setButtonEnabled(false); + } + + if (new_question_optional.value === "none") { + return setButtonEnabled(false); + } + + let question_type = new_question_type.value; + + if (question_type === "none") { + return setButtonEnabled(false); + } + + if (question_type === "radio") { + if (current_radio_options.length < 1) { + return setButtonEnabled(false); + } + } + + if ( question_type === "number" + || question_type === "range" + || question_type === "slider" + ) { + if (isNaN(parseInt(number_min.value))) { + return setButtonEnabled(false); + } + if (isNaN(parseInt(number_max.value))) { + return setButtonEnabled(false); + } + + if (number_min.value.length < 1 || number_max.value.length < 1) { + return setButtonEnabled(false); + } + } + + return setButtonEnabled(true); + } + + function setButtonEnabled(enabled) { + submit_button.disabled = !enabled; + } + + function addToTable(question) { + console.log(question); + if (all_questions.indexOf(question.id) === -1) { + all_questions.push(question.id); + + let element = document.createElement("tr"); + element.id = "row-" + question.id; + element.innerHTML = getRowHTML(question); + + table_body.appendChild(element); + } + + if (all_questions.length > 0) { + table.removeAttribute("hidden"); + no_questions_paragraph.setAttribute("hidden", "hidden"); + } + hookUpDeleteButtons(); + } + + function getRowHTML(question) { + let optional; + let data; + + if (question.optional) { + optional = "<i class=\"uk-icon uk-text-success fa-fw far fa-check\"></i>" + } else { + optional = "<i class=\"uk-icon uk-text-danger fa-fw far fa-times\"></i>" + } + + if (question.type === "number" || question.type === "range" || question.type === "slider") { + data = ` +<i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> ${question.data.max} +<br /> +<i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> ${question.data.min} + ` + + } else if (question.type === "radio") { + data = "<ul>"; + + for (let option of question.data.options) { + data = data + `<li>${option}</li>` + } + data = data + "</ul>"; + } else { + data = "" + } + + let type = toTitleCase(question.type); + let q_url = question_edit_url.replace("{NONE}", question.id); + + const row = ` + <td class="uk-table-shrink"> + <button class="uk-button-small uk-button uk-button-danger delete-question-button" style="padding-left: 5px; padding-right: 5px;" data-question-id="${question.id}"><i class="uk-icon fa-fw far fa-trash"></i></button> + <a href="${q_url}" class="uk-button-small uk-button uk-button-primary edit-question-button" style="padding-left: 5px; padding-right: 5px;"><i class="uk-icon fa-fw far fa-pencil"></i></a> + </td> + <td class="uk-text-truncate" title="${question.id}">${question.id}</td> + <td class="uk-table-shrink">${optional}</td> + <td title="${question.title}">${question.title}</td> + <td class="uk-table-shrink" title="${type}">${type}</td> + <td>${data}</td> + `; + return row + } + + hookUpDeleteButtons(); + </script> +{% endblock %} diff --git a/templates/staff/jams/forms/view.html b/templates/staff/jams/forms/view.html new file mode 100644 index 00000000..6d0a86af --- /dev/null +++ b/templates/staff/jams/forms/view.html @@ -0,0 +1,757 @@ +{% extends "main/base.html" %} +{% block title %}Staff | Jams | Form{% endblock %} +{% block og_title %}Staff | Jams | Form{% endblock %} +{% block og_description %}Manage the form for a code jam{% endblock %} +{% block extra_head %} + <script src="{{ static_file('js/jams.js') }}"></script> +{% endblock %} +{% block content %} + <div class="uk-container uk-container-small uk-section"> + <h1>Application Form {{ jam.number }}: {{ jam.title }}</h1> + + <a class="uk-button uk-button-default" href="{{ url_for("staff.jams.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> + <button class="uk-button uk-button-primary" id="add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add Question</button> + {# <a class="uk-button uk-button-secondary" target="_blank" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw far fa-eye"></i> Preview</a> #} + + {% if not questions %} + <p id="no-questions-paragraph">No questions found. Add one above!</p> + <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table" hidden="hidden"> + <thead> + <tr> + <th class="uk-table-shrink"> </th> + <th><strong>ID</strong></th> + <th class="uk-table-shrink">Optional</th> + <th>Title</th> + <th class="uk-table-shrink">Type</th> + <th>Data</th> + </tr> + </thead> + <tbody id="table-body"> + </tbody> + </table> + {% else %} + <p id="no-questions-paragraph" hidden="hidden">No questions found. Add one above!</p> + + <div class="uk-overflow-auto"> + <br /> + <table class="uk-table uk-table-divider uk-table-striped uk-border" id="table"> + <thead> + <tr> + <th class="uk-table-shrink"> </th> + <th><strong>ID</strong></th> + <th class="uk-table-shrink">Optional</th> + <th>Title</th> + <th class="uk-table-shrink">Type</th> + <th>Data</th> + </tr> + </thead> + <tbody id="table-body"> + {% for question in questions %} + <tr id="row-{{ question.id }}"> + <td class="uk-table-shrink"> + <button class="uk-button-small uk-button uk-button-danger delete-question-button" style="padding-left: 5px; padding-right: 5px;" data-question-id="{{ question.id }}"><i class="uk-icon fa-fw far fa-times"></i></button> + </td> + <td class="uk-text-truncate" title="{{ question.id }}">{{ question.id }}</td> + <td class="uk-table-shrink"> + {% if question.optional %} + <i class="uk-icon uk-text-success fa-fw far fa-check"></i> + {% else %} + <i class="uk-icon uk-text-danger fa-fw far fa-times"></i> + {% endif %} + </td> + <td title="{{ question.title }}">{{ question.title }}</td> + <td class="uk-table-shrink" title="{{ question.type.title() }}">{{ question.type.title() }}</td> + <td> + {% if question.type == "text" %} + + {% elif question.type == "number" %} + <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} + <br /> + <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} + {% elif question.type == "checkbox" %} + + {% elif question.type == "email" %} + + {% elif question.type == "textarea" %} + + {% elif question.type == "radio" %} + <ul> + {% for option in question.data.options %} + <li>{{ option }}</li> + {% endfor %} + </ul> + {% elif question.type == "range" %} + <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} + <br /> + <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} + {% elif question.type == "slider" %} + <i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> {{ question.data.max }} + <br /> + <i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> {{ question.data.min }} + {% else %} + {{ question.data }} + {% endif %} + </td> + </tr> + {% endfor %} + </tbody> + </table> + </div> + {% endif %} + </div> + + <div id="question-modal" class="uk-flex-top" uk-modal> + <div class="uk-modal-dialog"> + <button class="uk-modal-close-default" type="button" uk-close></button> + + <div class="uk-modal-header"> + <h2 class="uk-modal-title">Add Question</h2> + </div> + + <div class="uk-modal-body"> + <form class="uk-form-horizontal"> + <div id="question-source-section"> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="question-source">Source</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="question-source" required> + <option hidden="hidden" disabled selected value="none"></option> + <option value="new">New</option> + <option value="existing">Existing</option> + </select> + </div> + </div> + </div> + <div id="loading-spinner" class="uk-text-center uk-margin-small-top" hidden="hidden"> + <div uk-spinner></div> + </div> + <div id="new-question-section" hidden="hidden"> + <br /> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="new-question-title">Title</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="new-question-title" class="uk-input"> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="new-question-optional">Optional</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="new-question-optional"> + <option hidden="hidden" disabled selected value="none"></option> + <option value="optional">Optional</option> + <option value="required">Required</option> + </select> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="new-question-type">Type</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="new-question-type"> + <option hidden="hidden" disabled selected value="none"></option> + <option value="checkbox">Checkbox</option> + <option value="email">Email</option> + <option value="number">Number</option> + <option value="radio">Radio</option> + <option value="range">Range</option> + <option value="slider">Slider</option> + <option value="textarea">Text (Block)</option> + <option value="text">Text (Line)</option> + </select> + </div> + </div> + </div> + + <div id="radio-section" hidden="hidden"> + <br /> + <div> + <div class="uk-form-label"> + <button type="button" class="uk-button uk-button-primary uk-width-1-1" id="radio-add-button"><i class="uk-icon fa-fw far fa-plus"></i> Add</button> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="radio-add-input" class="uk-input" placeholder="Item"> + </div> + </div> + <div> + <div class="uk-form-label"> + <button type="button" class="uk-button uk-button-danger uk-width-1-1" id="radio-remove-button"><i class="uk-icon fa-fw far fa-minus"></i> Remove</button> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="radio-options"> + <option hidden="hidden" disabled selected value="none"></option> + </select> + </div> + </div> + </div> + + <div id="number-section" hidden="hidden"> + <br /> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="number-min">Min Value</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="number-min" class="uk-input"> + </div> + </div> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="number-max">Max Value</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <input type="text" id="number-max" class="uk-input"> + </div> + </div> + </div> + + <div id="existing-question-section" hidden="hidden"> + <br /> + <div> + <div class="uk-form-label"> + <label class="uk-form-label" for="existing-question">Question</label> + </div> + <div class="uk-form-controls-text uk-form-controls"> + <select class="uk-select" id="existing-question"> + <option hidden="hidden" disabled selected value="none"></option> + </select> + </div> + </div> + </div> + </form> + </div> + + <div class="uk-modal-footer"> + <div class="uk-text-center"> + <button class="uk-button uk-button-danger uk-modal-close" type="button" id="state-cancel"> + <i class="uk-icon fa-fw far fa-times"></i> Cancel + </button> + <button class="uk-button uk-button-primary" type="button" id="question-submit" disabled> + <i class="uk-icon fa-fw far fa-check"></i> Save + </button> + </div> + </div> + </div> + </div> + + <script type="application/javascript"> + "use strict"; + const actions = new Actions("{{ url_for("staff.jams.action") }}", "{{ csrf_token() }}"); + const form = parseInt("{{ jam.number }}"); + const table_body = document.getElementById("table-body"); + const table = document.getElementById("table"); + const no_questions_paragraph = document.getElementById("no-questions-paragraph"); + + let all_questions = {{ question_ids | safe }}; + + const add_button = document.getElementById("add-button"); + const modal = UIkit.modal(document.getElementById("question-modal")); + + const question_source_section = document.getElementById("question-source-section"); + const question_source = document.getElementById("question-source"); + const loading_spinner = document.getElementById("loading-spinner"); + + const new_question_section = document.getElementById("new-question-section"); + const new_question_title = document.getElementById("new-question-title"); + const new_question_optional = document.getElementById("new-question-optional"); + const new_question_type = document.getElementById("new-question-type"); + + const radio_section = document.getElementById("radio-section"); + + const radio_add_button = document.getElementById("radio-add-button"); + const radio_add_input = document.getElementById("radio-add-input"); + const radio_remove_button = document.getElementById("radio-remove-button"); + const radio_options = document.getElementById("radio-options"); + + const number_section = document.getElementById("number-section"); + + const number_min = document.getElementById("number-min"); + const number_max = document.getElementById("number-max"); + + const existing_question_section = document.getElementById("existing-question-section"); + const existing_question_select = document.getElementById("existing-question"); + + const submit_button = document.getElementById("question-submit"); + + let current_radio_options = Array(); + + add_button.onclick = function() { + clearModal(); + checkModal(); + modal.show(); + }; + + question_source.onchange = function () { + checkModal(); + + if (this.value === "new") { + existing_question_section.setAttribute("hidden", "hidden"); + loading_spinner.setAttribute("hidden", "hidden"); + new_question_section.removeAttribute("hidden"); + } else { + new_question_section.setAttribute("hidden", "hidden"); + loading_spinner.removeAttribute("hidden"); + + actions.get_questions(function(result, data) { + existing_question_section.setAttribute("hidden", "hidden"); + loading_spinner.setAttribute("hidden", "hidden"); + + if (!result) { + UIkit.notification({ + "message": "Failed to fetch questions", + "status": "danger", + "pos": "bottom-center", + "timeout": 5000 + }) + } else { + existing_question_select.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; + + for (let question of data.questions) { + let element = document.createElement("option"); + element.value = question.id; + element.text = question.title; + + existing_question_select.appendChild(element); + } + + existing_question_section.removeAttribute("hidden"); + } + }) + } + }; + + existing_question_select.onchange = function() { + if (all_questions.indexOf(existing_question_select.value) > -1) { + existing_question_select.classList.add("uk-form-danger"); + } else { + existing_question_select.classList.remove("uk-form-danger"); + } + + checkModal(); + }; + + new_question_type.onchange = function() { + if (this.value === "checkbox") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "email") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "number") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "radio") { + radio_section.removeAttribute("hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "range") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "slider") { + radio_section.setAttribute("hidden", "hidden"); + number_section.removeAttribute("hidden"); + } else if (this.value === "textarea") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else if (this.value === "text") { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } else { + radio_section.setAttribute("hidden", "hidden"); + number_section.setAttribute("hidden", "hidden"); + } + + checkModal(); + }; + + new_question_title.oninput = checkModal; + new_question_optional.onchange = checkModal; + + radio_add_input.onkeyup = function(event) { + event.preventDefault(); + + if (event.which === 13 || event.keyCode === 13) { + radio_add_button.onclick(undefined); + } + }; + + radio_add_button.onclick = function() { + let value = radio_add_input.value; + + if (value.length < 1) { + radio_add_input.classList.add("uk-form-danger"); + radio_add_input.focus(); + } else { + let index = current_radio_options.indexOf(value); + + if (index > -1 || value === "none") { + radio_add_input.classList.add("uk-form-danger"); + radio_add_input.focus(); + } else { + radio_add_input.classList.remove("uk-form-danger"); + radio_add_input.value = ""; + + let element = document.createElement("option"); + element.value = value; + element.text = value; + + radio_options.appendChild(element); + current_radio_options.push(value); + } + } + + checkModal(); + }; + + radio_remove_button.onclick = function() { + let value = radio_options.value; + + if (value === "none") { + return; + } + + let index = current_radio_options.indexOf(value); + + if (index < 0) { // We have a problem! + console.log("Unable to remove value from radio values because it doesn't exist: " + value) + } else { + current_radio_options.splice(index, 1); + } + + for (let element of radio_options.getElementsByTagName("option")) { + if (element.value === "none") { + continue; + } + + if (element.value === value) { + radio_options.removeChild(element); + } + } + + radio_options.value = "none"; + radio_add_input.focus(); + checkModal(); + }; + + number_min.oninput = function() { + if (this.value.length > 0 && isNaN(parseInt(this.value))) { + this.classList.add("uk-form-danger") + } else { + this.classList.remove("uk-form-danger") + } + + checkModal(); + }; + + number_max.oninput = function() { + if (this.value.length > 0 && isNaN(parseInt(this.value))) { + this.classList.add("uk-form-danger") + } else { + this.classList.remove("uk-form-danger") + } + + checkModal(); + }; + + submit_button.onclick = function () { + if (question_source.value === "existing") { + number_section.setAttribute("hidden", "hidden"); + existing_question_section.setAttribute("hidden", "hidden"); + new_question_section.setAttribute("hidden", "hidden"); + radio_section.setAttribute("hidden", "hidden"); + question_source_section.setAttribute("hidden", "hidden"); + loading_spinner.removeAttribute("hidden"); + + actions.associate_question(form, existing_question_select.value, function(result, data) { + if (result) { + addToTable(data.question); + modal.hide(); + clearModal(); + + UIkit.notification({ + "message": "Question added", + "status": "success", + "pos": "bottom-center", + "timeout": 5000, + }); + } else { + console.log(data); + UIkit.notification({ + "message": "Failed to add question to form", + "status": "danger", + "pos": "bottom-center", + "timeout": 5000, + }); + } + }) + } else { + let type = new_question_type.value; + let optional = new_question_optional.value === "optional"; + let title = new_question_title.value; + + let question_data = { + "type": type, + "optional": optional, + "title": title + }; + + if (type === "radio") { + question_data.data = {"options": current_radio_options}; + } else if (type === "number" + || type === "range" + || type === "slider") { + question_data.data = { + "max": parseInt(number_max.value), + "min": parseInt(number_min.value) + }; + } + + number_section.setAttribute("hidden", "hidden"); + existing_question_section.setAttribute("hidden", "hidden"); + new_question_section.setAttribute("hidden", "hidden"); + radio_section.setAttribute("hidden", "hidden"); + question_source_section.setAttribute("hidden", "hidden"); + loading_spinner.removeAttribute("hidden"); + + actions.create_question(question_data, function(result, data) { + if (result) { + actions.associate_question(form, data.id, function(result, data) { + modal.hide(); + clearModal(); + + if (result) { + addToTable(data.question); + + UIkit.notification({ + "message": "Question added", + "status": "success", + "pos": "bottom-center", + "timeout": 5000, + }); + } else { + console.log(data); + UIkit.notification({ + "message": "Question created, but failed to associate with the form", + "status": "warning", + "pos": "bottom-center", + "timeout": 5000, + }); + } + }) + } else { + console.log(data); + UIkit.notification({ + "message": "Failed to create question", + "status": "danger", + "pos": "bottom-center", + "timeout": 5000, + }); + } + }) + } + }; + + const toTitleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase()); + + function hookUpDeleteButtons() { + for (let element of document.getElementsByClassName("delete-question-button")) { + element.onclick = function() { + let question_id = this.getAttribute("data-question-id"); + let row = document.getElementById("row-" + question_id); + + actions.disassociate_question(form, question_id, function(result, data) { + if (result) { + table_body.removeChild(row); + + let index = all_questions.indexOf(question_id); + + if (index < 0) { // We have a problem! + console.log("Unable to remove question from memory because it doesn't exist: " + question_id) + } else { + all_questions.splice(index, 1); + } + + if (all_questions.length < 1) { + table.setAttribute("hidden", "hidden"); + no_questions_paragraph.removeAttribute("hidden"); + } + + UIkit.notification({ + "message": "Question removed", + "status": "success", + "pos": "bottom-center", + "timeout": 5000, + }); + } else { + console.log(data); + UIkit.notification({ + "message": "Failed to remove question", + "status": "danger", + "pos": "bottom-center", + "timeout": 5000, + }); + } + }) + } + } + } + + function clearModal() { + // Question source section + question_source.value = "none"; + question_source_section.removeAttribute("hidden"); + + // Existing question section + loading_spinner.setAttribute("hidden", "hidden"); + + new_question_section.setAttribute("hidden", "hidden"); + + // New question section + new_question_title.value = ""; + new_question_optional.value = "none"; + new_question_type.value = "none"; + + // Radio question section + radio_section.setAttribute("hidden", "hidden"); + + radio_add_input.value = ""; + radio_options.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; + radio_options.value = "none"; + + current_radio_options = Array(); + + // Number question section + number_section.setAttribute("hidden", "hidden"); + + existing_question_section.setAttribute("hidden", "hidden"); + + existing_question_select.innerHTML = "<option hidden=\"hidden\" disabled selected value=\"none\"></option>"; + existing_question_select.value = "none"; + } + + function checkModal() { + if (question_source.value === "none") { + return setButtonEnabled(false); + } else if (question_source.value === "new") { + if (new_question_title.value.length < 1) { + return setButtonEnabled(false); + } + + if (new_question_optional.value === "none") { + return setButtonEnabled(false); + } + + let question_type = new_question_type.value; + + if (question_type === "none") { + return setButtonEnabled(false); + } + + if (question_type === "radio") { + if (current_radio_options.length < 1) { + return setButtonEnabled(false); + } + } + + if ( question_type === "number" + || question_type === "range" + || question_type === "slider" + ) { + if (isNaN(parseInt(number_min.value))) { + return setButtonEnabled(false); + } + if (isNaN(parseInt(number_max.value))) { + return setButtonEnabled(false); + } + + if (number_min.value.length < 1 || number_max.value.length < 1) { + return setButtonEnabled(false); + } + } + } else { + if (existing_question_select.value === "none"){ + return setButtonEnabled(false); + } + + if (all_questions.indexOf(existing_question_select.value) > -1) { + return setButtonEnabled(false); + } + } + + return setButtonEnabled(true); + } + + function setButtonEnabled(enabled) { + submit_button.disabled = !enabled; + } + + function addToTable(question) { + console.log(question); + if (all_questions.indexOf(question.id) === -1) { + all_questions.push(question.id); + + let element = document.createElement("tr"); + element.id = "row-" + question.id; + element.innerHTML = getRowHTML(question); + + table_body.appendChild(element); + } + + if (all_questions.length > 0) { + table.removeAttribute("hidden"); + no_questions_paragraph.setAttribute("hidden", "hidden"); + } + hookUpDeleteButtons(); + } + + function getRowHTML(question) { + let optional; + let data; + + if (question.optional) { + optional = "<i class=\"uk-icon uk-text-success fa-fw far fa-check\"></i>" + } else { + optional = "<i class=\"uk-icon uk-text-danger fa-fw far fa-times\"></i>" + } + + if (question.type === "number" || question.type === "range" || question.type === "slider") { + data = ` +<i class="uk-icon fa-fw far fa-arrow-up" title="Max value"></i> ${question.data.max} +<br /> +<i class="uk-icon fa-fw far fa-arrow-down" title="Min value"></i> ${question.data.min} + ` + + } else if (question.type === "radio") { + data = "<ul>"; + + for (let option of question.data.options) { + data = data + `<li>${option}</li>` + } + data = data + "</ul>"; + } else { + data = "" + } + + let type = toTitleCase(question.type); + + const row = ` + <td class="uk-table-shrink"> + <button class="uk-button-small uk-button uk-button-danger delete-question-button" style="padding-left: 5px; padding-right: 5px;" data-question-id="${question.id}"><i class="uk-icon fa-fw far fa-times"></i></button> + </td> + <td class="uk-text-truncate" title="${question.id}">${question.id}</td> + <td class="uk-table-shrink">${optional}</td> + <td title="${question.title}">${question.title}</td> + <td class="uk-table-shrink" title="${type}">${type}</td> + <td>${data}</td> + `; + return row + } + + hookUpDeleteButtons(); + </script> +{% endblock %} diff --git a/templates/staff/jams/index.html b/templates/staff/jams/index.html index 336addee..b249ec3f 100644 --- a/templates/staff/jams/index.html +++ b/templates/staff/jams/index.html @@ -11,6 +11,7 @@ <a class="uk-button uk-button-default" href="{{ url_for("staff.index") }}"><i class="uk-icon fa-fw far fa-arrow-left"></i> Back</a> <a class="uk-button uk-button-primary" href="{{ url_for("staff.jams.create") }}"><i class="uk-icon fa-fw far fa-plus"></i> Create</a> + <a class="uk-button uk-button-primary" href="{{ url_for("staff.jams.forms.questions") }}"><i class="uk-icon fa-fw far fa-list"></i> Questions</a> {% if not jams %} <p> |