From Brotato Wiki

(docs, remove debug)
(initStatsCardsToggles - UX improvements (needed a bit of a rewrite, but now functions more like you'd expect ie. not janky))
Line 81: Line 81:
/**
/**
* Toggle a StatsCard box (.ibox)
* Toggle a StatsCard box (.ibox)
*  
*
* Targets elements with [data-ibox-type="item"], selecting them by the
* Targets elements with [data-ibox-type="item"], selecting them by the
* given class (eg. rarity1), which should be applied to the element with
* given class (eg. rarity1), which should be applied to the element with
* the data-ibox-type data attr
* the data-ibox-type data attr
*  
*
* @todo: Use the CSS class (ibox--hidden) instead of JS-injected opacity
* @todo: Use the CSS class (ibox--hidden) instead of JS-injected opacity
*
*
Line 95: Line 95:
var $bulkBtns = $( '[data-hide-target="show-all"], [data-hide-target="show-none"]' );
var $bulkBtns = $( '[data-hide-target="show-all"], [data-hide-target="show-none"]' );
var $nonBulkBtns = $allBtns.not( $bulkBtns );
var $nonBulkBtns = $allBtns.not( $bulkBtns );
var $allTargets = $( '[data-ibox-type="item"]' );
// Stores all target strings
// Used to prevent iboxs from being hidden when they shouldn't be
var allTargetStrs = [];
var activeTargetStrs = []
var specialFilters = [
'show-all',
'show-none'
];
$allBtns.each( function( i, el )
{
var $btn = $( el );
var filterStr = $btn.attr( 'data-hide-target' ); // eg "rarity3"
// ES5 version of Array.prototype.includes()
if ( ( allTargetStrs.indexOf( filterStr ) === -1 ) && ( specialFilters.indexOf( filterStr ) === -1 ) )
{
allTargetStrs.push( filterStr );
}
});
activeTargetStrs = allTargetStrs;


$allBtns.on( 'click', function( ev )
$allBtns.on( 'click', function( ev )
Line 100: Line 125:
var $btn      = $( ev.currentTarget );
var $btn      = $( ev.currentTarget );
var filterStr = $btn.attr( 'data-hide-target' ); // eg "rarity3"
var filterStr = $btn.attr( 'data-hide-target' ); // eg "rarity3"
var $targets  = $( '[data-ibox-type="item"].' + filterStr );
var $targets  = $( '[data-ibox-type="item"]' + filterStr );
var $all      = $( '[data-ibox-type="item"]' );
var $all      = $( '[data-ibox-type="item"]' );


Line 115: Line 140:
$nonBulkBtns.addClass( 'btn--active' );
$nonBulkBtns.addClass( 'btn--active' );
$nonBulkBtns.removeClass( 'btn--inactive' );
$nonBulkBtns.removeClass( 'btn--inactive' );
activeTargetStrs = allTargetStrs;
break;
break;


Line 122: Line 148:
$nonBulkBtns.removeClass( 'btn--active' );
$nonBulkBtns.removeClass( 'btn--active' );
$nonBulkBtns.addClass( 'btn--inactive' );
$nonBulkBtns.addClass( 'btn--inactive' );
activeTargetStrs = [];
break;
break;
}
}
Line 127: Line 154:
else
else
{
{
// Toggle specific targets
var strIndex = activeTargetStrs.indexOf( filterStr );
$btn.toggleClass( 'btn--active' );
$btn.toggleClass( 'btn--inactive' );


$targets.each( function( i, el )
if ( $btn.hasClass( 'btn--active' ) )
{
{
var $target = $( el );
// Button was active, so it's now INACTIVE
var isHidden = $target.hasClass( 'ibox--hidden' );


if ( isHidden )
// If all other buttons are active (ie. no buttons have been
// selected yet), make this one active and all others disabled
if ( activeTargetStrs.length === allTargetStrs.length )
{
// Disable all others, keep only this one
$nonBulkBtns.not( $btn ).removeClass( 'btn--active' );
$nonBulkBtns.not( $btn ).addClass( 'btn--inactive' );
activeTargetStrs = [];
activeTargetStrs.push( filterStr );
}
// Or, if this was the last (ie. only) active button and it
// was just disabled, enable every button
else if ( activeTargetStrs.length === 1 )
{
{
$target.removeClass( 'ibox--hidden' );
$nonBulkBtns.removeClass( 'btn--inactive' );
$targets.css( { opacity: 1 } );
$nonBulkBtns.addClass( 'btn--active' );
activeTargetStrs = allTargetStrs;
}
}
// Otherwise function normally: Just disable this button
else
else
{
{
$target.addClass( 'ibox--hidden' );
$btn.removeClass( 'btn--active' );
$targets.css( { opacity: 0.2 } );
$btn.addClass( 'btn--inactive' );
activeTargetStrs.splice( strIndex, 1 );
}
}
else
{
// Button was inactive, so it's now ACTIVE
$btn.removeClass( 'btn--inactive' );
$btn.addClass( 'btn--active' );
activeTargetStrs.push( filterStr );
}
 
// Apply filters
 
// Show all, if every filter is active (ie. if every ibox should be shown)
if ( activeTargetStrs.length === allTargetStrs.length )
{
$allTargets.removeClass( 'ibox--hidden' );
$allTargets.css( { opacity: 1 } );
}
// Otherwise, apply the actual filters
else
{
// Hide all to start with
$allTargets.addClass( 'ibox--hidden' );
$allTargets.css( { opacity: 0.2 } );
 
// Show any that match the currently active filters
for (let i = 0; i < activeTargetStrs.length; i++)
{
var targetStr = activeTargetStrs[i];
var $currentTargets = $allTargets.filter( '[data-ibox-type="item"].' + targetStr );
$currentTargets.removeClass( 'ibox--hidden' );
$currentTargets.css( { opacity: 1 } );
}
}
});
}
}
}
});
});
Line 154: Line 225:
/**
/**
* Toggle "misc" (costs/tags)
* Toggle "misc" (costs/tags)
*  
*
* Buttons: <span class="btn btn--active" data-hide-type="misc" data-hide-target=".myelement">
* Buttons: <span class="btn btn--active" data-hide-type="misc" data-hide-target=".myelement">
* Targets: <span class="myelement" data-target-type"misc">
* Targets: <span class="myelement" data-target-type"misc">

Revision as of 00:35, 17 December 2022

/* Any JavaScript here will be loaded for all users on every page load. */


/*
WARNING: ES5 ONLY!
*/


$(document).ready( function()
{
	// Inits
	// ============================================================================

	initCardTabs(); // Template:StatsCardWeaponTabs
	initStatsCardsToggles(); // Allows hiding StatsCard (.ibox) elements, via toggle buttons (WIP)
	initStatsCardsMiscToggles(); // Toggles for misc (costs/tags)


	// Funcs
	// ============================================================================

	/**
	 * Sets up tabs. Used by the StatsCardWeaponTabs template
	 *
	 * @link https://brotato.wiki.spellsandguns.com/Template:StatsCardWeaponTabs
	 * @link https://brotato.wiki.spellsandguns.com/MediaWiki:Common.css
	 *
	 * @return  {void}
	 */
	function initCardTabs()
	{
		var $containers = $( '[data-cardtabs]' );

		if ( !$containers.length )
		{
			return;
		}

		// Loop over every container
		$containers.each( function( i1, containerEl )
		{
			var $tabs = $( containerEl );

			// We use the extra step of targetting containers here, instead of
			// just using `.find`, because this lets us support nesteds tabs!
			var $panelsContainer = $tabs.children(   '[data-cardtabs-panels]' );
			var $btnsContainer   = $tabs.children(   '[data-cardtabs-btns]' );
			var $panels = $panelsContainer.children( '[data-cardtabs-panel]' );
			var $btns   = $btnsContainer.children(   '[data-cardtabs-btn]' );

			// Loop over buttons and set up their onclicks
			$btns.each( function( i2, btnEl )
			{
				var $btn     = $( btnEl );
				var btnNum   = $btn.attr( 'data-cardtabs-btn' );
				var $panel   = $panels.filter( '[data-cardtabs-panel="' + btnNum + '"]' );
				var btnActiveCls = 'cardtabs__button--active';
				var panelHideCls = 'cardtabs__panel--js-hidden';

				// Disabled buttons use "-1" for their numbers
				if ( btnNum === '-1' )
				{
					return;
				}

				$btn.on( 'click', function()
				{
					// Hide all other panels, then show the button's own panel
					$panels.addClass( panelHideCls );
					$panel.removeClass( panelHideCls );

					$btns.removeClass( btnActiveCls );
					$btn.addClass( btnActiveCls );
				});
			});

		});
	}//end:initCardTabs


	/**
	 * Toggle a StatsCard box (.ibox)
	 *
	 * Targets elements with [data-ibox-type="item"], selecting them by the
	 * given class (eg. rarity1), which should be applied to the element with
	 * the data-ibox-type data attr
	 *
	 * @todo: Use the CSS class (ibox--hidden) instead of JS-injected opacity
	 *
	 * @return  {void}
	 */
	function initStatsCardsToggles()
	{
		var $allBtns  = $( '[data-hide-type="item"]' );
		var $bulkBtns = $( '[data-hide-target="show-all"], [data-hide-target="show-none"]' );
		var $nonBulkBtns = $allBtns.not( $bulkBtns );
		var $allTargets = $( '[data-ibox-type="item"]' );

		// Stores all target strings
		// Used to prevent iboxs from being hidden when they shouldn't be
		var allTargetStrs = [];
		var activeTargetStrs = []

		var specialFilters = [
			'show-all',
			'show-none'
		];

		$allBtns.each( function( i, el )
		{
			var $btn = $( el );
			var filterStr = $btn.attr( 'data-hide-target' ); // eg "rarity3"

			// ES5 version of Array.prototype.includes()
			if ( ( allTargetStrs.indexOf( filterStr ) === -1 ) && ( specialFilters.indexOf( filterStr ) === -1 ) )
			{
				allTargetStrs.push( filterStr );
			}
		});

		activeTargetStrs = allTargetStrs;

		$allBtns.on( 'click', function( ev )
		{
			var $btn      = $( ev.currentTarget );
			var filterStr = $btn.attr( 'data-hide-target' ); // eg "rarity3"
			var $targets  = $( '[data-ibox-type="item"]' + filterStr );
			var $all      = $( '[data-ibox-type="item"]' );

			if ( filterStr === 'show-all' || filterStr === 'show-none' )
			{
				// Bulk toggle ALL targets
				$targets = $all;

				switch( filterStr )
				{
					case 'show-all':
						$targets.removeClass( 'ibox--hidden' );
						$targets.css( { opacity: 1 } );
						$nonBulkBtns.addClass( 'btn--active' );
						$nonBulkBtns.removeClass( 'btn--inactive' );
						activeTargetStrs = allTargetStrs;
						break;

					case 'show-none':
						$targets.addClass( 'ibox--hidden' );
						$targets.css( { opacity: 0.2 } );
						$nonBulkBtns.removeClass( 'btn--active' );
						$nonBulkBtns.addClass( 'btn--inactive' );
						activeTargetStrs = [];
						break;
				}
			}
			else
			{
				var strIndex = activeTargetStrs.indexOf( filterStr );

				if ( $btn.hasClass( 'btn--active' ) )
				{
					// Button was active, so it's now INACTIVE

					// If all other buttons are active (ie. no buttons have been
					// selected yet), make this one active and all others disabled
					if ( activeTargetStrs.length === allTargetStrs.length )
					{
						// Disable all others, keep only this one
						$nonBulkBtns.not( $btn ).removeClass( 'btn--active' );
						$nonBulkBtns.not( $btn ).addClass( 'btn--inactive' );
						activeTargetStrs = [];
						activeTargetStrs.push( filterStr );
					}
					// Or, if this was the last (ie. only) active button and it
					// was just disabled, enable every button
					else if ( activeTargetStrs.length === 1 )
					{
						$nonBulkBtns.removeClass( 'btn--inactive' );
						$nonBulkBtns.addClass( 'btn--active' );
						activeTargetStrs = allTargetStrs;
					}
					// Otherwise function normally: Just disable this button
					else
					{
						$btn.removeClass( 'btn--active' );
						$btn.addClass( 'btn--inactive' );
						activeTargetStrs.splice( strIndex, 1 );
					}
				}
				else
				{
					// Button was inactive, so it's now ACTIVE
					$btn.removeClass( 'btn--inactive' );
					$btn.addClass( 'btn--active' );
					activeTargetStrs.push( filterStr );
				}

				// Apply filters

				// Show all, if every filter is active (ie. if every ibox should be shown)
				if ( activeTargetStrs.length === allTargetStrs.length )
				{
					$allTargets.removeClass( 'ibox--hidden' );
					$allTargets.css( { opacity: 1 } );
				}
				// Otherwise, apply the actual filters
				else
				{
					// Hide all to start with
					$allTargets.addClass( 'ibox--hidden' );
					$allTargets.css( { opacity: 0.2 } );

					// Show any that match the currently active filters
					for (let i = 0; i < activeTargetStrs.length; i++)
					{
						var targetStr = activeTargetStrs[i];
						var $currentTargets = $allTargets.filter( '[data-ibox-type="item"].' + targetStr );
						$currentTargets.removeClass( 'ibox--hidden' );
						$currentTargets.css( { opacity: 1 } );
					}
				}
			}
		});
	}//end:initStatsCardsToggles


	/**
	 * Toggle "misc" (costs/tags)
	 *
	 * Buttons: <span class="btn btn--active" data-hide-type="misc" data-hide-target=".myelement">
	 * Targets: <span class="myelement" data-target-type"misc">
	 *
	 * @return  {void}
	 */
	function initStatsCardsMiscToggles()
	{
		var $btns = $( '[data-hide-type="misc"]' );

		$btns.each( function( i, el )
		{
			var $btn = $( el );
			var targetStr = $btn.attr( 'data-hide-target' );
			var $targets = $( '[data-target-type="misc"]' + targetStr );

			if ( !$targets.length )
			{
				return;
			}

			$btn.on( 'click', function( ev )
			{
				$btn.toggleClass( 'btn--active' );
				$btn.toggleClass( 'btn--inactive' );

				$targets.toggle();
			});
		});
	}

}); // end:$(document).ready