Ana Posted June 10 Share Posted June 10 Hi PW friends, How can I make a loadmore button that returns 6 more remaining pages of a list of pages. Which have been filtered? Link to comment Share on other sites More sharing options...
TomPich Posted June 10 Share Posted June 10 Hello Ana, As far as I know, there is no built-on system for that. I would go for a url hook in the init.php file and a little script on the page that display your pages to retrieve more pages. Find a way to store somewhere in your pages the number of already displayed pages (like a data-pages-number in your HTML wrapper). Then add an event listener to your button that run a fetch on your url hook, sending the number of already displayed pages. Inside your hook, get your pages, eliminate the pages already displayed and convert the pages data you want in JSON (like a title, a thumbnail, a link...). Send this data as a response to the fetch. Then, maybe with the help of a <template> tag, display these data on your page. That would be my choice. Link to comment Share on other sites More sharing options...
FireWire Posted June 10 Share Posted June 10 @Ana To add that type of user-facing functionality would best be achieved using AJAX. I think that this is a perfect use case for htmx which works very well with ProcessWire and is probably the fastest and easiest method to get the type of behavior you're looking for. Here's a working example of what this would look like. It takes about 5 minutes and you don't even have to leave your template file. <!DOCTYPE html> <html lang="en"> <head> <title><?=$page->title?></title> </head> <body> <!-- ...the rest of your template markup --> <!-- Your button to load more pages --> <div> <button hx-get="<?=$page->url?>?content=remaining-pages" hx-target="#remaining-pages-container" hx-select="#remaining-pages"> View More </button> <div id="remaining-pages-container"> <!-- Your additional page markup will be loaded here --> </div> </div> <!-- This page list will only render if the URL has ?content=remaining-pages appended --> <?php if ($input->get->content === 'remaining-pages'): ?> <ul id="remaining-pages"> <li>Remaining Pages</li> <?php foreach ($pages->find('your=selector,goes=here') as $remainingPage): ?> <li> <h2><?=$remainingPage->title?></h2> <a href="<?=$remainingPage->url?>">View Page</a> </li> <?php endforeach ?> </ul> <?php endif ?> <script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script> </body> </html> Explanation. Having added the htmx script tag to your document, the htmx library is available. Here's what happens: Clicking the "View More" button makes an AJAX request to the server The URL for the hx-get attribute has been appended with "?content=remaining-pages", this can be anything you prefer The conditional block for additional pages will only render if the ProcessWire $input->get->content matches the GET variable we appended to the hx-get attribute URL When the page is rendered and response sent back for the AJAX request, htmx finds the element with the id 'remaining-pages' If an element with the id of 'remaining-pages' is found, then the contents of that element are inserted into an element with the id of 'remaining-pages-container' which is specified in the hx-target attribute of the <button> element There are some other ways that you could organize your code and return the markup, that's entirely up to you and how you would like to organize that in your ProcessWire site. This works, but we can make this more efficient. In the example above, the entire page is rendered just to get the remaining pages. This may not be an issue for all websites, but if a page has a lot of fields or other features that make database calls, then there is a lot of work being done on the server to render content that won't be shown because htmx is only selecting the content inside the element with the id of 'remaining-pages'. Here's an improvement: <!-- This page list will only render if the URL has ?content=remaining-pages appended --> <?php if ($input->get->content === 'remaining-pages'): ?> <ul id="remaining-pages"> <li>Remaining Pages</li> <?php foreach ($pages->find('your=selector,goes=here') as $remainingPage): ?> <li> <h2><?=$remainingPage->title?></h2> <a href="<?=$remainingPage->url?>">View Page</a> </li> <?php endforeach ?> </ul> <?php return; ?> <?php endif ?> <!DOCTYPE html> <html lang="en"> <head> <title><?=$page->title?></title> </head> <body> <!-- ...the rest of your template markup --> <!-- Your button to load more pages --> <div> <button hx-get="<?=$page->url?>?content=remaining-pages" hx-target="#remaining-pages-container" hx-select="#remaining-pages"> View More </button> <div id="remaining-pages-container"> <!-- Your additional page markup will be loaded here --> </div> </div> <script src="https://unpkg.com/htmx.org@2.0.4" integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script> </body> </html> This is the exact same code as above, but here's what we did differently this time. The markup for the additional pages that only renders if 'content=additional-pages' is present has been moved above all of the other markup in the template After the closing <ul> tag and within the <?php endif ?> statement, we've added a return statement that prevents ProcessWire from rendering the rest of the page Depending on how "heavy" your template is, this could make the results appear to the user faster and very little work was needed on our part to do that. There are things that you can explore to make use of other ProcessWire features and improve the readability and/or reusability of your code Rather than using a GET variable, you could choose to use URL segments in ProcessWire to create and respond to a more natural URL You could use the render feature of FileTools in ProcessWire to store your remaining pages markup in a separate file You could use a GET variable such as "count=6" to set the number of pages to return rather than hard coding it Those are entirely optional, the example above is all you need to implement the feature you are looking for. Some notes on htmx If you use a build tool and npm, you can add htmx to your project as a package rather than the <script> tag htmx offers an easy way to create a 'loading' animation to let your users know that the button is retrieving the remaining pages while the AJAX request is being processed Hope this is useful for your project! The code example really did take only 5 minutes (maybe less!), without one line of JavaScript. If you prefer using a JavaScript oriented approach with JSON and markup such as the <template> tag as @TomPich mentioned, the same thing could be achieved using Alpine.js which is an easy way to add enhancements to your templates without the need for a full front end framework (just another personal favorite). 3 Link to comment Share on other sites More sharing options...
Ana Posted June 11 Author Share Posted June 11 Thanks 🙂 i will try your suggestions and let you know how it goes. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now