Last active
February 15, 2021 18:23
-
-
Save jeremy-farrance/b0c035d0ad03c807be84cc2ba6b707fd to your computer and use it in GitHub Desktop.
Effective and functional Load More button with no jQuery
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
@* 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