Can't select item in b-dropdown vuejs - vue.js

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: ''
}
}

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 dynamic ref show dropdown

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.

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
}
}

Select element inside dropdown menu issue

I am currently experimenting in Element UI a beautiful VueJS frame for ui.
I am having issue when putting an select element inside a dropdown menu because when I select an item inside the select element it will close the dropdown also.
How should I make the dropdown stay whenever I select an item in select element?
Here is the sample demo. fiddle
https://jsfiddle.net/vy70ogbz/
I got the same problem and I solved it by small hack: when a dropdown is open I set disabled="true" property to the trigger button.
<el-button
:disabled="dropdownIsOpen"
slot="button"
>Open</el-button>
It works because in the source code we have condition for this case
https://github.com/ElemeFE/element/blob/dev/packages/dropdown/src/dropdown.vue#L121
Example: click
Why dont you use a menu to achieve this. I find it is more flexible, you can use the menu-trigger="click" attribute to toggle the menu only when clicked. like this
<el-menu
:default-active="activeIndex"
mode="horizontal"
menu-trigger="click"
#select="handleSelect">
<el-submenu
class="sub-menu-more">
<template slot="title">
<b>Click to dropdown</b>
</template>
<el-menu-item
index="1">
<span >Team</span>
</el-menu-item>
<el-menu-item
index="2">
<span >Product</span>
</el-menu-item>
<el-menu-item
index="3">
<span >item</span>
</el-menu-item>
<el-menu-item
index="4">
<el-select v-model="value" placeholder="Select">
<el-option
:label="'test1'"
:value="'test1'">
</el-option>
<el-option
:label="'test1'"
:value="'test1'">
</el-option>
<el-option
:label="'test1'"
:value="'test1'">
</el-option>
</el-select>
</el-menu-item>
</el-submenu>
</el-menu>
see fiddle
You can prevent the dropdown from hiding.
Use the following code in your template
<el-dropdown ref="dropdown" trigger="click">
<span class="el-dropdown-link">
Dropdown List<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>Action 1</el-dropdown-item>
<el-dropdown-item>Action 2</el-dropdown-item>
<el-dropdown-item>Action 3</el-dropdown-item>
<el-dropdown-item>
<el-select v-model="selectData" #change="handleChange">
<el-option value="1">Option 1</el-option>
<el-option value="2">Option 2</el-option>
<el-option value="3">Option 3</el-option>
</el-select>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
And this in your script
new Vue({
data: {
selectData: null
},
methods: {
handleChange() {
this.$nextTick(() => {
this.$refs.dropdown.show();
});
}
}
}).$mount('#app')

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
}