[Solved] Tree filter: how to filter the tree from a button click in addition to search text



  • Hi. I have a tree that filters based on a search input. All good.

    I also want to filter based on a button that relates to a status property of each node. So, when I click the button, filter the tree nodes for status === 1 (for example)

    I have added the status filter to the custom filter method and as long as I type something into the search box the status filter works perfectly.

    But… how do I tell the tree to start filtering ONLY from the button click? i.e. even if the search input is empty, filter on status?

    I could not find a myTree.runFilter() method and as I am pretty new to Vue I could not work it out from the Quasar tree source code.

    Thanks,
    Murray



  • This post is deleted!


  • So, I want to filter the tree by both a Search input box and / or a value passed by a button click that represents a status property on the leaf nodes. (Actually, there are 5 such buttons, each representing a different status, but for simplicity’s sake we pretend there is just one status value.)

    This is the stripped-down solution.

    <!-- The search input box -->
    <q-input
      v-model="searchBox"
      label="Filter"
    ></q-input>
    
    <!-- The button to filter where node status = 1 -->
    <q-button @click="onClickStatus(1)">
      Status 1
    </q-button>
    
    <!-- The tree -->
    <q-tree
      ref="projectTree"
      :filter="filterTrigger"
      :filter-method="customFilterMethod"
     ....
    ></q-tree>
    
    export default {
      data () {
        return {
          searchBox: '',
          filterTrigger: 'true',
          statusFilter: ''
          ....
        }
      },
    
      watch: {
        // Whenever the searchBox property changes, 
        // use it to trigger the tree filter's reactivity
        // by assigning its value to the 
        // filterTrigger property. 
        // Actually, the value we assign here is irrelevant.
        searchBox: function (newVal, oldVal) {
          this.filterTrigger = newVal
        }
      },
    
      methods: {
        onClickStatus (statusId) {
          // This method is more complicated than this in reality,
          // but basically we track which of the 5 status' were clicked
          this.statusFilter = statusId
        },
    
        customFilterMethod (node, filterTrigger) {
          // The filterTrigger param is ignored in here.
    
          // Instead, we use the contents of the search box input ...
          const searchBoxText = this.searchBox.toLowerCase()
    
          const matchedNodeLabel = (node.label && node.label.toLowerCase().indexOf(searchBoxText) > -1)
    
          // And any status button that was clicked ....
          let matchedStatus = true
    
          if (this.statusFilter !== '') {
            // if the node status is in the list of filters, match it
            // Very simplified example code:
            matchedStatus = (this.statusFilter.indexOf(node.status) > -1)
          }
    
          // In our context we always AND the filters
          return (matchedNodeLabel && matchedStatus)
        }
      }
    }
    

    Now, if there is something typed into the search box, or if a status button is clicked, either or both of those values will be used to filter the tree nodes. Yay! 🙂


Log in to reply