Web sites often have lists and tables, divided into many pages with the possibility of switching between them. Sometimes on the lines of such lists you can perform some operations. Here are some examples:
- Moderating a web forum: bulk transfer, blocking, deleting topics.
- Mail client: mark selected messages as (un) read, add label, transfer to spam.
- The system of scientific data processing: highlight the lines of interest in a subset, mark with color as worthy of attention.
In all these cases, usability problems arise when there are more than one page. Is it possible to select all the lines of the list, and not just the current page? And all without one? Correctly invert selection? Select all the lines from the 1245th to the end, despite the fact that there are only 100 lines on one page, and 5000 lines in total in the list?
I came up with a simple thing that allows you to solve all these tasks. It is implemented in a single commercial web application and has worked well. I have not seen a more convenient solution, so I present to the public.
First, a couple of existing solutions. Here is GMail (using the spam folder as an example):

You can select the current page, and GMail gets out, showing the message “select all threads”:

Now, if I uncheck one box, will it be selected, 2735 messages or only 24 on the current page? I am no longer sure, and it is not written anywhere. In fact, it turns out 24, that is, to remove everything except one becomes a non-trivial task. If I removed one tick and put it again, I seemed to return everything as it was, but in reality only the current page was selected, and I’m no longer offered to select everything. The ability to invert the selection is not provided at all.
Old phpBB gets out differently:

You can select only on the current page, but there is an action “delete everything except the selected one”, that is, the tasks of inverting the selection and applying the action to all lines except one are solved. However, for each action an extra button is added and intuitiveness is lost. If there are a lot of actions, you can make the switch “perform an action for selected lines / for all lines except for selected ones”, but to select lines that you want to leave alone is somewhat awkward and incomprehensible.
')
My solution is:

If the page is not the first, an additional tick "+ X entries on previous pages" appears above the list. If the page is not the last, a check mark "+ Y records on subsequent pages" appears under the list. There are separate buttons “select page” (without these two checkboxes) and “select all”. If the list occupies one page, the button “select page” disappears.
I see the following advantages:
- Unlike GMail, it is always clear which specific lines are highlighted, including the lines on other pages.
- Removing and returning any checkbox results in the selection in the previous state.
- It is easy and intuitive to select everything, deselect a pair of lines and apply the action to all lines except this pair. It is also easy to apply an action only to all lines of this page except for a few. There is no need for buttons “to execute for all lines except selected ones”.
- The "invert" button simply switches the state of all the checkboxes and at the same time really correctly inverts the selection in the entire list.
- You can perform actions on the lines "from the beginning of the list to this" or "from this and to the end of the list" regardless of the location of this line. Highlight such ranges easily and intuitively using shift, grabbing one of the new checkboxes. Of course, such a range is also correctly inverted.
- New checkboxes along with a page switch additionally signal whether this page is the first or the last. This is convenient and reduces the number of erroneous actions.
As always, it was not without drawbacks:
- Additional implementation complexity. If regular checkboxes can refer to a unique identifier of a string, then the installation of new ones should either transfer to the server the identifiers of all the rows on other pages, or the server should be able to recover which records go on the following pages. If the list can be sorted and filtered in different ways, this should also be taken into account.
- Difficulties may arise if the list could change in the process. Say, on the given example, a new letter arrived, and I ticked off “+25 on the previous pages” and clicked “delete”. Should the action be applied to the new letter too, that is, in fact +26? This may depend on the semantics of the list. If not, the server should be able to restore the list in the same form that was at the time of loading the page. Keep the row order in the session? If the user within the same session in different windows at different times, opened the list? Issue a unique identifier and store all these lists? In general, there are some difficulties.
- The support of such features as “select read letters” is unclear. Apparently, this will still work within the current page, which is not very convenient.
In our application it was easier, because once the list created could not change, any changes created a new copy. Therefore, when performing a list action, the current sorting and filtering parameters were transmitted, and the server could accurately restore the order of the rows. We did not have the last problem either.
I would be glad if someone come in handy. If anyone has seen something similar or better, please write in the comments.