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) {
   if (rangeFilter === {}) {
+
   for (var cardIndex = 0; cardIndex < listToFilter.length; cardIndex++) {
    for (var i = 0; i < listToFilter.length; i++) {
+
    var card = listToFilter[cardIndex];
      var item = listToFilter[i];
+
    if (isObjectValuesIncludedInFilterWithRange(dataObject[cardIndex], filter, rangeFilter)) {
      if (isObjectValuesIncludedInFilter(item.dataset, filter)) {
+
      card.classList.remove("tabber-noactive");
        item.classList.remove("tabber-noactive");
+
    } else {
      } else {
+
      card.classList.add("tabber-noactive");
        item.classList.add("tabber-noactive");
 
      }
 
    }
 
  } else {
 
    for (var i = 0; i < listToFilter.length; i++) {
 
      var item = listToFilter[i];
 
      if (isObjectValuesIncludedInFilterWithRange(item.dataset, filter, rangeFilter)) {
 
        item.classList.remove("tabber-noactive");
 
      } else {
 
        item.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 key = target.parentElement.parentElement.id;
+
     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);
 
    
 
    
   filterItems(filter, listToFilter, rangeFilter);
+
   return [filter, rangeFilter, initialRange]
 +
}
 +
 
 +
 
 +
function loading() {
 
    
 
    
   return [filter, rangeFilter, initialRange]
+
   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);
  
})();