0

I have an issue with filtering. I have my filter working the way I want it to for the most part. Currently I take user input in string format, then compare that string vs the innerText of my itemWrapperColumns divs. This then creates an array of IDs that I use to compare against my original object of items that my itemWrapperColumnsare based on. I create a new object of only the items that are included in the filter. This then feeds into my function that creates my HTML content.

This is exactly what I want as I want to limit the content on screen to what the user wants to see through the filter so they can tehn apply sorts to the data ete....

The problem I have is if the user uses three criteria to filter, e.g; Start: 307 itemWrapperColumns User Filter: "x","y","z" End: 1 itemWrapperColumns

If the user deletes "z", thus leaving "x" and "y" I would expect to see 50 itemWrappers, but because the only itemWrapperColumnsI have at this point is the 1 from the previous filter thats all that stays.

An idea would be to create a snapshot of the 307 itemWrapperColumns that load at the beginning then use those as my filter data, but I cannot figure this part out. I was hoping the var itemWrapper would solve it, but that variable keeps updating as the filter starts restricting the content.

This is my code to filter my data;

// create a varaible full of all item wrappers from items in stash
var itemWrappers = document.getElementsByClassName('itemWrapperColumns');

function itemFilter(){

    var input, array, filter, txtValue, listofIDs, i, a;
    input = document.getElementById('userFilter');
    array = input.value.split(',');
    itemWrappers = itemWrappers;
    listofIDs = []
    // this loops through each item of object
    for (i = 0; i < itemWrappers.length; i++){
        // assigned a variable to each item
        a = itemWrappers[i];
        // grab all the text associated with the item
        txtValue = a.innerText;
//         console.log('item ID: ', a.getAttribute('data-id'))
        for (x = 0; x < array.length; x++){
            y = array[x]

       if(array.every(item => txtValue.toUpperCase().includes(item.toUpperCase()))==true){
             listofIDs.push(a.getAttribute('data-id'));
         }
      }
   }
    return listofIDs;
};


// returns an itemList that is either all the items if there is no text in the filter
// or returns a filtered down item list that gets passed onto displaying items
function newItemsList() {
    var filterInput = document.getElementById('userFilter');
    if (filterInput.value == ''){
        var itemList = items;
    }else{
        var itemList = items.filter(val => itemFilter().includes(val.id));
        }
    return itemList
};

// run functions on keyup of 'Enter'
$('#userFilter').keyup(function(event) {
    if (event.keyCode === 13) {displayingItems(newItemsList())
    }
});
  • The question needs more clarification. Show the part of the code that needs to be fixed. – ABDULLOKH MUKHAMMADJONOV Oct 05 '21 at 19:34
  • Indeed you need to collect the initial data, make the first filter and save this as a cache of your initial state. It should be held in a variable away from any of the logic of your code, you are not allowed to update this beyond the initial load of the table. Then you can access it by copying it or however you like, for whatever you need – AGE Oct 05 '21 at 19:35
  • 1
    `getElementsByClassName()` returns a "live" NodeList, so it changes when the classes change. Convert it to an array with `Array.from(...)` to make a snapshot. – Barmar Oct 05 '21 at 19:36
  • for example your flaw is that you are reusing `itemWrappers` where you mean to save this, why not instead use a new `var filteredItemWrappers = itemWrappers` and use`filteredItemWrappers` accordingly – AGE Oct 05 '21 at 19:37
  • The code i need help with i guess is making the content of this variable (itemWrappers) not changable after the first time the data fills up in it. – ConfusedSpark Oct 05 '21 at 19:38
  • @Barmar This works only when I test in the console. I added the same code into my JS file - var itemWrappersList = Array.from(itemWrappers); but it returns [ ] when i log it after loading the page – ConfusedSpark Oct 05 '21 at 19:51
  • What do you expect `itemWrappers = itemWrappers;` to do? – Barmar Oct 05 '21 at 19:52
  • @Barmar changed the naming of that to - ```itemWrappers1 = itemWrappers; ``` itemWrappers should ideally just be all of the itemWrappers (onload, not on the screen after filteR) which would be what the array.from returns - so itll be itemWrapperList if I can get it working – ConfusedSpark Oct 05 '21 at 19:55
  • If you're getting an empty array from that, it means you're doing it before the itemWrapper elements have been added to the DOM. – Barmar Oct 05 '21 at 19:56
  • @Barmar hmm okay, so the elements get added onload, i guess the question is then, does my JS file load before any onload functions? if so is there a way for me to get that itemWrappersList to run after? – ConfusedSpark Oct 05 '21 at 19:59
  • Yes. Codes that isn't in `onload` gets loaded before `onload` happens. – Barmar Oct 05 '21 at 20:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/237852/discussion-between-confusedspark-and-barmar). – ConfusedSpark Oct 05 '21 at 20:01

0 Answers0