Vue dynamic ref show dropdown - vue.js

I am using VueJS and want to use right click event to display the dropdown list. But I have multiple dropdown so need to use dynamic ref. How can I show the dropdown that I want when right click?
<div class="info" #contextmenu="handler($event)">
...
<b-dropdown size="sm" text="…" variant="transparent" no-caret :ref="`dropdown-${id}`" :item1="this.item1" :item2="this.item2">
<b-dropdown-item #click="showDetails(item1, item2)">Send</b-dropdown-item>
</b-dropdown>
</div>
handler(e) {
this.$ref.dropdown.show();
e.preventDefault();
}

You can send another parameter to the handler function that will be the value of the $ref you want to open:
<div class="info" #contextmenu="handler($event, id)">
...
<b-dropdown size="sm" text="…" variant="transparent" no-caret :ref="`dropdown-${id}`" :item1="this.item1" :item2="this.item2">
<b-dropdown-item #click="showDetails(item1, item2)">Send</b-dropdown-item>
</b-dropdown>
</div>
handler(e, id) {
this.$ref[`dropdown-${id}`].show();
e.preventDefault();
}
By the way you can use .prevent modifier instead of using the e.preventDefault:
<div class="info" #contextmenu.prevent="handler(id)">
// your methods
handler(id) {
this.$ref[`dropdown-${id}`].show();
}

You could use e.target to get the element (button) you just clicked and after that use a switch statement to determine which dropdown to show.

Related

Vue Bootstrap, how to interact with plus/minus icon on dynamic generated collapse content separately

I have a VueJS view that creates collapsed contents using Bootstrap Vue Collapse Component.
The data is dynamic and can contains hundreds of items, which is why you see in the code below it was created via a v-for loop in Vue.
<div class="inventory-detail" v-for="(partNumberGroup,index) in inventory" :key="index" >
<b-button block v-b-toggle="partNumberGroup.partNumber" v-bind:id="partNumberGroup.partNumber" variant="primary"
#click="(evt) =>{isActive = !isActive && evt.target.id == partNumberGroup.partNumber}">
<i v-bind:id="partNumberGroup.partNumber" class="float-right fa" :class="{ 'fa-plus': !isActive, 'fa-minus': isActive }"></i>
{{ partNumberGroup.partNumber }}
</b-button>
<div class="inventory-detail__card" v-for="item in partNumberGroup.items">
<b-collapse v-bind:id="partNumberGroup.partNumber" >
<b-card>
<!--Accordion/Collapse content -->
</b-card>
</b-collapse>
</div>
</div>
This works fairly well in that I can individually expand and collapse each content separately. However, the one issue I'm facing is each time I click the icon fa-minus (-) orfa-plus (+), all of them changed as per the images below.
Any tips on how I should implementing this? in my code I tried the dynamic CSS class switching but I still lack the ability to switch on specific element.
I feel like the solution to this is to somehow conditionally apply dynamic CSS class or somehow able to use the attribute 'aria-expanded'.
You can try something like this. Whenever somebody clicks on the icon, set its index as activeIndex (using the setActiveIndex method). Then you can set the class accordingly by comparing the activeIndex with current index
<i
#click="setActiveIndex(index)"
v-bind:id="partNumberGroup.partNumber"
class="float-right fa"
:class="{ 'fa-plus': !isActive(index), 'fa-minus': isActive(index) }">.
</i>
then in the script part:
...
data() {
return {
activeIndex: -1
}
},
methods: {
/* set active index on click */
setActiveIndex(index) {
this.activeIndex = index;
},
/* check if index is active or not */
isActive(index) {
return index === this.activeIndex;
}
}

Vue - How to change dropdown text properly?

I have Vue drop-down.
<b-dropdown id="dropdown-1" text= "UserName" class="m-md-2" >
<b-dropdown-item class="dropdown-link">Log out</b-dropdown-item>
</b-dropdown>
I need t change value of drop down. In my case it's UserName
I only found this way:
document.getElementById("dropdown-1").childNodes[1].innerHTML="new value"
I know it's not correct way but I didn't find correct way (via the API or something like that). This method does not work too:
text= "{{ variable }}"
Any ideas?
You can bind a dynamic value for text prop on <b-dropdown> and change it with the click event of <b-dropdown-item>
<b-dropdown :text="buttonTitle">
<b-dropdown-item #click="buttonTitle = 'new value'">Log out</b-dropdown-item>
</b-dropdown>
//script
data () {
return {
buttonTitle: 'Username'
}
}
MuratK is probably right, however I understand that you want to bind the dropdown item, not the parent element. You could do so with a v-for and text binding, like:
<b-dropdown id="dropdown-1" class="m-md-2" >
<b-dropdown-item v-for="item in items" v-text="item"></b-dropdown-item>
</b-dropdown>
Then, in your data define 'items' as an array of strings, such as ['log out', 'preferences', 'sign it']. You can also use this syntax, it does the same in your example:
<b-dropdown-item v-for="item in items">{{ item }}</b-dropdown-item>
To make text dynamic, you should bind it to a variable of your Vue component instance. An HTML attribute can be made dynamic and bound to a variable by using the : prefix before the attribute name (which is a shorthand of v-bind:)
Given :
<b-dropdown id="dropdown-1" :text="variable" class="m-md-2" >
<b-dropdown-item class="dropdown-link">Log out</b-dropdown-item>
</b-dropdown>
In the component you should have the corresponding variable declaration :
data() {
return {
variable: '' // Variable initialisation
}
}

Vuejs Display certain div when radio button is checked

How can I display divA when radio button A is checked and display divB when radio button B is checked?
<b-form-radio value="A">A</b-form-radio>
<b-form-radio value="B">B</b-form-radio>
<!-- divA -->
<div>
...
</div>
<!-- divB -->
<div>
...
</div>
Assuming your custom radio control (b-form-radio) supports v-model, you can do this:
<b-form-radio v-model="selected" value="A">A</b-form-radio>
<b-form-radio v-model="selected" value="B">B</b-form-radio>
<!-- divA -->
<div v-show="selected === 'A'">
...
</div>
<!-- divB -->
<div v-show="selected === 'B'">
...
</div>
Additionally, in your component data function, you need to make selected as a reactive property:
{
data() {
return {
// Initially selected will be null
// to hide both the div
selected: null
}
}
}
In summary, it is the combination of v-show directive together with v-model. Also, you can use v-if instead of v-show if you do not want other div to be rendered at all on the page.

How to get selected row index on #change event of child Select Dropdown in Element UI?

I'm generating a list of multiple input elements in which one is <el-select>. On changing this select menu, I'm getting value bounded with that select. But here, question is, I also want to get index/row number of the parent v-for items.
You can understand what I meant from the following code:
<el-form-item v-for="(domain, index) in Prescription.domains">
<div class="col-md-2" v-if="medicineIsSelected === true">
<small>Select Brand:</small>
<el-select v-model="domain.SelectedBrand" clearable placeholder="Select" #change="updateDropdowns"> <!-- Here I want to pass {{index}} also -->
<el-option
v-for="item in selectedMedicineMetaInfo.BrandName"
:key="item.value.name"
:label="item.value.name"
:value="item.value.rxcui">
</el-option>
</el-select>
</div>
</el-form-item>
As you can see from above code, I want to pass index in updateDropdowns.
I tried passing updateDropdowns(index), here I got the index number but lost the selected value of that dropdown. How can I pass both?
Here is the solution :
#change="updateDropdowns(index, $event)"
you can use $event to reference current event.
you can use custom event to manage this
<div>
<child #clicked="ongetChild"></child>
</div>
== child ==
watch your dropdown changes
export default {
watch: {
'domain.SelectedBrand':function(value) {
this.$emit('clicked', 'value')
}
}}
=== parent ==
export default {
ongetChild (value) {
console.log(value) // someValue
}
}
}
Use #change="updateDropdowns" in el-select tag
Use vue method:
updateDropdowns(index) {
this.selectedMedicineMetaInfo.BrandName[index-1]; // this gives selected option details
}

Can't select item in b-dropdown vuejs

Hy I'm creating a simple dropdown using bootstrap-vue in vuejs. The Code in my component is like this :
<b-col sm="2">
<b-dropdown :text="selectedItem" v-model="selectedItem">
<b-dropdown-item>Action</b-dropdown-item>
<b-dropdown-item>Another action</b-dropdown-item>
<b-dropdown-item>Something else here</b-dropdown-item>
</b-dropdown>
{{selectedItem}}
</b-col>
...
...
...
data () {
return {
selectedItem: ''
}
}
The problem is I can't select any item from dropdown item. Is there something that I missed here ?
Thanks in advance
Reference :
https://bootstrap-vue.js.org/docs/components/dropdown
This is a dropdown for navigation, not a select elem for forms. It does not support v-model and does not act like a form input.
You could use select instead, or if you still want to use dropdown as a form select, you could add click handler to control it.
For e.g.
<b-dropdown :text="selectedItem">
<b-dropdown-item #click="selectedItem='Action'">Action</b-dropdown-item>
<b-dropdown-item #click="selectedItem='Another action'">Another action</b-dropdown-item>
<b-dropdown-item #click="selectedItem='Something else here'">Something else here</b-dropdown-item>
</b-dropdown>
https://codesandbox.io/s/zky4j0zx94
I don't think a b-dropdown does what you think it does.
Bootstrap dropdowns are like menus. They don't have v-models.
What you seem to be needing is a Form Select instead:
<b-col sm="2">
<b-form-select v-model="selectedItem">
<option value="Action">Action</option>
<option value="Another action">Another action</option>
<option value="Something else here">Something else here</option>
</b-form-select>
<div>selectedItem: <strong>{{ selectedItem }}</strong></div>
</b-col>
...
...
...
data () {
return {
selectedItem: ''
}
}