MediaWiki:Tabs.js: Difference between revisions

From Zelda Dungeon Wiki
Jump to navigation Jump to search
Want an adless experience? Log in or Create an account.
mNo edit summary
(fix hiding deselected content when it's not in a container)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
var getChildrenByTagName = function(parent, name) {
/*
var nodeList = [];
Tabs script based on data attributes for arbitrary target selection and limited structure restrictions
for (var child = parent.firstChild; child != null; child = child.nextSibling) {
if (child.nodeType == 1 && name == child.nodeName) { nodeList.push(child); }
}
return nodeList;
};


/* Move tabs from the tabcontent section to the tab section */
First, create a target out of any element (usually a div):
/* This assumes that every tabcontent div is paired with one tab div. */
  -add class "zdw-tabcontainer"
var destinations = document.getElementsByClassName("tab");
  -add a unique id
var tabcontents = document.getElementsByClassName("tabcontent");


for( var i = 0; i < tabcontents.length; ++i ) {
Next, add content to the target:
var tabs = getChildrenByTagName(tabcontents[i], "UL");
  -each must be a div and a direct child to the target
for( var j = 0; j < tabs.length; ++j ) {
  -add class "zdw-tabcontent"
/* Move from tabcontents ul to tab ul */
  -add attribute "data-tab-content" to hold the unique (for this target) identifying string
destinations[i].firstChild.appendChild(tabs[j].firstChild);
  --for multiple selectors, use multiple "data-tab-content-selectorname" attributes
console.log(tabs[j].firstChild);
 
console.log(destinations[i].firstChild);
Then, add selectors:
/* Remove the now empty tabcontents ul */
  -they can go anywhere, inside or outside of the target
tabcontents[i].removeChild(tabs[j]);
  -add class "zdw-tabset"
}
  -set attribute "data-tab-target" to the target's id
}
  -set attribute "data-tab-type" to "click" or "hover" to control how the tabs are activated
  -optional: set attribute "data-tab-selector" to some string if you wish to have more than one tabset for the same selector
 
Finally, add tabs:
  -they must be descendants of their respective tabsets
  -add class "zdw-tab"
  -optional: set attribute "data-tab-selection" to a unique (for this selector) identifying string
  --this will be compared to "data-tab-content-selectorname" in the target
*/
 
$( function() {
$( 'body' ).on( 'mouseover click', '.zdw-tab', function( e ) {
  var tab = $( this );
  var tabset = tab.closest( '.zdw-tabset' );
  var selector = tabset.data( 'tabSelector' );
 
  // first check if we care about this event
  if ( (tabset.data( 'tabType' ) || '').split( ' ' ).indexOf( e.type ) == -1 ) {
    return;
  }
 
  // get target tabcontainer
  var target = tabset.data( 'tabTarget' );
  var container = target ? $( '#' + target ) : tabset.closest( '.zdw-tabcontainer' );
 
  // get all tabsets for container
  var tabsets = target ?
    $( '.zdw-tabset[data-tab-target="' + target + '"]' ) : // get all tabsets with the same target
    container.find( '.zdw-tabset' ).filter( function() { // get all child tabsets
      return $( this ).closest( '.zdw-tabcontainer' ).is( container ); // that aren't nested inside other containers
    } );
 
  // deactivate other tabs sharing the same selector and activate this one
  tabsets.filter( function() { return $( this ).data( 'tabSelector' ) == selector; } ).find( '.zdw-tab' ).removeClass( 'active' );
  tab.addClass( 'active' );
 
  // get selections
  var selections = {}
  tabsets.each( function() {
    var ts = $( this );
    var s = ts.data( 'tabSelector' );
    selections[ s == undefined ? '' : '-' + s ] = ts.find( '.active' ).data( 'tabSelection' );
  } );
 
  // make sure this tabset takes priority in case multiple tabsets use the same selector
  selections[ selector == undefined ? '' : '-' + selector ] = tab.data( 'tabSelection' );
 
  // hide contents (except nested contents)
  container.find( '.zdw-tabcontent' ).filter( function() {
    return target || $( this ).closest( '.zdw-tabcontainer' ).is( container );
  } ).hide();
 
  // show the selected content
  var selectors = Object.keys( selections ).map( function( s ) {
    return '[data-tab-content' + s + '="' + selections[ s ] + '"]';
  } );
  container.find( '.zdw-tabcontent' + selectors.join( '' ) ).show();
} );
} );

Latest revision as of 00:41, August 18, 2020

/*
Tabs script based on data attributes for arbitrary target selection and limited structure restrictions

First, create a target out of any element (usually a div):
  -add class "zdw-tabcontainer"
  -add a unique id

Next, add content to the target:
  -each must be a div and a direct child to the target
  -add class "zdw-tabcontent"
  -add attribute "data-tab-content" to hold the unique (for this target) identifying string
  --for multiple selectors, use multiple "data-tab-content-selectorname" attributes

Then, add selectors:
  -they can go anywhere, inside or outside of the target
  -add class "zdw-tabset"
  -set attribute "data-tab-target" to the target's id
  -set attribute "data-tab-type" to "click" or "hover" to control how the tabs are activated
  -optional: set attribute "data-tab-selector" to some string if you wish to have more than one tabset for the same selector

Finally, add tabs:
  -they must be descendants of their respective tabsets
  -add class "zdw-tab"
  -optional: set attribute "data-tab-selection" to a unique (for this selector) identifying string
  --this will be compared to "data-tab-content-selectorname" in the target
*/

$( function() {
$( 'body' ).on( 'mouseover click', '.zdw-tab', function( e ) {
  var tab = $( this );
  var tabset = tab.closest( '.zdw-tabset' );
  var selector = tabset.data( 'tabSelector' );

  // first check if we care about this event
  if ( (tabset.data( 'tabType' ) || '').split( ' ' ).indexOf( e.type ) == -1 ) {
    return;
  }

  // get target tabcontainer
  var target = tabset.data( 'tabTarget' );
  var container = target ? $( '#' + target ) : tabset.closest( '.zdw-tabcontainer' );

  // get all tabsets for container
  var tabsets = target ?
    $( '.zdw-tabset[data-tab-target="' + target + '"]' ) : // get all tabsets with the same target
    container.find( '.zdw-tabset' ).filter( function() { // get all child tabsets
      return $( this ).closest( '.zdw-tabcontainer' ).is( container ); // that aren't nested inside other containers
    } );

  // deactivate other tabs sharing the same selector and activate this one
  tabsets.filter( function() { return $( this ).data( 'tabSelector' ) == selector; } ).find( '.zdw-tab' ).removeClass( 'active' );
  tab.addClass( 'active' );

  // get selections
  var selections = {}
  tabsets.each( function() {
    var ts = $( this );
    var s = ts.data( 'tabSelector' );
    selections[ s == undefined ? '' : '-' + s ] = ts.find( '.active' ).data( 'tabSelection' );
  } );

  // make sure this tabset takes priority in case multiple tabsets use the same selector
  selections[ selector == undefined ? '' : '-' + selector ] = tab.data( 'tabSelection' );

  // hide contents (except nested contents)
  container.find( '.zdw-tabcontent' ).filter( function() {
    return target || $( this ).closest( '.zdw-tabcontainer' ).is( container );
  } ).hide();

  // show the selected content
  var selectors = Object.keys( selections ).map( function( s ) {
    return '[data-tab-content' + s + '="' + selections[ s ] + '"]';
  } );
  container.find( '.zdw-tabcontent' + selectors.join( '' ) ).show();
} );
} );