Quantcast
Channel: Ionic Framework - Ionic Forum
Viewing all articles
Browse latest Browse all 48980

Reorder on long press in Ionic 5

$
0
0

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

Read full topic


Viewing all articles
Browse latest Browse all 48980

Trending Articles