Skip to content

Instantly share code, notes, and snippets.

@jeremy-farrance
Last active February 15, 2021 18:23
Show Gist options
  • Save jeremy-farrance/b0c035d0ad03c807be84cc2ba6b707fd to your computer and use it in GitHub Desktop.
Save jeremy-farrance/b0c035d0ad03c807be84cc2ba6b707fd to your computer and use it in GitHub Desktop.
Effective and functional Load More button with no jQuery
@* 20210212 JRF
Load More reference pieces; there are many other ways to do this, and this leaves a lot open for enhancement.
This is not a working example, just the pieces *for reference*
Note 1a: this still sends ALL entries to the client, so this is not appropriate for more than 200 to 300 items IMHO
Note 1b: and if your output includes images, this would be BAD for slow connections and mobile
Note 2: this assumes Bootstrap 4.x is in place
The original was this using jQuery, at the time I was learning NOT to use jQuery
and this was an early attempt at doing something JS only.
https://codepen.io/Tigran_91/pen/JyaZPz
If you want to experiment with the JS part, here is a similar minimal setup on Codepen
(interestingly this version uses computed-styles)
https://codepen.io/accuraty/pen/RwoKywQ
Here is the original, working implementation
https://cuaerospace.com/publications
Issues to address, enhancement ideas:
x [Done 20210215 JRF] we call .querySelectorAll() twice, bad for performance
- need to demo a simple CSS animation to make the loadMore reveal nicer/modern
- would it make sense to redo this for computed-styles? (would that be performant?)
This is the server side setup:
*@
@{
@* ... other stuff ... *@
const int showOnLoad = 16; // how many to not-hide initially
const int loadMore = showOnLoad / 2; // how many to load when you click the button
int repeating = showOnLoad; // our (throw-away) counter
}
<div class="sxc-wrapper">
@foreach (var item in AsList( @* data source *@ )
.Where(i => i.Active == true)
{
@* ... other stuff ... *@
@* this is the main server-side work, we are writing the HTML
ready to display with NN (showOnLoad) already visible *@
<div class="content-item" style="@(repeating-- > 0 ? "display:block" : "display:none");">
@* ... other stuff ... *@
}
</div> @* end of main wrapper *@
<button id="loadMore" type="button" class="btn btn-info btn-sm">Load More</button>
@*
this is the JS we send to the client, important to
notice the 1 server-side variable we inject (@loadMore)
*@
<script>
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById("loadMore").addEventListener("click", function(e){
e.preventDefault();
// get the ones we need in to an array
var items = [... document.querySelectorAll(".publication")];
items
.filter(p => p.style.display == "none") // only include visible items
.slice(0, @loadMore) // only take the next few; Razor (server-side) injected variable
.forEach(p => p.style.display = "block"); // loop thru making them visible
if (items
.filter(p => p.style.display == "none") // how many hidden ones are left?
.length == 0) // true if all items are visble now
{
var lm = document.getElementById("loadMore"); // so we change the button
lm.className = "btn btn-outline-info btn-sm"; // from solid to outline
lm.innerHTML = "- end of Publications list -"; // make it informative
lm.disabled = true; // and insure clicking does nothing anymore
};
/* if you want debug info
console.count('clicks (so far)');
console.info("All=%s, Block=%s, None=%s",
items.length,
items.filter(p => p.style.display == "block").length,
items.filter(p => p.style.display == "none").length);
*/
});
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment