MediaWiki:Script/Filter.js : Différence entre versions
(Page créée avec « function handleDropdowns(form) { var activeButton = null; function toggleDropdown(button, dropdownMenu) { if (button === activeButton) { dropdownMenu.classL... ») |
|||
Ligne 64 : | Ligne 64 : | ||
− | function filterItems(filter, listToFilter, rangeFilter) { | + | function filterItems(filter, listToFilter, rangeFilter, dataObject) { |
− | + | for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) { | |
− | + | var card = listToFilter[cardIndex]; | |
− | + | if (isObjectValuesIncludedInFilterWithRange(dataObject[cardIndex], filter, rangeFilter)) { | |
− | + | card.classList.remove("tabber-noactive"); | |
− | + | } else { | |
− | + | card.classList.add("tabber-noactive"); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
} | } | ||
Ligne 104 : | Ligne 93 : | ||
− | function updateFilterObject(form, listToFilter, filter, rangeFilter, initialRange) { | + | function incrementCounter(counter, count) { |
+ | if (count === 0) { | ||
+ | counter.classList.remove("tabber-noactive"); | ||
+ | } | ||
+ | counter.textContent = count + 1; | ||
+ | } | ||
+ | |||
+ | |||
+ | function decrementCounter(counter, count) { | ||
+ | if (count === 1) { | ||
+ | counter.classList.add("tabber-noactive"); | ||
+ | } | ||
+ | counter.textContent = count - 1; | ||
+ | } | ||
+ | |||
+ | |||
+ | function updateFilterObject(form, listToFilter, filter, rangeFilter, initialRange, dataObject) { | ||
form.addEventListener("submit", function(e) { | form.addEventListener("submit", function(e) { | ||
Ligne 114 : | Ligne 119 : | ||
var value = target.dataset.filter; | var value = target.dataset.filter; | ||
var type = target.type; | var type = target.type; | ||
− | var | + | var grandParent = target.parentElement.parentElement; |
+ | var key = grandParent.id; | ||
+ | var counter = grandParent.nextElementSibling; | ||
+ | var count = Number(counter.textContent); | ||
if (type === "number") { | if (type === "number") { | ||
− | + | ||
var key = key.split("-range")[0]; | var key = key.split("-range")[0]; | ||
Ligne 128 : | Ligne 136 : | ||
} else { | } else { | ||
− | + | incrementCounter(counter, count); | |
var range = {"min": initialRange[key]["min"], "max": initialRange[key]["max"]}; | var range = {"min": initialRange[key]["min"], "max": initialRange[key]["max"]}; | ||
range[extremum] = currentValue; | range[extremum] = currentValue; | ||
Ligne 135 : | Ligne 143 : | ||
if ((rangeFilter[key]["max"] === initialRange[key]["max"]) && (rangeFilter[key]["min"] === initialRange[key]["min"])) { | if ((rangeFilter[key]["max"] === initialRange[key]["max"]) && (rangeFilter[key]["min"] === initialRange[key]["min"])) { | ||
+ | decrementCounter(counter, count); | ||
delete rangeFilter[key]; | delete rangeFilter[key]; | ||
} | } | ||
Ligne 141 : | Ligne 150 : | ||
if (target.checked) { | if (target.checked) { | ||
+ | |||
+ | incrementCounter(counter, count); | ||
+ | |||
if (filter[key]) { | if (filter[key]) { | ||
filter[key].push(value); | filter[key].push(value); | ||
Ligne 147 : | Ligne 159 : | ||
} | } | ||
} else { | } else { | ||
+ | |||
+ | decrementCounter(counter, count); | ||
+ | |||
var index = filter[key].indexOf(value); | var index = filter[key].indexOf(value); | ||
if (index !== -1) { | if (index !== -1) { | ||
Ligne 157 : | Ligne 172 : | ||
} | } | ||
} | } | ||
− | + | ||
− | filterItems(filter, listToFilter, rangeFilter); | + | filterItems(filter, listToFilter, rangeFilter, dataObject); |
}); | }); | ||
} | } | ||
Ligne 203 : | Ligne 218 : | ||
− | function filterWithURL(form, url, listToFilter) { | + | function filterWithURL(form, url, listToFilter, dataObject) { |
var params = new URLSearchParams(url.search); | var params = new URLSearchParams(url.search); | ||
Ligne 243 : | Ligne 258 : | ||
} | } | ||
} | } | ||
+ | |||
+ | filterItems(filter, listToFilter, rangeFilter, dataObject); | ||
− | + | return [filter, rangeFilter, initialRange] | |
+ | } | ||
+ | |||
+ | |||
+ | function loading() { | ||
− | + | window.addEventListener("load", function() { | |
+ | |||
+ | var mainContainer = document.getElementById("hide-all"); | ||
+ | var loadingAnimation = document.getElementById("loading-animation"); | ||
+ | |||
+ | mainContainer.classList.remove("tabber-noactive"); | ||
+ | loadingAnimation.classList.add("tabber-noactive"); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | |||
+ | function createDataObject(listToFilter) { | ||
+ | var dataObject = [] | ||
+ | for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) { | ||
+ | var item = listToFilter[cardIndex]; | ||
+ | var levelData = item.querySelector("[data-e0]"); | ||
+ | var [level, rank] = levelData.textContent.slice(1, -1).split(","); | ||
+ | var elementData = item.querySelector("[data-e2]").children; | ||
+ | if (elementData.length) { | ||
+ | var element = ""; | ||
+ | for (var elementIndex = 0; elementIndex < elementData.length; elementIndex++) { | ||
+ | element += elementData[elementIndex].title + " "; | ||
+ | } | ||
+ | } else { | ||
+ | var element = "Aucun"; | ||
+ | } | ||
+ | var typeData = item.querySelector("[data-e3]"); | ||
+ | var type = typeData.textContent.replace("Aucun type", "Aucun"); | ||
+ | var damageData = item.querySelector("[data-e4]"); | ||
+ | var damage = damageData.textContent.replace("DC", "Compétence"); | ||
+ | dataObject.push({e0: level, e1: rank, e2: element, e3: type, e4: damage}) | ||
+ | } | ||
+ | return dataObject | ||
} | } | ||
Ligne 255 : | Ligne 308 : | ||
var form = document.getElementById("filter-form"); | var form = document.getElementById("filter-form"); | ||
var url = new URL(window.location.href); | var url = new URL(window.location.href); | ||
− | var [filter, rangeFilter, initialRange] = filterWithURL(form, url, listToFilter); | + | var dataObject = createDataObject(listToFilter); |
− | + | var [filter, rangeFilter, initialRange] = filterWithURL(form, url, listToFilter, dataObject); | |
+ | |||
+ | loading(); | ||
keyboard(form); | keyboard(form); | ||
handleDropdowns(form); | handleDropdowns(form); | ||
− | updateFilterObject(form, listToFilter, filter, rangeFilter, initialRange); | + | updateFilterObject(form, listToFilter, filter, rangeFilter, initialRange, dataObject); |
+ | |||
})(); | })(); |
Version du 23 août 2023 à 20:28
function handleDropdowns(form) {
var activeButton = null;
function toggleDropdown(button, dropdownMenu) {
if (button === activeButton) {
dropdownMenu.classList.add('tabber-noactive');
activeButton = null;
} else {
if (activeButton) {
activeButton.nextElementSibling.classList.add('tabber-noactive');
}
dropdownMenu.classList.remove('tabber-noactive');
activeButton = button;
}
}
function closeDropdowns() {
if (activeButton) {
activeButton.nextElementSibling.classList.add('tabber-noactive');
activeButton = null;
}
}
form.addEventListener('click', function(event) {
var target = event.target;
var button = target.closest('button');
if (button) {
var dropdownMenu = button.nextElementSibling;
toggleDropdown(button, dropdownMenu);
} else if (!target.closest('.dropdown-menu')) {
closeDropdowns();
}
});
document.addEventListener('click', function(event) {
if (!form.contains(event.target)) {
closeDropdowns();
}
});
}
function isObjectValuesIncludedInFilter(obj, filter) {
return Object.keys(filter).every(function(prop) {
return obj[prop].split(' ').some(function(val) {
return filter[prop].indexOf(val) !== -1;
});
});
}
function isObjectValuesIncludedInFilterWithRange(obj, filter, rangeFilter) {
return isObjectValuesIncludedInFilter(obj, filter) && Object.keys(rangeFilter).every(function(prop) {
var propValue = Number(obj[prop]);
return rangeFilter[prop]["min"] <= propValue && rangeFilter[prop]["max"] >= propValue;
});
}
function filterItems(filter, listToFilter, rangeFilter, dataObject) {
for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) {
var card = listToFilter[cardIndex];
if (isObjectValuesIncludedInFilterWithRange(dataObject[cardIndex], filter, rangeFilter)) {
card.classList.remove("tabber-noactive");
} else {
card.classList.add("tabber-noactive");
}
}
}
function createInitialRangeObject(form) {
var initialRange = {}
form.querySelectorAll('[id$="-range"]').forEach(function(e) {
var minMax = {min: 0, max: 0}
e.querySelectorAll('input').forEach(function(input){
var extrem = input.id.split('-')[1];
minMax[extrem] = Number(input[extrem]);
});
initialRange[e.id.split("-")[0]] = minMax;
});
return initialRange
}
function incrementCounter(counter, count) {
if (count === 0) {
counter.classList.remove("tabber-noactive");
}
counter.textContent = count + 1;
}
function decrementCounter(counter, count) {
if (count === 1) {
counter.classList.add("tabber-noactive");
}
counter.textContent = count - 1;
}
function updateFilterObject(form, listToFilter, filter, rangeFilter, initialRange, dataObject) {
form.addEventListener("submit", function(e) {
e.preventDefault();
});
form.addEventListener("change", function(e) {
var target = e.target;
var value = target.dataset.filter;
var type = target.type;
var grandParent = target.parentElement.parentElement;
var key = grandParent.id;
var counter = grandParent.nextElementSibling;
var count = Number(counter.textContent);
if (type === "number") {
var key = key.split("-range")[0];
var extremum = target.id.split(key + "-")[1];
var currentValue = Number(target.value);
if (rangeFilter[key]) {
rangeFilter[key][extremum] = currentValue;
} else {
incrementCounter(counter, count);
var range = {"min": initialRange[key]["min"], "max": initialRange[key]["max"]};
range[extremum] = currentValue;
rangeFilter[key] = range;
}
if ((rangeFilter[key]["max"] === initialRange[key]["max"]) && (rangeFilter[key]["min"] === initialRange[key]["min"])) {
decrementCounter(counter, count);
delete rangeFilter[key];
}
} else if (type === "checkbox") {
if (target.checked) {
incrementCounter(counter, count);
if (filter[key]) {
filter[key].push(value);
} else {
filter[key] = [value];
}
} else {
decrementCounter(counter, count);
var index = filter[key].indexOf(value);
if (index !== -1) {
if (filter[key].length === 1) {
delete filter[key];
} else {
filter[key].splice(index, 1);
}
}
}
}
filterItems(filter, listToFilter, rangeFilter, dataObject);
});
}
function keyboard(form) {
var focusableElements = form.querySelectorAll('a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], input[type="number"], select');
var buttons = form.querySelectorAll("button");
form.addEventListener("keydown", function(e) {
var target = e.target;
if (target.tagName === "INPUT") {
if (e.key === "Enter") {
target.click();
}
} else if (target.tagName === "BUTTON") {
if (e.key === "ArrowRight" || e.key === "ArrowLeft") {
var currentElement = document.activeElement;
var currentIndex = Array.prototype.indexOf.call(buttons, currentElement);
var nextIndex = e.key === "ArrowRight" ? (currentIndex + 1) % buttons.length : (currentIndex - 1 + buttons.length) % buttons.length;
buttons[nextIndex].focus();
}
}
if (target.type !== "number") {
if (e.key === "ArrowDown" || e.key === "ArrowUp") {
var currentElement = document.activeElement;
var currentIndex = Array.prototype.indexOf.call(focusableElements, currentElement);
var nextIndex = e.key === "ArrowDown" ? (currentIndex + 1) % focusableElements.length : (currentIndex - 1 + focusableElements.length) % focusableElements.length;
focusableElements[nextIndex].focus();
}
}
});
}
function filterWithURL(form, url, listToFilter, dataObject) {
var params = new URLSearchParams(url.search);
var filter = {}
var initialRange = createInitialRangeObject(form);
var rangeFilter = {}
for (var [key, value] of params.entries()) {
var input = form.querySelector("[id^='" + key + "'][data-filter='" + value + "']");
if (input) {
input.checked = true;
filter[key] = params.getAll(key);
} else {
var checkbox = form.querySelector("#" + key);
if (checkbox) {
var [filterKey, extremum] = key.split("-");
if (rangeFilter[filterKey]) {
rangeFilter[filterKey][extremum] = Number(value);
} else {
var range = {"min": initialRange[filterKey]["min"], "max": initialRange[filterKey]["max"]};
range[extremum] = Number(value);
rangeFilter[filterKey] = range;
}
checkbox.value = value;
}
}
}
filterItems(filter, listToFilter, rangeFilter, dataObject);
return [filter, rangeFilter, initialRange]
}
function loading() {
window.addEventListener("load", function() {
var mainContainer = document.getElementById("hide-all");
var loadingAnimation = document.getElementById("loading-animation");
mainContainer.classList.remove("tabber-noactive");
loadingAnimation.classList.add("tabber-noactive");
});
}
function createDataObject(listToFilter) {
var dataObject = []
for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) {
var item = listToFilter[cardIndex];
var levelData = item.querySelector("[data-e0]");
var [level, rank] = levelData.textContent.slice(1, -1).split(",");
var elementData = item.querySelector("[data-e2]").children;
if (elementData.length) {
var element = "";
for (var elementIndex = 0; elementIndex < elementData.length; elementIndex++) {
element += elementData[elementIndex].title + " ";
}
} else {
var element = "Aucun";
}
var typeData = item.querySelector("[data-e3]");
var type = typeData.textContent.replace("Aucun type", "Aucun");
var damageData = item.querySelector("[data-e4]");
var damage = damageData.textContent.replace("DC", "Compétence");
dataObject.push({e0: level, e1: rank, e2: element, e3: type, e4: damage})
}
return dataObject
}
(function(){
var listToFilter = document.getElementById("list-to-filter").children;
var form = document.getElementById("filter-form");
var url = new URL(window.location.href);
var dataObject = createDataObject(listToFilter);
var [filter, rangeFilter, initialRange] = filterWithURL(form, url, listToFilter, dataObject);
loading();
keyboard(form);
handleDropdowns(form);
updateFilterObject(form, listToFilter, filter, rangeFilter, initialRange, dataObject);
})();