<< back to overview WebYep - The Shiny Tiny WebCMS
This is one of a series of articles about WebYep and web design. Things are under development right now, so appearance and content may change over time.

Accordion Effekt with WebYep

The basic idea

This tutorial will show you how to create an accordion effect with WebYep and a few lines of JavaScript.

An "accordion" is a bunch of pairs of elements like for example a headline and some accompanying text. After loading the page only the headlines are visible. When you click on a headline, the corresponding text entry expands (like an accordion - hence the name). When you click another headline, the new text expands while the other entry contracts simultaneously. Here is an example page for those who want to see it in action.

The HTML part

In our example we'll use several <div>s to separate the elements:

One for the header (a WebYep ShortText element) and one for the actual content (WebYep RichText). In order to let the user add, remove and reorder each entry, we'll wrap them in another <div> to clearly separate each entry and put this inside a WebYep Loop. Finally we wrap the whole thing in another <div> so we can easily address everything related to our accordion effect.

The HTML part should now look like this:

<div class="accordion">
<?php foreach (WYLoopElement::aLoopIDs("newsLoop") as $webyep_oCurrentLoop->iLoopID) {
       $webyep_oCurrentLoop->loopStart(true); ?>
  <div>
    <div class="accordionHeader"><?php webyep_shortText("newsHeader", false); ?></div>
    <div class="accordionContent"><?php webyep_richText("newsContent", false, "", true); ?></div>
  </div>
<?php $webyep_oCurrentLoop->loopEnd(); } ?>
</div>

The WebYep field names are marked in red. You may want to change them to suit your needs. The CSS classes are marked in green. If you change them you must also change the jQuery code!

The JavaScript magic

For the sake of flexibility we'll use namespacing for the jQuery library. This will move the $-function of jQuery to another namespace (in our example this is WY, but you can of course use any other valid identifier) so it won't interfere with other libraries we might need.

In the page's <head> include the following javascripts (in this order):

• The jQuery library
• Some custom code to remove jQuery from the global scope (namespacing):
  1. <!-- namespacing jQuery -->
  2. <script type="text/javascript">/*<![CDATA[*/
  3.   var WY = window.WY || {}; WY.$ = jQuery.noConflict(true);
  4. /*]]>*/</script>

This moves the jQuery library to the namespace WY (as you might have guessed, WY stands for WebYep). From now on we must use WY.$() instead of just $() but the great thing is that other libraries (e.g. prototype) can now use their own $-function without problems.

If you don't need other libraries like prototype or you also need jQuery for other effects on your site you can omit the namespacing code and remove the namespace from the jQuery calls (i.e. delete "WY." globally).

• Some code that waits for the document to finish loading and then initializes the accordion:
  1. <!--  initialize accordion when the DOM is ready -->
  2. <script type="text/javascript">/*<![CDATA[*/
  3.   WY.$(document).ready(function(){
  4.     // check whether we are in edit mode
  5.     if (!WY.$('.accordion').find('.WebYepLoopAddButton').length){
  6.       // determine height of every .accordionContent and write it to the DOM
  7.       WY.$('.accordionContent').each(function(){
  8.         WY.$(this).css({'height':WY.$(this).height()+'px'});
  9.       });
  10.       // hide all .accordionContent items
  11.       WY.$('.accordionContent').css({'display':'none'});
  12.       // attach a click handler to each .accordionHeader
  13.       WY.$('.accordionHeader').each(function(){
  14.         WY.$(this).click(function(){
  15.           WY.$('.accordionContent').slideUp(350);
  16.           WY.$(this).siblings('.accordionContent').stop().slideToggle(350);
  17.         });
  18.       });
  19.     }
  20.   });
  21. /*]]>*/</script>

Let's look at the details of this code. Line 3 sets up the code to run as soon as the page is loaded. It's the jQuery equivalent of onload — nothing special so far.

In line 5 we check whether we are in edit mode or not. This is done by searching the .accordion container for an item with the CSS class WebYepLoopAddButton. Since the entries of the accordion are in a WebYep Loop there will be at least one edit button if we are in edit mode. The button to add a loop item will always be present - even if we've got an otherwise empty page - so we'll look for the CSS class of the WebYep Loop Add button.

Lines 7-9 prepare the .accordionContent containers for smooth animations. jQuery seems to have a problem with determining the correct height of an animated block element under certain circumstances (causes the animation to be jerky). This problem is fixed by putting the actual height into the style attribute.

After setting up the height we hide the .accordionContent containers in line 11.

Finally we add a click handler to each .accordionHead. By clicking a header all .accordionContent containers shall slide up (line 15), except the one sibling of the clicked header which we stop and then slide down (line 16).

A note on styles

One last word about the styles and mobile devices:

As you can see from the source code of the example pages, there is nothing fancy in the stylesheet — except one thing.

Mobile Safari has a habit of resizing text if it feels like it. Most of the time this is great since web designers don't have to redo all their pages for iOS and they are still readable. But there are also times when this default behaviour can be rather annoing. Setting explicit text sizes and container heights like in this example is such a case. If you want to use this accordion effect in your pages then you might need to tell Safari to leave the text-size alone. This can be done by setting -webkit-text-size-adjust: 100%; on the body. Don't use webkit-text-size-adjust: none; since this will completely disable zooming!

Example Pages

We've prepared 2 example pages – one for WebYep like described above and one as plain HTML. Both are essentially the same, but you'll need a working WebYep installation for the .php version.