{% extends "layouts/base.html" %} {% block title %}BBS - Command Melding{% endblock %} {% block head %} <style> table { .charlist { display: inline-grid; grid-template-columns: repeat(3, 1fr); gap: 15px; .aqua { color: #97c8ff; } .ventus { color: #26ff62; } .terra { color: #ff7400; } } tbody tr:hover { background-color: #4f4f4f; } & tr, th, td { border: 1px solid #fff; padding: 7px; } } </style> <script> let charFilter = ""; let typeFilter = ""; let searchType = "commands"; document.addEventListener("DOMContentLoaded", (event) => { const searchFilter = document.getElementById("filter"); let filterHandler = debounce(() => filter()); searchFilter.addEventListener("keyup", filterHandler); searchFilter.placeholder = "Search commands..."; const searchInputs = document.querySelectorAll( 'input[type="radio"][name="search"]', ); searchInputs.forEach(function (item, index) { item.addEventListener("input", function () { searchType = this.checked ? this.value : ""; searchFilter.placeholder = "Search " + this.value + "..."; filter(); }); }); const charFilters = document.querySelectorAll( 'input[type="radio"][name="charFilter"]', ); charFilters.forEach(function (item, index) { item.addEventListener("input", function () { charFilter = this.checked ? this.value : ""; filter(); }); }); const typeFilters = document.querySelectorAll( 'input[type="radio"][name="typeFilter"]', ); typeFilters.forEach(function (item, index) { item.addEventListener("input", function () { typeFilter = this.checked ? this.value : ""; filter(); }); }); }); function debounce(callback, wait = 300) { let timeoutId = null; return (...args) => { window.clearTimeout(timeoutId); timeoutId = window.setTimeout(() => { callback(...args); }, wait); }; } function filter() { const table = document.querySelector("table tbody"); const search = document .getElementById("filter") .value.toLowerCase(); for (const child of table.children) { const tds = child.children; resetStyle(child, tds); if (search.length > 0) { if (searchType === "commands") { // Check for command name if (!tds[1].innerText.toLowerCase().includes(search)) { child.style.display = "none"; } else { applyStyle(tds[1]); } } else if (searchType === "ingredients") { // Ingredients if (!tds[2].innerText.toLowerCase().includes(search)) { if ( !tds[3].innerText.toLowerCase().includes(search) ) { child.style.display = "none"; } else { applyStyle(tds[3]); } } else { applyStyle(tds[2]); if ( tds[3].innerText.toLowerCase().includes(search) ) { applyStyle(tds[3]); } } } else if (searchType === "abilities") { // Abilities hasLine = false; for (let i = 0; i < 7; i++) { const id = i + 6; const ablName = tds[id].innerText.toLowerCase(); if (ablName.includes(search)) { applyStyle(tds[id]); hasLine = true; break; } } if (!hasLine) { child.style.display = "none"; } } } const typeCheck = typeFilter === "" || tds[1].className === typeFilter; const charCheck = charFilter === "" || child.className.includes(charFilter); if (child.style.display == "" && (!typeCheck || !charCheck)) { child.style.display = "none"; } } } function resetStyle(child, tds) { child.style.display = ""; for (const td of tds) { td.style.fontWeight = "inherit"; td.style.color = "#fff"; } } function applyStyle(el) { el.style.fontWeight = "bold"; el.style.color = "red"; } </script> {% endblock %} {% block content %} {% include "components/bbs/search.html" %} <br /> {% include "components/bbs/type-filters.html" %} <br /> {% include "components/bbs/char-filters.html" %} <table> <thead> <tr> <th rowspan="2">Character</th> <th rowspan="2">Command</th> <th rowspan="2">Ingredient A</th> <th rowspan="2">Ingredient B</th> <th rowspan="2">Type</th> <th rowspan="2">Chance</th> <th colspan="7">Abilities</th> </tr> <tr> {% for crystal in crystals %} <th>{{ crystal }}</th> {% endfor %} </tr> </thead> <tbody> {% for cmd in commands %} {% for recipe in cmd.recipes %} <tr class="{{ recipe.get_unlock_chars() }}"> <td> <div class="charlist"> <!-- RGB moment --> <span class="terra"> {% if recipe.can_unlock(Character::Terra) %}T{% endif %} </span> <span class="ventus"> {% if recipe.can_unlock(Character::Ventus) %}V{% endif %} </span> <span class="aqua"> {% if recipe.can_unlock(Character::Aqua) %}A{% endif %} </span> </div> </td> <td class="{{ cmd.category }}">{{ cmd.name }}</td> <td>{{ recipe.ingredients.0 }}</td> <td>{{ recipe.ingredients.1 }}</td> <td>{{ recipe.type }}</td> <td>{{ recipe.chance }}%</td> {% for crystal in crystals %} {% let ability = recipe.get_ability(crystal) %} <td> {% if ability.is_some() %} {{ ability.unwrap().name }} {% else %} - {% endif %} </td> {% endfor %} </tr> {% endfor %} {% endfor %} </tbody> </table> {% endblock %}