Home > Software engineering >  How to reset toggled item(s) back to default state
How to reset toggled item(s) back to default state

Time:12-07

I'm working no an app that onclick shows a div. Now if someone clicks the button to open another div, I want to hide the previously opened div. So far I was able to get this functionality by manually setting this.movies[index].open = false and this.movies[index].hideImg = true however - if there were thousands of entries this would be impossible to solve with this solution. I'm talking about the toggle(id) method

<template>
  <div v-for="(movie, index) in movies" :key="index" >
    <div >
      <h3>{{ movie.name }}</h3>
      <p >{{ movie.duration }}</p>

      <button @click="toggle(movie.id)" >
        <p v-if="movie.hideImg">►</p>
        <p v-else>▼</p>
      </button>
    </div>
    <div v-if="movie.open">
      <video controls="controls" autoplay name="media">
        <source
          :src="require(`@/assets/movie${index   1}.mp4`)"
          alt="video"
          type="video/mp4"
          width="500px"
          autoplay
        />
      </video>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      movies: [
        {
          name: "Windy Highway",
          duration: "15 seconds",
          hideImg: true,
          open: false,
          id: 1,
          movieStart: "0:00",
          movieMid: "0.08",
          movieEnd: "0:15",
        },
        {
          name: "Sunny Station",
          duration: "32 seconds",
          hideImg: true,
          open: false,
          id: 2,
          movieStart: "0:00",
          movieMid: "0.16",
          movieEnd: "0:32",
        },
        {
          name: "Abstract Material",
          duration: "9 seconds",
          hideImg: true,
          open: false,
          id: 3,
          movieStart: "0:00",
          movieMid: "0.05",
          movieEnd: "0:09",
        },
        {
          name: "Pumpkin Drilling",
          duration: "17 seconds",
          hideImg: true,
          open: false,
          id: 4,
          movieStart: "0:00",
          movieMid: "0.09",
          movieEnd: "0:17",
        },
      ],
    };
  },
  methods: {
    toggle(id) {
      
      this.movies[0].open = false;
      this.movies[1].open = false;
      this.movies[2].open = false;
      this.movies[3].open = false;
      this.movies[0].hideImg = true;
      this.movies[1].hideImg = true;
      this.movies[2].hideImg = true;
      this.movies[3].hideImg = true;

      this.movies[id - 1].hideImg = !this.movies[id - 1].hideImg;
      this.movies[id - 1].open = !this.movies[id - 1].open;
      console.log(
        this.movies[id - 1].movieStart,
        "-",
        this.movies[id - 1].movieMid,
        "-",
        this.movies[id - 1].movieEnd
      );
    },
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin: 60px auto 0;
}
.watchBtn {
  background-color: red;
  border-radius: 10px;
  margin-left: 10px;
  height: 20px;
  display: flex;
  align-items: center;
}
.watchBtn:hover {
  background-color: rgb(255, 191, 107);
  cursor: pointer;
}
.movieContainer {
  margin: 5px auto;
  display: flex;
  flex-direction: column;
}
.center {
  margin: 0 auto;
  display: flex;
  align-items: center;
}
.duration {
  margin: 0 5px 0 10px;
}
.movieContainer video {
  width: 500px;
}
</style>

here's StackBlitz

CodePudding user response:

...
toggle(id) {
  this.movies.forEach(movie => { movie.open = false, movie.hideImg = true })
  this.movies[id - 1].hideImg = false;
  this.movies[id - 1].open = true;
},
...

I would also make the following changes:

  • change v-if to v-show, it's faster to show/hide DOM instead of adding/removing
  • Remove hideImg, and base all logic on a single value open
  • save the current state, so you can close the currently open item again

StackBlitz

<template>
  <div v-for="(movie, index) in movies" :key="index" >
    <div >
      {{ movie.name }}
      <button @click="toggle(movie.id)" >
        <p v-show="!movie.open">►</p>
                         
  • Related