Add event on slot - vue.js

I'm trying to implement generic modal component with Vue 3.
And I want to close modal window on click outside the modal's content.
So I added 'close' event on modalWrapper and 'contentClick' to prevent closing (bubbling) when content is clicked:
contentClick(event:Event){
event.stopPropagation();
}
Modal:
<template>
<teleport to="body">
<div class="modal-window" v-on:click="close" v-show="isOpened">
<slot class="modal-window__content" v-on:click="contentClick($event)"></slot>
</div>
</teleport>
</template>
The problem is that contentClick(event:Event) is not fired for some reason. I can wrap slot into another div and put contentClick event on it, but not sure that it's a good solution

Related

Cannot catch scroll-event in vue.js component

I have this.
<template>
<md-dialog :md-active.sync="show"
#md-closed="hideModal"
#md-clicked-outside="hideModal"
class="modal-tabs"
#keypress.enter.prevent="handleEnter"
>
<md-dialog-content ref="my-modal" v-on:scroll.native="handleScrolling" #click.native="handleScrolling">
<!--content-->
</md-dialog-content>
</md-dialog>
</template>
and handler function is
handleScrolling(): void {
console.log('scroll is on');
this.$root.$emit('scrollingModal', this.$refs['my-modal'].$el.scrollTop);
}
It easily called by clicking on content but cannot be called by scrolling content. Why? Regards.
In order for v-on:scroll to be triggered the element first needs to by overflowing with a scroll style declared.
Try doing this:
<div style="max-height: 300px; overflow: scroll;" v-on:scroll="handleScrolling()">
<md-dialog-content ref="my-modal" #click.native="handleScrolling">
<!--content-->
</md-dialog-content>
</div>
This should show you a proof of concept. As you scroll inside that div you should see the messages being logged.
This problem solved by wrapping content with md-tabs and md-tab tags. In my case, to achieve scroll event triggering i have changed code above to:
<template>
<md-dialog :md-active.sync="show"
#md-closed="hideModal"
#md-clicked-outside="hideModal"
class="modal-tabs"
#keypress.enter.prevent="handleEnter"
>
<md-dialog-content ref="edit-contact-modal" v-on:scroll.native="handleScrolling">
<md-tabs>
<md-tab><!--here md-tab in fact is first custom div of mine-->
<!--content-->
</md-tab>
</md-tabs>
</md-dialog-content>
</md-dialog>
</template>

How to pass click event to another button and trigger popup

I am using this component https://element.eleme.io/#/en-US/component/popover
I need to pass click event correctly from one button to another and show popup under forwarded button
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui#2.8.2/lib/index.js"></script>
<div id="app">
<template>
<el-button #click="$refs.forward.click()">Click to forward</el-button>
<el-popover
placement="bottom"
title="Title"
width="200"
trigger="click"
content="this is content, this is content, this is content">
<el-button ref="forward" slot="reference">Click to activate</el-button>
</el-popover>
</template>
</div>
I've passed click event via $refs.forward.click() but that doesn't trigger popup. Am I missing something?
https://codepen.io/anon/pen/dEdENJ
You're over thinking it here:
add a new property to data called visible
visible: false
And then just mutate that on click to forward
#click="visible = !visible"
Finally, assign that to the v-model of the popover:
v-model="visible"
Done.

Modal ls not firing with V-Show

I have a modal that is being imported and added to a page as a component. The modal is called into the page as
<TwoFactorStatus v-show="showTwoFactoreModal"></TwoFactorStatus>
Then a button has a click event as such
<button class="btn btn-danger pull-right" #click="ShowTwoFactoreModal()" type="danger">Disable two-factor authentication</button>
Which then calls a method to
ShowTwoFactoreModal() {
this.showTwoFactoreModal = true;
}
The Modal looks like so
<template>
<div class="modal fade" id="showTwoFactoreModal" data-keyboard="false" data-backdrop="static" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header text-center">
Two Factor Switch Off
</div>
<div class="modal-body">
<p>This modal must pass</p>
</div>
</div>
</div>
</div>
</template>
Change your ShowTwoFactoreModal function to something like this:
ShowTwoFactoreModal() {
this.showTwoFactoreModal = true;
$('#showTwoFactoreModal').modal('show');
}
Either that or maybe using :class bindings and appending the active class, but this is more straight. I usually do it with an eventBus, but it might be overkill for your project... if you were to do it with an event bus, you could attach an eventListener to the modal component, and attach a showModal function callback to that listener where you don't need to set IDs you can just call it like: $(this.$el).modal('show'); ... but thats another story...
Bootstrap modal is using its own js functions to handle show and hide modal. Vue v-show can only show and hide the components which you programmed its logic. But bootstrap modal is showing and hiding by appending class to modal component.
If you want to use without bootstrap.js to toggle you can use jQuery with Vue as below. (if just want show then change method .show())
//200 is duration of fade animation.
<button #click="toggleModal"></button>
function toggleModal() {
$('#your_modal_id').fadeToggle(200)
}
If you want to use bootstrap own modal with their js then you can copy and paste modal code
here. https://getbootstrap.com/docs/4.0/components/modal/
If you want Vue v-show to handle all process then write logic to do it. If need help just ask.

Vuejs. uiv, keep bootstrap popover alive while the popover is being hovered?

I know that there are similar questions with jquery, but this is related to vue.js
I'm using uiv which is a boostrap version for vue.js. Checking the docs I'm trying to trigger manually the popover using trigger="manual" with a hover event:
<popover title="Title" v-model="show">
Toggle Popover
<template slot="popover">
<p>Popover content</p>
</template>
</popover>
<script>
export default {
data () {
return {
show: false
}
}
}
</script>
Well, I understand why the popover is being closed due when I leave the button I set show to false.
So my question is: Where do I have to place that #mouseleave event in order to prevent closing the popover when it is being hovered?
Here I have a plunker link: https://plnkr.co/edit/gTsOJE4k8fQUMcMUpqS6?p=preview
I've solved my problem doing this:
<popover trigger="hover" title="Title">
<a href="#" #click.prevent>Toggle Popover</a>
<template slot="popover">
<p>Popover content</p>
</template>
</popover>
Basically, we can use trigger="hover" to prevent closing the popover when it is being hovered.
Take a look at this example: https://plnkr.co/edit/RSjhazfxqBhaNqcKijXe?p=preview

Aurelia router-view inside dialog not working on reopening dialog

As per example given in aurelia documentation I am opening dialog box with viewmodel (say prompt ). This prompt has view inside in which I am adding "router-view" tag.
My routes are already configured. So when first time I open dialog it opens correct views as configured in routes and everything works well. But when I close dialog and re-opens dialog, It's not showing first route view. If I click other route link and come back to first route it works.
I have observed it's not creating instance of view model of first route( when opened dialog second time).
How to fix this issue?
Prompt html
<template><div class="row">
<left-menu ></left-menu>
<router-view></router-view>
</div></template>
<template>
and left-menu.htm
<template>
<div class="list-group">
<template repeat.for="item of items">
<a class="list-group-item ${$parent.selectedNav === item.routeName ? 'active' : ''}" route-href="route.bind: item.routeName;" click.delegate="$parent.select(item)">${item.text}</a>
</template>
</div>
Using a router inside a modal window seems off to me. The router is used to manage pages, but a modal is used to manage content within a page.
I would suggest building a modal window component, you can use <slot> tags to inject content and set it's model bindings to any data within the current view model.
Here's an example of my component that I use for this.
<template>
<div show.bind="visibility" class="modal-window">
<div>
<button class="btn btn-danger btn-sm close-button" click.delegate="close()">close</button>
</div>
<slot></slot>
</div>
<div show.bind="visibility" class="modal-window-overlay" click.delegate="close()"></div>
</template>
-
import { bindable } from 'aurelia-framework';
export class ModalContent {
#bindable visibility: boolean;
close(){
this.visibility = false;
}
}
<modal-content id.bind="'add-variant-window'">
<h4>Modal Content</h4>
<div>you can bind this to things on the current viewmodel</div>
</modal-content>