Needs work
Project:
Views Infinite Scroll
Version:
2.0.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
12 Feb 2016 at 09:14 UTC
Updated:
10 Jul 2023 at 10:21 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
david.gil commentedThis could help, interested in this issue...
https://css-tricks.com/rethinking-dynamic-page-replacing-content/
best
David
Comment #3
david.gil commentedHi,
i have a solution for this problem using an external library:
https://github.com/highrisehq/snapback_cache.
For those of you that need something similar i just created a custom JS function in my theme:
In my views-infinite-scroll-pager.html.twig i have added a class to views-infinite-scroll : js-infinite-scroll
Works perfect!
Comment #4
david.gil commentedHere is my last version of this:
Comment #5
vinlaurens commentedI am proposing a patch for this issue to incorporate this functionality into views_infinite_scroll. A patch is attached.
The patch offers an extra option in views_infinite_scroll settings interface where one can select to "preserve history" on a per view/per display basis when using the back button. It also works with views in blocks.
The solution works with sessionStorage to save the current status of the view. window.performance.navigation is used to determine if the user used the back button functionality. This methodology appears supported by all major browsers.
Any feedback is appreciated.
Comment #6
vinlaurens commentedWhoops. Seems something went wrong with attaching the patch.
Comment #7
vinlaurens commentedFixing schema.
Comment #8
vinlaurens commentedComment #9
legolasboWouldn't it be possible to store a single object containing both the previousItems (content?) and the previousPager? That would make checking for presence of data and clearing data from session storage a lot more straight forward.
Wouldn't 'hasDataInSessionStorage' be more descriptive for this method?
'getContentFromSessionStorage' would better describe this method.
Same here, this gets a pager from session storage, so 'getPagerFromSessionStorage' would be more appropriate.
I also noticed that getContent and getPager both have the same code, differing only in the item they get from session storage. This duplication should be removed.
This could do with some blank lines to improve readability.
Besides that, I'm wondering what
$('.view-id-'+viewId+'.view-display-id-'+viewDisplay+'.js-view-dom-id-'+domViewId.replace('views_dom_id:', '')+' > .view-content > .views-infinite-scroll-content-wrapper', context).append(content);does, it's one excessively long line. Can't that be broken up into several more descriptive statements?Do we really need to manually escape HTML? Can't we use some built in HTMLEncode function?
We're bound to have forgotten a symbol which someone surely is going to have inserted into the content being displayed in a view, which would then break everything. So let's try to not re-invent the wheel.
Why was this comment removed?
I like how you've made this option opt-in so it doesn't affect existing sites unless they want it to.
These changes are unrelated.
This newline is unrelated.
So the default setting is to have history preservation turned off, but if the option hasn't been set yet we're turning it on? Seems like an error to me.
Oops. patchception. (in other words, you've added a patch to your patch)
Comment #10
vinlaurens commentedThanks @legolasbo for your comments. I looked into them and provide the following patch. I agree with a lot of your points and they have been reflected in this new patch.
The line is long because the content has to be appended in the exact right spot (children of certain identifiers, these identifiers include the view id, display id and dom id). This is to ensure we are really replacing the content of the right view. If you have suggestions on how to make this shorter without losing it's specificness, I'm open to ideas.
There doesn't appear to be a good solution for this in javascript (as far as I know). The developers of mustache.js apparently had the same problem (https://github.com/janl/mustache.js/blob/master/mustache.js#L60) and this is where I took this code excerpt from.
The patchception has been removed in the latest patch. ;)
Comment #11
vinlaurens commentedComment #12
legolasboYou could use encodeURIComponent and it's decodeURIComponent counterpart.
Your latest patch seems to be missing this file. Are you sure you've got all relevant changes in there?
Comment #13
vinlaurens commentedMy bad. It was indeed accidentally omitted from the patch. I've corrected this in the new patch.
This doesn't seem to escape all special characters in my local environment. I see special characters popping up when loading content from sessionStorage. I will look into this further, but my current patch still uses the "old" method.
Comment #14
vinlaurens commentedComment #15
legolasboI'm not sure what this does exactly, but to me it seems like you're searching for some matches in the class list of an element selected through jQuery.
Extracting the parameter for .exec() into a variable and giving that variable a meaningfull name would make this code easier to read and understand.
I see this
"viewsPreviousData_"+viewsIdentifierrepeated quite a bit. how about extracting that into agetSessionStorageId(viewIdentifier)function.reads a lot better.
This could be something like
to make it easier to read and understand what's going on.
Here you default preserve_history to FALSE in php. In javascript you do the opposite...
Here you default preserve-history to TRUE in javascript. In PHP you do the opposite...
In regards to
encodeURIComponent... if it doesn't work, then it doesn't work.Comment #16
vinlaurens commented@legolasbo Thank you for your comments. I've changed the patch accordingly.
Regarding your points 5 and 6; I took the example of views_infinite_scroll itself in how it acts on the "automatic scrolling" setting. It also uses a default value of FALSE, while TRUE is defined in the preprocess function.
views_infinite_scroll.module
InfiniteScroll.php
I think this should be modified as well, in that case. It is not part of this change, so this is not included in this patch. I've tested the preserve history functionality with FALSE for "preserve-history" in views_infinite_scroll_preprocess_views_infinite_scroll_pager() and it appears to work correctly with that change. I've included the change for "preserve-history" in this patch as a consequence.
Comment #17
vinlaurens commentedComment #19
vinlaurens commentedApparently changing the value for preserve-history to FALSE will fail testing.
Comment #20
vinlaurens commentedComment #21
luksakThere are a lot of selectors used in this script that don't have a
js-prefix wich are not present in my custom theme and therefore completely breaks the functionality. After switching to the seven theme, the patch works perfectly. How could we resolve this?Comment #22
vinlaurens commentedLukas, few questions.
Initially I developed this patch for a customer with a custom theme based on "classy". Does your custom theme perhaps omit important Drupal css classes/ids?
Comment #23
YurkinPark commentedHi all and thank you for your work. I was trying to implement this patch using composer and i couldn't. I double check what happened and realize that patch has useless modification for info.yml file (check git version and what can be downloaded, this file is different in 2 places :) ), i removed it and works ok + notice: to apply this patch on 8.x-1.5 you have to apply patch from this issue before https://www.drupal.org/node/2897611
Comment #24
YurkinPark commentedComment #25
YurkinPark commentedWe found one more bug related to behaviors order, so
ViewsInfiniteScrollHistorycan be run afterViewsAjaxViewand replaced pager can be just link wirhout AJAX attachments.Comment #26
luksakWell, our theme is based on stable and most selectors used in JS in this patch don't work. here is one example:
var viewSelector = $('div.view-id-' + viewId + '.view-display-id-' + viewDisplay);Basically the patch should work using the stable theme and not having the views wrapped in a
<div>for example.Comment #27
finnsky commentedafter patch #25 was applied i catched issue when sessionStorage is empty for anonimous user on custom theme
Comment #28
dexterns88 commentedWith this patch views_infinite_scroll_history_2667516_8.patch I have missing 'views-row' element wrapper for new loaded element from cache. I made patch to fix this and store element with this wrapper.
Comment #29
YurkinPark commentedi got rid of selectors which are based on viewId and viewDisplayId. Now it works only using
.js-view-dom-id-selector.Comment #30
YurkinPark commentedComment #31
andypost@YurkinPark please provide interdiff, it's really hard to follow your changes
Comment #32
YurkinPark commentedInterdiff
Comment #33
YurkinPark commentedComment #34
vinlaurens commented@YurkinPark, thanks for your contributions! I have applied views_infinite_scroll_history_2667516_10.patch to my project and it seems to be working as expected. I will try out these changes on a few other themes to see if I still run into things.
Comment #35
finnsky commentedOn my side i had masonry module enabled. So after adding of
masonry layout wasn't updated for me.
Suggested patch helps.
Comment #36
dtv_rb commentedHi guys,
i was not able to apply the patches #35 or #29 via composer. After calling "composer update" the whole module folder "views_infinite_scroll" is gone. There was no error regarding applying the patch in composer update output. Any idea what could be the reason for this?
Composer config for the module is "drupal/views_infinite_scroll": "1.x-dev".
Drupal 8.5
Best,
Reiner
Edited: Got it running now. The patch in #23 solved my issue.
Comment #37
finnsky commentedHi all! I added rework for #29
From my point of view it is better to put in storage loadMore urls. and attach them on back button. And better to use $.fn.infiniteScrollInsertView from module instead of simple html append.
Thanks.
Comment #38
timwoodRe-rolled patch for latest dev.
Comment #39
timwoodjs/infinite-scroll.behaviors.js doesn't account for the case where you have a view configured for infinite scroll, but not have AJAX enabled. Errors with:
Comment #40
timwoodIn testing the module with this patch, I also saw issues where clicking a link from a view result, using back to go back to the view listing and clicking "load more" to display more results from the view would display duplicate results. Like it isn't remembering the right "page" of results I was on.
Comment #41
siavash commentedI'm experiencing the same problems. Also if you load more twice before clicking on an item and go back, the pages loaded again are in the wrong order. When you load more again, the page that was loaded first (But was last) is loaded again.
I'm also seeing js errors in the console when editing views ui, but it doesn't seem to be effecting anything (yet).
Thanks for working on this, I think it's an important feature to have!
Sia
Comment #42
siavash commentedI'm doing some debugging, it looks like the following two 'href's are stored and called on back button
(2) ["/products?search=&page=1", "/views/ajax?search=&page=2"]
Although these are triggered at the correct order, it seems like page 2 loads first. Could it be that it's faster because of the ajax callback or something?
I'm on the view page, exposed filter as a block with ajax enabled.
Comment #43
siavash commentedSeems like the url being different (page url vs internal views/ajax) doesn't matter, neither does the order of which they trigger. It always seems to load page 3 before 2 when you go back and then loads 3 again when you load more. Not sure what's going on.
Comment #44
gfed commentedI've ran into the issue of preserving the state of infinite scroll (although with manual "load more" method). When using a module such as views_ajax_history, which mutates the URL to include exposed filter values as well as last page, we can modify the offset and limit values of the view using the "page" parameter (which will be in place as view_ajax_history pushes url changes to browser history using history.js library), in effect preserving state with minimal interference.
* Accidentally uploaded wrong file, not sure how to remove it. Actual patch below.
Comment #45
gfed commentedComment #47
YurkinPark commentedIn patch #47 i've re-rolled patch from #35. I've tested solution with ajax requests after clicking back and this works ugly for me: i've moved away from page after 4 load more and when i back - i've seen 4 ajax requests and infinite throbber.
Comment #48
YurkinPark commentedProvided front tests, seems like patch needs post update as well, will provide it too.
Comment #49
YurkinPark commentedAdded post_update and update test.
Comment #50
nimoatwoodwayRe-rolled patch for latest dev.
Comment #52
YurkinPark commentedNew rerolled version
Comment #54
dinesh18 commentedI need to achieve the same thing on D7, Is there any patch available for D7 as well ?
Comment #55
YurkinPark commented@Dinesh18 check this issue https://www.drupal.org/project/views_infinite_scroll/issues/1986788
Comment #56
YurkinPark commentedFinally, i've realized that chrome doesn't set exact pixel position after clicking back button, confirmed even on desktop version. It seems like it started from some version.
Comment #57
ion.macaria commentedGreat job. #56 works like a charm.
Comment #58
wturrell commented(edited)
Small bug report with #56 if anyone can reproduce and has time to investigate?
- Keep clicking 'Load more' on your view until all items have been shown (and button therefore disappears)
- either click on an item and then navigate back OR don't click anything, but navigate back to preceding page, then go forward again
In either case, all items still visible, but "Undefined" shown in pager. Specifically:
<ul class="js-pager__items pager" data-drupal-views-infinite-scroll-pager="" data-drupal-views-infinite-scroll-history="preserve-history">undefined</ul>No JS console errors.
Present in Firefox (70.0.1) and Chrome (78.0.3904.108) on macOS (10.13.6)
Safari (13.0.3) is OK though.
Drupal core 8.8-rc1.
Comment #59
Anonymous (not verified) commentedFixed bug mentioned in #58
Comment #60
Anonymous (not verified) commentedNot sure what I was thinking there, previous patch does not work. This one does.
Comment #61
Anonymous (not verified) commentedinterdiff
Comment #62
lammensj commentedI was seeing console errors, complaining about an undefined index in `settings` (`settings.views.ajaxViews`). The included patch adds a check in `infinite-scroll.behaviors.js`.
Comment #63
olivier.br commentedModifications from #62 were deleting my view content.
Here is a fix to that.
Comment #64
neslee canil pintoPatch failed to apply.
Comment #65
maithri shetty commentedComment #66
YurkinPark commentedComment #67
YurkinPark commentedNot sure if this task is helpful since we have #2972129 already merged. I think task can be closed as outdated.
Comment #68
andypostAs it has tests and improves keyboard navigation - it makes sense)
Comment #69
luksak#2972129: Add option to initially load all pages up to the requested page when loading pages beyond the first solves this issue completely for me. Feel free to re-open if needed.
Comment #70
gambryI don't see how #2972129: Add option to initially load all pages up to the requested page when loading pages beyond the first fixes the problem in here?
I haven't tried myself so if someone can formulate if that brings history states and get the browser back button working that would be nice.As #68 suggests this issue still bring benefits by introducing history state and tests.
Setting Needs Review back to trigger testbot, however likely this needs work for refactoring the code on top of the dev branch.
UPDATE: I've tried #2972129: Add option to initially load all pages up to the requested page when loading pages beyond the first and no, it doesn't bring history states and the back button doesn't work so this issue is still valid.
Comment #71
gambryPatch needs re-roll.
Comment #72
suresh prabhu parkala commentedJust a re-roll.
Comment #73
YurkinPark commentedFixing wrong conflict resolves in tests
Comment #74
gordon commentedI found this issue when I was trying to resolve an issue with Views ajax history when pressing the back after loading a few pages.
Why would I use this patch when the above module works and covers everything like filters, sorts and anything ajax and works when you are not using this pager.
This issue I was having was with going back, it would only load the last page, and and not all the previous pages. This has been resolved with 1.8 and the new option initially load all pages.
Comment #75
vuil#73 patch works perfect for us.
I set the issue status to RTBC. Thank you @YurkinPark!
Comment #76
olivier.br commentedPatch re-roll for 2.0 version
Comment #78
geophysicist commentedThanks @gfed for the beautiful solution. Added some customization to apply #39 patch for 2.0.0 version.
It works with views_ajax_history
Comment #79
nicklasmf commented#73 can't be applied anymore. I'm on Core 8.9 and views_infinite_scroll 1.9.
Comment #80
attisan#78 + views_ajax_history = this is the way 💪
Comment #81
anybodyThanks all! Could this please be reworked as MR?
Furthermore I'm unsure if we should really merge it without being a separate option, that can be disabled. I think we should first have tests for this module to ensure it doesn't break important functionality.