Toggle

Summary: Adds links or buttons for toggling (hiding/showing) elements on a page
Version: 2022-06-17
Prerequisites: Modern PmWiki (tested with 2.3.5); PHP 7 or greater
Status: stable
Maintainer: Said Achmiz
License: GPL2+
Discussion: Toggle-Talk
Users: +13 (View / Edit)
Download: toggle.phpΔ (or toggle_2022-11-18.phpΔ for PHP versions earlier than 7)

Toggle Popup Box

This is an example of what this recipe can do. This is an absolutely positioned div element. See the page source for more information.

This recipe depends on JavaScript.

NOTE: If you are using a version of Toggle that is older than 2018-10-15, please upgrade immediately to fix a critical security vulnerability!

Questions answered by this recipe

How can I add toggle switches to show and hide sections of the page?

Description

The script adds markup for links, buttons or images for toggling (hiding/showing) elements (sections/blocks/etc.).

Installation

Download toggle.phpΔ and place the script in your cookbook/ folder. Add the following to config.php:

include_once("$FarmD/cookbook/toggle.php");

NOTE: If you are using an older version of PHP (lower than PHP 7), download toggle_2022-11-18.phpΔ instead. (Some features will not be available.)

Configuration

No initial configuration is necessary; the recipe should work immediately when installed.

Customizing default values

You can customize the default values of the (:toggle:) directive (see below) for your wiki by setting the values of the $ToggleConfig array.
For example, you can place the following code in your config.php (before including toggle.php):

$ToggleConfig = [
	'show' => '[Unveil]',
	'hide' => '[Conceal]'
];

You can also customize the behavior of Toggle by using the (:toggleset:) directive (see below) to set default values on a per-page basis.

Usage

(:toggle:) directive

Short syntax

(:toggle hide box1 button=1:)
>>id=box1 border='1px solid #999' padding=5px bgcolor=#edf<< 
The text in this section can be hidden/shown 
>><<

The text in this section can be hidden/shown

More (:toggle:) usage examples (click to expand)

Long syntax

(:toggle id=box2 init=hide button=1:)
>>id=box2 border='1px solid #999' padding=5px bgcolor=#edf<< 
The text in this section can be hidden/shown 
>><<

The text in this section can be hidden/shown

Toggle link examples

(:toggle box3:)
>>id=box3 border='1px solid #999' padding=5px bgcolor=#fed<< 
The text in this section can be hidden/shown 
>><<

Hide

The text in this section can be hidden/shown

(:toggle hide box4:)
>>id=box4 border='1px solid #999' padding=5px bgcolor=#fed<< 
The text in this section can be hidden/shown 
>><<

Show

The text in this section can be hidden/shown

(:toggle box5a box5b:)
>>id=box5a border='1px solid #999' padding=5px bgcolor=#fed<< 
Toggle between two divs. First div.
>>id=box5b border='1px solid #999' padding=5px bgcolor=#edf<< 
Some text in second div.  
>><<

Hide

Toggle between two divs. First div.

Some text in second div.

Toggle group example

>>id="line1" frame bgcolor=#edf<<
'''Line 1''' always shows to start off with. When any of lines 2 to 4 display line 1 is hidden. When none of lines 2 to 4 are showing line 1 is displayed.
>>id="line2" class="lines" frame bgcolor=#efd<<
'''Line 2''' is hidden to start. When line 2 is shown line 1 and all other lines are hidden.
>>id="line3" class="lines" frame bgcolor=#fed<<
'''Line 3''' is hidden to start. When line 3 is shown line 1 and all other lines are hidden.
>>id="line4" class="lines" frame bgcolor=#def<<
'''Line 4''' is hidden to start. When line 4 is shown line 1 and all other lines are hidden.
>><<

In this example only one line should ever show at a time.

* (:toggle id="line1"             group="lines" init=show show="show line 1" hide="hide line 1":)
* (:toggle id="line2" id2="line1" group="lines" init=hide show="show line 2" hide="hide line 2":)
* (:toggle id="line3" id2="line1" group="lines" init=hide show="show line 3" hide="hide line 3":)
* (:toggle id="line4" id2="line1" group="lines" init=hide show="show line 4" hide="hide line 4":)

Line 1 always shows to start off with. When any of lines 2 to 4 display line 1 is hidden. When none of lines 2 to 4 are showing line 1 is displayed.

Line 2 is hidden to start. When line 2 is shown line 1 and all other lines are hidden.

Line 3 is hidden to start. When line 3 is shown line 1 and all other lines are hidden.

Line 4 is hidden to start. When line 4 is shown line 1 and all other lines are hidden.

In this example only one line should ever show at a time.

Required parameters

id=divnameThe id attribute of element which the toggle link or button acts on.
Example: togglelink (:toggle abc:) on div >>id=abc<<

Optional parameters

ParameterDefault valueExplanation
id2=divname ID of an optional second element which the toggle will show when hiding the first element, toggling between the two elements.
init=hideshowHides the element initially.
show="labeltext""Show"Text of link/button when element is hidden.
hide="labeltext""Hide"Label of button when element is shown.
label="labeltext" Label of link or button for both toggle states.
(Equivalent to giving the same value for both show and hide.)
ttshow="tooltiptext""Show"Text that appears when the user hovers over the "Show" link.
tthide="tooltiptext""Hide"Text that appears when the user hovers over the "Hide" link.
tt="tooltiptext" Text that appears when the user hovers over the toggle link in both states.
(Equivalent to giving the same value for both ttshow and tthide.)
group=classname When showing the element with the specified id= (i.e., clicking "Show"), hide all other elements with class classname.
(Hiding the element still works as normal, with no additional behavior.)
display=valueblockWhat the display property of the specified element should be set to, when it's shown
(block, inline-block, etc.—see https://www.w3schools.com/CSSref/pr_class_display.asp for details).
display2=valueblockWhat the display property of the specified alternate element should be set to, when it's shown.
set=10Remember toggle state by setting a cookie.
button=10Display a button instead of a link.
printhidden=11Print hidden elements (i.e., show hidden elements when printing).
nojs=integer0Set to 1 or 2 will show toggle links/buttons if browser does not support JavaScript.
Set to 2 will hide hidden elements via style in page head and not via JavaScript, so that for non-JS browser initially hidden elements stay hidden.

Shortcut syntax

You can avoid some of the parameter keywords and use keyless/valueless arguments in the markup instead.

Short (keyless) syntaxEquivalent full syntax
(:toggle divname:)(:toggle id=divname:)
(:toggle hide divname:)(:toggle init=hide id=divname:)
(:toggle divname1 divname2:)(:toggle id=divname1 id2=divname2:)
Short (valueless) syntaxEquivalent full syntax
(:toggle id=divname set:)(:toggle id=divname set=1:)
(:toggle id=divname button:)(:toggle id=divname button=1:)
(:toggle id=divname printhidden:)(:toggle id=divname printhidden=1:)

(:toggleset:) directive

The (:toggleset:) directive takes all the same parameter as the (:toggle:) directive. However, it does not create a toggle; instead, it uses the values of the parameters given to it to set default values for those parameters, which then apply to all (:toggle:) elements that appear further down the page. (These default values override the default values set in the $ToggleConfig array, whether in the script itself or in your config.php.)

You can have multiple (:toggleset:) directives on a page. The default values set by any (:toggleset:) directive override any previously set default values, so that the default value for any parameter of (:toggle:) is the one set by the most recent (:toggleset:) directive that set that particular parameter (if any).

The values specified in any (:toggle:) directive always override any default values, whether set by a (:toggleset:) or via $ToggleConfig.

Example of setting default parameter values (click to show)

Suppose you had the following in your config.php:

$ToggleConfig = [
	'show' => '[Unveil]',
	'hide' => '[Conceal]'
];

And on your page you had the following:

(:toggle block1:)

(:toggleset show='[Reveal]':)

(:toggle block2:)

(:toggle block3:)

(:toggleset hide='[Obscure]':)

(:toggle block4:)

(:toggleset button:)

(:toggle block5:)

In this case:

  • The toggles for block1, block2, and block3 would have the label "[Conceal]" when the blocks are visible (because it was set in config.php, via the $ToggleConfig array, and not modified by any (:toggleset:) directive).
  • The toggle for block1 would have the label "[Unveil]" when the block is hidden (again, because it was set in config.php, via the $ToggleConfig array, and not modified by any (:toggleset:) directive).
  • The toggles for block2, block3, block4, and block5 would have the label "[Reveal]" when the blocks are hidden (because it was set in the first (:toggleset:) directive, and not overridden by any subsequent (:toggleset:) directive).
  • The toggles for block4 and block5 would have the label "[Obscure]" when the block is visible (because it was set in the second (:toggleset:) directive, and not overridden by any subsequent (:toggleset:) directive).
  • The toggles for block1, block2, block3, and block4 would be links (the default).
  • The toggle for block5 would be a button (because this was set in the third (:toggleset:) directive).

Explanation of parameters and features

Custom labels and tooltips

For custom labels (link text or button text), use parameters show="labeltext" or hide="labeltext" (or label="labeltext" for one show and hide label).

For custom tooltips (title attribute, shown as tooltip on mouse hover), use parameters ttshow="tooltiptext" or tthide="tooltiptext" (or tt="tooltiptext" for one show and hide tooltip).

Images as toggles

You can have images displayed instead of link text. Use the image file name with extension as label text, like show=myshow.gif hide=myhide.gif (or label=mytoggle.gif for a single image for both show and hide). Then clicking the image will toggle the element display, and if you use different images for show and hide these images will toggle as well.

Images should be attached to the page (use action=upload to upload file to page or group). (Syntax like label=Attach:myimage.ext does not work!) If your uploaded image file is attached to a different group, for instance if it was uploaded to the Site group, then use syntax like show=Site/myshow.gif.

The toggle markup recognizes images with extensions svg, png, gif, jpg, jpeg and ico (and extension matching is not case-sensitive, so picture.gif, picture.GIF, and picture.GiF all work). (If there are problems with uploading such images, make sure you follow all the advice about uploading images and necessary permissions are set.)

Specifying image tooltips

You can specify the tooltip (title attribute) for an image used as a toggle within the show= / hide= / label= parameter itself. The name of the image should be followed by a | (pipe character), then the tooltip text (make sure to surround the whole thing with quotes):

(:toggle block6 show="show.png|Show element" hide="hide.png|Hide element":)

Image tooltip markup example (click to show)
(:toggle block6 show="show.png|Show element" hide="hide.png|Hide element":)
>>id=block6<<
Initially visible text. Hidden when Attach:hide.png (@@hide.png@@) is clicked; made visible when Attach:hide.png (@@show.png@@) is clicked.
>><<

Initially visible text. Hidden when Attach:Attach:hide.png Δ (hide.png) is clicked; made visible when Attach:Attach:hide.png Δ (show.png) is clicked.

(You can also use the ttshow= / tthide= / tt= parameters to specify tooltips, as normal.)

Tips

  • A toggle button can act on any element of the page that has an id attribute, even a sidebar or other structural element outside the normal page content. (But in such a case it may not make a too good job, because to hide such a element effectively may need more than applying display:none, for instance resetting of margins.)
  • A toggle button can also act on all types of elements with an id= set, for instance tables. It is not restricted to divs.
  • A toggle button or link can toggle two elements, hiding one and showing the other, alternating. Name the first element id with id=... and the second with id2=....
  • Two toggle buttons or two toggle links can act together as a pair on one element. For instance put one on top of a block element, and the other inside at the bottom, to conveniently close it.
  • If you set the default values of the set, button, or printhidden parameters to 1 (via the $ToggleConfig variable, or with a (:toggleset:) directive), you can override that default in an individual (:toggle:) directive with set=0, button=0, or printhidden=0.
  • To show a set of elements with a single click, without them all having the same id (so they can also be individually toggled) you can use the Cookbook:HttpVariables recipe. For example, you can set init=hide in config.php, so the toggles default to hidden. Then base the initial value of each toggle that you want to participate in "Show all" on a URL request variable, e.g (:toggle {$?showstatus} myhiddendiv1:). Then provide on the page a link such as "[[{*$FullName}?showstatus=show|Show all]]". The page will normally hide the participating elements, but if the user clicks the link the page will reload with the selected elements all shown.
  • You can place the (:toggleset:) directive in a group header to set default values for (:toggle:) directive parameters for a whole wiki group.

Notes

The script requires a JavaScript-enabled modern browser. It places a JavaScript function into the HTML body, which will achieve instant toggle effects without page reloads.

Ensure that the skin/template you're using has a <!--HTMLFooter--> tag towards the bottom. This is needed to load the JavaScript. (Older skins often lack this tag.)

Backward compatibility

The script is backwards compatible with the togglelink markup syntax. lshow= works same as show= parameter, lhide= works same as hide= parameter, div= works same as id= parameter, div2= works same as id2= parameter.

Buttons are implemented with a button=1 parameter, and work that way like ShowHide Buttons.

This recipe supersedes the ShowHide and ToggleLink scripts.

Release Notes

  • 2022-06-17: Fixed bug with printhidden parameter functionality.
  • 2022-06-06: Fixed bug.
  • 2022-06-05: Major code overhaul; updated for compatibility with PHP 8; no longer compatible with PHP earlier than 7. Added (:toggleset:) feature, tt parameter, display parameter, new image tooltip syntax. Fixed bugs with nojs= option (and many others).
  • 2021-11-18: Fixed missing tooltip when button is used.
  • 2018-10-15: Fixed critical security issue.
  • 2018-01-03: Fixed bug where element ids with dashes in them could not be toggled.
  • 2017-11-07: Update for compatibility with PHP versions earlier than 5.3.
  • 2017-11-05: Major rewrite; all outstanding bugs fixed.
  • 2017-08-24: Added display parameter; fixed JS bug.
  • 2017-06-17: Updated markup definition to be PHP 7.2 compatible.
  • 2014-02-21: Updated markup definition to be PHP 5.5 compatible.
  • 2011-04-06: Changed JS code to always set display attribute.
  • 2011-04-04: Fixed bug inhibiting initial hiding of divs if toggle was in SideBar or other subpage.
  • 2011-04-03: Added nojs= option for controlling JS/non-JS behaviour. Changed non-JS default behaviour to show only one div when toggling between two.
  • 2011-03-30: Fixed Toggle to make it non-JavaScript friendly. Added tooltips to links. Added grouped toggling.
  • 2009-07-23: Fixed bug preventing initial state in sidebar. Fixed bug in cookie name.
  • 2009-03-09: Added image option.
  • 2009-03-06: Initial release, as an upgrade to ShowHide and ToggleLink scripts, combining both, and expanding the syntax.
    Changes from ShowHide/ToggleLink:
    Disbanded showhide and togglelink markup in favour of new (:toggle ... :) markup. Fixed single quotes in labels. Added button=1 parameter. Changed parameter names, but the old ones should still work. Added shortcut parameter syntax. Tidied up JavaScript.

See Also

  • ShowHide - original recipe, now superseded.
  • AddToggle - A GUIEdit button to convert selected text to a toggle link
  • UnToggle - A show/hide switch where the contents is visible even for browsers with JavaScript disabled.
  • ToggleNext - Unobtrusive WikiStyle-based toggle-next element; core feature since pmwiki-2.2.124.
  • Request - Lets the user change what is shown without JavaScript, by calling the page again with a URL request.

Comments

See discussion at Toggle-Talk

User notes +13: If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.