Javascript paging component: xPagination. js example

Source: Internet
Author: User
Tags prev versions

After joining a new company, I have been very busy. My work in the new company includes writing some public components, such as calendars, pages, and so on. I think there are many people to use this paging component, so I made it independent, A native JS version without dependency is made for users who need it.

Component download: https://github.com/wslx520/wslx520.github.io/tree/master/pagination

Usage:
Var xxx = xPagination (pagediv, options );
Pagediv is a div node, and options is a parameter.

Options parameter description:
Supported options:
Max: displays multiple pages at most simultaneously.
Curr: current page number
Size: The number of entries displayed on each page. The default value is 15. It can be 15, 30, or 50. If the value is false, the label for switching the number of entries per page is not displayed.
2015.12.17: size can be used to input any number. If the value is not transferred or false, the default value is 15. It is no longer related to whether to display the number switching function.
Pages: A total of many pages. If you do not need to pass the parameter but only the items parameter, pages are calculated by the items and size parameters.
Items: recommended for the total number of data entries. With this parameter, you can dynamically modify the number of page numbers when switching the number of lines displayed per page.
Onpagination: This function is triggered when a page jump occurs. When this function is executed, two parameters are automatically input: page (current page) and size (number of items displayed on the current page)
Info: whether to display page number information. The default value is true. A page-text is added to display information such as "N pages in total, n pages currently".
2015.12.17: new function. info can be a function. This function receives options as a parameter, returns a string, inserts it into the div of info, and refreshes every page turning.
Jump: whether to allow page skipping. The default value is true. A page number input box and a confirmation button are added.
Prev: the text displayed on the previous page. If it is set to false, the previous page button is not displayed, the same below.
Next: text displayed on the next page, same as above
Last: the text displayed on the last page. The same as above. The default value is false (2015/12/14). This option is removed because the page number algorithm changes and the page number displays the first and last pages at any time, button is not needed)
First: text displayed on the home page button, same as above; default value: false /5/12/14
ShowSize: 2015.12.17 indicates whether to display the number of switches per page on the left. The default value is false. If it is set to true, the current page number is multiplied by 1, 2, and 3 respectively. If it is set to an array such as [20, 40, 80], the corresponding size switch is generated based on this array.

Properties of the xPagination instance:

Options: Object. Static setting options listed above
CurrPageElement: the node of the current page number.
PageList: Node array, page number node list


This article only describes some ideas for writing this component for your reference.

Update record:

: Fixed the bug: clicking the next page button is invalid (the page will jump to page 1st)

Reason: Previously, the total number of pages was saved with the pages local variable (if not passed, it would be 0), but it will be fixed again later. However, after I separate the function that generates the page number, of course, the code for resetting the pages variable is deleted. As a result, pages are always 0.

Solution: directly call options. pages. The value is set correctly.

------

The origin of this component was too hasty. I originally went to the headquarters to "learn" the component development method of this framework. At that time, I wrote a simple one, and later I needed to complete it, then I extracted a pure JS version, and then I want to maintain the two versions at the same time. Today I have updated the two versions at the same time, so I decided to release this article.

We have seen a lot of paging components, and we will not mention the style in this article. I will introduce some implementation logic on JS.

In the initial version, I plan to allow the paging component to customize the maximum number of pages displayed, whether to display the upper and lower pages, and the last pages of the home page; in addition, a function (used to initiate ajax requests) should be triggered during page skipping ).

Then, the requirement is added: to display omitted pages, for example, to display a maximum of eight pages at the same time, but you have 100 pages, a ellipsis will be displayed after the eight pages, so that users can know that there are still at the end.

This demand leads to another requirement: when I flip to the back page, the ellipsis will also be displayed in front; when the current page is very close to the first or last page, you need to hide the ellipsis (...) before or after.

Of course, there is also a need: when the first page is displayed, the buttons on the previous page and the home page will be disabled; when the last page is displayed, the buttons on the next and last pages will be disabled.

At that time, I still had a deep impression that when there was only one page in total, the buttons on the top and bottom pages and the buttons on the first and last pages should all be disabled. At that time, my judgment logic used else if, that is, if the current page is equal to 1, it would not be equal to the total number of pages -- the total number of results pages is 1, only the previous page button is disabled, but the next page button can be clicked.

Html structure:
The html structure is as follows:

Homepage-previous page-ellipsis-1, 2, 3, 4-ellipsis-next page-last page

At this time, I thought that if the current maximum number of 8 pages is displayed, but the total number of pages is only 5, there is no need to generate a ellipsis. An additional judgment is made: if the total number of pages exceeds the maximum and the number of pages is displayed, a ellipsis is generated.

Then the specific code is implemented. And I took a detour here.

First, it will save code and improve efficiency. I use an array for lis to save the html strings of all pages, and finally join and insert them to the corresponding node.

For example, if there are a total of 100 pages and a maximum of 8 pages are displayed at the same time, I will refresh all the pages when turning to 9th pages, from 1-8 to 2-9, the ellipsis is displayed. When the page number is near the last page, the ellipsis is hidden.

In order to control the display and hiding of two ellipsis, I plan to cache them as variables and then directly use hide (xxx.

However, the difficulty in caching these elements is that the buttons on top and bottom pages are optional, while the pages on my pages are all generated using innerHTML, therefore, you cannot obtain the corresponding elements directly during generation. Instead, you must calculate whether there is a previous page or homepage, calculate the index of the ellipsis in the corresponding situation, and then cache it.

I have made several bugs here, for example, when there are no buttons on the first and last pages, they are normal. Some people have added these two buttons, and my index is not correct, so an error is reported.

Finally, I wrote a long string of ternary operations to calculate the correct ellipsis index.

For the buttons on the top and bottom pages, the index of the buttons on the first and last pages also needs to be done in this way.

Fortunately, we have a standard document for paging components, which does not mention the first and last page features.

However, the page generation specification has been changed,

The new specification is as follows:
Previous Page-1-ellipsis, 12,13, 14-ellipsis-44-Next page

That is, the page number between 1 and the last page is always displayed, and the ellipsis appears between the middle and the last page. Therefore, the "first and last page" button is obviously no longer needed.

However, the previous page number generation rules will be overturned.

Similarly, I still intend to generate a ellipsis only when the total number of pages exceeds the maximum number of displayed pages.

After being changed to the subsequent specification, there are actually fewer dom elements. After half a month of other work, I reviewed the idea of generating a page number.

First, there must be at least one page

So I pushed a page directly to the lis array.

Then, push 2, 3, 4 in a loop... Note that the cycle starts from 2. When the maximum page is 1, this cycle does not enter.

Then, output the page number of the last page-the number of the last page will never change. You also need to judge that it is necessary to enter the last page only when the last page is greater than 1.

After all pages are pushed in, determine whether the previous page has the prev parameter. If yes, use unshift to add the previous page; if yes, use push.

Finally, the join array is still attached to the corresponding innerHTML.

Then there is a problem we have encountered before: how can we determine the index of the next page on the previous page and the two omitted pages?

A colleague reminded me that I should not write such a complicated judgment, directly loop through all the page numbers, and perform corresponding operations on the page numbers. Previously, I thought that this was not desirable in terms of performance. Later, I felt that this was not a serious drag on performance-because when I changed the page number in the middle part, it also passed the loop, even if you add the upper and lower pages and omit pages, there are four more pages.

As I know from the previous process of generating innerHTML, the top and bottom pages in the page number will never be changed after being generated. At most, the pages will be disabled, enabled, hidden, and displayed, and other numbers will be displayed, it will change the number, for example, from 2-7 to 3-8.

Therefore, I add a ui-page attribute to each page number. This is used to save the actual page number of the page number, but I set the top and bottom pages to prev and next respectively, if the page is omitted, it is ellipsis. When I loop through the page number queue, if it is a number, it changes innerHTML (here I first determine whether the current page needs to be changed, otherwise it will not change ); if these three words are used, the relationship between the current page and the total number of pages is determined and hidden and displayed.

Here we use A technique: when two functions A and B require the same parameters, and I want to call two functions separately based on different conditions, what should I do?

The answer is:

1
(Aaa? A: B) (arg1, arg2 );
For example, when the current page number is 1, I will disable prev; otherwise, I will enable prev, and disabled by addClass and removeClass, the two parameters are the same.

Page number generation algorithm

There are two different page number generation algorithms. The same is that the current page must always be in the center of the page number (of course, this is an exception if it is too front or back ). One is that when the numbers in the middle part of the page need to be updated, I wrote a function to calculate the number of pages that should start:

 

// Calculate the displayed page number based on the current page and total page number.
Pagec1c = function (curr, pages, max ){
// Console. log ('curr, pages, max', curr, pages, max)
Var start = 1,
// Var end = max;
// Var truehalf = max/2;
Half = Math. floor (max/2 ),
MaxLength = Math. min (pages, max)-1;
// If (pages <end ){
// End = pages;
//}
// Console. log ('Start, half, max', start, half, max)
// If the total number of pages has exceeded the maximum number of pages displayed, and the current page is greater than half of the maximum number of pages displayed, the current page is placed in the middle
If (pages> max & curr> = half ){
Start = curr-half;
// End = (curr + half)> pages? Pages: curr + half;
If (curr = pages-1 ){
// Start = curr-half-(half <truehalf? 1: 2 );
Start = curr-(half + 1 );
                }
If (curr === pages ){
Start = curr-maxLength;
Start = start | 1;
                }
            }
// If the start + maximum display page has exceeded the total number of pages, start needs to be moved forward
If (start + maxLength> pages ){
Start = pages-maxLength;
            }
Start = start> 0? Start: 1;
Return start;
        }
This function requires three parameters, which are the current page, the total number of pages, and the maximum number of simultaneously displayed pages. After execution, a start is returned, that is, the start page of the function. One of the most important points is that if the start + maximum display page has exceeded the total number of pages, start should be moved forward, make the page number generated by start end at the end of the last page (at the same time, the ellipsis at the end should also be hidden ).

In my paging component, there is a max parameter that specifies the maximum number of pages to be displayed at the same time, such as 8 pages and 7 pages. Therefore, he has the problem of parity. Pay special attention when calculating the page number.

Algorithm After requirement change

After the requirement is changed, since the numbers on the 1st and last pages remain unchanged, you can ignore them directly when refreshing the page number. This algorithm is simple and only involves logic issues:


// By default, it is assumed that the page number is center.
Var start = page-(Math. ceil (half-1)-1 );
If (page <= Math. ceil (half )){
// Front of the page number
Start = 2;
} Else if (page> = Math. ceil (pages-half )){
// Back the page number
Start = Math. floor (pages-half );
                    }
SetPageNumbers (start );
The half in it is max/2 (not rounded up), and the page is the incoming page number to jump to (that is, it will become curr ). We describe these algorithms in two different scenarios:

1, max = 8, pages = 21

Half is an integer of 4.

1) when curr (the current page, which I wrap up with []) is 1 by default, the html structure is as follows:

[1 ,..., 21

2) at this time, when curr> 4, for example, 5, the html structure will change:

1 ,..., 3, 4, [5], 6, 7, 8 ,..., 21

3) when curr is back, for example, 17:

1 ,..., , [17], 20, 21

4) when curr is <17, for example, 16:

1,..., 14,15, [16], 17,18, 19,..., 21

In this case, the 16 position is actually the same as the 5 position under 2).

2, max = 7, pages = 21

At this time, half is 3.5.

1) when curr = 1 by default

[1], 2, 3, 4, 5, 6 ,..., 21

In this case, one page is missing.

2) when curr = 5

1 ,..., 3, 4, [5], 6, 7 ,..., 21

3) when curr> 17, such as 18

1 ,..., 16,17, [18], 19,20, 21

4) when curr = 17

1 ,..., , [17 ,..., 21

Mom, I'm exhausted. Simply put, I got the final formula through the above inference.

Saving things in this province
For example, when pages <= max, there will be no ellipsis. In this case, you should directly change the page number and set the page number of the corresponding index to active. That's all, and no loop is needed.

Page number recalculation
For example, when I initialize, size = 15 and items = 300, the total page number is 20. I clicked it with a try. "30 & Prime ;, that is, if each page is changed to 30, the total page number should be changed to 10.

What's worse, if you are on page 20th and the total page number is 10, where should you go?

So I have to reset the page number and select the page number closest to the current page number.

This is just a way of thinking, so I will separate the function that generates the page number.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.