6
votes

In the tree view component, I would like to open all the nodes where there is some search text. But the expected is not happening.

Desired output: Open all the parents where there's some search text. enter image description here Here's the codepen for the same.

https://codepen.io/anon/pen/MdxPKN?&editors=101

<div id="app">
  <v-container grid-list-md>
    <v-layout wrap>
      <v-flex xs6>
        <v-text-field label="search" v-model="search" box />

        <v-treeview :items="tree"
          :search="search"
          active-class="grey lighten-4 indigo--text"
          item-key="name"
          open-on-click
          :open-all="{searchLength}>0?true:false"
          hoverable />
      </v-flex>
    </v-layout>
  </v-container>
</div>
3
Whats not happing?, working fine in the fiddle from what I can see. - Lawrence Cherone
Please check the image that I've added now. Tree should be open while there's some search text. - SatishV
Reading the documentation , I don't think that possible When true will cause all branch nodes to be opened when component is mounted . - Core972
You need to work with the open prop, that should work - Borjante
So you basically gonna have to provide the serach functionality by yourself, pass the filtered elements to the treeview, and the pass the keys of the filtered elements as an array to the open prop. That should work - Borjante

3 Answers

6
votes

So it got a little tricky, you can't use the builtin search functionality, but there's an acceptably easy workaround.

You basically have to implement the filter yourself, and just send the items you need to v-treeview.

Then you can create another computed property from your filteredElements which just return the key and pass it to the :open property of treeview.

Made a codepen for you.

https://codepen.io/brafols/pen/XwGQov

4
votes

Here is an approach based off your example that works with the built-in search.

https://codepen.io/totalhack/pen/KKzzXvr

I added a search input event handler that uses the treeview updateAll function to open all items when a search starts. It then returns to the previous open state when the search text is empty. Note that if you use the built-in clearable prop of v-text-field you may need to handle events from that too (I haven't tried it).

<div id="app">
  <v-app id="inspire">
    <v-container>
      <v-layout>
        <v-flex xs6>        
          <v-text-field
            label="Search"
            v-model="search"
            @input="handleSearch"
            >         
          </v-text-field>
          <v-treeview 
            ref="tree"
            :items="tree"
            :search="search"
            :open.sync="open"
            open-on-click
            hoverable>
          </v-treeview>
        </v-flex>
      </v-layout>
    </v-container>
  </v-app>
</div>
new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data(){
    return{
      search: '',
      open: [1],
      allOpened: false,
      lastOpen: [],
      tree: [
        {
          id: 1,
          name: 'Applications',
          children: [
            { id: 2, name: 'Calendar' },
            { id: 3, name: 'Chrome' },
            { id: 4, name: 'Webstorm' }
          ]
        },
        {
          id: 10,
          name: 'Languages',
          children: [
            { id: 20, name: 'English' },
            { id: 30, name: 'French' },
            { id: 40, name: 'Spannish' }
          ]
        }
        
      ]
    }
  },
  methods: {
    handleSearch: function (val) {
      if (val) {
        if (!this.allOpened) {
          this.lastOpen = this.open;
          this.allOpened = true;
          this.$refs.tree.updateAll(true);
        }
      } else {
        this.$refs.tree.updateAll(false);
        this.allOpened = false;
        this.open = this.lastOpen;
      }
    }
  }
})
0
votes

I modified totalhack's solution slightly to get what I wanted. Basically if there is a string in the search box I call updateAll(true).

<template>
<v-card>
  <v-card-title>File Open</v-card-title>
  <v-sheet class="pl-4 pr-4">
    <v-text-field
      label="Search"
      v-model="search"
      @input="handleSearch"
      flat
      solo-inverted
      hide-details
      clearable
      clear-icon="mdi-close-circle-outline"
    ></v-text-field>
  </v-sheet>
  <v-card-text>
    <v-container>
      <v-treeview
        ref="tree"
        :items="tree"
        :search="search"
        open-on-click
        return-object
        activatable
        dense
      >
        <template v-slot:prepend="{ item, open }">
          <v-icon v-if="!item.file">
            {{ open ? 'mdi-folder-open' : 'mdi-folder' }}
          </v-icon>
          <v-icon v-else>
            {{ 'mdi-language-ruby' }}
          </v-icon>
        </template></v-treeview>
    </v-container>
  </v-card-text>
  <v-card-actions>
    <v-btn color="primary" text @click="open()">Ok</v-btn>
    <v-spacer></v-spacer>
    <v-btn color="primary" text @click="show = false">Cancel</v-btn>
  </v-card-actions>
</v-card>
</template>

<script>
export default {
  data() {
    return {
      tree: [],
      search: null,
    }
  },
  methods: {
    handleSearch(input) {
      if (input) {
        this.$refs.tree.updateAll(true)
      } else {
        this.$refs.tree.updateAll(false)
      }
    },
  },
}
</script>