I used this reference:
https://stackoverflow.com/a/53108600
to close an outer v-tooltip on an inner v-tooltip hover.
The problem is that this approach is only elegant when there is one container to deal with.
When you start to have many containers then you have to create a data variable in vue for each one.
Code sample:
https://jsfiddle.net/jyts1fug/6/
As shown in the fiddle I now have 2 variables, isOpen
and isOpen2
.
I would like to find a more elegant solution for this.
Asked
Active
Viewed 473 times
0

yuval
- 2,848
- 4
- 31
- 51
1 Answers
1
You need something to track which elements are open and which isn't. This will rely heavily on the existing data structure you are using.
In the case, in your code sample, I would do something like the following:
Note: index+'inner'
is not a very clean way, it's just for demonstration. You can choose whatever variable inside the loop to track by. like user Id and user posts Ids for example.
console.clear()
new Vue({
el: '#app',
data: {
openId: null,
message: 'Outer Tooltip'
},
})
body {
font-family: sans-serif;
margin: 42px;
}
.tooltip {
display: block !important;
z-index: 10000;
}
.tooltip .tooltip-inner {
background: black;
color: white;
border-radius: 16px;
padding: 5px 10px 4px;
}
.tooltip .tooltip-arrow {
width: 0;
height: 0;
border-style: solid;
position: absolute;
margin: 5px;
border-color: black;
}
.tooltip[x-placement^="top"] {
margin-bottom: 5px;
}
.tooltip[x-placement^="top"] .tooltip-arrow {
border-width: 5px 5px 0 5px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
bottom: -5px;
left: calc(50% - 5px);
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="bottom"] {
margin-top: 5px;
}
.tooltip[x-placement^="bottom"] .tooltip-arrow {
border-width: 0 5px 5px 5px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-top-color: transparent !important;
top: -5px;
left: calc(50% - 5px);
margin-top: 0;
margin-bottom: 0;
}
.tooltip[x-placement^="right"] {
margin-left: 5px;
}
.tooltip[x-placement^="right"] .tooltip-arrow {
border-width: 5px 5px 5px 0;
border-left-color: transparent !important;
border-top-color: transparent !important;
border-bottom-color: transparent !important;
left: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
}
.tooltip[x-placement^="left"] {
margin-right: 5px;
}
.tooltip[x-placement^="left"] .tooltip-arrow {
border-width: 5px 0 5px 5px;
border-top-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
right: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
}
.tooltip[aria-hidden='true'] {
visibility: hidden;
opacity: 0;
transition: opacity .15s, visibility .15s;
}
.tooltip[aria-hidden='false'] {
visibility: visible;
opacity: 1;
transition: opacity .15s;
}
.box{
border: 1px solid red;
border-radius: 2px;
padding: 15px;
margin: 20px;
text-align: center;
cursor: pointer;
}
.box:hover{
box-shadow: 0 0 4px;
}
<script src="https://unpkg.com/popper.js"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/v-tooltip"></script>
<div id="app">
<div v-for="index in 2"
v-tooltip="{content: message, show: openId === index}"
class="box"
@mouseover.stop="openId=index"
>
{{ message }}
<div v-tooltip="{content: 'Inner',
show: openId === index+'inner'}" @mouseover.stop="openId=index+'inner'" class="box">
okokok
</div>
</div>
</div>

Omar Atta
- 11
- 1
- 4
-
I can't necessarily add all my containers under a v-for tag. These containers might be located in different places in the html. – yuval Oct 31 '20 at 17:48
-
The v-for isn't necessary you can use any unique id. – Omar Atta Oct 31 '20 at 18:32