Skip to content
Snippets Groups Projects
Pagination.vue 3.08 KiB
Newer Older
Florent Lavelle's avatar
dev
Florent Lavelle committed
<template>
  <div style="display: flex;">
    <nav style="margin: 0 auto;">
      <ul class="custom-pagination">
Florent Lavelle's avatar
dev
Florent Lavelle committed
        <li
          class="page-item"
          :class="{ disabled: page === 1 }"
        >
          <a
            class="page-link"
Florent Lavelle's avatar
dev
Florent Lavelle committed
            @click="page -= 1"
          >
Florent Lavelle's avatar
Florent Lavelle committed
            <i
              class="ui icon big angle left"
              aria-hidden="true"
            />
Florent Lavelle's avatar
dev
Florent Lavelle committed
          </a>
        </li>
Timothee P's avatar
Timothee P committed
        <div
          v-if="nbPages > 5"
          style="display: contents;"
        >
Florent Lavelle's avatar
dev
Florent Lavelle committed
          <li
            v-for="index in pagination(page, nbPages)"
            :key="index"
            class="page-item"
            :class="{ active: page === index }"
          >
            <a
              class="page-link"
Florent Lavelle's avatar
dev
Florent Lavelle committed
              @click="changePage(index)"
            >
              {{ index }}
            </a>
          </li>
        </div>
Timothee P's avatar
Timothee P committed
        <div
          v-else
          style="display: contents;"
        >
Florent Lavelle's avatar
dev
Florent Lavelle committed
          <li
            v-for="index in nbPages"
            :key="index"
            class="page-item"
            :class="{ active: page === index }"
          >
            <a
              class="page-link"
Florent Lavelle's avatar
dev
Florent Lavelle committed
              @click="page = index"
            >
              {{ index }}
            </a>
          </li>
        </div>
        <li
          class="page-item"
          :class="{ disabled: page === nbPages }"
        >
          <a
            class="page-link"
Florent Lavelle's avatar
dev
Florent Lavelle committed
            @click="page += 1"
          >
Florent Lavelle's avatar
Florent Lavelle committed
            <i
              class="ui icon big angle right"
              aria-hidden="true"
            />
Florent Lavelle's avatar
dev
Florent Lavelle committed
          </a>
        </li>
      </ul>
    </nav>
  </div>
</template>

<script>
export default {
  name: 'Pagination',

  props: {
    nbPages: {
      type: Number,
      default: 1
    },

    onPageChange: {
      type: Function,
      default: () => {
        return () => 1;
      }
    }
  },

  data() {
    return {
Florent Lavelle's avatar
Florent Lavelle committed
      currentLocation: `${window.location.origin}${window.location.pathname}#`,
Timothee P's avatar
Timothee P committed
    };
Florent Lavelle's avatar
dev
Florent Lavelle committed
  },

  watch: {
    page: function(newValue, oldValue) {
      if (newValue !== oldValue) {
        this.onPageChange(newValue);
        this.$emit('change-page', newValue);
      }
    }
  },

  methods: {
    pagination(c, m) {
      const current = c,
Timothee P's avatar
Timothee P committed
        last = m,
        delta = 2,
        left = current - delta,
        right = current + delta + 1,
        range = [],
        rangeWithDots = [];
Florent Lavelle's avatar
dev
Florent Lavelle committed
      let   l;

      for (let i = 1; i <= last; i++) {
        if (i === 1 || i === last || i >= left && i < right) {
Timothee P's avatar
Timothee P committed
          range.push(i);
Florent Lavelle's avatar
dev
Florent Lavelle committed
        }
      }
      for (const i of range) {
        if (l) {
          if (i - l === 2) {
Timothee P's avatar
Timothee P committed
            rangeWithDots.push(l + 1);
Florent Lavelle's avatar
dev
Florent Lavelle committed
          } else if (i - l !== 1) {
Timothee P's avatar
Timothee P committed
            rangeWithDots.push('...');
Florent Lavelle's avatar
dev
Florent Lavelle committed
          }
        }
        rangeWithDots.push(i);
        l = i;
      }

      return rangeWithDots;
    },

    changePage(num) {
      if (typeof num === 'number') {
        this.page = num;
      }
    }
  }
Timothee P's avatar
Timothee P committed
};
Florent Lavelle's avatar
dev
Florent Lavelle committed
</script>