Home > other >  unordered list to flexbox
unordered list to flexbox

Time:10-25

Good afternoon folks,

I have an unordered list that I would like to apply pagination with flexboxes. Any help is highly appreciated:

> <template>
  <div id="app">

  <ul>

    <li v-for="item in items.results" :key="item.id">
        {{ item.pub_date }} {{item.image.file}} {{item.title}}
         <div >
          <span
            v-for="downloadable in item.downloadable.filter(d => !!d.document_en)"
            :key="downloadable.id"
           >{{ downloadable.document_en.file }}</span>
           </div>
    </li>
    </ul>

  
  </div>

</template>



<style>

</style>

CodePudding user response:

That's pretty much state forward.

Create few constants:

const ROW_PER_PAGE = 10;
const CURRENT_PAGE = 0;

add them in your data method:

return {
 rowPerPage: ROW_PER_PAGE,
 currentPage: CURRENT_PAGE,
 items: allMyData
}

use computed property to return only the required number of rows:

computed: {
 getPaginatedData() {
    const start = this.currentPage * this.rowPerPage;
    const end = start   this.rowPerPage;
    return this.items.slice(start, end); // end index won't be included
 }
}

Now simply use this getPaginatedData in your template

 <li v-for="item in getPaginatedData" :key="item.id">

The last piece is have buttons to change the page. And on each page change, simply update the currentPage var.

For adding pagination buttons, ofcourse you can create your own component, but if you are less on time then you may use per-developed component. The one which I like is https://getbootstrap.com/docs/4.0/components/pagination/

CodePudding user response:

Step 1: Create Pagination.vue component

<template>
  <ul >
    <li >
      <button type="button" @click="onClickFirstPage" :disabled="isInFirstPage">First</button>
    </li>
    <li >
      <button type="button" @click="onClickPreviousPage" :disabled="isInFirstPage">Previous</button>
    </li>
    <li :key="page.id" v-for="page in pages" >
      <button type="button" @click="onClickPage(page.name)" :disabled="page.isDisabled"
        :>{{ page.name }}</button>
    </li>
    <li >
      <button type="button" @click="onClickNextPage" :disabled="isInLastPage">Next</button>
    </li>
    <li >
      <button type="button" @click="onClickLastPage" :disabled="isInLastPage">Last</button>
    </li>
  </ul>
</template>

<script>
export default {
  name: 'pagination',
  props: {
    maxVisibleButtons: {
      type: Number,
      required: false,
      default: 3
    },
    totalPages: {
      type: Number,
      required: true
    },
    perPage: {
      type: Number,
      required: true
    },
    currentPage: {
      type: Number,
      required: true
    }
  },
  computed: {
    isInFirstPage () {
      return this.currentPage === 1
    },
    isInLastPage () {
      if (this.totalPages === 0) {
        return true
      }
      return this.currentPage === this.totalPages
    },
    startPage () {
      // When on the first page
      if (this.currentPage === 1) {
        return 1
      }
      // When on the last page
      if (this.totalPages < this.maxVisibleButtons) {
        return 1
      }
      if (this.currentPage === this.totalPages) {
        return this.totalPages - this.maxVisibleButtons   1
      }
      // When in between
      return this.currentPage - 1
    },
    endPage () {
      if (this.totalPages === 0) {
        return 1
      }
      if (this.totalPages < this.maxVisibleButtons) {
        return this.totalPages
      }
      return Math.min(this.startPage   this.maxVisibleButtons - 1, this.totalPages)
    },
    pages () {
      const range = []
      for (let i = this.startPage; i <= this.endPage; i = 1 ) {
        range.push({
          name: i,
          isDisabled: i === this.currentPage 
        })
      }
      return range
    }
  },
  methods: {
    onClickFirstPage () {
      this.$emit('pagechanged', 1)
    },
    onClickPreviousPage () {
      this.$emit('pagechanged', this.currentPage - 1)
    },
    onClickPage (page) {
      this.$emit('pagechanged', page)
    },
    onClickNextPage () {
      this.$emit('pagechanged', this.currentPage   1)
    },
    onClickLastPage () {
      this.$emit('pagechanged', this.totalPages)
    },
    isPageActive (page) {
      return this.currentPage === page
    }
  }
}
</script>

<style scoped>
  .pagination {
    list-style-type: none;
    float: right;
    margin: 10px 0;
  }
  .pagination-item {
    display: inline-block;
  }
  .active {
    background-color: #943849;
    color: #ffffff !important;
    font-weight: bold;
  }
  button[disabled], html input[disabled] {
    cursor: default;
    color: lightgray;
  }
</style>

Step 2: Add Pagination component reference in app.vue component

import Pagination from './components/Pagination'

Add Pagination component in app.vue

export default {
  components: {
   Pagination,
},

Step 3: Create model data with pagination object

data() {
  return {
    items:[],
    page: 1,
    totalPages: 0,
    totalRecords: 0,
    recordsPerPage: 10
  }
},

Step 4: Create an methods for load data and adding pagination

methods: {
  loadPressRelease () {
    this.showLoader = true
    axios.get(`https://zbeta2.mykuwaitnet.net/backend/en/api/v2/media-center/press-release/?page=${this.page}&page_size=${this.recordsPerPage}&type=5`)
    .then(response => {
      this.showLoader = false
      this.items = response.data
      this.totalPages = Math.ceil(response.data.count / this.recordsPerPage)
      this.totalRecords = response.data.count
    })
  },
  onPageChange(page) {
    this.page = page
    this.loadPressRelease()
  }
}

Step 5: Default page load on created methods

created() {
  this.loadPressRelease()
},

Step 6: HTML template with pagination reference

<div id="app">
    <ul>
      <li v-for="item in items.results" :key="item.id">
        {{ item.pub_date }} {{item.image && item.image.file}} {{item.title}}
        <div >
          <span v-for="downloadable in item.downloadable.filter(d => !!d.document_en)"
            :key="downloadable.id">{{ downloadable.document_en.file }}
          </span>
        </div>
      </li>
    </ul>
    <Pagination v-if="items.results" :total-pages="totalPages" :per-page="this.recordsPerPage" :current-page="page" @pagechanged="onPageChange" />
 </div>

DEMO with Loader

  • Related