user6579211
user6579211

Reputation:

Open one div at a time and close all others which are opened in VueJS

Trying to implement a show/hide description box.

If the user clicks on the first showDesc link it opens it's description box. Then if the user clicks the second showDesc link it opens it's description box and should close all the others which are opened in VueJs.

I tried something as show below.

enter image description here

Below is my code:

new Vue({
  el: "#app",
  data: {
    Show: false
  },
  methods: {
		showDesc: function() {
    		this.Show = !this.Show;
			}
  }
})
.descContainer {
  position: relative;
  padding: 24px 40px 24px 24px;
  border-top: 1px solid rgba(0, 0, 0, .08);
  display: none;
  line-height: 24px;
  background-color: #fdfdfd;
}

.descContainer.show {
  position: relative;
  padding: 24px 40px 24px 24px;
  border-top: 1px solid rgba(0, 0, 0, .08);
  display: block;
  line-height: 24px;
  background-color: #fdfdfd;
}

a.mainSmooth.showDesc {
    color: dodgerblue;
    text-decoration: underline;
    cursor: pointer;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<main id="app">
  <section>
    <article class="feedBox mainSmooth">
      <div class="feedContainer">
        <div class="feedContent">
          <h3>Title</h3>
          <div class="feedButtonContainer"></div>
          <ul class="list-inline feedExtras">
            <li class="">
              <a @click="showDesc" class="mainSmooth showDesc">show description</a>
            </li>
          </ul>
        </div>
      </div>
      <div :class="{ show: Show }" class="descContainer">
        <div>Description Text</div>
      </div>
    </article>
    <br/>
    <article class="feedBox mainSmooth">
      <div class="feedContainer">
        <div class="feedContent">
          <h3>Title</h3>
          <div class="feedButtonContainer"></div>
          <ul class="list-inline feedExtras">
            <li class="">
           <a @click="showDesc" class="mainSmooth showDesc">show description</a>
            </li>
          </ul>
        </div>
      </div>
      <div :class="{ show: Show }" class="descContainer">
        <div>Description Text</div>
      </div>
    </article>
    <br/>
    <article class="feedBox mainSmooth">
      <div class="feedContainer">
        <div class="feedContent">
          <h3>Title</h3>
          <div class="feedButtonContainer"></div>
          <ul class="list-inline feedExtras">
            <li class="">
              <a @click="showDesc" class="mainSmooth showDesc">show description</a>
            </li>
          </ul>
        </div>
      </div>
      <div :class="{ show: Show }" class="descContainer">
        <div>Description Text</div>
      </div>
    </article>
  </section>
</main>

Upvotes: 1

Views: 1580

Answers (1)

amedina
amedina

Reputation: 3426

How about in this way:

new Vue({
  el: "#app",
  data: {
  },
  methods: {
		showDesc: function(e) { 
        let allA = document.querySelectorAll("a");
        for(let a of allA) {
        	let descContainer = a.closest("article").querySelector("div.descContainer");
          descContainer.classList.remove('show');
          
        	if(a === e.target) {
          	descContainer.classList.add('show');
          } 
        }
			}
  }
})
.descContainer {
  position: relative;
  padding: 24px 40px 24px 24px;
  border-top: 1px solid rgba(0, 0, 0, .08);
  display: none;
  line-height: 24px;
  background-color: #fdfdfd;
}

.descContainer.show {
  position: relative;
  padding: 24px 40px 24px 24px;
  border-top: 1px solid rgba(0, 0, 0, .08);
  display: block;
  line-height: 24px;
  background-color: #fdfdfd;
}

a.mainSmooth.showDesc {
    color: dodgerblue;
    text-decoration: underline;
    cursor: pointer;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<main id="app">
  <section>
    <article class="feedBox mainSmooth">
      <div class="feedContainer">
        <div class="feedContent">
          <h3>Title</h3>
          <div class="feedButtonContainer"></div>
          <ul class="list-inline feedExtras">
            <li class="">
              <a @click="showDesc" class="mainSmooth showDesc">show description</a>
            </li>
          </ul>
        </div>
      </div>
      <div class="descContainer">
        <div>Description Text 1</div>
      </div>
    </article>
    <br/>
    <article class="feedBox mainSmooth">
      <div class="feedContainer">
        <div class="feedContent">
          <h3>Title</h3>
          <div class="feedButtonContainer"></div>
          <ul class="list-inline feedExtras">
            <li class="">
              <a @click="showDesc" class="mainSmooth showDesc">show description</a>
            </li>
          </ul>
        </div>
      </div>
      <div class="descContainer">
        <div>Description Text 2</div>
      </div>
    </article>
        <br/>
    <article class="feedBox mainSmooth">
      <div class="feedContainer">
        <div class="feedContent">
          <h3>Title</h3>
          <div class="feedButtonContainer"></div>
          <ul class="list-inline feedExtras">
            <li class="">
              <a @click="showDesc" class="mainSmooth showDesc">show description</a>
            </li>
          </ul>
        </div>
      </div>
      <div class="descContainer">
        <div>Description Text 3</div>
      </div>
    </article>
  </section>
</main>

Here's the fiddle.

It's just a raw idea of how it can be done. I hope it helps.

Upvotes: 0

Related Questions