Skip to content
Snippets Groups Projects
Pagination.vue 2.95 KiB
Newer Older
  • Learn to ignore specific revisions
  • <template>
    
    Georg Krause's avatar
    Georg Krause committed
      <div
        v-if="maxPage > 1"
        class="ui pagination menu component-pagination"
        role="navigation"
        :aria-label="labels.pagination"
      >
        <a
          href
    
          :disabled="current - 1 < 1"
    
          role="button"
          :aria-label="labels.previousPage"
    
    Georg Krause's avatar
    Georg Krause committed
          :class="[{'disabled': current - 1 < 1}, 'item']"
    
          @click.prevent.stop="selectPage(current - 1)"
    
    Georg Krause's avatar
    Georg Krause committed
        ><i class="angle left icon" /></a>
    
        <template v-if="!compact">
    
    Georg Krause's avatar
    Georg Krause committed
          <a
    
            v-for="page in pages"
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
            :key="page"
    
    Georg Krause's avatar
    Georg Krause committed
            href
            :class="[{'active': page === current}, {'disabled': page === 'skip'}, 'item']"
    
    Georg Krause's avatar
    Georg Krause committed
          >
    
    Ciarán Ainsworth's avatar
    Ciarán Ainsworth committed
            <span v-if="page !== 'skip'">{{ page }}</span>
            <span v-else></span>
    
          </a>
    
    Georg Krause's avatar
    Georg Krause committed
        <a
          href
    
          :disabled="current + 1 > maxPage"
    
          role="button"
          :aria-label="labels.nextPage"
    
    Georg Krause's avatar
    Georg Krause committed
          :class="[{'disabled': current + 1 > maxPage}, 'item']"
    
          @click.prevent.stop="selectPage(current + 1)"
    
    Georg Krause's avatar
    Georg Krause committed
        ><i class="angle right icon" /></a>
    
      </div>
    </template>
    
    <script>
    
    Kasper Seweryn's avatar
    Kasper Seweryn committed
    import { range as lodashRange, sortBy, uniq } from 'lodash-es'
    
    
    export default {
      props: {
    
        current: { type: Number, default: 1 },
        paginateBy: { type: Number, default: 25 },
    
    Georg Krause's avatar
    Georg Krause committed
        total: { type: Number, required: true },
    
        compact: { type: Boolean, default: false }
    
      },
      computed: {
    
    Georg Krause's avatar
    Georg Krause committed
        labels () {
    
    Georg Krause's avatar
    Georg Krause committed
            pagination: this.$pgettext('Content/*/Hidden text/Noun', 'Pagination'),
            previousPage: this.$pgettext('Content/*/Link', 'Previous Page'),
            nextPage: this.$pgettext('Content/*/Link', 'Next Page')
    
    Georg Krause's avatar
    Georg Krause committed
        pages: function () {
          const range = 2
          const current = this.current
    
    Kasper Seweryn's avatar
    Kasper Seweryn committed
          const beginning = lodashRange(1, Math.min(this.maxPage, 1 + range))
          const middle = lodashRange(
    
            Math.max(1, current - range + 1),
            Math.min(this.maxPage, current + range)
          )
    
    Kasper Seweryn's avatar
    Kasper Seweryn committed
          const end = lodashRange(this.maxPage, Math.max(1, this.maxPage - range))
    
          let allowed = beginning.concat(middle, end)
    
    Kasper Seweryn's avatar
    Kasper Seweryn committed
          allowed = uniq(allowed)
          allowed = sortBy(allowed, [
    
    Georg Krause's avatar
    Georg Krause committed
          const final = []
    
          allowed.forEach(p => {
    
    Georg Krause's avatar
    Georg Krause committed
            const last = final.slice(-1)[0]
    
            let consecutive = true
    
    Georg Krause's avatar
    Georg Krause committed
            if (last === 'skip') {
    
              consecutive = false
            } else {
              if (!last) {
                consecutive = true
              } else {
                consecutive = last + 1 === p
              }
            }
            if (consecutive) {
              final.push(p)
            } else {
    
    Georg Krause's avatar
    Georg Krause committed
              if (p !== 'skip') {
                final.push('skip')
    
                final.push(p)
              }
            }
          })
          return final
    
    Georg Krause's avatar
    Georg Krause committed
        maxPage: function () {
    
          return Math.ceil(this.total / this.paginateBy)
        }
      },
      methods: {
    
    Georg Krause's avatar
    Georg Krause committed
        selectPage: function (page) {
    
          if (page > this.maxPage || page < 1) {
            return
          }
    
          if (this.current !== page) {
    
    Georg Krause's avatar
    Georg Krause committed
            this.$emit('page-changed', page)