Action when modal closes in vuejs - vue.js

I am using Modal component from vue strap. I want to know if an action/method can be run if modalshow is false. Basically I want to do a status check and then refresh the page when the modal closes.

use watch in parent component:
watch: {
'showModal': function (newVal, oldVal) {
if(newVal == false)
doSomething();
}
},
when modal show status changes this event should fire up.
Remember to use twoWay binding in modal component for showModal:
<modal large :show.sync="showModal" effect="zoom">

Related

Can't change transition on the fly for a transition group

In my app, clicking a modal's close button makes it disappear with a fade animation whereas swiping it down makes it disappear with a swipe animation. This is done by changing the modal's <transition name> based on event.
The same thing doesn't seem to work with a transition group. Am I doing something wrong, or is it actually not possible?
CodeSandbox
Template:
<transition-group :name="itemTransition">
<div
v-for="item in items"
:key="item.id"
v-hammer:swipe.up="() => onSwipeUp(notification.id)"
>
</div>
</transition-group>
Script:
export default {
data () {
return {
applySwipeTransition: false
}
},
computed: {
itemTransition () {
return this.applySwipeTransition ? 'swipe' : 'fade'
}
},
methods: {
onSwipeUp (id) {
this.applySwipeTransition = true
this.$nextTick(() => {
this.closeItem(id)
this.applySwipeTransition = false
})
}
}
}
CSS:
.fade-leave-active {
animation: fade-out .75s;
}
.swipe-leave-active {
animation: slide-up .25s;
}
The problem lies in the timing of component update. You are switching the transition mode back to fade in the same update cycle as when the element is closed. Thus, when the next component update is triggered (by removal of the item), the transition is already switched back to fade. At this point, you may have guessed that all that needs to be done, is to switch the transition back in the next update, triggered by removal of the item:
onSwipeUp (id) {
this.applySwipeTransition = true
this.$nextTick(() => {
this.closeItem(id)
this.$nextTick(()=>{
this.applySwipeTransition = false
})
})
}
Since there are no reasons to wait for component update to close the item, you can simplify the code a bit:
onSwipeUp (id) {
this.applySwipeTransition = true
this.closeItem(id)
this.$nextTick(() => {
this.applySwipeTransition = false
})
}
Here is your working sandbox: https://codesandbox.io/s/vue-template-forked-60lkk?file=/src/App.vue
So, I've worked around with your CSS by manually changing the name of the <transition-group to either fade or swipe to see if the there's a problem with the CSS animations.
Verdict: The fade works. swipe only transitions the list-item off the page by a click and drag, not true swipe, if that concerns you (by the way, my swipe is MacOS swipe - two-finger, no click)
Still, without changing the CodePen, the issue seems to be with your computed property where there's nothing telling the name to change dynamically even though you've bound it to a computed property - the logic for itemTransition() seems to always default to fade because the applySwipeTransition would never equal to "swipe", given that the CSS does work when you manually change name to swipe (see "Verdict)".
To see where the underlying issue was, I worked around with your itemTransition():
computed: {
itemTransition() {
return this.applySwipeTransition ? "fade" : "swipe";
},
Switching the order of the fade and swipe now makes swipe work. I hope this gives you some insight into the issue. You may need to create a custom Vue directive or event to handle the swipe / fade logic if needed.

Refresh inside function of react-navigation screen

Using react-navigation I am doing stuff inside one of screens, where I display items, and optionally delete them. When deleting, I need to update the screen, which I am having trouble with. I tried navigating to the same screen or updating useState hook variables, which should re-render the screen but dont. For now, I am refreshing it in the dumbest way: I delete the item, navigate to other screen, timeout 5ms and go back to the screen that I want to update.
function ListScreen({navigation}) {
<FlatList>
...stuff
<ListItem.Chevron onPress={ () => Alert.alert('Alert Title', 'Do you really want to delete this?',
[{ text: 'YES', onPress: () => deleteAndRefresh(id) }
/>
function deleteAndRefresh(id) {
deleteProduct(id); //database call
navigation.navigate('Home');
setTimeout(function () {
navigation.navigate('List');
}, 5);
}
}
How could I refresh the screen inside deleteAndRefresh more ... elegantly?
Did you try push ?
navigation.push('List');

How can I get CKEditor 5 "Link" dialog box to pin to custom DOM element instead of 'document.body'

I'm building a Vue.js web application. I'm using CKEditor in a form that is placed inside a modal window. By design, the user's focus is "trapped" in the modal. In CKEditor, when user clicks the "Link" icon in toolbar, the editor opens a dialog box and attaches the new DOM element to 'document.body'. With respect to the DOM, the "Link" dialog is now outside of trapped focus. The user cannot click or tab his way to the "Link" dialog input.
I dug into the ckeditor5-ui source and found relevant code in balloonpanelview.js. I've unsuccessfully tried to configure CKEditor based on https://ckeditor.com/docs/ckeditor5/latest/api/module_utils_dom_position-Options.html
In my Vue.js component, I have:
import ClassicEditor from '#ckeditor/ckeditor5-build-classic';
...
data: () => ({
editor: ClassicEditor,
editorConfig: {
toolbar: ['bold', 'italic', 'bulletedList', 'numberedList', 'link'],
},
...
})
...
I want the CKEditor "Link" dialog DOM element to be attached to a DOM element id that I specify.
In Vuetify dialog component is required to disable retain-focus
<v-dialog :retain-focus="false" />
There may be much time since you opened the issue. However... This issue was happening to me too. This is happening because Bootstrap modal trap the focus in the active modal. If you're using bootstrap-vue, do this.
In your <b-modal> add the prop no-enforce-focus.
no-enforce-focus is reactive. To properly apply this workaround you can use this prop with a variable, that detects when your CKeditor have focus. If have focus, disable the enforce focus. If doesn't have, restore it. You can apply it by the following way:
<template>
<b-modal
...
:no-enforce-focus="editorFocus">
<ckeditor
...
#focus="toggleEditorFocus(true)"
#blur="toggleEditorFocus(false)"
/>
</b-modal>
</template>
<script>
export default {
...
data () {
return {
editorFocus: false
}
},
methods: {
toggleEditorFocus (val = !this.editorFocus) {
setTimeout(() => {
this.editorFocus = val
}, 10)
}
}
}
</script>
I know the setTimeout is a tricky method, but at least is working now for me.

how to close modal popup when browser back button is clicked in vuejs?

We make use of modal component from https://github.com/yuche/vue-strap. When browser back button is clicked, the default behavior is back to previous path but the modal popup isn't closed. How can I change the behavior to close the modal popup upon browser's back button click event?
This helped me.
https://jessarcher.com/blog/closing-modals-with-the-back-button-in-a-vue-spa/
created() {
const backButtonRouteGuard = this.$router.beforeEach((to, from, next) => {
if (from.name == 'menu') {
/* Blocking back button in menu route */
next(false);
this.yourCallBackMethod()
} else {
/* allowing all other routes*/
next(true);
}
});
this.$once('hook:destroyed', () => {
backButtonRouteGuard();
});
},
methods: {
yourCallBackMethod() {
// Go to the previous step, or close the modal
}
},
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

Disable closing of sideNav when click outside the sideNav

I am using sideNav of MaterializeCSS in my application. I do not want to close sideNav while clicking outside. It can be achievable in modals like this:
{ dismissible: false }
How to do this in sideNav?
MaterializeCSS doesn't have a built-in method for achieve this task, but you can use a workaround, unbinding the click event from sideNav overlay:
$(function(){
$(".button-collapse").sideNav();
$(".drag-target").unbind('click');
$("#sidenav-overlay").unbind('click');
});
Update:
As of late, you can modify options of the sidenav by doing the following
$(".button-collapse").sideNav({
menuWidth: 300, // Default is 300
edge: 'left', // Choose the horizontal origin
closeOnClick: false, // clicking outside of the nav will not close it
draggable: true, // Choose whether you can drag to open on touch screens,
onOpen: function(el) { }, // A function to be called when sideNav is opened
onClose: function(el) { }, // A function to be called when sideNav is closed
});
});
you can take a look here to learn more: http://materializecss.com/side-nav.html