Alexander Mashkevich
Alexander Mashkevich

Reputation: 29

Acknowledged and accepted algorithm or utility for a paging navigation rendering?

Is there already an acknowledged .NET implementation for a page navigation rendering with skips? E.g.:

1) 12 pages, subset size 6, current page 9 will produce: 1 ... 9 10 11 12 (dots lead to page 4)

2) 5 pages, subset size 3, current page 3 will produce: ... 3 ... (dots lead to 1-2 and 4-5)

3) 14 pages, subset size 8, current page 6 will produce: 1 ... 5 6 8 9 ... 14 (dots lead to 3 and 11)

The result must be an array or list to be used in rendering. The links below do not give the acceptable implementation/unit testing:

Smart pagination algorithm

Algorithm / pseudo-code to create paging links?

Making First, Last, Next 10, Prev 10 is irrelevant here.

Doing this myself feels like reinventing the bicycle.

Upvotes: 1

Views: 210

Answers (2)

Doin
Doin

Reputation: 8174

It may be overkill for a small number of pages, but for paginating really large data sets, consider the logarithmic technique described here. I posted algorithms for that in both PHP and (classic) ASP, but it'd be quite easy to convert to ASP.NET.

Upvotes: 0

Alexander Mashkevich
Alexander Mashkevich

Reputation: 29

Got no answer and had to write my own. Maybe this may be useful to someone...

Negative values tell that "..." must be used and the abs of the value gives a page number where "..." leads to. The result array is to be used to render the navigation pages.

/// <summary>
        /// Creates the template to be used for rendering the page navigation with skips.
        /// </summary>
        /// <param name="a_pagesNum"></param> Total pages number
        /// <param name="a_pageSetSize"></param> The size of the page set to render
        /// <param name="a_curPageNum"></param> The current page number (not index)
        /// <returns></returns>
public static int[] DoPageDist(int a_pagesNum, int a_pageSetSize, int a_curPageNum)
        {
            // Validate 
            if (a_pagesNum < 1 || a_pageSetSize < 1 || a_curPageNum < 1 | a_curPageNum > a_pagesNum)
            {
                return null;
            }

            if (a_pageSetSize > a_pagesNum)
            {
                a_pageSetSize = a_pagesNum;
            }

            // What are the conditions around the current index?
            int leftNums = a_curPageNum;
            int rightNums = a_pagesNum - a_curPageNum;
            int rightSlots = a_pageSetSize / 2;
            int leftSlots = rightSlots + a_pageSetSize % 2;

            int tail = rightNums - rightSlots;
            if (tail < 0)
            {
                leftSlots -= tail;
            }
            else
            {
                tail = leftNums - leftSlots;
                if (tail < 0)
                {
                    rightSlots -= tail;
                }
            }

            int[] result = new int[a_pageSetSize];

            int slotNum = 0;
            for (int idx = (a_pageSetSize > 2) ? 1 : a_curPageNum - leftSlots + 1; idx <= a_pagesNum && slotNum < a_pageSetSize; idx++)
            {
                if (idx <= a_curPageNum)
                {
                    if ((1 == idx && a_pageSetSize > 4) ||
                        (idx >= a_curPageNum - (leftSlots - 1)))
                    {
                        result[slotNum] = idx;
                    }
                    else
                    {
                        result[slotNum] = (slotNum > 0) ? -((a_curPageNum - (leftSlots - 2)) / 2) : -1;
                        idx = a_curPageNum - (leftSlots - 2) - 1;
                    }
                    leftSlots--;
                }
                else
                {
                    if ((rightNums - rightSlots <= 0) ||
                        (idx <= a_curPageNum + (rightSlots - 2)) ||
                        (idx == a_pagesNum))
                    {
                        result[slotNum] = idx;
                    }
                    else if (idx < a_pagesNum)
                    {
                        result[slotNum] = (slotNum < a_pageSetSize - 1) ? -(idx + (a_pagesNum - idx) / 2) : -a_pagesNum;
                        idx = a_pagesNum - (a_pageSetSize - slotNum - 1);
                    }
                }
                slotNum++;
            }

            return result;
        }

Upvotes: 1

Related Questions