Vue.js modal: How can I get response from modal? - vue.js

I am using Vue.js modal package and I don't know how can I get response data out of my modal window. I created a component for my modal window. Component usage looks like this:
<MyModal :data="data"
#closed="modalClosed"/>
And I want to get data from the closed event. I open my modal with:
this.$modal.show('my-modal')
And close it with:
<button type="button" #click="$modal.hide('my-modal', {success: true})" class="delete mr-3" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
My modal is defined in MyModal component (I left out the html and script code):
<template>
<modal
name="my-modal"
transition="nice-modal-fade"
:delay="100"
:width="'100%'"
:height="'auto'"
:classes="['v--modal', 'col-xl-6', 'col-lg-6', 'col-md-8', 'col-sm-12', 'col-xs-12', 'offset-md-2', 'offset-lg-3', 'offset-xl-3']"
:scrollable="true"
:adaptive="true"
:maxHeight="100">
</modal>
</template>
The #closed hook works inside the modal but not outside where I need it. I don't have any experience in Vue.js, and this is my first attempt at modal windows, so I don't really know what am I missing here, and the documentation is really bad.

If you want it to work outside of your modal component you could chain an event.
<button #click="show">show modal</button>
<modal
name="my-modal"
#closed="closedEvent"
>
modal content
</modal>
Then down in your methods obj you can emit another event from your #closed event
methods: {
closedEvent() {
this.$emit('chainClosedEvent', this.componentDataGoesHere)
}
}
Check out this fiddle https://jsfiddle.net/caseyjoneal/sm6gu1je/299/
If you end up needing your modal data throughout your app you should look at vuex

Check out the events section: there is a closed event you can hook into.
https://www.npmjs.com/package/vue-js-modal#events

Have you tried using "before-close" event handler instead of "close"?
As I've understood this component, on "close" event it doesn't $emit any data from component, and because of that, you can't get it in parent-component.

I just tried out this package locally. The #closed hook does work as designed. The markup I used is below
<button #click="show">show modal</button>
<modal
name="my-modal"
#closed="closedEvent"
>
modal content
</modal>
You definitely need a name attribute on the modal component. It does not appear that you have that.

If someone is looking for a solution, I coded as below:
In the view that calls the modal:
Define the modal components and the event that will be raised:
<template>
...
<grupo-alteracao #fechado="grupoAlteracaoFechado"/>
<grupo-novo #fechado="grupoNovoFechado"/>
</template>
<script>
...
import GrupoAlteracao from '#/views/GrupoAlteracao.vue'
import GrupoNovo from '#/views/GrupoNovo.vue'
export default {
name: 'grupo',
components:{
GrupoAlteracao,
GrupoNovo,
},
...
methods: {
novo: function(){
this.$modal.show('grupo-novo');
},
alterar: function(){
this.$modal.show('grupo-alteracao',this.selecionado);
},
grupoAlteracaoFechado(event){
this.pesquisarGrupos();
},
grupoNovoFechado(event){
this.pesquisarGrupos();
},
}
In the modal raise the event (fechado):
<template>
<modal name="grupo-alteracao"
:width=largura
:height="268"
:clickToClose="false"
#before-open="beforeOpen"
#before-close="beforeClose"
style="z-index: 49">
...
</modal>
</template>
...
...
methods: {
beforeOpen (event) {
this.grupo = event.params;
},
beforeClose (event) {
this.$emit("fechado");
},
I hope this helps.

Related

How to bind a click event to a button when component is mounted vue js?

I am using a third party app (vue slick carousel) and I need to bind a click event to below button
<button type="button" data-role="none" class="slick-arrow slick-next" style="display: block;">
<svg...</svg>
</button>
So everytime I click this button a function gets triggered. This is what I tried in mounted and created life cycle, but didn't bind click event to it.
// console.log(document.querySelector(".slick-next")); // this returns element stated above
document.querySelector(".slick-next").addEventListener("click", () => {
console.log("Works");
});
I tried using setAttribute hoped it works, but it didn't work either.
Any help is appreciated. Thank you in advance.
I suspect they're probably using stopPropagation on the button click inside the component then.
There might be another way around this depending on your needs:
<VueSlickCarousel #beforeChange="checkChange">
...
</VueSlickCarousel>
methods: {
checkChange(oldSlideIndex, newSlideIndex) {
if (newSlideIndex > oldSlideIndex) {
console.log("Next button clicked");
}
}
}
Another option might be to use the <template #nextArrow="{ currentSlide, slideCount }"></template> slot inside the Carousel tag and use your own button. You'd probably have to implement your own logic for setting the next slide if you went this route.
You must to use the events handling of vuejs. Vuejs have many events for multiple cases.
For example in your case, you can use the event v-bind:click or simply #click. In documentation of vue slick, show this examples, wich is essentially the same.
I attach an code snippet:
<template>
<VueSlickCarousel ref="carousel">
<div><h3>1</h3></div>
/*...*/
</VueSlickCarousel>
<button #click="showNext">show me the next</button>
</template>
<script>
export default {
methods: {
showNext() {
this.$refs.carousel.next()
},
},
}
</script>

click event as props in Vue.js

I created a dynamic overlay component with Vue.js to handle the close event, when we click on the screen away from the intended object the object closes my problem here the click event does not work here's my code
<template>
<button
v-if="action"
#click="clicked"
tabindex="-1"
class="fixed z-40 w-full h-full inset-0 bg-black opacity-50 cursor-default"
></button>
</template>
<script>
export default {
name: "Overlay",
props: {
action: Boolean,
},
methods: {
clicked() {
if (this.action === true) {
return false
}
}
}
};
</script
Usually you are not allowed to update properties passed to the component.
The proper way should be for you to emit the click from where it is used like:
clicked() {
this.$emit("clicked");
}
Then when you use the overlay component like:
<overlay #clicked="doSomethingHere"></overlay>
You can alter your toggle variable outside of the component, but within the component you should use data() { action: false } instead of attempting to update properties.
Finally you can read more about properties here: https://v2.vuejs.org/v2/guide/components-props.html
i was looking for the same thing but my solution was to use v-if without if true component doesn't fire
<Toast
v-if="show"
type="error"
description="desc"
/>
<button #click="show = !show">Toast active !</button>

Prevent Bootstrap-Vue Modal From Opening

I am using the Bootstrap-Vue modal and want to stop it from opening at times. I'm not sure with how to block the default behavior.
<b-img
ref='cal-modal-button'
id='cal-modal-button'
class="cal-icon"
v-bind:src="imagePath + calimage"
v-b-modal.date-time-modal
>
</b-img>
And then the stripped down modal is set up as such:
<b-modal id="date-time-modal" name="header-modal" ref="date-time-modal" hide-footer title="Set Date and Time">
...
</b-modal>
Is there a way to prevent it from popping up without using JQuery?
From the documentation you can cancel modal by using show event :
<template>
// ...
<b-modal #show="onShow" ... />
</template>
<script>
export default {
// ...
data:() => ({
modalDisabled:true
}),
methods: {
onShow(bvModalEvt) {
if(this.modalDisabled) {
bvModalEvt.preventDefault()
}
}
}
}
</script>
show event reference :
https://bootstrap-vue.js.org/docs/components/modal/#comp-ref-b-modal-events
Always emits just before modal is shown. Cancelable
BvModalEvent object. Call bvModalEvt.preventDefault() to cancel show

Vue Launch Modal with Message

I am trying to launch a modal window, much like a normal alert()
I am using bootstrap-vue BModal
How to generate Modal class from code and launch it
or, add modal in the root app.vue and call it from child classes.
I found an example to but wasn't able to replicate that - https://codesandbox.io/embed/4l3w20zomw
I think you need to use show(), hide(), and toggle() component methods and here's Link, but the difference here you will call show() method to mounted() hook it will call showModal method in mounted cycle so when application is hosted you will see modal like alert, example
<template>
<div>
<b-modal ref="myModalRef" hide-footer title="Using Component Methods">
<div class="d-block text-center">
<h1>Any Content here</h1>
</div>
</b-modal>
</div>
</template>
<script>
export default {
methods: {
showModal() {
this.$refs.myModalRef.show()
},
hideModal() {
this.$refs.myModalRef.hide()
}
},
mounted() {
this.showModal();
}
}
</script>

Modal component in VueJS

I am building a web app. I have few components that are modals (that show data about customers, lessons, ...).
I search a way to show one of the components easily.
And if possible doing lazy loading.
What's the best way to perform this?
Check out conditional rendering, specifically v-if. This would only load the modal if the button is clicked for example.
https://v2.vuejs.org/v2/guide/conditional.html#v-if
Single page component:
<template>
<div>
<div
v-if="showModal"
class="modal">
Stuff
</div>
<button #click="toggleModal">
Toggle Modal
</button>
</div>
</template>
<script>
export default {
data () {
return {
showModal: false
}
},
methods: {
toggleModal() {
this.showModal = !this.showModal
}
},
}
</script>