Getting a v-checkbox to work in a v-expansion-panel-header - vue.js

I have a v-expansion-panel-header which contains a v-checkbox. If I click on the checkbox the checkbox does not check/uncheck. Instead the expansion panel opens/closes. How do I allow the checkbox to work and have the panel only open when the default icon that is supplied is clicked on?
I have tried using #click.stop and #click.native.stop, #click.capture, #change.stop etc on the v-checkbox, but it doesn't work.
<v-expansion-panels>
<v-expansion-panel>
<v-expansion-panel-header>
<v-checkbox v-model="checkbox" label="MyCB" #click.stop />
</v-expansion-panel-header>
<v-expansion-panel-content>
Lorem ipsum dolor.
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>

The issue here is that the event is bubbling up from the checkbox to the expansion panel. What you need to do is, when the checkbox is being clicked, pass the event into a function, and cancel the event bubbling.
check: function(e) {
e.cancelBubble = true;
}
Check the working code here
Note that, in the example I had wrapped a v-flex around the v-checkbox. This is because the v-checkbox was spanning the whole width of the expansion panel and I think you still want the expansion to work when you click on places that are not close to the checkbox. You can probably find some other ways of preventing full width in CSS but this was just a quick and dirty way to demonstrate the prevent event bubbling solution.

Related

Vuetify Expansion Panels with Virtual Scroll

I have a dynamic list of expansion panels and I want to use a virtual scroll on them as the list can be quit big
Here is my example
https://codepen.io/amaieras/pen/XWVBoWo?editors=1010
<v-expansion-panels>
<v-virtual-scroll
:items="items"
height="300"
item-height="64">
<template v-slot:default="{ item }">
<v-expansion-panel>
<v-expansion-panel-header>
Item
</v-expansion-panel-header>
<v-expansion-panel-content>
some content
</v-expansion-panel-content>
</v-expansion-panel>
</v-virtual-scroll>
</v-expansion-panels>
The problem is that when expanding one panel it is not well displayed due to the position absolute of the virtual item.
I want to make the expansion work as expected
Mainly the problem is how to make a child of an absolute element move the parent's sibling down on expand

How do I add a bottom bar in ElectronJS like the VSCode one?

I'm tryin to add a bar at the bottom of my ElectronJS application and I'd like it to be positioned in the same way as the blue bottom bar in VSCode, where the scroll bar ends/stops above it.
Unfortunately, there always seems to be a small space on the right side where the scroll bar would appear when the content overflows (I don't want to disable the scroll bar / behavior with things such as overflow: hidden; See Edit 2).
I did some testing and with the code below you can see my desired behavior seems to happen with the nav-drawer, i.e. its scroll bar stops right above the v-bottom-navigation, which would be my bottom bar (the thick grey line you see is the scroll bar).
I'm semi-new to this, but I can't figure out why exactly that happens and how to modify it in order to get the same behavior for the whole application.
VueComponent.vue
<template>
<div id="nav-drawer">
<v-navigation-drawer
v-model="drawer"
app
color="white darken-3"
mini-variant
permanent
>
<v-avatar
v-for="n in 30"
:key="n"
:color="`grey ${n === 1 ? 'darken' : 'lighten'}-1`"
size="36"
class="d-block text-center mx-auto my-3"
>
<span>TT</span>
</v-avatar>
<v-avatar class="d-block mx-auto">
<v-btn icon small color="primary">
<v-icon>fas fa-window-maximize</v-icon>
</v-btn>
</v-avatar>
</v-navigation-drawer>
<v-bottom-navigation v-model="value" height="20px" background-color="primary" app>
<v-spacer></v-spacer>
<v-btn icon small>
Button
</v-btn>
</v-bottom-navigation>
</div>
</template>
<script>
export default {
name: "NavDrawer",
components: {
//
},
data: () => ({
drawer: true,
})
}
</script>
P.S. I'm using ElectronJS with VueJS+VuetifyJS - I set it up as described here. Any help is appreciated.
Edit 1: I went through the VSCode source code and found the UI elements (vscode/src/vs/base/browser/ui/). Unfortunately, I wasn't able to figure out which of those is the bar at the bottom (apparently called System Bar, according to some threads I found here and there).
I think it might be the toolbar, but that seems to be part of the actionbar, which is the menu on the left (by default) and doesn't seem to have much CSS to indicate that it's the bar at the bottom.
Edit 2: I tried adding html {overflow: hidden;} in the style section of the main index.html file. It removes the bar of the main page section (the scrollbar you see in the second picture with the two arrows and green button) and the possibility to scroll, but the scrollbar of the nav-drawer remains and the scrolling still works. So, I guess this would be an option if I could still have the scrollbar in the main page section with the code above with the hidden feature enabled as well. Not sure if that's possible though.
Edit 3: Using html {overflow-y: auto;} in the index.html file, removes the scrollbar when there isn't content that is overflowing and it looks just like I want it, but when there is, it still taking up space and looks like the the second image in my post.
Found this example: CodePen
For my case the solution is adapting the :root {...} part to my application, which means to mark the bottom bar as the footer and calculate the content area depending on its size.
The html {overflow: hidden;} must also be in the index.html file's style section.

v-edit-dialog inside v-data-table restores original value when closed

I have a Vue application that is using Vuetify. For some reason the v-chip component is not re-rendering when the binded value is changed.
<v-data-table>
<template v-slot:item.active="{ item }">
<v-edit-dialog :return-value.sync="item.active">
<v-chip :key="item.active" outlined :color="item.active ? 'success' : 'error'">{{ item.active ? "Open" : "Closed" }}</v-chip>
<template v-slot:input>
<v-switch
#change="saveRowField(item.id, 'active', item.active)"
v-model="item.active"
:true-value="1" :false-value="0"
color="success" label="Open"
></v-switch>
</template>
</v-edit-dialog>
</template>
</v-data-table>
The v-switch in the v-edit-dialog correctly updates the binded field item.active. However the v-chip component inside the template does not rerender on state change.
The :key attribute is binded to the same field as the v-switch.
Why is the v-chip not re-rendering when the value binded to the key is changed?
Tried your code and re-rendering content of v-chip is not an issue. What I see is chip is changed once I click v-switch but when v-edit-dialog is closed, the original value is restored.
So the problem is in v-edit-dialog. If you put large prop on it, it will display buttons - "Save" and "Cancel". If you use "Save" button, the value is saved. If "Cancel", original value is restored.
Without buttons, only way to close the dialog is clicking "away", which is interpreted as "Cancel" by v-edit-dialog and thus original value is restored...
Possible solutions:
Either let user use "Save"/"Cancel" buttons to confirm/cancel editing
Or remove :return-value.sync="item.active" (responsible for this Save/Cancel behavior).
Demo

How do I make the expansion-panel open only on clicking collapse icon on the right?

How do I make this expansion-panel open content only on clicking icon?
Tried using readonly but it didn't help.
Thanks in advance!
https://vuetifyjs.com/en/components/expansion-panels#expansion-panel
You can put online the argument in all collapse like: expanded={!expanded}
and in the icon you put the onClick={toggle}
I was having the same problem and just found a solution for that.
You need to implement a custom button on the expansion panel, so it will accept custom events. You can achieve that using template and v-slot:
<v-expansion-panel #click.prevent="onClick()">
<v-expansion-panel-header>
...your expansion panel code here
<template v-slot:actions>
<v-btn icon #click.stop="onClick()">
<v-icon>mdi-filter-variant</v-icon>
</v-btn>
</template>
</v-expansion-panel-header>
</v-expansion-panel>
...and your onClick method would be like this:
onClick() {
/*this will toggle only by icon click. at the same time, will prevent toggle
by clicking on header. */
const curr = this.panel
this.panel = curr === undefined ? 0 : undefined
}
It may seem a little magical that the same function is toggling on icon click and preventing toggle on header click, but this happens because the custom icon button does not toggle itself, so we force that using the onClick method. On the other hand, the expansion panel header has its native property of toggling the panel. So when we click it, its value will automatically change and we need to change it back to what it was before the click.
To make the expansion-panel open only on clicking icon you can use css that disables all clicks on the header and only allows clicks on the icon:
<style>
.v-expansion-panel-header{
pointer-events: none;
}
.v-expansion-panel-header__icon{
pointer-events: All;
}
</style>
Keep in mind if you are using scoped style you have use >>>:
https://vue-loader.vuejs.org/guide/scoped-css.html#deep-selectors
Here is the template example, I added #click to provide btn like experience when user clicks on an icon, it's not necessary:
<template>
<v-expansion-panel>
<v-expansion-panel-header>
<template #actions>
<v-icon class="icon Icon Icon--32 icon-utility-arrows-carrot_down-32"
#click/>
</template>
</v-expansion-panel-header>
<v-expansion-panels >
<v-expansion-panel-content >
<!--content here-->
</v-expansion-panel-content>
</v-expansion-panels>
</v-expansion-panel>
</template>

Prevent open when click v-btn in v-expansion-panel headers

test (e) {
e.preventDefault()
console.log('foo')
},
<v-expansion-panel>
<v-expansion-panel-content>
<div slot="header">
<v-btn icon flat #click="test($event)"><v-icon>add</v-icon></v-btn>
title
</div>
<contents />
</v-expansion-panel-content>
</v-expansion-panel>
This is v-expansion-panel with action button in it's header.
When I click action button, expansion panel is opened.
Can I have expansion panel doesn't open when I click the button?
By using #click.native.stop on v-btn your button click will work and your expansion panel will not open.
The simplest way is by using #click.stop=""
Sorry.
I didn't know stopPropagation method.