NestedText
Question
How can I create a page that allows the reader to expand or collapse the text to reveal or hide certain text?
Answer
The core includes a ConditionalMarkup directive for showing and hiding text, but the existing conditions focus on environmental values (names, date, etc) rather than values that the user can be prompted to provide.
The ViewModes recipe, which is implemented in this group, provides an opportunity to test the concept of user prompted conditional markup because it provides both a variable whose value can be reset by a link and a corresponding Conditional Markup condition that can test for the value of that variable.
Update! Two new recipes are now available. Jump ahead to the discussion of Show Hide and Page Variable Extensions.
Show Me
Here are some examples of different ways to prompt users to decide whether to expand or collapse the text of this page to show or hide additional text that is wrapped in conditional markup. In each case, the additional text discusses the method used to prompt the user.
Example 1 (simple links):
expand / collapse
[[{$Name}?view=display| expand]] / [[{$Name}?view=standard| collapse]]
These are the simplest links, because they do not require conditional markup to determine which link to display when.
Example 2 (toggled links)):
collapse
(:if view display :) [[{$Name}?view=standard| collapse]] (:if view standard :) [[{$Name}?view=display| expand]] (:if:)
Placing both links before the conditional markup makes it simpler, because then the conditional markup can focus on the text, without having to also deal with the links, as is the case with the following examples.
Example 3 (toggled InputForms buttons):
(:if view display :) (:input form "{$Name}?view=standard":) (:input submit value="Collapse":) (:input end:) (:if view standard :) (:input form "{$Name}?view=display":) (:input submit value="Expand":) (:input end:) (:if:)
Right now, these InputForms don't do anything more than what ordinary links do -- they post the specified url -- but they may have greater potential. The default action is to Post a url, but an optional argument called "method" can specify different actions. I can't find any documentation on what those are. (I have found an example that incorporates an accesskey). At the very least, InputForms seem to have potential simply because they are already focused on obtaining and acting on user input.
Notes
Don't use ViewModes. I am using ViewModes just to test this concept. Using ViewModes for anything more would not be a good idea because resetting the views to expand and collapse text will change the views in skins that use ViewModes, and visa-versa.
Limitations. The current test using ViewModes reveals some limitations that would be nice to avoid.
- All or nothing expansion
- No provision for selectively expanding certain sections, or levels
- Changes return the reader to the top of the page expand / collapse
- The current ViewModes link does not work with page location markers, e.g
[[{$Name}#showme]]
is a simple link that would take you to the section called showme. Try it: NestedText#showme[[{$Name}?view=display| expand]]
would render the current page in the display view. Try it: expand[[{$Name}#showme?view=display| expand and return]]
would not do anything. Try it: expand and return
Other approaches
JavaScript: Show Hide
The most visually pleasing approaches, in my opinion, are those that use JavaScript, because they avoid the delay that results from reposting. For example, take a look at how nicely HansB makes sidebars snap in and out of the page on Triad (with the small links in the corners that toggle between "hide" and "show").
This recipe uses java script to create toggle buttons (and links) which will show/hide sections (divs) on a page. Thanks for your encouragement to develop this! I expanded the concept used for Triad skin's toggle buttons and generalised it to work with multiple buttons for multiple sections. Note that pmwiki does not allow nesting of divs, so there is a limitation. ~HansB
On the other hand, those solutions are dependent on users having JavaScript enabled and, as Hagan points out in his post to the forum here, reposting "isn't necessarily bad. For one thing, it provides feedback in the logs about which content is being sought."
New markup: Page Variable Extensions
Note: This page was a proof of concept that was confined to using the currently available features of ViewModes, which is enabled for this group, to supply variables that can be set by actions and used by ConditionalMarkup. If we break free of this limited testing context, then many more possibilities arise, including the creation of new markup, see PM's reply to Pierre's thread in the PmWiki forum here
Dfaure's new Page Variable Extensions recipe allows you to set new page variables that can be set by action links and tested by Conditional Markup. While this has many applications, it can clearly be used for a show hide function and, because it uses reposting and conditional markup, it can make more efficient use of limited resources when used to toggle between directives (as noted above).
The default setup for this recipe does not have the action links enabled. To allow users to set variables using links, you will need to set the $EnableUrlSetVar by adding the following line to you rconfig.php (or farmconfig.php) before the include line for the recipe:
$EnableUrlSetVar = 1; include_once("$FarmD/cookbook/extendvars.php");
With that addition, you can use a link to create a new page variable. For example, if we want to create a new page variable called {$Choice}
and assign it a value of "hide", we can use an action that combines ?set_
with the desired name and value of the new page variable, which, in this case, would be: ?set_Choice=hide
.
To use that with a link, append it to the end of the link, which you can do programatically by using the existing Page Variable {$PageUrl}
, like this: [[{$PageUrl}?set_Choice=hide]]
That creates a page variable called {$Choice}
and assigns a value of "hide". To reassign a different value, just substitute the new value, like this [[{$PageUrl}?set_Choice=hide]]
. Use multiple links to set and display different values, like this: [[({$PageUrl}?set_Choice=)show]]
or [[({$PageUrl}?set_Choice=)hide]]
At that point, you can use conditions to test for the values, including a condition to test for no value (the default before either link is clicked):
(:if equal {$Choice} "":) Default: no choice has been selected (:if equal {$Choice} "show":) Show: The show link was selected (:if equal {$Choice} "hide":) Hide: The hide link was selected (:if end:)
As with the earlier examples, a toggle effect can be created by placing different links inside of conditions, so that a "show" state includes a "hide" link, and a "hide" state includes a "show" link, like this:
(:if equal {$Choice} "":) Show state (default) [[({$PageUrl}?set_Choice=)hide]] (displayed link) (:if equal {$Choice} "show":) Show state (selected) [[({$PageUrl}?set_Choice=)hide]] (displayed link) (:if equal {$Choice} "hide":) Hide state (selected) [[({$PageUrl}?set_Choice=)show]] (displayed link) (:if end:)
To simplify this, the condition for the default state can be combined with the show (or hide) state using boolean conditions, available on more recent versions of PmWiki, as follows:
(:if expr equal {$Choice} "" || equal {$Choice} "show" :) Show state (by default or choice) [[({$PageUrl}?set_Choice=)hide]] (displayed link) (:if equal {$Choice} "hide":) Hide state (selected) [[({$PageUrl}?set_Choice=)show]] (displayed link) (:if end:)
Or, even easier, condition the show state on the negative of the hide state, like this:
(:if !equal {$Choice} "hide":) Show state (by default or choice) [[({$PageUrl}?set_Choice=)hide]] (displayed link) (:if equal {$Choice} "hide":) Hide state (selected) [[({$PageUrl}?set_Choice=)show]] (displayed link) (:if end:)
Comments
From PmWikiForum
See Also
PmWiki recipes using conditions or variables set by links, or both
- ConditionalMarkup .
- Cookbook:ViewModes.
- Skins:SkinChange
- Cookbook:Quiz very simple example of creating a new condition in config.php
JavaScript use in PmWiki to toggle solected text between show and hide
- Cookbook:PageTableOfContents $ToggleText for 'hide' and 'show' text using Java
- Cookbook:PostItNotes notehidden markup requires Java
- GroupCustomizations
- Skins:Triad left and right bars can be hidden with JavaScript toggle
PmWiki forum threads
- invisible/visible text Proposing new markup
- Conditional Markup for prompted user input
Solutions in other WikiWorlds
CSS and JavaScript examples in the wild
- jedbrown.net
- No documentation, but try the links that say "click for more information"
- cookbook.sitellite.org
- tjkdesign.com
- Prepared FAQs solution with discussion. Option to expand the entire page or selected protions
JavaScript examples with workarounds for script disabled browers
- webtips.dan.info/graceful.html
- General article about graceful degradation, with specific tips
- tjkdesign.com
- Claims to degrade well without java; but did not work when I tested with Netscape 7 (but did with Safari)
- bobbyvandersluis.com
- Proposal for "unobtrusive" show hide, requires separate CSS
- webmasterworld.com
- Forum comment: skip DISPLAY: none styling; let javascript hide on page load
- developer.apple.com
- Lots of suggestions, e.g. return opposite values (swap false to true) so that link is followed on failure)
- holovaty.com
- Used wrapping each link with a valid link and onclick event handlers returning false
Some general JavaScript articles
- webmonkey.wired.com
- Progressive Enhancement and the Future of Web Design
- developer.mozilla.org
- A Reintroduction to JavaScript