How to programatically close ion-sliding-item?

I have a component below which renders information for each element in the list:

<template>
  <ion-item-sliding>
    <ion-item-options side="start">
      <ion-item-option color="danger">
        <ion-icon :icon="trashOutline" slot="icon-only"></ion-icon>
      </ion-item-option>
    </ion-item-options>
    <ion-item lines="full" color="secondary">
      <ion-icon
        :src="require(`@/static/icons/categories.svg`)"
        slot="start"
      ></ion-icon>
      <ion-label>{{ category.name }}</ion-label>
    </ion-item>
    <ion-item-options side="end">
      <ion-item-option @click="editCategory(category.id)">
        <ion-icon :icon="create" slot="icon-only"></ion-icon>
      </ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</template>

<script>
  import { useRouter } from 'vue-router'
  import { trashOutline, create } from 'ionicons/icons'
  export default {
    name: 'CategoryListItem',
    props: {
      category: {
        type: Object,
        required: true,
      },
    },
    setup() {
      const router = useRouter()

      const editCategory = async (categoryId) => {
        await router.push(`/categories/edit/${categoryId}`)
      }

      return {
        trashOutline,
        create,
        editCategory,
      }
    },
  }
</script>

In this component I have ion-item-sliding component rendering the information. The ion-label inside the ion-item-sliding has option of Delete to the left and the option of Edit to the right. Now, what I would like to do is reset or close the ion-item-sliding element with the close() function after the Edit or Delete function is pressed. I tried to close it with ref, but I was unsuccessful (ref pointing to the ion-item-sliding component). Request anyone to please help me in closing the ion-item-sliding programatically after I have routed ahead to the edit page in editCategory function.

@ldebeasi Can you please help me in this?

get a ref to the element using ref and then call the appropriate method - https://ionicframework.com/docs/api/item-sliding

I have found that doing a closeSlidingItems on the list containing the elements is more effective. https://ionicframework.com/docs/api/list

1 Like

@aaronksaunders Thanks for the reply.

So, what I have attempted is as given below:

Parent Component:

<template>
  <ion-list class="ion-no-padding" ref="categoryListRef">
    <category-list-item
      v-for="category in categories"
      :key="category.id"
      :category="category"
      @onDelete="resetSlides"
    />
  </ion-list>
</template>

<script>
  import { ref } from 'vue'
  import CategoryListItem from '@/components/categories/CategoryListItem.vue'
  export default {
    name: 'CategoryList',
    props: {
      categories: {
        type: Array,
        required: true,
      },
    },
    components: {
      CategoryListItem,
    },
    setup() {
      const categoryListRef = ref(null)
      const resetSlides = () => {
        categoryListRef.value.closeSlidingItems()
      }

      return {
        resetSlides,
        categoryListRef,
      }
    },
  }
</script>

<style scoped></style>

Child Component (CategoryListItem.vue):

<template>
  <ion-item-sliding ref="slidingRef">
    <ion-item-options side="start">
      <ion-item-option color="danger">
        <ion-icon :icon="trashOutline" slot="icon-only" />
      </ion-item-option>
    </ion-item-options>
    <ion-item lines="full" color="secondary">
      <ion-icon :src="require(`@/static/icons/categories.svg`)" slot="start" />
      <ion-label>{{ category.name }}</ion-label>
    </ion-item>
    <ion-item-options side="end">
      <ion-item-option @click="editCategory(category.id)">
        <ion-icon :src="require(`@/static/icons/edit.svg`)" slot="icon-only" />
      </ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</template>

<script>
  import { useRouter } from 'vue-router'
  import { trashOutline, create } from 'ionicons/icons'
  export default {
    name: 'CategoryListItem',
    props: {
      category: {
        type: Object,
        required: true,
      },
    },
    setup(_, { emit }) {
      const router = useRouter()

      const editCategory = async (categoryId) => {
        await router.push(`/categories/edit/${categoryId}`)
        emit('onDelete')
      }

      return {
        trashOutline,
        create,
        editCategory,
      }
    },
  }
</script>

<style scoped></style>

As you can see, in the parent component, I am already getting the ref for ion-list and I am calling categoryListRef.value.closeSlidingItems on the onDelete function emitted by the Child Component. But, I gett an error in the console like this:

Can you please suggest a solution to this?

I need to document this better, but you need to do categoryListRef.value.$el.closeSlidingItems(). Due to limitations in Vue, it’s not currently possible to forward your ref to the underlying Web Component, which is where the method is defined. By using $el, you can access the Web Component instance.

3 Likes

I added a Troubleshooting guide to the Ionic Vue docs that covers this (and other issues): https://ionicframework.com/docs/vue/troubleshooting You might need to do a hard refresh to see it.

edit: This is also covered in the quickstart guide now: https://ionicframework.com/docs/vue/quickstart#calling-methods-on-components

3 Likes

@ldebeasi Thanks a lot for this…