|
|
<!doctype html> <html> <head> <title>Orna Tools - atr0phy.net</title>
<meta charset="utf-8"> <meta name="viewport" contents="width=device-width, initial-scale=1">
<!-- <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}"> -->
<!-- UIkit CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.2.4/dist/css/uikit.min.css" />
<!-- UIkit JS --> <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.4/dist/js/uikit.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/uikit@3.2.4/dist/js/uikit-icons.min.js"></script> <script src="https://cdn.jsdelivr.net/combine/npm/tablesort@5.2.0,npm/tablesort@5.2.0/src/sorts/tablesort.number.min.js"></script> </head> <body> <nav class="uk-navbar-container" uk-navbar> <div class="uk-navbar-center"> <a href="" class="uk-navbar-item uk-logo">Orna Tools - Equipment Combinations</a> </div> </nav> <div class="uk-container"> <div id="help-container" class="uk-padding-large uk-text-center uk-text-muted uk-margin-large-left uk-margin-large-right"> <div>Use the three tabs to input your options for each equipment slot (head/chest/leg). Click the calculate button to populate a table with possible combinations. Click on the column headers to sort results.<br/><br/><strong>Ctrl+Enter</strong> adds a new row to existing table, or use the green <strong>+</strong> to input additional items.</div> </div> <div id="equipment-container" class="uk-padding-large"> <ul class="uk-flex-center" uk-tab> <li class="uk-active" tbl="head-table"><a href="">Head</a></li> <li tbl="chest-table"><a href="">Chest</a></li> <li tbl="leg-table"><a href="">Leg</a></li> </ul> <ul class="uk-switcher"> {% for slot in ["Head", "Chest", "Leg"] %} <li> <div class="uk-padding-large uk-padding-remove-vertical"> <table id="{{ slot | lower }}-table" class="uk-table"> <caption>{{ slot }} Gear</caption> <thead> <tr> <th class="uk-table-shrink"></th> <th class="uk-table-expand">Item Name</th> <th class="uk-table-shrink">Defense</th> <th class="uk-table-shrink">Resistance</th> <th class="uk-table-shring"></th> </tr> </thead> <tbody> <tr> <td>1</td> <td><input type="text" class="uk-input" autocomplete="off"/></td> <td><input type="text" class="uk-input" autocomplete="off"/></td> <td><input type="text" class="uk-input" autocomplete="off"/></td> <td><a class="uk-icon-button del-row-button" uk-icon="icon:minus-circle;ratio:1"></a></td> </tr> </tbody> </table> <div class="uk-text-center"> <a id="{{ slot | lower }}-button" class="uk-icon-button add-row-button" uk-icon="icon:plus-circle;ratio:2"></a> </div> </div> </li> {% endfor %} </ul> </div> <div class="uk-text-center uk-margin-bottom"> <button id="clear-button" class="uk-button uk-button-danger">Clear</button> <button id="calculate-button" class="uk-button uk-button-primary">Calculate</button> </div>
<div id="results-panel" class="uk-section uk-overflow-auto" hidden> <hr class="uk-divider-icon" /> <table id="results-table" class="uk-table uk-table-divider uk-table-striped uk-table-hover"> <thead> <th data-sort-default>Total</th> <th>Defense</th> <th>Resistance</th> <th class="uk-table-expand" data-sort-method='none'>Head</th> <th class="uk-table-expand" data-sort-method='none'>Chest</th> <th class="uk-table-expand" data-sort-method='none'>Legs</th> </thead> <tbody></tbody> </table> </div>
<!-- Footer --> <footer class="uk-text-center uk-margin-large-top uk-margin-small-bottom"> © <script>document.write(new Date().getFullYear());</script> by <a href="http://binaryatrocity.name">binaryatrocity</a> | Created for the <span class="uk-text-success">Legends of Palisma</span> Kingdom | <a href="http://playorna.com">OrnaRPG</a> </footer> </div> </body> <script> // Support adding rows to the equipment tables function addEquipmentTableRow(findByQuery=false) { let input_element = document.createElement("input"); input_element.className="uk-input"; input_element.type = "text";
// Create the delete button let delete_button = document.createElement("a"); delete_button.className="uk-icon-button del-row-button"; delete_button.setAttribute("uk-icon", "icon:minus-circle;ratio:1"); delete_button.addEventListener("click", deleteEquipmentTableRow, false);
// If called manually, find specific table, otherwise determine based on event element let tbody = findByQuery ? document.querySelector(findByQuery) : this.parentElement.previousElementSibling.children[2]; let new_row = tbody.insertRow(-1);
// Append all of the child cells needed new_row.insertCell(0).appendChild(delete_button); new_row.insertCell(0).appendChild(input_element.cloneNode()); new_row.insertCell(0).appendChild(input_element.cloneNode()); new_row.insertCell(0).appendChild(input_element.cloneNode()); new_row.insertCell(0).appendChild(document.createTextNode(tbody.children.length))
if(findByQuery) { // If this was a hotkey, then focus the new field new_row.children[1].firstChild.focus(); } }
// Support deleting rows from the equipment table function deleteEquipmentTableRow() { this.parentElement.parentElement.remove(); }
// Process results and display table function processEquipmentResults(results) { var results_tbody = document.querySelector("table#results-table > tbody"); for(result of results) { let new_row = results_tbody.insertRow(-1);
// Append all of the child cells new_row.insertCell(0).appendChild(document.createTextNode(result['eq'][2])); new_row.insertCell(0).appendChild(document.createTextNode(result['eq'][1])); new_row.insertCell(0).appendChild(document.createTextNode(result['eq'][0])); new_row.insertCell(0).appendChild(document.createTextNode(result['res'])); new_row.insertCell(0).appendChild(document.createTextNode(result['def'])); new_row.insertCell(0).appendChild(document.createTextNode(result['def'] + result['res'])); } table_sort.refresh(); document.querySelector("div#results-panel").hidden = false;
results_tbody.scrollIntoView(); }
// Send data to backend function calculateEquipment() { let data = gatherEquipmentData();
// Store data in localStorage localStorage.setItem('eq_data', JSON.stringify(data));
// Clear out existing table rows for(let row of document.querySelectorAll("table#results-table > tbody > tr")) { row.remove(); }
fetch('/results', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }).then((response) => response.json()).then((data) => { processEquipmentResults(data); }).catch((error) => { console.log(error); alert("There was a problem..."); }); }
function gatherEquipmentData() { var eq_head = [], eq_chest = [], eq_legs = [];
// Gather head gear for(let row of document.querySelectorAll("table#head-table > tbody > tr")) { eq_head.push([ row.children[1].firstChild.value, parseInt(row.children[2].firstChild.value) || 0, parseInt(row.children[3].firstChild.value) || 0 ]); }
// Gather chest gear for(let row of document.querySelectorAll("table#chest-table > tbody > tr")) { eq_chest.push([ row.children[1].firstChild.value, parseInt(row.children[2].firstChild.value) || 0, parseInt(row.children[3].firstChild.value) || 0 ]); }
// Gather leg gear for(let row of document.querySelectorAll("table#leg-table > tbody > tr")) { eq_legs.push([ row.children[1].firstChild.value, parseInt(row.children[2].firstChild.value) || 0, parseInt(row.children[3].firstChild.value) || 0 ]); }
let data = { "head": eq_head, "chest": eq_chest, "legs": eq_legs };
return data; }
function clearExistingData() { localStorage.clear();
// Clear out existing table rows for(let row of document.querySelectorAll("table > tbody > tr")) { row.remove(); } }
function loadExistingData() { var data = localStorage.getItem('eq_data');
function appendToTable(eq, table_id) { let input_element = document.createElement("input"); input_element.className="uk-input"; input_element.type = "text"; input_element.autocomplete = "off";
// Create the delete button let delete_button = document.createElement("a"); delete_button.className="uk-icon-button del-row-button"; delete_button.setAttribute("uk-icon", "icon:minus-circle;ratio:1"); delete_button.addEventListener("click", deleteEquipmentTableRow, false);
let query = "table#" + table_id + " > tbody"; let tbody = document.querySelector(query); let new_row = tbody.insertRow(-1);
// Append all of the child cells needed new_row.insertCell(0).appendChild(delete_button); input_element.value = eq[2]; new_row.insertCell(0).appendChild(input_element.cloneNode()); input_element.value = eq[1]; new_row.insertCell(0).appendChild(input_element.cloneNode()); input_element.value = eq[0]; new_row.insertCell(0).appendChild(input_element.cloneNode()); new_row.insertCell(0).appendChild(document.createTextNode(tbody.children.length)) }
if(data) { data = JSON.parse(data);
// Remove existing rows from all tables clearExistingData();
// Populate new rows in all eq tables for(let hg of data['head']) { appendToTable(hg, "head-table"); } for(let cg of data['chest']) { appendToTable(cg, "chest-table"); } for(let lg of data['legs']) { appendToTable(lg, "leg-table"); } } }
function confirmDataCleanse() { if(confirm("Are you sure you want to clear all existing data?")) { clearExistingData(); } }
function listenForHotkeys(e) { if(e.ctrlKey && e.which == 13) { // Determine the active tab let tbl_id = "table#" + document.querySelector(".uk-active").getAttribute("tbl") + " > tbody"; addEquipmentTableRow(tbl_id); } }
// Add event listeners to our table buttons const add_row_buttons = document.querySelectorAll("a.add-row-button"); for(let button of add_row_buttons) { button.addEventListener("click", addEquipmentTableRow, false); } const del_row_buttons = document.querySelectorAll("a.del-row-button"); for(let button of del_row_buttons) { button.addEventListener("click", deleteEquipmentTableRow, false); }
// Add event listener to Calculate button, call backend document.querySelector("#calculate-button").addEventListener("click", calculateEquipment, false); document.querySelector("#clear-button").addEventListener("click", confirmDataCleanse, false);
// Enable sorting for our results table var table_sort = new Tablesort(document.querySelector("table#results-table"), {descending: true});
// Configure keyboard hotkeys document.onkeyup = listenForHotkeys;
// Load any existing data from LocalStorage loadExistingData(); </script> <style type="text/css"> table:not(#results-table) > tbody > tr > td:first-child { color: #999; }
div > a.add-row-button { color: #32d296; }
table a.del-row-button { color: #f0506e; }
table#results-table > tbody > tr > td:first-child { font-weight: bold; color: #6c9f12; }
/* Result Table from Tablesort.css */ th:not(.no-sort) { cursor: pointer; }
th[role=columnheader]:not(.no-sort):after { content: ''; float: right; margin-top: 7px; border-width: 0 4px 4px; border-style: solid; border-color: #404040 transparent; visibility: hidden; opacity: 0; -ms-user-select: none; -webkit-user-select: none; -moz-user-select: none; user-select: none; }
th[aria-sort=ascending]:not(.no-sort):after { border-bottom: none; border-width: 4px 4px 0; }
th[aria-sort]:not(.no-sort):after { visibility: visible; opacity: 0.4; }
th[role=columnheader]:not(.no-sort):hover:after { visibility: visible; opacity: 1; } </style> </html>
|