I’m trying to reorder items using ion-reorder after long-pressing on an item. (I want to do it only after a long press because simply wrapping an ion-item with ion-reorder prevents you from being able to scroll the page when your finger touches the item.)
As a solution I tried adding a long press gesture to ion-item and enabling reorder only after the long press gesture has been triggered. But it seems that if a custom gesture is registered on the element then built-in Ionic gestures like reorder and sliding won’t work.
Any thoughts on getting reorder to work on items that also have a custom gesture registered? Or other ways to reorder after a long press? Here’s the Vue code I tried for reference.
<template>
<ion-page>
<ion-header :translucent="true">
<ion-toolbar>
<ion-title>Reorder Test</ion-title>
</ion-toolbar>
</ion-header>
<ion-content :fullscreen="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Reorder Test</ion-title>
</ion-toolbar>
</ion-header>
<div class="top_status">
<div>
Reorder is {{ (reorderIsDisabled) ? 'disabled' : 'enabled' }}
<a @click.prevent="reorderIsDisabled = !reorderIsDisabled" href="#">[Toggle]</a>
</div>
<div>
Long press gesture is {{ (gestureIsEnabled) ? 'enabled' : 'disabled' }}
<a @click.prevent="gestureIsEnabled = !gestureIsEnabled" href="#">[Toggle]</a>
</div>
<div :style="{visibility: (gestureIsEnabled) ? 'visible' : 'hidden'}">
Can enable reorder via long press gesture
</div>
</div>
<ion-reorder-group @ionItemReorder="doReorder($event)" :disabled="reorderIsDisabled" ref="reorderGroup">
<ion-reorder>
<ion-item>
<ion-label>Item 1</ion-label>
</ion-item>
</ion-reorder>
<ion-reorder>
<ion-item>
<ion-label>Item 2</ion-label>
</ion-item>
</ion-reorder>
<ion-reorder>
<ion-item>
<ion-label>Item 3</ion-label>
</ion-item>
</ion-reorder>
</ion-reorder-group>
<div class="bottom_filler">
Bottom filler (to make sure page is long enough to scroll)
</div>
</ion-content>
</ion-page>
</template>
<script>
import { createGesture, IonContent, IonHeader, IonItem, IonLabel, IonPage, IonReorder, IonReorderGroup, IonTitle, IonToolbar } from '@ionic/vue';
import { defineComponent, onMounted, ref, watch } from 'vue';
export default defineComponent({
name: 'Home',
components: {
IonContent,
IonHeader,
IonItem,
IonLabel,
IonPage,
IonReorder,
IonReorderGroup,
IonTitle,
IonToolbar
},
setup() {
const doReorder = (event) => {
event.detail.complete();
}
const reorderGroup = ref();
const reorderIsDisabled = ref(true);
const gestureIsEnabled = ref(false);
const gestures = ref([]);
// Set long press gesture for each ion-item
// Based on https://ionicframework.com/blog/building-interactive-ionic-apps-with-gestures-and-animations/
onMounted(() => {
const timeoutDuration = 500;
for (const el of reorderGroup.value.$el.getElementsByTagName('ion-item')) {
let timeout;
const clearGestureTimeout = () => {
if (timeout) {
clearTimeout(timeout);
timeout = undefined;
}
};
const gesture = createGesture({
el: el,
threshold: 0,
onStart: () => {
clearGestureTimeout();
timeout = setTimeout(() => {
reorderIsDisabled.value = false;
timeout = undefined;
}, timeoutDuration);
},
onMove: (detail) => {
// Allow a little bit of movement
if (detail.deltaX <= 10 && detail.deltaY <= 10) {
return;
}
clearGestureTimeout();
},
onEnd: () => {
clearGestureTimeout();
reorderIsDisabled.value = true;
},
});
gestures.value.push(gesture);
}
});
// Toggle whether gesture is enabled for each ion-item when gestureIsEnabled value changes
watch(gestureIsEnabled, (gestureIsEnabled) => {
for (const gesture of gestures.value) {
gesture.enable(gestureIsEnabled);
}
});
return {
doReorder,
reorderGroup,
reorderIsDisabled,
gestureIsEnabled,
}
}
});
</script>
<style scoped>
.top_status div {
margin: 20px;
}
.top_status a {
margin-left: 5px;
text-decoration: none;
}
.bottom_filler {
height: 80vh;
padding: 20px;
}
</style>
1 post - 1 participant