Rick Reumann
Rick Reumann

Reputation: 393

Vuetify expansion panels - how can I capture onOpen/Show onClose/Collapse?

I'm new to using Vue.js and Vuetify, I'm messing around with expansion panels, and in my case, I need to be able to destroy some ajax processing taking place when the user switches to another panel. While using bootstrap-vue I was able to handle this with the "show" event and set the value of a watched property (to the id of the panel selected), which each panel could check to see if matches their panel id, and if it didn't, it could cancel some things. (In my case I have some polling going on and I'd like to kill the polling for the panels not being displayed.)

Similarly, when the panel is opened again I'd like to resume some polling.

Thanks for some help.

Upvotes: 10

Views: 12028

Answers (6)

Ueda Takeyuki
Ueda Takeyuki

Reputation: 871

With <v-expansion-panels>, it knows whether or not the child <v-expansion> gets openning. So how about following?

<template>
  <v-expansion-panels v-model="panel">
    <v-expansion-panel>
    </v-expansion-panel>
  </v-expansion-panels v-model="panel">
</template>

<script>
export default {
  data: () => ({
    panel: "",
  }),
  computed: {
    isPanelOpened: function(){
      if (this.panel === 0){
        return true
      } else {
        return false
      }
    }
  }
}
</script>

Upvotes: 0

Jackson
Jackson

Reputation: 483

<template>
  <v-expansion-panels>
    <v-expansion-panel @click="handleClick">
      
    </v-expansion-panel>
  </v-expansion-panels>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false,
    };
  },

  methods: {
    handleClick() {
      this.isOpen = !this.isOpen;
      
      if (this.isOpen) {
        // Do something
      }
    },
  },
};
</script>

Upvotes: 0

Aviz
Aviz

Reputation: 41

*One-panel one solution

If isOpenExpan is true the panel is open, if false the panel is closed

If isOpenExpan is true the panel is open, if false the panel is closed

Upvotes: 0

tesla_coil
tesla_coil

Reputation: 191

Darkproduct almost got it.. but i think the correct code should be using event.currentTarget.classList.contains('v-expansion-panel-header--active') and not event.target.classList.contains('v-expansion-panel-header--active')

so the code should be

<template>
  <v-expansion-panel class="expanel" @click="onExpansionPanelClick">
    <v-expansion-panel-header>
    </v-expansion-panel-header>

    <v-expansion-panel-content>
    </v-expansion-panel-content>
  </v-expansion-panel>
</template>

<script>
export default {
  name: "ExPanel",
  components: {},
  props: {},
  data: function() {
    return {}
  },
  methods: {
    onExpansionPanelClick(event) {
      if(event.currentTarget.classList.contains('v-expansion-panel-header--active')) {
        console.log("Panel is closing/now closed.")
      } else {
        console.log("Panel is opening/now open.")
      }
    }
  }
}
</script>```

Upvotes: 6

Darkproduct
Darkproduct

Reputation: 1237

Not sure, if this is a good way to do this in Vue, but here is my solution.

<template>
  <v-expansion-panel class="expanel" @click="onExpansionPanelClick">
    <v-expansion-panel-header>
    </v-expansion-panel-header>

    <v-expansion-panel-content>
    </v-expansion-panel-content>
  </v-expansion-panel>
</template>

<script>
export default {
  name: "ExPanel",
  components: {},
  props: {},
  data: function() {
    return {}
  },
  methods: {
    onExpansionPanelClick(event) {
      if(event.target.classList.contains('v-expansion-panel-header--active')) {
        console.log("Panel is closing/now closed.")
      } else {
        console.log("Panel is opening/now open.")
      }
    }
  }
}
</script>

The important bit is the onExpansionPanelClick(event) function, which does all the magic. I wanted a solution within v-expansion-panel and not v-expansion-panels because I modeled each panel as its own component.

Upvotes: 1

Rick Reumann
Rick Reumann

Reputation: 393

Got help from jvanst in discord.

Was simpler than I thought. Bind v-model on expansion panel:

 <v-expansion-panel v-model="panelIndex">

Then I was able to watch for that property and you'll have the index of the panel selected.

props: {
  stuff: ''
  panelIndex: -9
},
watch: {
  panelIndex: function() {
    console.log("watch panelIndex id: " + this.panelIndex) 
    //if this panelIndex matches this component's index.. do stuff since we're selected
  }
}

In my case, my panel was a separate component (not static content) and needed to refresh if it was selected, so I passed in that index as a prop and watched for it, then compared to the original index position of the panel that it was set up with. If they were the same it was a match, and that was the correct panel to be refreshed.

Upvotes: 12

Related Questions