-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix multi-row range selection on lazily paginated multi-selection Datatable (#7227) #7226
Open
henrynguyen7
wants to merge
1
commit into
primefaces:master
Choose a base branch
from
henrynguyen7:patch-1
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…atable On a datatable that has the paginator enabled, with lazy=true, and selectionMode="multiple", then on the first page, shift-clicking multiple rows functions properly as expected by selecting all shift-clicked rows. However, when navigating to any page other than the first page, shift-clicking does NOT work, and instead cancels out any selection. What's happening is that inside the [`selectRange()`](https://github.com/primefaces/primevue/blob/master/packages/primevue/src/datatable/DataTable.vue#L1190) method of datatable, `this.processedData` contains an array of data that is rendered on the current page of the table, and we use the indexes of rows that the user has shift+clicked in order to access the array by those indexes, which we call [`rangeStart` and `rangeEnd`](https://github.com/primefaces/primevue/blob/master/packages/primevue/src/datatable/DataTable.vue#L1190). For example, consider a collection of data containing 50 total items. On a datatable displaying 10 rows at a time, `this.processedData` will contain an array of length 10, and when the user shift+clicks the first three rows, we will assign a `rangeStart` of 0 and a `rangeEnd` of 2 for selection. The problem is that when we navigate to the other pages other than the first, `this.processedData` still only contains a subset of the total dataset, but our `rangeStart` and `rangeEnd` indexes contain the indexes relative to the entire total dataset. Continuing on with the previous example, when we navigate to page 2 and try to shift+click the first three rows, `this.processedData` still only contains an array of length 10, since we are only rendering 10 items at a time, but `rangeStart` will be 10 and `rangeEnd` will be 12, which are both outside the bounds of the `this.processedData` array so no rows end up being selected. Currently there is [code that meant to account for this](https://github.com/primefaces/primevue/blob/master/packages/primevue/src/datatable/DataTable.vue#L1182C13-L1182C45), by subtracting the number rows from previous pages so that we get the properly offset indexes relative to the `this.processedData` subset, not the total. Specifically, it first determines `rangeStart` and `rangeEnd` relative to the total dataset, and then subtracts `this.first` from both values, where `this.first` appears as though it's meant to be the number of items that are contained in the pages previous to the current page (a.k.a. the index of the _first_ item on the _current_ page of the subset of data from the total dataset). The bug is that `this.first` does not actually contain the expected value here to properly perform the offset. Continuing from the above example, when shift+clicking the first three rows on the second page of results, `rangeStart` and `rangeEnd` will be 10 and 12 respectively, and we would expect that we subtract 10 from the first page of results to get correct values of 0 and 2. However, `this.first` is actually 0, and so we end up with `rangeStart` and `rangeEnd` of 10 and 12, which are outside the bounds of `this.processedData` which cannot be processed on subsequent lines. This PR attempts to fix this bug by adjusting the subtraction to use `this.d_first` instead of `this.first`, which has been confirmed to contain the desired value of the total number of rows in previous pages. In the above example, it contains 10 for the second page, 20 for the third page, 30 for the fourth page, so on, which causes `rangeStart` and `rangeEnd` to contain the proper expected values for accessing `this.processedData` correctly. Alternatively, we could've instead updated the assignment of `this.first` to contain `this.d_first`, so that the current code here would function correctly. However, I'm not sure what other undesired effects that might cause, so am requesting more knowledgeable eyes to review the above proposal. Many thanks!! 🙏 ❤️
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 2 Skipped Deployments
|
Open
4 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Attempts to fix #7227.
On a datatable that has the paginator enabled, with lazy=true, and selectionMode="multiple", then on the first page, shift-clicking multiple rows functions properly as expected by selecting all shift-clicked rows. However, when navigating to any page other than the first page, shift-clicking does NOT work, and instead cancels out any selection.
What's happening is that inside the
selectRange()
method of datatable,this.processedData
contains an array of data that is rendered on the current page of the table, and we use the indexes of rows that the user has shift+clicked in order to access the array by those indexes, which we callrangeStart
andrangeEnd
. For example, consider a collection of data containing 50 total items. On a datatable displaying 10 rows at a time,this.processedData
will contain an array of length 10, and when the user shift+clicks the first three rows, we will assign arangeStart
of 0 and arangeEnd
of 2 for selection.The problem is that when we navigate to the other pages other than the first,
this.processedData
still only contains a subset of the total dataset, but ourrangeStart
andrangeEnd
indexes contain the indexes relative to the entire total dataset. Continuing on with the previous example, when we navigate to page 2 and try to shift+click the first three rows,this.processedData
still only contains an array of length 10, since we are only rendering 10 items at a time, butrangeStart
will be 10 andrangeEnd
will be 12, which are both outside the bounds of thethis.processedData
array so no rows end up being selected.Currently there is code that is meant to account for this, by subtracting the number rows from previous pages so that we get the properly offset indexes relative to the
this.processedData
subset, not the total. Specifically, it first determinesrangeStart
andrangeEnd
relative to the total dataset, and then subtractsthis.first
from both values, wherethis.first
appears as though it's meant to be the number of items that are contained in the pages previous to the current page (a.k.a. the index of the first item on the current page of the subset of data from the total dataset).The bug is that
this.first
does not actually contain the expected value here to properly perform the offset. Continuing from the above example, when shift+clicking the first three rows on the second page of results,rangeStart
andrangeEnd
will be 10 and 12 respectively, and we would expect that we subtract 10 from the first page of results to get correct values of 0 and 2. However,this.first
is actually 0, and so we end up withrangeStart
andrangeEnd
of 10 and 12, which are outside the bounds ofthis.processedData
which cannot be processed on subsequent lines.This PR attempts to fix this bug by adjusting the subtraction to use
this.d_first
instead ofthis.first
, which has been confirmed to contain the desired value of the total number of rows in previous pages. In the above example, it contains 10 for the second page, 20 for the third page, 30 for the fourth page, so on, which causesrangeStart
andrangeEnd
to contain the proper expected values for accessingthis.processedData
correctly.Alternatively, we could've instead updated the assignment of
this.first
to containthis.d_first
, so that the current code here would function correctly. However, I'm not sure what other undesired effects that might cause, so am requesting more knowledgeable eyes to review the above proposal. Many thanks!! 🙏 ❤️###Defect Fixes
#7227
###Feature Requests
Due to company policy, we are unable to accept feature request PRs with significant changes as such cases has to be implemented by our team following our own processes.