Skip navigation
eboyjr
Currently Being Moderated

Dynamically Adding/Editing/Deleting Tabs on Tabbed Panels

Aug 24, 2007 8:26 PM

I am using the tabbed panels and need to know how to dynamically create a new tab with javascript with some content inside ( and switch to it ). Also, I need to figure out how I can delete tabs at "runtime"? I have tried many things to do this, but everytime, it has been failing. I need a functions just like this:

addTab(title, innerHTMLcontent);
deleteTab(currIndex);

Also, I think all of the Spry Widgets should have an easy way to dynamically change content.
 
Replies
  • Currently Being Moderated
    Aug 26, 2007 9:46 AM   in reply to eboyjr
    Hi,

    I have extended Spry's Tabbed Panel and added methods to add and remove tabs. It has been working fine. Let me know if you need that...

    -JV
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 29, 2007 12:12 PM   in reply to eboyjr
    Hi,

    here is the js file. I am also attaching a sample (I named it as Spry.Widget.ExtendedTabbedPanels, may be you could change it). Let me know if you face any issues.

    ===================START-JS FILE==============================

    var Spry; if (!Spry) Spry = {}; if (!Spry.Widget) Spry.Widget = {};

    Spry.Widget.ExtendedTabbedPanels = function(element, opts) {
    Spry.Widget.TabbedPanels.call(this, element, opts);
    };

    Spry.Widget.ExtendedTabbedPanels.prototype = new Spry.Widget.TabbedPanels();
    Spry.Widget.ExtendedTabbedPanels.prototype.constructor = Spry.Widget.ExtendedTabbedPanels;

    Spry.Widget.ExtendedTabbedPanels.prototype.addTab = function (tabname, tabcontent, position) {
    var tabs = this.getTabs();

    if((!position && position != 0)|| position > tabs.length)
    position = tabs.length;

    var newtab = tabs[tabs.length - 1].cloneNode(true);
    this.setElementNodeValue(newtab, tabname);

    this.getTabGroup().insertBefore(newtab, tabs[position]);

    var tabContents = this.getContentPanels();
    var newContentPanel = tabContents[tabContents.length - 1].cloneNode(false);
    newContentPanel.innerHTML = tabcontent;
    this.getContentPanelGroup().insertBefore(newContentPanel, tabContents[position]);

    this.addPanelEventListeners(newtab, newContentPanel);

    this.showPanel(position);
    }

    Spry.Widget.ExtendedTabbedPanels.prototype.removeTab = function(tabindex) {
    var tabs = this.getTabs();

    if((tabs.length == 1) || (!tabindex && tabindex != 0) || tabindex >= tabs.length)
    return false;

    var tabToRemove = tabs[tabindex];

    this.getTabGroup().removeChild(tabToRemove);

    var contentPanelToRemove = this.getContentPanels()[tabindex];
    this.getContentPanelGroup().removeChild(contentPanelToRemove);

    this.removePanelEventListeners(tabToRemove, contentPanelToRemove);

    if(this.getCurrentTabIndex() == tabindex) {
    if(this.getTabs().length <= tabindex)
    this.showPanel(this.getTabs().length - 1);
    else
    this.showPanel(tabindex);
    }
    }

    Spry.Widget.ExtendedTabbedPanels.removeEventListener = function(element, eventType, handler, capture)
    {
    try
    {
    if (element.removeEventListener)
    element.removeEventListener(eventType, handler, capture);
    else if (element.detachEvent)
    element.detachEvent("on" + eventType, handler);
    }
    catch (e) {}
    };


    Spry.Widget.ExtendedTabbedPanels.prototype.removePanelEventListeners = function(tab, panel)
    {
    var self = this;
    Spry.Widget.ExtendedTabbedPanels.removeEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);
    Spry.Widget.ExtendedTabbedPanels.removeEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);
    Spry.Widget.ExtendedTabbedPanels.removeEventListener(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.ExtendedTabbedPanels.removeEventListener(this.focusElemen t, "focus", function(e) { return self.onTabFocus(e, tab); }, false);
    Spry.Widget.ExtendedTabbedPanels.removeEventListener(this.focusElemen t, "blur", function(e) { return self.onTabBlur(e, tab); }, false);
    Spry.Widget.ExtendedTabbedPanels.removeEventListener(this.focusElemen t, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);
    }
    }
    };



    Spry.Widget.ExtendedTabbedPanels.prototype.setElementNodeValue = function(element, nodevalue) {
    var currentElement = element;
    var tmpElement = this.getElementChildren(element);

    while(tmpElement.length != 0) {
    currentElement = tmpElement[0];
    tmpElement = this.getElementChildren(tmpElement[0]);
    }
    currentElement.innerHTML = nodevalue;
    }

    ====================END JS FILE==================================



    ===================SAMPLE TEST===================================
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns=" http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    <link href="SpryAssets/SpryTabbedPanels.css" rel="stylesheet" type="text/css" />
    <script src="SpryAssets/SpryTabbedPanels.js" type="text/javascript"></script>
    <script src="SpryAssets/SpryExtendedTabbedPanels.js" type="text/javascript"></script>
    </head>

    <body>
    <div id="TabbedPanels1" class="TabbedPanels">
    <div class="TabbedPanelsTabGroup">
    <span class="TabbedPanelsTab" tabindex="0"><b>Tab 1</b></span>
    <span class="TabbedPanelsTab" tabindex="0">Tab 2</span>
    </div>
    <div class="TabbedPanelsContentGroup">
    <div class="TabbedPanelsContent">Content 1</div>
    <div class="TabbedPanelsContent">Content 2</div>
    </div>
    </div>
    <input type="text" id="tabname" />
    <input type="text" id="tabcontent" />
    <input type="text" id="position" />

    <input type="button" value="add tab" onclick="add();" />
    <input type="button" value="delete tab" onclick="TabbedPanels1.removeTab(parseInt(document.getElementById('po sition').value));" />

    <script type="text/javascript">
    <!--
    var TabbedPanels1 = new Spry.Widget.ExtendedTabbedPanels("TabbedPanels1");

    function add() {
    var tabTitle = document.getElementById("tabname").value;
    var tabcontent = document.getElementById("tabcontent").value;
    var position = document.getElementById("position").value;

    TabbedPanels1.addTab(tabTitle, tabcontent, parseInt(position));
    }
    //-->
    </script>
    </body>
    </html>

    ===================SAMPLE TEST END=======================
     
    |
    Mark as:
  • Currently Being Moderated
    Sep 17, 2007 1:47 PM   in reply to jvenu
    I've been trying to figure out if I can dynamically add tabs. Thanks for extending the widget. I tried using it. It's not working for me. I was curious if your code is tied to a specific version of the Spry Framework. I'm using 1.5 (dated 051707) and get the following error when loading the sample page. Note: The tabs content is all displaying as one and tabs can't be selected:

    panels[tpIndex] has no properties in SpryTabbedPanels.js line 363
    this.getElement is not a function in SpryTabbedPanels.js line 36

    The odd thing is that if I just use the standard Tab Panel widget, the content displays and functions as tabs, but I still get the first error listed above. So maybe the problem is in the latest pre-release of Spry.

    What version of Spry Framework did you develop your extended class from?

    Thanks so much,
    Jack
     
    |
    Mark as:
  • Currently Being Moderated
    Sep 17, 2007 2:22 PM   in reply to jackinva
    Hi,

    I am sorry, I forgot to mention about the following change that you need to make in SpryTabbedPanels.js.

    Please add the following sentence in the SpryTabbedPanels.js constructor. This should be first statement in the constructor.

    if(!element) return;

    It should work fine after applying the above change.

    Let me know if it works.

    - JV
     
    |
    Mark as:
  • Currently Being Moderated
    Sep 18, 2007 7:56 AM   in reply to jvenu
    Hi JV,

    Thanks so much for extending the tabbed panels widget! Adding the one line above as you mentioned fixed everything for me.

    Not only does this add tabbed panels, but if you're using those tabs within a form, the entered data on one form tab is not lost when adding another. This is the solution to what I've been wanting for a project I'm working on.

    You rock!

    Thanks again,
    Jack
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 2, 2007 11:22 PM   in reply to jvenu
    Hello,

    I was looking at your extended tabbed panel javascript. I am currently using a (7) tab tabbed panel. The content to each tab is dynamically created. What I am trying to figure out is an easy way to hide a tab if the tab contains no dynamic content. If the tab has content then I want to show the tab and its content. I have tried IF statements around the <li> tag and the <div> for the content. Didn't work. Any ideas what might work? This script?

    Thanks....
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 3, 2007 11:38 AM   in reply to westco5
    I don't see why it wouldn't work. The extended widget JV created allows you to add and delete tabs. So you could delete a tab (including its content) when you had nothing to put in it. Then add it back when you had something to show.
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 7, 2007 10:19 PM   in reply to jackinva
    Have you tested your ExtendedTab class with 1.6 yet? I am having a problem getting it to work after upgrading to 1.6\

    Thanks

    Z
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 7, 2007 10:34 PM   in reply to ZeusChicago
    Hi,

    There are no changes in SpryTabbedPanels.js in 1.5 & 1.6. It is supposed to work with Spry1.6 also,
    Did u modify the SpryTabbedPanels.js as suggested by me to make it work? Please see my previous posts in this thread and modify the SpryTabbedPanels.js accordingly.

    Let me know if it works.
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 8, 2007 6:57 AM   in reply to jvenu
    Yeah. I belive I added it to the correct area at least.This is the error I am getting when even trying to use your sample page (this error is generated when the page loads)

    Spry.Widget.SpryTabbedPanels is not a constructor
    [Break on this error] var TabbedPanels1 = new Spry.Widget.SpryTabbedPanels("TabbedPanels1");

    Here is the Spry.Widget.TabbedPanels class I modifed per your instructions

    Spry.Widget.TabbedPanels = function(element, opts)
    {
    if(!element) return;
    this.element = this.getElement(element);
    ....... rest of class
    }

    I have your test page setup here
    http://www.gillespiecrm.com/t.html

    Thanks in advance for your help!

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 8, 2007 10:22 AM   in reply to ZeusChicago
    Hi,

    Did you rename the class to "Spry.Widget.SpryTabbedPanels"? (My class name was "Spry.Widget.ExtendedTabbedPanels").
    If so, you need to make the changes in the javascript file accordingly to reflect the new name.
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 8, 2007 1:01 PM   in reply to jvenu
    Grrrr. I had already found one, but that just lead me to this I was using

    = new Spry.Widget.ExtendedTabbedPanel
    instead of
    = new Spry.Widget.ExtendedTabbedPanel s <-- the s on the end

    Thanks for the help and thanks for the added features. This is excatly what I needed for my project as well (would be great addition to see to the next release of spry IMHO

    Z
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 9, 2007 12:47 PM   in reply to eboyjr
    Hum. One last question, in regards to cross-brower functionality. The extended tab works great with Firefox, but seems to have problems with IE6 and IE7. In that when you go to add a tab I can only get the IE browser to work when I set the tab index to 1. Leaving off the tab index (or specificy the next one) I get an error on IE.

    Regards

    Z
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 9, 2007 1:43 PM   in reply to ZeusChicago
    Hi,

    I have modified the addTab function to work with both IE & firefox. Please replace addTab function with the following code.

    Spry.Widget.ExtendedTabbedPanels.prototype.addTab = function (tabname, tabcontent, position) {
    var tabs = this.getTabs();

    if((!position && position != 0)|| position > tabs.length)
    position = tabs.length;

    var newtab = tabs[tabs.length - 1].cloneNode(true);
    this.setElementNodeValue(newtab, tabname);

    if(position == tabs.length)
    this.getTabGroup().appendChild(newtab);
    else
    this.getTabGroup().insertBefore(newtab, tabs[position]);

    var tabContents = this.getContentPanels();
    var newContentPanel = tabContents[tabContents.length - 1].cloneNode(false);
    newContentPanel.innerHTML = tabcontent;

    if(position == tabs.length)
    this.getContentPanelGroup().appendChild(newContentPanel);
    else
    this.getContentPanelGroup().insertBefore(newContentPanel, tabContents[position]);

    this.addPanelEventListeners(newtab, newContentPanel);

    this.showPanel(position);
    }
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 9, 2007 2:52 PM   in reply to eboyjr
    Thanks so much for the help (and the modification for IE). I dont supposed you have an paypal account or a website with a donation button do you?

    Would feel much better if i was able to send you a "thank you" donation. Take yourself out for dinner or something!

    Z
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 9, 2007 9:50 PM   in reply to ZeusChicago
    Hi,

    Those who are using my Spry.Widget.ExtendedTabbedPanels widget, and wants to add a new tab from a URL can add the following code snippet to the existing ExtendedTabbedPanels.js and call addTabFromURL() instead of just addTab().

    Spry.Widget.ExtendedTabbedPanels.tabIDPrefix = "tabdivID_";
    Spry.Widget.ExtendedTabbedPanels.tabIDCounter = 0;
    Spry.Widget.ExtendedTabbedPanels.getNewTabID = function(){
    return Spry.Widget.ExtendedTabbedPanels.tabIDPrefix + Spry.Widget.ExtendedTabbedPanels.tabIDCounter++ ;
    };

    Spry.Widget.ExtendedTabbedPanels.prototype.addTabFromURL = function (tabname, tabURL, position) {
    var contentDivID = Spry.Widget.ExtendedTabbedPanels.getNewTabID();
    var tabContent = "<div id='" + contentDivID + "' class='TabbedPanelsContent'></div>";

    this.addTab(tabname, tabContent, position);
    Spry.Utils.updateContent(contentDivID, tabURL);
    };

    Let me know if it helps you.

    -JV
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 12, 2007 6:02 AM   in reply to eboyjr
    Jvenu,

    I am goig to test IE6 when I get into the office today (I have been working from home all week l ong). But the changed made to support IE (at least in IE7) is still not working 100%.

    I can click on a new tab (and it gets created), but when I try to select the newly created tab, All Tabs (but tab 0) are highlighted when I "hover" over any of them. And when I click on any of the "Added" tabs, tab 1 is always the tab that gets pulled up.

    Not sure if this matters, but by defualt (i.e. without using your addTab function) I build 2 tabs (tab 0 and tab 1) when the page first loads. I then use your addTab to dynamicly add tabs via the UI.

    Z
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 12, 2007 6:12 AM   in reply to eboyjr
    Hum. For giggles I went back to the first addTab in your first post @ the top and switched back to adding tab 0 always and the same Hover/Click tab above I described happens in the last version to (I just never noticed it).

    Thankfully I can just have everyone at work use Firefox for now because its works great with that (of course..lol) ~shakes fist at Bill Gates ~

    Z

     
    |
    Mark as:
  • Currently Being Moderated
    Dec 30, 2007 1:15 PM   in reply to eboyjr
    *bump* Thinks this would still be a great feature for the next release :-)
     
    |
    Mark as:
  • Currently Being Moderated
    Dec 31, 2007 4:43 AM   in reply to ZeusChicago
    quote:

    Originally posted by: ZeusChicago
    *bump* Thinks this would still be a great feature for the next release :-)

    There is a special topic, where u can post your feature requests

    http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=7 2&catid=602&threadid=1296091&highlight_key=y&keyword1=feature
     
    |
    Mark as:
  • Currently Being Moderated
    Apr 2, 2008 2:43 PM   in reply to eboyjr
    Sorry, im confused. What exactly is the overall outcome of the file and is that file to go along with the Spry one is should it replace the spry one?
    Then how do you call the add and remove?
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 16, 2008 6:30 PM   in reply to eboyjr
    Hello,

    I have 2 simple questions about spry tabbed panels. First, I added this.showPanel(tab); to the mouseover location of the javascript to make the panels open on hover. But, how do I get the panels to go back to the default panel when they mouseout?

    Secondly, I want to make the default panel different depending on what page they are on. I added id tags to the body of every page. I need javascript that will say if they are on a page with the id of "shop" the default tab will be the tab with the id tag of "1" and so on. Any help is greatly appreciated.
     
    |
    Mark as:
  • Currently Being Moderated
    Aug 5, 2011 5:40 AM   in reply to eboyjr

    Hello,

    I am using this class and having problems with IE8. The tabs are created just fine but when I go to select one other than the one currently selected I get an error in IE8.

    I create the tabs by selecting an item off of the horizontal menu above the tab control.

    Tabs add great and work in FF,Opera,Safari and Google Chrome but I get this error when I am selecting tabs after they have been loaded.

    They do not display in IE8

     

    I upgraded to spry 1.6 but it didn't make any difference

     

     

     

    Webpage error details

     

    User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.3; OfficeLivePatch.0.0; .NET CLR 1.1.4322; Tablet PC 2.0; .NET4.0C; WinNT-A8I 21.12.2010)

    Timestamp: Thu, 4 Aug 2011 16:43:27 UTC

     

     

    Message: 'style' is null or not an object

    Line: 392

    Char: 2

    Code: 0

    URI: http://www.tgftibdrivingschool.com/testing/SpryAssets/SpryTabbedPanels .js

    Message: 'style' is null or not an object
    Line: 392
    Char: 2
    Code: 0

     

     

    To see an example go here:

    http://www.tgftibdrivingschool.com/testing/

     
    |
    Mark as:
  • Currently Being Moderated
    Aug 9, 2011 1:37 PM   in reply to jvenu

    Hey jvenu!

    The addTabFromURL() function works well, but I am having trouble with static data inside the first tab being erased after a new tab is added. Is there a way to make the first tab actually persistent?

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points