MediaWiki:Script/Filter.js : Différence entre versions
Ligne 1 : | Ligne 1 : | ||
− | function handleDropdowns( | + | function hideElement(element) { |
+ | element.classList.add("tabber-noactive"); | ||
+ | } | ||
+ | |||
+ | |||
+ | function showElement(element) { | ||
+ | element.classList.remove("tabber-noactive"); | ||
+ | } | ||
+ | |||
+ | |||
+ | function removeAccent(str) { | ||
+ | return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase() | ||
+ | } | ||
+ | |||
+ | |||
+ | function toNormalForm(str) { | ||
+ | return removeAccent(str).replace(/[^a-zA-Z0-9 ]/g, '');; | ||
+ | } | ||
+ | |||
+ | |||
+ | function loading() { | ||
+ | |||
+ | var mainContainer = document.getElementById("hide-all"); | ||
+ | var loadingAnimation = document.getElementById("loading-animation"); | ||
+ | |||
+ | mainContainer.classList.remove("tabber-noactive"); | ||
+ | loadingAnimation.classList.add("tabber-noactive"); | ||
+ | } | ||
+ | |||
+ | |||
+ | function handleDropdowns(filterInformation) { | ||
+ | |||
+ | var form = filterInformation.form; | ||
var activeButton = null; | var activeButton = null; | ||
Ligne 47 : | Ligne 79 : | ||
− | function isObjectValuesIncludedInFilter( | + | function filterItems(filterInformation, cardInformation) { |
− | + | ||
− | + | function isObjectValuesIncludedInFilter(parameters, filter) { | |
− | + | return Object.keys(filter).every(function(property) { | |
+ | return parameters[property].split(' ').some(function(value) { | ||
+ | return filter[property].indexOf(value) !== -1; | ||
+ | }); | ||
}); | }); | ||
− | }); | + | } |
− | } | + | |
+ | function filterByName(parameters, filterName) { | ||
+ | if (filterName) { | ||
+ | return parameters.name.indexOf(filterName) !== -1; | ||
+ | } | ||
+ | return true; | ||
+ | } | ||
+ | |||
+ | function isObjectValuesIncludedInFilterWithRange(parameters, filter, rangeFilter, filterName) { | ||
+ | return isObjectValuesIncludedInFilter(parameters, filter) && filterByName(parameters, filterName) && Object.keys(rangeFilter).every(function(property) { | ||
+ | var propertyValue = parameters[property]; | ||
+ | return rangeFilter[property].min <= propertyValue && rangeFilter[property].max >= propertyValue; | ||
+ | }); | ||
+ | } | ||
− | + | var filter = filterInformation.filters.filter; | |
− | + | var rangeFilter = filterInformation.filters.rangeFilter; | |
− | + | var filterName = filterInformation.filters.filterName; | |
− | + | var listToFilter = cardInformation.listToFilter; | |
− | + | var cardData = cardInformation.data; | |
− | + | ||
− | |||
− | |||
− | |||
− | |||
for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) { | for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) { | ||
var card = listToFilter[cardIndex]; | var card = listToFilter[cardIndex]; | ||
− | if (isObjectValuesIncludedInFilterWithRange( | + | var cardParameters = cardData[cardIndex]; |
− | card | + | if (isObjectValuesIncludedInFilterWithRange(cardParameters, filter, rangeFilter, filterName)) { |
+ | showElement(card); | ||
} else { | } else { | ||
− | card | + | hideElement(card); |
} | } | ||
} | } | ||
Ligne 76 : | Ligne 121 : | ||
− | function | + | function updateFilterObject(filterInformation, cardInformation) { |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | function incrementCounter(counterElement, counterValue) { | ||
+ | |||
+ | if (counterValue === 0) { | ||
+ | showElement(counterElement); | ||
+ | } | ||
+ | |||
+ | counterElement.textContent = counterValue + 1; | ||
+ | } | ||
− | function | + | function decrementCounter(counterElement, counterValue) { |
− | + | ||
− | + | if (counterValue === 1) { | |
+ | hideElement(counterElement); | ||
+ | } | ||
+ | |||
+ | counterElement.textContent = counterValue - 1; | ||
} | } | ||
− | + | ||
− | + | function updateFilter(event, filterByName = false) { | |
− | |||
− | |||
− | function | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | function handleNumberType(target) { | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | + | var [filterName, extremum] = target.id.split("-"); |
− | |||
− | |||
var currentValue = Number(target.value); | var currentValue = Number(target.value); | ||
+ | var counterElement = filterInformation.range[filterName].counter; | ||
+ | var counterValue = Number(counterElement.textContent); | ||
+ | var initialRange = filterInformation.range[filterName].init; | ||
+ | var rangeFilter = filterInformation.filters.rangeFilter; | ||
− | if (rangeFilter[ | + | if (rangeFilter[filterName]) { |
+ | rangeFilter[filterName][extremum] = currentValue; | ||
+ | } else { | ||
+ | var range = {min: initialRange.min, max: initialRange.max}; | ||
− | + | incrementCounter(counterElement, counterValue); | |
− | |||
− | |||
− | incrementCounter( | ||
− | |||
range[extremum] = currentValue; | range[extremum] = currentValue; | ||
− | rangeFilter[ | + | rangeFilter[filterName] = range; |
} | } | ||
− | + | if ((rangeFilter[filterName].max === initialRange.max) && (rangeFilter[filterName].min === initialRange.min)) { | |
− | if ((rangeFilter[ | + | decrementCounter(counterElement, counterValue); |
− | decrementCounter( | + | delete rangeFilter[filterName]; |
− | delete rangeFilter[ | ||
} | } | ||
+ | } | ||
+ | |||
+ | function handleCheckbox(target) { | ||
− | + | var filterName = target.id.split("-")[0]; | |
+ | var filter = filterInformation.filters.filter; | ||
+ | var filterValue = target.dataset.filter; | ||
+ | var counterElement = filterInformation.checkbox[filterName].counter; | ||
+ | var counterValue = Number(counterElement.textContent); | ||
if (target.checked) { | if (target.checked) { | ||
− | + | incrementCounter(counterElement, counterValue); | |
− | incrementCounter( | + | if (filter[filterName]) { |
− | + | filter[filterName].push(filterValue); | |
− | if (filter[ | ||
− | filter[ | ||
} else { | } else { | ||
− | filter[ | + | filter[filterName] = [filterValue]; |
} | } | ||
} else { | } else { | ||
− | + | decrementCounter(counterElement, counterValue); | |
− | decrementCounter( | + | var index = filter[filterName].indexOf(filterValue); |
− | |||
− | var index = filter[ | ||
if (index !== -1) { | if (index !== -1) { | ||
− | if (filter[ | + | if (filter[filterName].length === 1) { |
− | delete filter[ | + | delete filter[filterName]; |
} else { | } else { | ||
− | filter[ | + | filter[filterName].splice(index, 1); |
} | } | ||
} | } | ||
− | } | + | } |
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var target = | + | var target = event.target; |
− | + | ||
− | if (target. | + | if (filterByName) { |
+ | filterInformation.filters.filterName = toNormalForm(target.value); | ||
+ | } else { | ||
+ | var type = target.type; | ||
− | if ( | + | if (type === "number") { |
− | + | handleNumberType(target); | |
− | target | + | } else if (type === "checkbox") { |
− | + | handleCheckbox(target); | |
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | filterItems(filterInformation, cardInformation); | |
− | + | } | |
− | + | ||
− | + | var form = filterInformation.form; | |
− | + | var debounceTimer; | |
− | + | ||
− | + | form.addEventListener("submit", function(event) { | |
− | } | + | event.preventDefault(); |
+ | }); | ||
+ | |||
+ | form.addEventListener("change", function(event) { | ||
+ | updateFilter(event); | ||
+ | }); | ||
+ | |||
+ | form.addEventListener("input", function(event) { | ||
+ | if (event.target.id === "filter-name") { | ||
+ | clearTimeout(debounceTimer); | ||
+ | debounceTimer = setTimeout(function() { | ||
+ | updateFilter(event, true); | ||
+ | }, 500); | ||
} | } | ||
}); | }); | ||
Ligne 218 : | Ligne 233 : | ||
− | function | + | function filterInitialization() { |
+ | function createSpan() { | ||
+ | var span = document.createElement("span"); | ||
+ | span.style.color = '#9F9F9F'; | ||
+ | span.style.fontSize = '12px'; | ||
+ | return span; | ||
+ | } | ||
+ | |||
+ | var form = document.getElementById("filter-form"); | ||
+ | var filters = { filterName: "", filter: {}, rangeFilter: {} }; | ||
+ | var filterInformation = { form: form, filters: filters, range: {}, checkbox: {} }; | ||
+ | var allButton = form.querySelectorAll("button"); | ||
+ | |||
+ | allButton.forEach(function(button) { | ||
+ | var buttonSibling = button.nextElementSibling; | ||
+ | if (!buttonSibling) return; | ||
− | + | var filterName = buttonSibling.id; | |
− | + | var counter = buttonSibling.nextElementSibling; | |
− | + | if (!filterName || !counter) return; | |
− | |||
− | + | var infoType = filterName.endsWith("-range") ? "range" : "checkbox"; | |
− | + | var filterObj = filterInformation[infoType][filterName.replace("-range", "")] = { counter: counter }; | |
− | var | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | var | + | if (infoType === "checkbox") { |
− | + | filterObj.values = {}; | |
− | + | var allInput = buttonSibling.querySelectorAll("input"); | |
− | + | allInput.forEach(function(input) { | |
− | var | + | var filterValue = input.dataset.filter; |
− | + | if (!filterValue) return; | |
− | if ( | ||
− | |||
− | |||
− | |||
− | |||
− | + | var span = createSpan(); | |
− | + | input.parentElement.appendChild(span); | |
− | + | filterObj.values[filterValue] = { value: 0, span: span }; | |
− | + | }); | |
− | + | } else if (infoType === "range") { | |
− | + | filterObj.init = {} | |
− | + | filterObj.init.min = Number(buttonSibling.children[0].firstChild.min); | |
− | + | filterObj.init.max = Number(buttonSibling.children[0].firstChild.max); | |
− | |||
} | } | ||
− | } | + | }); |
− | + | return filterInformation; | |
− | |||
− | |||
} | } | ||
− | function | + | function getCardInformation(filterInformation) { |
− | + | var listToFilter = document.getElementById("list-to-filter").children; | |
+ | var allCardInformation = []; | ||
+ | var filterNames = Object.keys(filterInformation.checkbox).concat(Object.keys(filterInformation.range)); | ||
+ | |||
+ | for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) { | ||
+ | var card = listToFilter[cardIndex]; | ||
+ | var cardInformation = {}; | ||
+ | var cardName = card.querySelector("[data-name]").textContent; | ||
+ | cardInformation.name = toNormalForm(cardName); | ||
− | var | + | if (filterNames.indexOf("e0") !== -1) { |
− | + | var e0Element = card.querySelector("[data-e0]"); | |
+ | var [e0Value, e1Value] = e0Element.textContent.slice(1, -1).split(", "); | ||
+ | cardInformation.e0 = Number(e0Value); | ||
+ | cardInformation.e1 = removeAccent(e1Value); | ||
+ | } | ||
− | + | if (filterNames.indexOf("e2") !== -1) { | |
− | + | var e2Element = card.querySelector("[data-e2]").children; | |
− | + | var e2Value = ""; | |
− | + | if (e2Element.length) { | |
− | + | for (var e2ValueIndex = 0; e2ValueIndex < e2Element.length; e2ValueIndex++) { | |
− | + | e2Value += e2Element[e2ValueIndex].title + " "; | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | } | + | e2Value = e2Value.trim() || "Aucun"; |
− | var | + | cardInformation.e2 = removeAccent(e2Value); |
+ | } | ||
+ | |||
+ | if (filterNames.indexOf("e3") !== -1) { | ||
+ | var e3Value = card.querySelector("[data-e3]").textContent.replace(" type", ""); | ||
+ | cardInformation.e3 = removeAccent(e3Value); | ||
+ | } | ||
+ | |||
+ | if (filterNames.indexOf("e4") !== -1) { | ||
+ | var e4Value = card.querySelector("[data-e4]").textContent.replace('+ ', ''); | ||
+ | cardInformation.e4 = removeAccent(e4Value); | ||
} | } | ||
− | + | ||
− | + | allCardInformation.push(cardInformation); | |
− | |||
− | |||
− | |||
} | } | ||
− | return | + | allCardInformation = { listToFilter: listToFilter, data: allCardInformation }; |
+ | |||
+ | return allCardInformation; | ||
} | } | ||
− | + | ||
(function(){ | (function(){ | ||
+ | var filterInformation = filterInitialization(); | ||
+ | var cardInformation = getCardInformation(filterInformation); | ||
− | + | handleDropdowns(filterInformation) | |
− | + | updateFilterObject(filterInformation, cardInformation); | |
− | |||
− | |||
− | |||
− | |||
loading(); | loading(); | ||
− | |||
− | |||
− | |||
− | |||
})(); | })(); |
Version du 28 août 2023 à 22:25
function hideElement(element) {
element.classList.add("tabber-noactive");
}
function showElement(element) {
element.classList.remove("tabber-noactive");
}
function removeAccent(str) {
return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase()
}
function toNormalForm(str) {
return removeAccent(str).replace(/[^a-zA-Z0-9 ]/g, '');;
}
function loading() {
var mainContainer = document.getElementById("hide-all");
var loadingAnimation = document.getElementById("loading-animation");
mainContainer.classList.remove("tabber-noactive");
loadingAnimation.classList.add("tabber-noactive");
}
function handleDropdowns(filterInformation) {
var form = filterInformation.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 filterItems(filterInformation, cardInformation) {
function isObjectValuesIncludedInFilter(parameters, filter) {
return Object.keys(filter).every(function(property) {
return parameters[property].split(' ').some(function(value) {
return filter[property].indexOf(value) !== -1;
});
});
}
function filterByName(parameters, filterName) {
if (filterName) {
return parameters.name.indexOf(filterName) !== -1;
}
return true;
}
function isObjectValuesIncludedInFilterWithRange(parameters, filter, rangeFilter, filterName) {
return isObjectValuesIncludedInFilter(parameters, filter) && filterByName(parameters, filterName) && Object.keys(rangeFilter).every(function(property) {
var propertyValue = parameters[property];
return rangeFilter[property].min <= propertyValue && rangeFilter[property].max >= propertyValue;
});
}
var filter = filterInformation.filters.filter;
var rangeFilter = filterInformation.filters.rangeFilter;
var filterName = filterInformation.filters.filterName;
var listToFilter = cardInformation.listToFilter;
var cardData = cardInformation.data;
for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) {
var card = listToFilter[cardIndex];
var cardParameters = cardData[cardIndex];
if (isObjectValuesIncludedInFilterWithRange(cardParameters, filter, rangeFilter, filterName)) {
showElement(card);
} else {
hideElement(card);
}
}
}
function updateFilterObject(filterInformation, cardInformation) {
function incrementCounter(counterElement, counterValue) {
if (counterValue === 0) {
showElement(counterElement);
}
counterElement.textContent = counterValue + 1;
}
function decrementCounter(counterElement, counterValue) {
if (counterValue === 1) {
hideElement(counterElement);
}
counterElement.textContent = counterValue - 1;
}
function updateFilter(event, filterByName = false) {
function handleNumberType(target) {
var [filterName, extremum] = target.id.split("-");
var currentValue = Number(target.value);
var counterElement = filterInformation.range[filterName].counter;
var counterValue = Number(counterElement.textContent);
var initialRange = filterInformation.range[filterName].init;
var rangeFilter = filterInformation.filters.rangeFilter;
if (rangeFilter[filterName]) {
rangeFilter[filterName][extremum] = currentValue;
} else {
var range = {min: initialRange.min, max: initialRange.max};
incrementCounter(counterElement, counterValue);
range[extremum] = currentValue;
rangeFilter[filterName] = range;
}
if ((rangeFilter[filterName].max === initialRange.max) && (rangeFilter[filterName].min === initialRange.min)) {
decrementCounter(counterElement, counterValue);
delete rangeFilter[filterName];
}
}
function handleCheckbox(target) {
var filterName = target.id.split("-")[0];
var filter = filterInformation.filters.filter;
var filterValue = target.dataset.filter;
var counterElement = filterInformation.checkbox[filterName].counter;
var counterValue = Number(counterElement.textContent);
if (target.checked) {
incrementCounter(counterElement, counterValue);
if (filter[filterName]) {
filter[filterName].push(filterValue);
} else {
filter[filterName] = [filterValue];
}
} else {
decrementCounter(counterElement, counterValue);
var index = filter[filterName].indexOf(filterValue);
if (index !== -1) {
if (filter[filterName].length === 1) {
delete filter[filterName];
} else {
filter[filterName].splice(index, 1);
}
}
}
}
var target = event.target;
if (filterByName) {
filterInformation.filters.filterName = toNormalForm(target.value);
} else {
var type = target.type;
if (type === "number") {
handleNumberType(target);
} else if (type === "checkbox") {
handleCheckbox(target);
}
}
filterItems(filterInformation, cardInformation);
}
var form = filterInformation.form;
var debounceTimer;
form.addEventListener("submit", function(event) {
event.preventDefault();
});
form.addEventListener("change", function(event) {
updateFilter(event);
});
form.addEventListener("input", function(event) {
if (event.target.id === "filter-name") {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(function() {
updateFilter(event, true);
}, 500);
}
});
}
function filterInitialization() {
function createSpan() {
var span = document.createElement("span");
span.style.color = '#9F9F9F';
span.style.fontSize = '12px';
return span;
}
var form = document.getElementById("filter-form");
var filters = { filterName: "", filter: {}, rangeFilter: {} };
var filterInformation = { form: form, filters: filters, range: {}, checkbox: {} };
var allButton = form.querySelectorAll("button");
allButton.forEach(function(button) {
var buttonSibling = button.nextElementSibling;
if (!buttonSibling) return;
var filterName = buttonSibling.id;
var counter = buttonSibling.nextElementSibling;
if (!filterName || !counter) return;
var infoType = filterName.endsWith("-range") ? "range" : "checkbox";
var filterObj = filterInformation[infoType][filterName.replace("-range", "")] = { counter: counter };
if (infoType === "checkbox") {
filterObj.values = {};
var allInput = buttonSibling.querySelectorAll("input");
allInput.forEach(function(input) {
var filterValue = input.dataset.filter;
if (!filterValue) return;
var span = createSpan();
input.parentElement.appendChild(span);
filterObj.values[filterValue] = { value: 0, span: span };
});
} else if (infoType === "range") {
filterObj.init = {}
filterObj.init.min = Number(buttonSibling.children[0].firstChild.min);
filterObj.init.max = Number(buttonSibling.children[0].firstChild.max);
}
});
return filterInformation;
}
function getCardInformation(filterInformation) {
var listToFilter = document.getElementById("list-to-filter").children;
var allCardInformation = [];
var filterNames = Object.keys(filterInformation.checkbox).concat(Object.keys(filterInformation.range));
for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) {
var card = listToFilter[cardIndex];
var cardInformation = {};
var cardName = card.querySelector("[data-name]").textContent;
cardInformation.name = toNormalForm(cardName);
if (filterNames.indexOf("e0") !== -1) {
var e0Element = card.querySelector("[data-e0]");
var [e0Value, e1Value] = e0Element.textContent.slice(1, -1).split(", ");
cardInformation.e0 = Number(e0Value);
cardInformation.e1 = removeAccent(e1Value);
}
if (filterNames.indexOf("e2") !== -1) {
var e2Element = card.querySelector("[data-e2]").children;
var e2Value = "";
if (e2Element.length) {
for (var e2ValueIndex = 0; e2ValueIndex < e2Element.length; e2ValueIndex++) {
e2Value += e2Element[e2ValueIndex].title + " ";
}
}
e2Value = e2Value.trim() || "Aucun";
cardInformation.e2 = removeAccent(e2Value);
}
if (filterNames.indexOf("e3") !== -1) {
var e3Value = card.querySelector("[data-e3]").textContent.replace(" type", "");
cardInformation.e3 = removeAccent(e3Value);
}
if (filterNames.indexOf("e4") !== -1) {
var e4Value = card.querySelector("[data-e4]").textContent.replace('+ ', '');
cardInformation.e4 = removeAccent(e4Value);
}
allCardInformation.push(cardInformation);
}
allCardInformation = { listToFilter: listToFilter, data: allCardInformation };
return allCardInformation;
}
(function(){
var filterInformation = filterInitialization();
var cardInformation = getCardInformation(filterInformation);
handleDropdowns(filterInformation)
updateFilterObject(filterInformation, cardInformation);
loading();
})();