Skip to content

Instantly share code, notes, and snippets.

@neodigm
Last active July 12, 2020 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save neodigm/61ef246d89121e7a8453d349746d5f10 to your computer and use it in GitHub Desktop.
Save neodigm/61ef246d89121e7a8453d349746d5f10 to your computer and use it in GitHub Desktop.
Simple Vanilla JavaScript Expand and Collapse (async). Summary and Details paired elements 1:1
var oSimpleExpand = (function( doc ){ // Simple expand / collapse
var aSum, aDet; // Summary and Details paired elements 1:1
return {
"rebind": function(){
aSum = [].slice.call( doc.querySelectorAll("[data-expand-summary]") );
aDet = [].slice.call( doc.querySelectorAll("[data-expand-details]") );
aSum.forEach( function( aE ){
var aDecl = aE.dataset.expandSummary.split("|");
if( aDecl.length > 0 ){
aE.aDecl = aDecl;
aE.eDet = aDet.filter( function( eDet ){ // match
if( eDet.dataset.expandDetails == aDecl[0] ){ return true; }
})[0];
aE.removeEventListener( "click", oSimpleExpand.click );
aE.addEventListener( "click", oSimpleExpand.click );
}
});
},
"click": function( ev ){ // hide or show
var eDet = this.eDet;
var aDecl = this.aDecl;
if( eDet.classList.contains("hide") ){
eDet.classList.remove("hide");
if( aDecl[1] ) this.classList.add( aDecl[1] );
if( aDecl[2] ) { // swap temp
aDecl[3] = this.innerHTML;
this.innerHTML = aDecl[2];
}
}else{
eDet.classList.add("hide");
if( aDecl[1] ) this.classList.remove( aDecl[1] );
if( aDecl[3] ) this.innerHTML = aDecl[3]; // undo
}
ev.preventDefault();
}
}
})( document );
@neodigm
Copy link
Author

neodigm commented Oct 15, 2019

What is significant about this solution is that it can rebind well after the page has loaded. This is good for regions that get populated via AJAX (xhr, fetch). Also it maintains the state of the actual label text so for example a element might display the words either CLOSE or OPEN.

@neodigm
Copy link
Author

neodigm commented Oct 15, 2019

Ands its declarative.

@neodigm
Copy link
Author

neodigm commented Oct 18, 2019

Simplified Vue.js version:

**@click.prevent="doSimpleExpand('navBtnContent_1')"

doSimpleExpand( nameContent ){ // Expand or Collapse on existence in array if( this.vueSimpleExpand.includes( nameContent ) ){ // Collapse this.vueSimpleExpand = this.vueSimpleExpand .filter( item => (item !== nameContent) ); }else{ this.vueSimpleExpand.push( nameContent ); // Expand } }

@neodigm
Copy link
Author

neodigm commented Oct 21, 2019

Please and some A11Y attributes | aria-controls, aria-expanded, aria-haspopup, and ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment