SitePoint Sponsor

User Tag List

Results 1 to 4 of 4

Hybrid View

  1. #1
    SitePoint Enthusiast Jenny McDermott's Avatar
    Join Date
    Jan 2002
    Location
    St. Louis Park MN
    Posts
    87
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    tabbed panels go back to showing default when coming back from clicking away

    I've built a tabbed panels navigation system using Spry at www.conklin.com/roofingmicrosite.cfm. When you are on any panel other than default (Fabric Reinforced), click a link to open one of the .pdfs, then go back using the Back button, the default tab is displayed again. To get another .pdf from one of the non-default panels, you'd have to remember which one you want, click the tab again, download the .pdf, and go through the same process if you want any more downloads. Obviously this would be a tedious and confusing experience for the user.

    I've tried several ways to fix this but haven't had any success. Now I'm running out of time because they want this puppy published asap. Can anyone show me what to tweak so the selected panel will stay put? Here's the javascript:

    (function() { // BeginSpryComponent
    if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {};
    Spry.Widget.TabbedPanels = function(element, opts)
    {
    this.element = this.getElement(element);
    this.defaultTab = 0; // Show the first panel by default.
    this.tabSelectedClass = "TabbedPanelsTabSelected";
    this.tabHoverClass = "TabbedPanelsTabHover";
    this.tabFocusedClass = "TabbedPanelsTabFocused";
    this.panelVisibleClass = "TabbedPanelsContentVisible";
    this.focusElement = null;
    this.hasFocus = false;
    this.currentTabIndex = 0;
    this.enableKeyboardNavigation = true;
    this.nextPanelKeyCode = Spry.Widget.TabbedPanels.KEY_RIGHT;
    this.previousPanelKeyCode = Spry.Widget.TabbedPanels.KEY_LEFT;
    Spry.Widget.TabbedPanels.setOptions(this, opts);
    // If the defaultTab is expressed as a number/index, convert
    // it to an element.
    if (typeof (this.defaultTab) == "number")
    {
    if (this.defaultTab < 0)
    this.defaultTab = 0;
    else
    {
    var count = this.getTabbedPanelCount();
    if (this.defaultTab >= count)
    this.defaultTab = (count > 1) ? (count - 1) : 0;
    }
    this.defaultTab = this.getTabs()[this.defaultTab];
    }
    // The defaultTab property is supposed to be the tab element for the tab content
    // to show by default. The caller is allowed to pass in the element itself or the
    // element's id, so we need to convert the current value to an element if necessary.
    if (this.defaultTab)
    this.defaultTab = this.getElement(this.defaultTab);
    this.attachBehaviors();
    };
    Spry.Widget.TabbedPanels.prototype.getElement = function(ele)
    {
    if (ele && typeof ele == "string")
    return document.getElementById(ele);
    return ele;
    };
    Spry.Widget.TabbedPanels.prototype.getElementChildren = function(element)
    {
    var children = [];
    var child = element.firstChild;
    while (child)
    {
    if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
    children.push(child);
    child = child.nextSibling;
    }
    return children;
    };
    Spry.Widget.TabbedPanels.prototype.addClassName = function(ele, className)
    {
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
    return;
    ele.className += (ele.className ? " " : "") + className;
    };
    Spry.Widget.TabbedPanels.prototype.removeClassName = function(ele, className)
    {
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
    return;
    ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
    };
    Spry.Widget.TabbedPanels.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
    {
    if (!optionsObj)
    return;
    for (var optionName in optionsObj)
    {
    if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
    continue;
    obj[optionName] = optionsObj[optionName];
    }
    };
    Spry.Widget.TabbedPanels.prototype.getTabGroup = function()
    {
    if (this.element)
    {
    var children = this.getElementChildren(this.element);
    if (children.length)
    return children[0];
    }
    return null;
    };
    Spry.Widget.TabbedPanels.prototype.getTabs = function()
    {
    var tabs = [];
    var tg = this.getTabGroup();
    if (tg)
    tabs = this.getElementChildren(tg);
    return tabs;
    };
    Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function()
    {
    if (this.element)
    {
    var children = this.getElementChildren(this.element);
    if (children.length > 1)
    return children[1];
    }
    return null;
    };
    Spry.Widget.TabbedPanels.prototype.getContentPanels = function()
    {
    var panels = [];
    var pg = this.getContentPanelGroup();
    if (pg)
    panels = this.getElementChildren(pg);
    return panels;
    };
    Spry.Widget.TabbedPanels.prototype.getIndex = function(ele, arr)
    {
    ele = this.getElement(ele);
    if (ele && arr && arr.length)
    {
    for (var i = 0; i < arr.length; i++)
    {
    if (ele == arr[i])
    return i;
    }
    }
    return -1;
    };
    Spry.Widget.TabbedPanels.prototype.getTabIndex = function(ele)
    {
    var i = this.getIndex(ele, this.getTabs());
    if (i < 0)
    i = this.getIndex(ele, this.getContentPanels());
    return i;
    };
    Spry.Widget.TabbedPanels.prototype.getCurrentTabIndex = function()
    {
    return this.currentTabIndex;
    };
    Spry.Widget.TabbedPanels.prototype.getTabbedPanelCount = function(ele)
    {
    return Math.min(this.getTabs().length, this.getContentPanels().length);
    };
    Spry.Widget.TabbedPanels.addEventListener = function(element, eventType, handler, capture)
    {
    try
    {
    if (element.addEventListener)
    element.addEventListener(eventType, handler, capture);
    else if (element.attachEvent)
    element.attachEvent("on" + eventType, handler);
    }
    catch (e) {}
    };
    Spry.Widget.TabbedPanels.prototype.cancelEvent = function(e)
    {
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;
    return false;
    };
    Spry.Widget.TabbedPanels.prototype.onTabClick = function(e, tab)
    {
    this.showPanel(tab);
    return this.cancelEvent(e);
    };
    Spry.Widget.TabbedPanels.prototype.onTabMouseOver = function(e, tab)
    {
    this.addClassName(tab, this.tabHoverClass);
    return false;
    };
    Spry.Widget.TabbedPanels.prototype.onTabMouseOut = function(e, tab)
    {
    this.removeClassName(tab, this.tabHoverClass);
    return false;
    };
    Spry.Widget.TabbedPanels.prototype.onTabFocus = function(e, tab)
    {
    this.hasFocus = true;
    this.addClassName(tab, this.tabFocusedClass);
    return false;
    };
    Spry.Widget.TabbedPanels.prototype.onTabBlur = function(e, tab)
    {
    this.hasFocus = false;
    this.removeClassName(tab, this.tabFocusedClass);
    return false;
    };
    Spry.Widget.TabbedPanels.KEY_UP = 38;
    Spry.Widget.TabbedPanels.KEY_DOWN = 40;
    Spry.Widget.TabbedPanels.KEY_LEFT = 37;
    Spry.Widget.TabbedPanels.KEY_RIGHT = 39;

    Spry.Widget.TabbedPanels.prototype.onTabKeyDown = function(e, tab)
    {
    var key = e.keyCode;
    if (!this.hasFocus || (key != this.previousPanelKeyCode && key != this.nextPanelKeyCode))
    return true;
    var tabs = this.getTabs();
    for (var i =0; i < tabs.length; i++)
    if (tabs[i] == tab)
    {
    var el = false;
    if (key == this.previousPanelKeyCode && i > 0)
    el = tabs[i-1];
    else if (key == this.nextPanelKeyCode && i < tabs.length-1)
    el = tabs[i+1];
    if (el)
    {
    this.showPanel(el);
    el.focus();
    break;
    }
    }
    return this.cancelEvent(e);
    };
    Spry.Widget.TabbedPanels.prototype.preorderTraversal = function(root, func)
    {
    var stopTraversal = false;
    if (root)
    {
    stopTraversal = func(root);
    if (root.hasChildNodes())
    {
    var child = root.firstChild;
    while (!stopTraversal && child)
    {
    stopTraversal = this.preorderTraversal(child, func);
    try { child = child.nextSibling; } catch (e) { child = null; }
    }
    }
    }
    return stopTraversal;
    };
    Spry.Widget.TabbedPanels.prototype.addPanelEventListeners = function(tab, panel)
    {
    var self = this;
    Spry.Widget.TabbedPanels.addEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e, tab); }, false);
    if (this.enableKeyboardNavigation)
    {
    // XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
    // rely on adding the tabindex attribute if it is missing to enable keyboard navigation
    // by default.
    // Find the first element within the tab container that has a tabindex or the first
    // anchor tag.

    var tabIndexEle = null;
    var tabAnchorEle = null;
    this.preorderTraversal(tab, function(node) {
    if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)
    {
    var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
    if (tabIndexAttr)
    {
    tabIndexEle = node;
    return true;
    }
    if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
    tabAnchorEle = node;
    }
    return false;
    });
    if (tabIndexEle)
    this.focusElement = tabIndexEle;
    else if (tabAnchorEle)
    this.focusElement = tabAnchorEle;
    if (this.focusElement)
    {
    Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "focus", function(e) { return self.onTabFocus(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "blur", function(e) { return self.onTabBlur(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);
    }
    }
    };
    Spry.Widget.TabbedPanels.prototype.showPanel = function(elementOrIndex)
    {
    var tpIndex = -1;

    if (typeof elementOrIndex == "number")
    tpIndex = elementOrIndex;
    else // Must be the element for the tab or content panel.
    tpIndex = this.getTabIndex(elementOrIndex);

    if (!tpIndex < 0 || tpIndex >= this.getTabbedPanelCount())
    return;
    var tabs = this.getTabs();
    var panels = this.getContentPanels();
    var numTabbedPanels = Math.max(tabs.length, panels.length);
    for (var i = 0; i < numTabbedPanels; i++)
    {
    if (i != tpIndex)
    {
    if (tabs[i])
    this.removeClassName(tabs[i], this.tabSelectedClass);
    if (panels[i])
    {
    this.removeClassName(panels[i], this.panelVisibleClass);
    panels[i].style.display = "none";
    }
    }
    }
    this.addClassName(tabs[tpIndex], this.tabSelectedClass);
    this.addClassName(panels[tpIndex], this.panelVisibleClass);
    panels[tpIndex].style.display = "block";
    this.currentTabIndex = tpIndex;
    };
    Spry.Widget.TabbedPanels.prototype.attachBehaviors = function(element)
    {
    var tabs = this.getTabs();
    var panels = this.getContentPanels();
    var panelCount = this.getTabbedPanelCount();
    for (var i = 0; i < panelCount; i++)
    this.addPanelEventListeners(tabs[i], panels[i]);
    this.showPanel(this.defaultTab);
    };
    })(); // EndSpryComponent

    And in case it's helpful, here are the relevant css style definitions:

    .TabbedPanels {
    overflow: hidden;
    margin: 0;
    padding: 0;
    clear: none;

    .TabbedPanelsTabGroup {
    margin: 0;
    padding: 6px 2px 4px 0;
    background-image: url(/images/tab_shadow.png);
    background-repeat:repeat-x;
    background-position:bottom left;
    float:left;
    height:24px;
    width:100%;
    }

    .TabbedPanelsTab {
    position: relative;
    top: 1px;
    float: left;
    width:159px;
    padding: 4px 3px 4px 3px;
    margin: 2px 2px 0 0;
    height:16px;
    font-size:13px;
    font-family:sans-serif;
    font-weight:bold;
    color:#c10e38;
    background-color: #ede5d2;
    text-align:center;
    list-style: none;
    /*border-left: solid 2px #CCC;*/
    border-bottom:solid 1px #ccc;
    /*border-top: solid 2px #ccc;
    border-right: solid 2px #ccc;*/
    -moz-user-select: none;
    -khtml-user-select: none;
    cursor: pointer;
    display:inline;
    -webkit-text-size-adjust:none;
    }

    .TabbedPanelsTabHover {
    background-color: #f6f0e2;
    }

    .TabbedPanelsTabSelected {
    background-color: #fff;
    border-bottom: 2px solid #fff;
    position: relative;
    top: 1px;
    margin-bottom:-2px;
    }

    .TabbedPanelsTab a {
    float:left;
    display:block;
    text-decoration: none;
    }

    .TabbedPanelsContentGroup {
    clear: both;
    /*border-left: solid 1px #CCC;
    border-bottom: solid 1px #CCC;
    border-top: solid 1px #999;
    border-right: solid 1px #999;*/
    background-color: #fff;
    margin-top:3px;
    }

    .TabbedPanelsContent {
    overflow: hidden;
    padding:20px 20px 30px 40px;
    background:#FFF;
    margin-top:6px;
    }

    .TabbedPanelsContentVisible {
    }


    The html element in question:

    <div id="TabbedPanels1" class="TabbedPanels">
    <ul class="TabbedPanelsTabGroup" >
    <li class="TabbedPanelsTab" tabindex="0" style="margin-left:-2px;"><nobr>Fabric Reinforced</nobr></li>
    <li class="TabbedPanelsTab" tabindex="1"><nobr>Metal Roof Restoration </nobr></li>
    <li class="TabbedPanelsTab" tabindex="2"><nobr>Single-Ply Membrane </nobr></li>
    <li class="TabbedPanelsTab wideTab" tabindex="3" style="text-align:left;"><nobr> Single-Ply Recoating System</nobr> </li>
    <li class="TabbedPanelsTab wideTab" tabindex="4"> <nobr>Spray Polyurethane Foam</nobr> </li>
    </ul>

    <div class="TabbedPanelsContentGroup"><!--only one content group-->
    <!-- a panels content for each tab-->
    <div class="TabbedPanelsContent">
    <!--fabric reinforced-->
    <div id="chooseSys">Choose a system above to download MSDS sheets, Spec Sheets, and Guide Specifications</div>
    <div id="pdfLists">
    <div class="section">

    <h3>Benchmark</h3> (etc.)
    "Nobody ever went broke by underestimating
    the taste of the American public." -- H.L. Mencken

  2. #2
    SitePoint Wizard
    Join Date
    Dec 2003
    Location
    USA
    Posts
    2,582
    Mentioned
    29 Post(s)
    Tagged
    0 Thread(s)
    The problem is that your panels get changed with Javascript, but when you go back, the page is essentially reset to it's original position.

    Something I did on a similar project was make it so all the tab links change the URL (by doing something like #tab2, etc). Then, when the page loads, it checks for the #, and if present will go to that tab directly. It also allows you to give direct links to specific tabs.

  3. #3
    SitePoint Enthusiast Jenny McDermott's Avatar
    Join Date
    Jan 2002
    Location
    St. Louis Park MN
    Posts
    87
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the suggestion, but it didn't work. Assuming I correctly interpreted your advice, I added <a href=Microsite prototype, etc. to each tabbed panels tab. Unfortunately it made no difference.
    "Nobody ever went broke by underestimating
    the taste of the American public." -- H.L. Mencken

  4. #4
    SitePoint Wizard
    Join Date
    Dec 2003
    Location
    USA
    Posts
    2,582
    Mentioned
    29 Post(s)
    Tagged
    0 Thread(s)
    You want the links to be #whatever, not just whatever.

    You also have to do a little bit of Javascript to make it work.

    So, first you'll want to determine if there is something with # after it:
    Code:
    var loc = window.location.href;
    var matches = loc.match(/#(.*)/);
    
    if(matches.length > 0) {
      // Code to do something here
    }
    Then, inside of the if statement, you use matches[0] in a switch or something. If it matches one of your existing tabs, you can then make that tab the active one.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •