Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

326
Views
make all <b-collapse> non visible in child.vue when button is clicked in parent

I'm working with BootstrapVue.

I have following situation: I have a parent.vue and a child.vue. In my parent.vue I have a v-for where I can create multiple Buttons. Each of these is triggering a b-collapse in my child.vue and each of this has multiple b-collapse as well. (see Code)

Now I need to do following: I want to close all of my b-collapse inside my child.vue when my b-collapse in my parent.vue will be closed. But I could not figure out how to do that.. (they should be closed as well when I reopen my parent.vue-collapse)

I have reduced my code to the minimum. But just for additional info I will do this.inputs.push[{id: this.id +=1}] each time adding a new Item or Element. So each of them has an unique id.

Hopefully someone can help me out!

CODE

parent.vue

<div v-for="item in inputs" :key="item.id">
  <b-button v-b-toggle="'NewItem'+item.id"></b-button>
</div>

<Child/>

<b-button @click="addNewItem()"></b-button>

child.vue

<b-collapse visible :id="'NewItem' + item.id">  //Here i need a solution
  <div v-for="element in inputs" :key="element.id">
    <b-button v-b-toggle="'Element' + element.id"></b-button>
    <b-collapse :id="'Element' + element.id>
      <div>Here is Element {{element.id}}</div>
    </b-collapse>
  </div>

  <b-button @click="addElement()"></b-button>
</b-collapse>

EDIT - Full Code:

Parent.vue

<template>
<div class="container">
  <div v-for="(item, index) in inputs" :key="item.id">
    <b-button v-b-toggle="'NewItem'+item.id" @click="closeAll()">Item {{index + 1}}</b-button>
  </div>

  <Child :idParent="item.id" :closeAllProducts="closeAllProducts" />

  <b-button @click="addNewItem()">Add new Item</b-button>
</div>
</template>

<script>

import Child from "./components/child.vue"

export default {

  components: {
    Child,
  },

  data() {
    return {
      closeAllProducts: true,
      id: 1,
      inputs: [{
        id: 1,
      }]
    }
  },

  methods: {
    addNewItem() {
      this.inputs.push({id: this.id += 1})
    },

    closeAll() {
      this.closeAllProducts = false;
    }
  }
}
</script>

Child.vue

<template>
  <b-collapse :visible="closeAllProducts" :id="'NewItem'+item.id">  
    <div v-for="(element, index) in inputs" :key="element.id">
      <b-button v-b-toggle="'Element' + element.id"></b-button>
      <b-collapse :id="'Element' + element.id">
        <div>Here is Element {{index + 1}}</div>
      </b-collapse>
    </div>

    <b-button @click="addElement()">Add new Element</b-button>
  </b-collapse>
</template>

<script>
export default {
  props: ["idParent", "closeAllProducts"],

  data() {
    return {
      id: 1,
      inputs: [{
        id: 1,
      }]
    }
  },

  methods: {
    addElement() {
      this.inputs.push({id: this.id += 1})
    }
  }
}
</script>

NEW EDIT: Added closeAllProducts - If I'm clicking my button in my parent.vue it should trigger the function to change the boolean to **false**. But when I use it like this all elements in every item will be non visible.. I need to pass a parameter with it but I could not figure out how..

over 4 years ago ยท Santiago Trujillo
1 answers
Answer question

0

One solution is to create a child prop that collapses its b-collapse elements, and have the parent control that prop:

  1. Create a Boolean prop named collapsed in the child:

    // child.vue
    export default {
      props: {
        collapsed: Boolean
      }
    }
    
  2. In addElement(), insert a visible prop to match the b-collapse's visible prop. We'll bind each item's visible to the corresponding b-collapse prop. Note we use b-collapse's v-model to bind its visible prop, which keeps the item's visible prop in sync with the actual visibility state.

    <!-- child.vue -->
    <script>
    export default {
      data() {
        return {
          inputs: [
            {
              id: 1,
              visible: false,
            },  ๐Ÿ‘†
          ],
        }
      },
      methods: {
        addElement() {
          this.inputs.push({ id: ++this.id, visible: false })
        }                                      ๐Ÿ‘†
      }
    }
    </script>
    
    <template>
      โ‹ฎ                              ๐Ÿ‘‡
      <b-collapse v-model="element.visible" โ‹ฏ>
         <div>Here is Element {{ index + 1 }}</div>
      </b-collapse>
    </template>
    
  3. Add a watcher on the collapsed prop in the child. This watcher will set each element's visible prop to false only when collapsed is true:

    // child.vue
    export default {
      watcher: {
        collapsed(collapsed) {
          if (collapsed) {
            this.inputs.forEach(input => input.visible = false)
          }
        },
      }
    }
    
  4. To ensure each element's ID is globally unique in the context of the parents, incorporate the parent ID into the child IDs:

    <!-- child.vue -->
    <div v-for="(element, index) in inputs" :key="element.id">
      <b-button v-b-toggle="'Element' + idParent + '.' + element.id" โ‹ฏ>
        โ‹ฏ                                   ๐Ÿ‘†
      </b-button>
      <b-collapse :id="'Element' + idParent + '.' + element.id" โ‹ฏ>
        โ‹ฏ                             ๐Ÿ‘†
      </b-collapse>
    </div>
    
  5. In the parent's addNewItem(), add a collapsed property. We'll bind each child's collapsed prop to this new property, and toggle it upon a button-click:

    <!-- parent.vue -->
    <script>
    export default {
      data() {
        return {
          inputs: [
            {
              id: 1,
              collapsed: false,
            },  ๐Ÿ‘†
          ],
        }
      },
      methods: {
        addNewItem() {
          this.inputs.push({ id: ++this.id, collapsed: false })
        }                                      ๐Ÿ‘†
      }
    }
    </script>
    
    <template>
      โ‹ฎ
      <div v-for="(item, index) in inputs" :key="item.id">
        <b-button @click="item.collapsed = !item.collapsed">
          โ‹ฏ                       ๐Ÿ‘†
        </b-button>
        <Child :idParent="item.id" :collapsed="item.collapsed" />
      </div>                                          ๐Ÿ‘†
    </template>
    

demo

over 4 years ago ยท Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
ยฉ 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!