206 lines
5.1 KiB
HTML
206 lines
5.1 KiB
HTML
{% extends "layouts/base.html" %}
|
|
|
|
{% block title %}Commands{% endblock %}
|
|
|
|
{% block head %}
|
|
<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 %}
|