In Aurelia, say I have custom component named popup that has an open and close method on it. I can call those methods in the component, but how would I call them from outside the component?
app.html:
<template>
<require from="popup"></require>
Pop-up test
<popup>
<popup-body>
<button click.trigger="close()">Close</button>
</popup-body>
</popup>
</template>
popup.html:
<template>
<button click.trigger="open()">Open</button>
<button click.trigger="close()">Close</button>
<div class="popup" show.bind="visible">
Pop-up!
<content select="popup-body"></content>
</div>
</template>
popup.js
export class Popup {
constructor() {
this.visible = false;
}
open() {
this.visible = true;
}
close() {
this.visible = false;
}
}
Notice in app.html I'm adding a button to try to close the modal. Obviously close() won't work because it is looking for that method in app.js. How do I call the close method in popup.js?
Here is a working Plunker example of the above.
You can get a hold of the view model of the component by using view-model.ref:
<popup view-model.ref="popup">
and then call close:
export class App {
close(){
popup.close();
}
}
here is the plunker
Oh, I think I figured it out with view-model.ref
<template>
<require from="popup"></require>
Pop-up test
<popup view-model.ref="popup">
<popup-body>
<button click.trigger="popup.close()">Close</button>
</popup-body>
</popup>
</template>
Related
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>
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
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>
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.
How do I access & share variables between custom elements? I have the following files...
tip.html
<template>
<div class="tip-container">
<content select="tip-trigger"></content>
<content select="tip-content"></content>
</div>
</template>
tip.js
export class Tip {}
tip-trigger.html
<template>
<span class="tip-trigger" click.trigger="showTip()">
<content></content>
</span>
</template>
tip-trigger.js
export class TipTrigger {
showTip() {
console.debug(this);
}
}
tip-content.html
<template>
<span class="tip">
<content></content>
<span class="tip__close tip__close--default">×</span>
<span class="tip__color"></span>
</span>
</template>
tip-content.js
export class TipContent {}
In my Tip class I would like to have a variable name visible. When showTip is triggered visible would be set to true, which I would then use to add a class in tip-content.html. How can I share variables between these custom elements to do this?
The idea is to create an element to show tip pop-ups where any type of content can be the trigger and any type of content can be displayed when triggered. Basic example:
<tip>
<tip-trigger><button>?</button></tip-trigger>
<tip-content><div>Here is some helpful info...</div></tip-content>
</tip>
Here is a solution to your problem in Plunker.
Note that the tip-trigger and tip-content elements are just replaceable parts of the template. They don't needed to be components themselves (that confused me a lot in the "original" custom elements article).
app.html:
<template>
<require from="tip"></require>
<tip>
<tip-trigger><button>?</button></tip-trigger>
<tip-content><div>Here is some helpful info...</div></tip-content>
</tip>
</template>
tip.html:
<template>
<div class="tip-container">
<div>
<div click.trigger="showContent()">
<content select="tip-trigger"></content>
</div>
</div>
<div show.bind="contentVisible">
tip content:
<content select="tip-content"></content>
</div>
</div>
</template>
tip.js:
export class Tip {
showContent(){
this.contentVisible = !this.contentVisible;
}
}
Do you just need to turn Tip into a service-like class and import it?
export class Tip {
constructor() {
this.visible = false;
}
show() {
this.visible = true; // Or whatever to show the content
}
hide() {
this.visible = false;
}
}
Then:
import {inject} from 'aurelia-framework';
import {Tip} from './tip';
#inject(Tip)
export class TipTrigger {
constructor(tip) {
this.tip = tip;
}
showTip() {
this.tip.show();
// Or I suppose you could access 'visible' directly
// but I like the implementation details a method call offers.
}
}
*Disclaimer: This is untested.