0

I have a question about vue pagination. So, I have a ticket object that you can see code below. Currently it displays something like this: enter image description here

So what I am trying to achieve is to display all the tickets in my object. But weekly. I mean this week is the 31st week of the year. Then from today to Sunday, it should show on the first page. But from next Monday to Sunday (32nd week), it should be displayed on the next page, when you click the next button. So I could able to find the weeks of the object in my case it includes 31, 32 and 33 and since there is 3 different weeks, you can click the next button 2 times(because there is 3 different weeks/pages). What I couldnt do, pagination. I would be really glad, if you can help me with this. Here is my component:

<template>
    <div class="container" id="app">
        <div class="filter input-group mb-3">
        </div>
        <table class="table" v-for="date in dateSets()">
            <thead>
            <tr class="list-heading">
                <td colspan="3">
                    {{ date.getDate() }}/{{ date.getMonth() + 1 }}/{{
                        date.getFullYear()
                    }}
                    {{ setDayOfDate(date.getDay()) }}
                </td>
            </tr>
            </thead>
            <tbody>
            <tr class="list-content" v-for="ticket in findProducts(tickets, date)">
                <!--                <th>{{ (currPage-1) * countOfPage + index + 1 }}</th>-->
                <td>{{ ticket.time }}</td>
                <td>{{ ticket.date }}</td>
                <td>{{ ticket.name }}</td>
            </tr>
            </tbody>
        </table>
        <nav aria-label="Page navigation">
            <ul class="pagination justify-content-center">
                <li
                    class="page-item"
                    v-bind:class="{ disabled: currPage === 1 }"
                    @click.prevent="setPage(currPage - 1)"
                >
                    <a class="page-link" href="">Prev</a>
                </li>
                <li
                    class="page-item"
                    v-bind:class="{ disabled: currPage === weeksSize }"
                    @click.prevent="setPage(currPage + 1)"
                >
                    <a class="page-link" href="">Next</a>
                </li>
            </ul>
        </nav>
    </div>
</template>

<script>
export default {
    data() {
        return {
            currPage: 1,
            filter_name: "",
            tableHeader: "",
            // oldestFirst: false,
            weeks: new Set(),
            tickets: [
                {
                    id: 0,
                    time: "09:45",
                    date: new Date(),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 1,
                    time: "09:45",
                    date: new Date(),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 2,
                    time: "09:45",
                    date: new Date("2021-08-06"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 3,
                    time: "06:30",
                    date: new Date("2021-08-05"),
                    name: "Schwimmen im Hangeweiher",
                },
                {
                    id: 4,
                    time: "09.45",
                    date: new Date("2021-08-03"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 5,
                    time: "09.45",
                    date: new Date("2021-08-07"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 6,
                    time: "09.45",
                    date: new Date("2021-08-08"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 7,
                    time: "09:45",
                    date: new Date("2021-08-09"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 8,
                    time: "09:45",
                    date: new Date("2021-08-10"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 9,
                    time: "09:45",
                    date: new Date("2021-08-09"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 10,
                    time: "06:30",
                    date: new Date("2021-08-10"),
                    name: "Schwimmen im Hangeweiher",
                },
                {
                    id: 11,
                    time: "09.45",
                    date: new Date("2021-08-12"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 12,
                    time: "09.45",
                    date: new Date("2021-08-11"),
                    name: "Swimming in the hillside pond",
                },
                {
                    id: 13,
                    time: "09.45",
                    date: new Date("2021-08-13"),
                    name: "Swimming in the hillside pond",
                },
            ],
        };
    },
    computed: {
        weeksSize() {
            const s = this.getAllWeekNumbers(this.tickets);
            return s.size;
        },
        splitDate: function () {
            let newDate = [...this.list];
            newDate.map((el) => {
                return (el.date = el.date.split(" "));
            });
            return newDate;
        },
    },
    methods: {
        setPage: function (idx) {
            if (idx <= 0 || idx > this.totalPage) {
                return;
            }
            this.currPage = idx;
        },
        currentDate() {
            const current = new Date();
            const date = `${current.getDate()}/${
                current.getMonth() + 1
            }/${current.getFullYear()}`;
            return date;
        },
        dateSets() {
            const today = new Date();
            const sunday = new Date();
            sunday.setDate(sunday.getDate() - sunday.getDay() + 7);
            const dates = [];
            const diff = sunday.getDate() - today.getDate();
            for (let i = 0; i <= diff; i++) {
                const upDate = new Date();
                upDate.setDate(today.getDate() + i);
                dates.push(upDate);
            }
            console.log(dates);
            return dates;
        },
        setDayOfDate(number) {
            if (number === 0) {
                return "Sonntag";
            } else if (number === 1) {
                return "Montag";
            } else if (number === 2) {
                return "Dienstag";
            } else if (number === 3) {
                return "Mittwoch";
            } else if (number === 4) {
                return "Donnerstag";
            } else if (number === 5) {
                return "Freitag";
            } else {
                return "Samstag";
            }
        },
        getAllWeekNumbers(tickets) {
            tickets.forEach(ticket => {
                let result = this.getWeekNumber(ticket.date);
                this.weeks.add(result)
            });
            this.sortSet(this.weeks);
            console.log(this.weeks);
            return this.weeks;
        },
        getWeekNumber(date) {
            const oneJan = new Date(date.getFullYear(), 0, 1);
            const numberOfDays = Math.floor((date - oneJan) / (24 * 60 * 60 * 1000));
            let weekNumber = Math.ceil((date.getDay() + 1 + numberOfDays) / 7);
            return weekNumber;
        },
        sortSet(set) {
            const entries = [];
            for (const member of set) {
                entries.push(member);
            }
            set.clear();
            for (const entry of entries.sort()) {
                set.add(entry);
            }
            return set;
        },
        findProducts(products, date) {
            return products.filter((product) => {
                return (
                    product.date.getDate() === date.getDate() &&
                    product.date.getMonth() === date.getMonth() &&
                    product.date.getFullYear() === date.getFullYear()
                );
            });
        },
    },
};
</script>

I know it is a little bit long but I have been struggling with this for a while. So please have a look and give me some advice. Thanks

magic bean
  • 787
  • 12
  • 39

1 Answers1

1

I'm guessing you want to do this in the frontend (usually pagination is done BE-side, so you'd receive an array of weeks by an API e.g.).

I'd strongly recommend to use a library like https://date-fns.org/ or https://momentjs.com/ in this case. With that, you can do easy operations on dates, so you could cluster your array of tickets and order them by the week, like ..

import { getWeek } from "date-fns";

let currentWeek = getWeek(tickets[0].date, { weekStartsOn: 1 });

// contains all the 'week'-arrays - represents your pages in the pagination.
const ticketsClustered = [];

// contains all tickets of one week
let week = [];

tickets.forEach((ticket) => {
  if (getWeek(ticket.date, { weekStartsOn: 1 }) === currentWeek) {
    week.push(ticket);
  } else {
    ticketsClustered.push(week);

    // clear the array and increment the week
    week = [];
    currentWeek++;
  }
});

ticketsClustered.push(week);

The output would be an array which contains arrays with tickets itself. This would represent your pages (or weeks) in the end.

As your tickets are not really sorted by date now, you should sort them (e.g. like described here or with 'datefns').

pacman
  • 156
  • 1
  • 4