0
votes

I wanted to build a custom-filter for my v-data-table (containing books) which

  • allows to narrow down search results by entering multiple space separated search terms
  • separates compound words with hyphens into separate search terms
  • all search terms should appear in the item, but they can appear in different columns/props, so searching for "tolkien hobbit" would give you back a book with title "The Hobbit" and author "J.R.R. Tolkien"

I figured that using "value" in the customFilter function would require all of the search terms to appear in the same prop, so I used item instead, but vuetify gives the complete item to the filter function, not only the filterable headers of the data table, which will yield unwanted search results, so I'm re-initializing the item to get rid of unwanted props.

methods: {
  customFilter(value, search, item) {
          item = {
            number: item.number,
            title: item.title,               
            author: item.author
          };

          const haystack = Object.values(item).join().toLowerCase();                
          let s = search.toString().toLowerCase(); 
          let needles = s.replace('-',' ').split(' ');

          return needles.filter(needle => haystack.indexOf(needle) >= 0).length == needles.length               
        }
}

My questions

  • Is there a way to tell vuetify to only give the filterable header props to the custom-filter as item?
  • if not, is there a better way to get rid of unwanted props than re-initializing? (destructuring with spread operator also works, but is longer and eslint nags about unused vars)
  • Is there maybe even a way to realize my requirements with "value" instead of "item"? (I don't see how)
1
I've worked out sth. in the meantime, just if someone else end up here:bdasliva83

1 Answers

0
votes

Answering my own questions:

  • No, you can't tell vuetify to pass only specific props of the item to the custom filter, you just pass the item object
  • I get rid of unwanted props by filtering / reducing now
  • value only gives you one value, presumably it defaults to the first column, but I'm not 100% sure

My solution now:

methods: {
itemFilterMultipleSearchTermsAnd(value, search, item) {     
  const nonSearchableColumns = ["excludedPropName1", "excludedPropName2"];
  const reducedObject = Object.keys(item)
    .filter((key) => !nonSearchableColumns.includes(key))
    .reduce((res, key) => ((res[key] = item[key]), res), {});

  const haystack = Object.values(reducedObject)
    .join()
    .toLowerCase();
  let s = search.toString().toLowerCase();
  let needles = s.replace("-", " ").split(" ");

  return (
    needles.filter((needle) => haystack.indexOf(needle) >= 0).length ==
    needles.length
  );
}

}