Spry Dynamic Tabs 2

A reader recently asked about my Spry Panel with Dynamic Content post:

How do I extend it to automatically generate each TAB from an external file as well.

The tabs are generated from [an] external XML data (the XML contains the link to be run when the Tab is clicked), and then each tab generates it's content when it is clicked.

In my post the tabs were hard coded, to dynamically generate the tabs using an xml file and then dynamically load the content specified in the xml file it's just a little bit more work (but less typing!).

I started out with a simple xml file that looks like:


<?xml version="1.0" encoding="UTF-8"?>
<tabs>
    <tab>
        <title>Tab1</title>
        <url>examples/tab1.html</url>
    </tab>
    <tab>
        <title>Tab2</title>
        <url>examples/tab2.html</url>
    </tab>
</tabs>

A simple enough structure that has the title of the tab and a URL which will ultimately be used to populate the tab.

We need to set up the appropriate links to the required css and Javascript files that will make it all work.


    <link href="../assets/css/SpryTabbedPanels.css" rel="stylesheet" type="text/css" />
    <script language="JavaScript" type="text/javascript" src="../assets/js/xpath.js"></script>
    <script language="JavaScript" type="text/javascript" src="../assets/js/SpryData.js"></script>
    <script language="JavaScript" type="text/javascript" src="../assets/js/SpryTabbedPanels.js"></script>

The Code

The HTML in this case is a little bit different because we will be generating the tabs dynamically from the xml data, but it will also be a heck of a lot shorter.


<script type="text/javascript">
//set up our dataset

var dsTabs = new Spry.Data.XMLDataSet("data/data.xml", "tabs/tab");
//function to dynamically load the contents of a url into the specified tab

function loadContent(panel,url){
    Spry.Utils.updateContent(panel,url);
}
//observer set to run after the data is loaded to populate the first tab.

Spry.Data.Region.addObserver("example1Region",dateLoadedCallback);
function dateLoadedCallback(notificationType, notifier, data)
{
    if (notificationType =="onPostUpdate"){    
         row= dsTabs.getRowByRowNumber(0)
         if(row){
         loadContent('0',row.url)
         }
}
}
</script>

    <div id="example1Region" spry:region="dsTabs">
    <div id="dynamicTabs" class="TabbedPanels">
        <ul class="TabbedPanelsTabGroup">
            <li spry:repeat="dsTabs" class="TabbedPanelsTab" onclick="loadContent('{ds_RowID}','{url}');" tabindex="0">{title}</li>
        </ul>
        <div class="TabbedPanelsContentGroup">
            <div spry:repeat="dsTabs" id="{ds_RowID}" class="TabbedPanelsContent"></div>
        </div>
    </div>
        <script type="text/javascript">
        var t1 = new Spry.Widget.TabbedPanels("dynamicTabs");
    </script>
</div>
The big change here is the addition of the spry:repeat="dsTabs" attribute. This tells spry to create an element for every entry in the data set. Basically an automated loop through every record. We do this twice once for the tabs (TabbedPanelsTab) and once for the tab panels (TabbedPanelsContent). Also in order for us to dynamically load the content into our dynamically created records I use an internal spry dataset row id ds_RowId as the unique id for each tab. This lets me set up an onclick event on each tab.

On the Tab


onclick="loadContent('{ds_RowID}','{url}');"

On the tab Content:


<div spry:repeat="dsTabs" id="{ds_RowID}" class="TabbedPanelsContent">

The loadContent javascript function is responsible for loading the content from the external file specified by our binding.


function loadContent(panel,url){
    Spry.Utils.updateContent(panel,url);
}

And then lastly I set up an Observer function to fire after the data is loaded. Since we didn't set which tab to have open by default it is the 1st tab (tab zero). Without the observer function our tab would initially be empty.


Spry.Data.Region.addObserver("example1Region",dateLoadedCallback);
function dateLoadedCallback(notificationType, notifier, data)
{
    if (notificationType =="onPostUpdate"){    
         row= dsTabs.getRowByRowNumber(0,true)
         if(row){
         loadContent('0',row.url)
         }
}
}

Note that this is not the most efficient method of defining an observer you can also do it all in one line like below but for clarity sake I have it broken out.


Spry.Data.Region.addObserver("example1Region",
    {onPostUpdate: function(ds,data)
        {row= dsTabs.getRowByRowNumber(0)
         if(row){
            loadContent('0',row.url)
         }
        }
    });

Summary

As with most of the Spry API a little Javascript goes a long way. In this example we used a hard coded xml file but we could easily change our dataset to use xml generated dynamically by a ColdFusion component or another server-side language, which in turn could contain a URL to another server-side page which would dynamically generate our contents.

Happy Coding...

Related Blog Entries

6 Comments to "Spry Dynamic Tabs 2"- Add Yours
Staca's Gravatar Hello and thank you for this Tuto !
I m newbie with the spry adobe
One question, i ' m tried to give dynamic Accordion like this Tabbed.
Could you explain how to do like this Tabbed ?
Thank you
# Posted By Staca | 3/14/08 4:07 PM
kyzer's Gravatar Thanks for your great info.
Is there a way the panel loaded in the Spry tab to be a Spry generated table as well. meaning that for a certain tab I need to load a new page that displays a Spry table. Got this working through "including" that page directly and not using the onclick feature, however I need the onclick so I can pass a variable to that Spry table, can you help me in this?
# Posted By kyzer | 10/4/08 3:35 PM
Rob Nijlaan's Gravatar Hello!

If i like to place this button in place of a title how do i do it????

<table class="Button">
<tr>
<td style="padding-right:0px" title ="Home">
<a href="NA" title="Home" style="background-image:url(../Buttons/Home.png);width:172px;height:75px;display:block;">
</a></td>
</tr>
</table>
# Posted By Rob Nijlaan | 4/6/10 7:35 PM
Rob Nijlaan's Gravatar By the way;

Im running my desktop on 1680×1080 and the code fields are so small on this page i need to zoom in on it to be abled to see the code.
# Posted By Rob Nijlaan | 4/6/10 8:15 PM
Rob Nijlaan's Gravatar If i insert a html or php not everything is showed.

The recaptcha is missing in form, a simple html doc doesnt show etc...

Im waiting for help...

Please help!
# Posted By Rob Nijlaan | 4/7/10 5:09 PM
Rob Nijlaan's Gravatar HELP!
# Posted By Rob Nijlaan | 4/8/10 8:30 PM

Powered By Railo

Subscribe

Subscribe via RSS
Follow garyrgilbert on Twitter Follow me on Twitter
Or, Receive daily updates via email.

Tags

adobe air ajax apple cf community cfml coldfusion examples ext flash flex google javascript max2007 max2008 misc open source programming railo software technology ui

Recent Entries

Converting structkeys to lowercase

Blogroll

An Architect's View
CFSilence
Rey Bango
TalkingTree

Wish List

My Amazon.com Wish List