Select element inside dropdown menu issue - vue.js

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')

Related

vue 's v-show doesn't show up as expected

I am using vue to make a menu which can show and hide the description when click the title.
The original menu is like this showing the title
The expanded menu is like this expanding the menu description
<li class="cursor-pointer p-2 flex" v-for="(menu, index) in menus" :key="index" >
<div class="w-full flex items-center justify-between px-2" #click="handleSelect(menu,index)">
<div class="text-sm w-full ">
<i class="el-icon-document" ></i> {{ menu.name }}
</div>
</div>
<!-- menu show and hide-->
<ul class="py-4 px-1 rounded-b border-gray-100" v-show="menu.showed">
{{ menu.description }}
</ul>
</li>
handleSelect(menu,index){
console.log('select',index,menu.showed);
this.menus[index].showed=!menu.showed
},
menus:[
{
name:'Introduction',
showed: false,
decription:''
},
{
name:'Feedback Is Important',
showed: false,
decription:''
},
{
name:'Client Briefing and Debriefing',
showed: false,
decription:''
},
]
my expected result is that the expanded status of the menu could show and hide when clicking the menu title. However, clicking the first menu could change the 'showed' variable but doesn't show the expansion, only clicking the second menu will show the first menu.
It seems like the v-show not working, any solution or idea to solve it or better way to deal with menu show-up.
Your data needs to be reactive. Put your menus array inside the data section when using options API , or inside a setup script when using composition API

Collapsing vertical menu in element.io

I try to create a layout with element.io which has a collapsing sidebar menu.
It works quite well, the only problem is that I do not gain anything since the width of the menu and the content part are fixed.
My code looks like this:
<template>
<el-row>
<el-col :span="4">
<template>
<el-menu :router="true"
:default-active="$route.path"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
:collapse="isCollapse"
class="el-menu-vertical-demo"
>
<template v-for="rule in routes">
<el-menu-item :index="rule.path">
<i :class="rule.icon"></i>
<span slot="title">{{ rule.name }}</span>
</el-menu-item>
</template>
</el-menu>
</template>
</el-col>
<el-col :span="20">
<el-row>
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px;">
<el-radio-button :label="true" :disabled="isCollapse" border>
<i class="fas fa-caret-left"></i>
</el-radio-button>
<el-radio-button :label="false" :disabled="!isCollapse" border>
<i class="fas fa-caret-right"></i>
</el-radio-button>
</el-radio-group>
</el-row>
<el-row>
<router-view></router-view>
</el-row>
</el-col>
</el-row>
</template>
<script>
export default {
data() {
return {
routes: this.$router.options.routes,
activeLink: null,
isCollapse: false
};
},
mounted: function () {
},
methods: {
}
};
</script>
How can I fix it so the content block will occupy 100% of the available width?
Ok, I found a simple solution.
First, I moved to element-io elements. The menu is now embedded inside el-aside tag, while the main part is embedded inside an el-container tag.
Second, I added a dynamic css class to the el-aside tag:
<el-aside v-bind:class="[isCollapse ? 'menu-collapsed' : 'menu-expanded']">
Now, if you don't want to mess around with transitions, simply add to the el-menu component :collapse-transition="false" and that's it!

bootstrap vue all b-dropdown-item with router link are active

I'm really enjoying Vue and Bootstrap Vue - very nice. However, one small issue - here's my template:
<template>
<div >
<b-dropdown variant="link" size="lg" no-caret>
<template slot="button-content">
<img src="../assets/logo.png">
</template>
<div v-for="row in navOptions" :key="row.id">
<b-dropdown-item v-bind:to="row.url" >{{ row.text }}</b-dropdown-item>
</div>
<b-dropdown-item>User</b-dropdown-item>
</b-dropdown>
</div>
</template>
The generated html for the items in the v-for loop is:
<a data-v-6949e825="" href="/xxxx/map" class="dropdown-item active" role="menuitem" target="_self">Map</a>
My problem is the "active" that is added to the class, it looks poor:
and isn't relevant as the items are not active.
I have the same issue with <b-nav-item>
Is there bootstrap vue way to disable 'active'?
You can do something like this:
<router-link to="/" tag="li" active-class="active" exact><a>Home</a></router-link>
This is going to create an tag with the active property and is going to change on the bases of the route.
If you are creating nested routes like /something/somethingelse is order to add the active class at /something li you need to add the exact property
For me does not work. The solution that worked for me:
<b-dropdown-item :to="{ path: '/new-task' }">New Task</b-dropdown-item>
More here: https://github.com/bootstrap-vue/bootstrap-vue/issues/3066#issuecomment-491258662

Dayspan Vuetify: Add a button inside day cell

I'm working on a project based on Dayspan Vuetify library (
https://github.com/ClickerMonkey/dayspan-vuetify ).
I don't know how i can add a button inside each day cell. Someone help will be welcome!
Live Demo
You can put whatever you want in the template (see the button):
https://github.com/ClickerMonkey/dayspan-vuetify-example/blob/master/src/App.vue
<template slot="eventTimeTitle" slot-scope="{calendarEvent, details}">
<div>
<v-icon class="ds-ev-icon"
v-if="details.icon"
size="14"
:style="{color: details.forecolor}">
{{ details.icon }}
</v-icon>
<v-btn outline #click="doSomething" color="indigo">Button</v-btn>
<strong class="ds-ev-title">{{ details.title }}</strong>
</div>
<div class="ds-ev-description">{{ getCalendarTime( calendarEvent ) }}</div>
</template>
Add a method for the click:
doSomething(e) {
console.log(e);
alert('clicked')
}

What is the best way to propagate event to few component instance in Vue Js?

I need to implement folowing behavior->
I have the list with simple elements (just text). In elements i put the button "edit", that open edit element form on same place.
I have "add" button on top of list, that open same form.
I'd like to: when user click on "add" or "edit" another opened forms close. Also forms closed after sending request to server..
Sorry for my English! )
It looks like that:
List and add element form:
<template>
<el-row>
<el-col :span="24">
<el-button type="text" #click="show_add_form = true">Добавить</el-button>
<edit-dict-element-form
v-bind:dict="dictName"
v-if="show_add_form"
v-on:closeAddForm="show_add_form = false">
</edit-dict-element-form>
</el-col>
<el-col :span="24"
v-for="(element, index) in dict"
v-bind:key="element.id">
<dict-element
v-bind:element="element"
v-bind:index="index"
v-bind:dict="dictName">
</dict-element>
</el-col>
</el-row>
Element component:
<template>
<div>
<el-card v-if="!show_edit_form">
{{element.name}}
<el-button class="edit-button" type="text" #click="show_edit_form = true">Изменить</el-button>
</el-card>
<edit-dict-element-form
v-bind:dict="dict"
v-bind:edit_element="element"
v-if="show_edit_form"
v-on:closeAddForm="show_edit_form = false">
</edit-dict-element-form>
</div>
</template>
Add\Edit element form:
<template>
<el-card>
<el-form :rules="rules" :model="element" label-position="top" ref="AddDictElement">
<el-form-item label="Введите значение" prop="name">
<el-input v-model="element.name"></el-input>
</el-form-item>
</el-form>
<el-button type="danger" #click="$emit('closeAddForm')">Закрыть</el-button>
<el-button type="success" #click="addDictElement">Сохранить</el-button>
</el-card>
</template>
I'd like to only one add\edit form was opened at same time.
You could use an 'event bus' system for communicating between components (non parent-child communication).
var bus = new Vue()
// in component A's method
bus.$emit('id-selected', 1)
// in component B's created hook
bus.$on('id-selected', function (id) {
// ...
})
Please see:
https://v2.vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication