Spry tutorial: linking to a non-default panel
February 9th, 2008
Several readers have asked me to explain how to create a link to a specific panel in a Spry tabbed panels widget or accordion. The Essential Guide to Dreamweaver CS3 shows how to do this from the same page, but not from another page. It’s quite simple to do with the help of SpryURLUtils.js, which was added to the Spry framework in version 1.6. I’ve added step-by-step instructions in the Tutorials section of my site, complete with a zip file containing a simple example. I hope you find it useful.
Entry Filed under: AJAX/JavaScript, Books, Dreamweaver
13 Comments Add your own
1. adrian | February 23rd, 2008 at 1:49 pm
Hi David,
Many thanks for creating code that Adobe should have built in first day. i can’t believe they overlooked a linking process so basic. When I implement your changes i get the error message saying :
“A script in file EditingUtils.js has been running for a long time”
This hangs up dreamweaver and renders the page uneditable. I pretty sure I followed your steps as the linking does work but when I close Dreamweaver and attempt to open file I get the error.
Any help appreciated
regards
2. Mike | March 3rd, 2008 at 12:04 am
David
Thanks for the tutorial; the code works great and I am using it on my website for tabbed panels now. I really needed this capability so really glad to see you put this out there.
I had one problem at first, that I solved quickly, and others may have it too so here it is. In your tutorial step 2, the code as displayed there assumes the target page is in the root directory. If however you store your target page in a subfolder of the root, I think you need to modify that step 2 code to look like this:
The diff is the “../” in front of the SpryAssets folder. I think that converts the path from a doc-relative one to a root-relative one (so should work no matter where on the site you hide the target page).
But let me know if that causes any other problems!
Thanks again for the excellent tutorial.
M
3. Mike | March 3rd, 2008 at 12:08 am
In the post I just placed above the sample code was stripped out. So really the message is this: if your target pages are in subfolders, then in step 2 of the tutorial place a “../” in front of the word “SpryAssets” to convert the path to a root relative path.
M
4. Joe | March 12th, 2008 at 7:44 pm
Hi David,
I am not sure where to turn, I been Googling and looking all around and came across your site - I have a question regarding Tabbed Panels in Dreamweaver - is it possible to have the Tabs remember which one was opened last when using the Back button in a browser? My web page has a tab on it - I click on one (other than the default tab) hit a link - go to a new page - hit the back button - the default tab is open, not the one I last was on.
<>
I know this is probably not the right place to post this question - a simple YES or NO from you will be fine - and I will keep looking,
<>
Thank you in advance for your time and forgive the post.
5. William Patterson | April 9th, 2008 at 6:17 pm
code works great. I found it easier to use after I had established the working pages and links. Then there where not any issues with path statements for finding the js files.
One item that would be a nice add is to have the target open the panel if the target page has the panels set to be all closed using the following string; var Accordion1 = new Spry.Widget.Accordion(”Accordion1″, { useFixedPanelHeights: false, defaultPanel: -1 });
I like to have the panels all closed when opening the page that has the accordion.
6. Michael Fischler | April 14th, 2008 at 6:50 pm
I have been searching for the same answer that Joe is. I would like to return a visitor to the exact page he left, opened panels and all.
Thanks in advance for any insights shared.
7. seatoad | April 16th, 2008 at 8:16 pm
Michael and Joe, try this (btw, here’s hoping I tag the code I’m going to post correctly so it doesn’t get stripped out…I’ll try wrapping it in “code” tags and see what that does)…
1. On the source page (that is, the page with your tabbed or according panels), set everything up as David described.
2. Also on the source page, on the links on your various tabs, add a URL parameter that identifies tab number each link resides on. You can name the parameter anything you want, but “tab” seems good
enough. If you have more than one set of tabbed panels on the page, you also need to add a parameter that identifies the target tabbed panel’s id. (But if you only have one set of panels and you’ve used the default DW id–e.g.,”TabbedPanels1″ you can skip this).
So, for example, the urls on the second tab (cuz the counting starts at 0, will look something like:
<a href="destination.htm?tab=1" rel="nofollow">and if you have 2 sets of tabbed panels, the urls on the second tab of the second panel set will look something like:
<a href="destination.htm?tab=1&panel=1" rel="nofollow">3. Now go to your destination page where you need to add two scripts: the first script will parse the url parameters you set up in the source page to get their values; the second script will write a link back to the source page, using its referrer information and the parameter values you passed.
3a. To parse the url parameters, you could write your own function, but I see no reason to reinvent the wheel. There’s a perfectly good script here:
http://www.netlobo.com/url_query_string_javascript.html
Just copy the function into a text file, save it as something like urlparser.js, and then call the script from the head section of your destination page.
3b. Now in the body of your destination page where you want the back link to appear, insert a script that: a) gets the referrer url of the source page; b) appends to it the parsed url parameters that identify the tab and panel set you want to go to; and c) writes it into a link.
For example:
var goback;
goback = (document.referrer);
var tab_param = parserfunctionname( 'tab' );
var panel_param = parserfunctionname( 'panel' );
if (document.referrer){
document.write("<a href='" + goback + "?tab=" + tab_param + "#TabbedPanels=" + panel_param' rel="nofollow">Previous Page</a>");
}
If you only have one set of tabbed panels per page, and you use the default DW id (TabbedPanels1) it’s even simpler. Don’t pass the panel id as a param from the source page and just hard code it in the back link. Like:
var goback;
goback = (document.referrer);
var tab_param = parserfunctionname( 'tab' );
if (document.referrer){
document.write("<a href='" + goback + "?tab=" + tab_param + "#TabbedPanels1"' rel="nofollow">Previous Page</a>");
}
There are probably much more compact ways of doing this. For example, you could write a function for the source page that automatically gets the id of the current tab and panel and appends that to your urls. But in the meantime this works. Only caveat is if the user has referrer information turned off in their browser, that’d be an issue. But you could code around that if you really wanted by passing the source page url as a parameter as well.
8. seatoad | April 18th, 2008 at 11:51 pm
Thanks for fixing that David
One big problem with the destination page script I posted above–it works fine the first time you use the back link to return to the source (panels page). But I didn’t think about what happens if users flip back and forth multiple times between the source and destination pages. In that case, the parameters added by the back link on the destination page become part of the source page’s referrer url. Which means the next time they visit the destination page and click the back link there will be two tab parameters in the URL. And then three, etc. Boo to me not testing more before posting.
So here’s a revised script for the back link on the destination page that first tests the referrer for the presence of URL parameters and strips them out if necessary.
var tab_param = parserfunctionname( 'tab' );var get_referrer = document.referrer;
var get_index = get_referrer.indexOf("?");
var clean_referrer = get_referrer.substring(0,get_index);
var goback;
if (get_index == -1){goback = get_referrer;
}
else {
goback = clean_referrer;
}
if (document.referrer){document.write("<a href='" + goback + "?tab=" + tab_param + "#TabbedPanels1' rel="nofollow">Go Back</a>");
}
9. Emile | April 26th, 2008 at 3:19 pm
David, I wondered if you would mind explaining how one might use the idea of framesets without using actual framesets. I want to use the vertical or horizontal menu’s but make sure the menu structures remain visible when you click one of the Item links.
I don’t want to open the link in a new page and I don’t want the menu to disappear when one clicks a link. I know this is possible to do when using framesets but is there a way to do it without framesets….perhaps using one of the default css layouts with a header, sidebar, footer and mainContent. You see, I want the sidebar to always display the navigation menu, (say using the vertical version) while the header always displays my header and logo, but use the mainContent to display the page relative to the menu item’s link. The target box attributes (_blank; _self; _parent; _top) only applies to framesets…which defeats the purpose? Any ideas? Thanks so much.
10. Joshua | April 29th, 2008 at 7:47 pm
David,
Excellent tutorial, very well laid-out and a great use of the Spry technologies. I have the script working wonderfully on a client site, but I do have a strange bug that I can’t seem to work around.
When linking externally to a different sliding panel, the panel opens correctly, but all panels before the opened one seem to be forgotten by Spry, and I can’t navigate to them using either the Previous/Next links, or on-page direct references. It appears as if Spry has decided the the first open panel will be 0, and enumerates from there, forgetting about panels before.
I have poured through the javascript for both the SprySlidingPanels and SpryURLUtils, but can’t seem to make sense of why this is happening. The behavior can be seen at http://www.gopaperlessnow.com/pages/ptdental.php, scrolling to the bottom, and clicking on one of the modules/features. On the newly opened page, try to navigate to a module/feature listed before the open one. Bizarre eh?
Thanks again for the great tutorial, and I hope we can figure this one out!
Joshua
11. David Powers | April 30th, 2008 at 8:51 am
@Emile: This should definitely be possible with Spry/Ajax, but I don’t have any quick, easy solutions. I’m up to my eyeballs working on a couple of books at the moment, so it’s not something I’ll have time to look at in the near future. Sorry.
@Joshua: A lot of Spry is a mystery
. I’m visiting the Dreamweaver team in California next month, when I hope they might sprinkle some magic dust of understanding on me.
12. Raf | May 1st, 2008 at 6:50 pm
David, thanks for this site and the great tutorials. Very useful stuff. I have one question that is somewhat along the same lines as #5 above, and that is, is it possible to open up a collapsed panel when linking to it from another page? So essentially passing the contentIsOpen variable thru the query string (link). Any ideas? Thanks again.
13. John M. Shaw | June 17th, 2008 at 12:45 pm
Wish I could cross-link collapsible panels from different pages. The SpryURLUtils.js tutorials, I have found only seem to deal with Accordians or tabbed panels, but the same solution for those, do not work for collapsible panels. I am tryin to link to another page, open a particular collapsible panel and display the information. I have one other aspect I would be very happy if working, once I got that part of the href to work, and it would be then activating a partuclar link in an unordered list, in that targeted collapsible panel, in order to display the proper HTML gfrgment in the SpryHTML panel I have in each collapsible panel.
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed