Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I love Christophe Humbert's Easy Tabs for SharePoint. I'm using jQuery on my page layouts and want to add his great code to the $(document).ready() function. However, it keeps blowing up with this error:

Error: p.innerHTML is undefined

And this is on the line with this JS:

do {p=p.parentNode;sT=p.innerHTML.split("MSOZoneCell_WebPart");}while (sT.length<4 && p.parentNode.id!="MSO_ContentTable")

Here's my code:

$(document).ready(function () {
if ($('#enableEasyTabs').length){
     $(enableEasyTabs);
}
});

/* Easy Tabs v 5.0 * Copyright (c) 2009-2010 Christophe Humbert * http://www.pathtosharepoint.com */
function enableEasyTabs(){
var AP="",sec=0,Header="none",Split="No",Expand="Expand All",Print="Print Preview";
if (document.forms[0].elements["_wikiPageMode.value"]=="true"||document.forms[0].elements["MSOLayout_InDesignMode"].value=="1"){return;}
var el=document.getElementsByTagName("SCRIPT"),p=el[el.length-1],sT,a,sep,tabRow;
do {p=p.parentNode;sT=p.innerHTML.split("MSOZoneCell_WebPart");}while (sT.length<4 && p.parentNode.id!="MSO_ContentTable")
if (p.getAttribute("contenteditable")=="true"){return;}
if (p.nodeName=="DIV"){sep=document.createElement("div");p.insertBefore(sep,p.firstChild);tabRow=document.createElement("div");p.insertBefore(tabRow,p.firstChild);}
else{sep=document.createElement("td");var sepTR=document.createElement("tr");sepTR.appendChild(sep);tabRow=document.createElement("td");var tabTR=document.createElement("tr");tabTR.appendChild(tabRow);if (p.nodeName=="TBODY"){p.insertBefore(sepTR,p.firstChild);p.insertBefore(tabTR,p.firstChild);}else if (p.nodeName=="TR"){p.parentNode.insertBefore(tabTR,p);p.parentNode.insertBefore(sepTR,p);}else {return;}}
sep.className="et-separator";tabRow.className="et-tabrow";var children=p.childNodes;p=p.parentNode;var etRoot=[],etHeader=[],etTab=[],tabsID=[];
for (var j=0;j<children.length;j++){try{var d=children[j].getElementsByTagName("td");for (i=0;i<d.length;i++) {if(d[i].id.indexOf("WebPartTitle")==0){var WPid=d[i].id.replace(/WebPartTitle/,"");if (d[i].innerHTML.indexOf("(Hidden)")==-1) {var up=d[i];while (up!=children[j]){if (up.parentNode.innerHTML.indexOf('id=WebPart'+WPid+' ')>=0||up.parentNode.innerHTML.indexOf('id="WebPart'+WPid+'" ')>=0){WPid="et"+WPid;etHeader[WPid]=up;etRoot[WPid]=children[j];etTab[WPid]=d[i].getElementsByTagName("span")[0].cloneNode(true);etTab[WPid].id=WPid;etTab[WPid].className="et-tab et-inactivetab";etTab[WPid].onclick=function(){activateTab(this);};tabRow.appendChild(etTab[WPid]);tabsID.push(WPid);break;}up=up.parentNode;}}}}}catch(e){}}
var Tabs=tabRow.getElementsByTagName("span"),TabCount=Tabs.length;
if (Split=="Yes") {var sd=document.createElement("div"),index=Math.floor(TabCount*0.5);tabRow.insertBefore(sd,Tabs[index]);}
if(AP.length && sec>0) {sec=sec*1000;interval="";a=document.createElement("span");a.innerHTML="|>";a.className="et-tab et-inactivetab";a.onclick=function(){if(interval==""){this.innerHTML="||";interval=window.setInterval(function(){Autoplay();},sec)}else{this.innerHTML="|>";window.clearInterval(interval);interval=""}};tabRow.appendChild(a);var Autoplay=function(){for(i=0;i<TabCount;i++)if(Tabs[i].className=="et-tab et-activetab"){var j=(i+1)%TabCount;activateTab(Tabs[j]);break}};if (AP=="Play"){a.innerHTML="||";interval=window.setInterval(function(){Autoplay();},sec)};}
if (Expand.length) {a=document.createElement("span");a.innerHTML=Expand;a.className="et-tab et-inactivetab";a.onclick=function(){for(i=0;i<tabsID.length;i++){etTab[tabsID[i]].className="et-tab et-inactivetab";etRoot[tabsID[i]].className=etRoot[tabsID[i]].className.replace(/et-offscreen/g,"");etRoot[tabsID[i]].style.pageBreakAfter="always";etHeader[tabsID[i]].style.display="";}};tabRow.appendChild(a);}
if (Print.length) {a=document.createElement("span");a.innerHTML=Print;a.className="et-tab et-inactivetab";a.onclick=function(){this.style.display="none";var f=document.getElementById("s4-workspace")||document.getElementsByTagName("body")[0],ed=p.parentNode.insertBefore(document.createElement(p.nodeName),p);f.appendChild(p);for (j=0;j<f.childNodes.length-1;j++) {try{f.childNodes[j].className+=" et-offscreen";}catch(e){}}a=document.createElement("span");a.innerHTML="Back to Page";a.className="et-tab et-inactivetab";a.onclick=function(){this.previousSibling.style.display="inline-block";this.parentNode.removeChild(this);ed.parentNode.insertBefore(p,ed);ed.parentNode.removeChild(ed);for (j=0;j<f.childNodes.length;j++) {try{f.childNodes[j].className=f.childNodes[j].className.replace(/\s*et-offscreen/g,"");}catch(e){}}};tabRow.appendChild(a);};tabRow.appendChild(a);}
function activateTab(t){document.cookie=tabsID.join("_")+"="+t.id+";path=/";for(i=0;i<tabsID.length;i++){etHeader[tabsID[i]].style.display=Header;if(t.id==tabsID[i]){etTab[tabsID[i]].className="et-tab et-activetab";etRoot[tabsID[i]].className=etRoot[tabsID[i]].className.replace(/\s*et-offscreen/g,"");}else{etTab[tabsID[i]].className="et-tab et-inactivetab";etRoot[tabsID[i]].className+=" et-offscreen";}}}var m=GetCookie(tabsID.join("_"))?GetCookie(tabsID.join("_")):tabsID[0];activateTab(etTab[m]);} 
share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

what is the purpose of wrapping the Easy Tabs in jQuery?

You can always combine the Easy Tabs with jQuery - they are both written in the same language, JavaScript.

However, the specific issue here is that you want the Easy Tabs to run after the document is ready, and this is not the correct timing. The way it is written, the script needs to run in the flow of the page, in the context of the Web Part zone where the tabs will be created.

If you wan to run it after the page is ready, you'll need to add a couple steps to find the Web Part zone.

share|improve this answer
    
Thanks, Christophe, for your reply. The reason is this: I have a page layout that will allow users to toggle tabs on/off. Based on the variable, I want to either enable tabs or disable them. I found a way to do this within the flow of the page: I detect if the user wants to enable tabs; if so, I include the script. –  Alex C Sep 7 '11 at 5:20
    
Another question: Is it possible to have the tabs inserted in a specific location? I need it inserted after an H1 tag with ID "page-title". I'm trying to use jQuery to move the tabs but not quite working: All the click events seem to get lost. Thanks. –  Alex C Sep 7 '11 at 5:22
1  
In addition to or instead of moving the tabs, try to move the tabs container. As for toggling the tabs, you could enable them but keep them hidden (again via the container) and inactive, until they are toggled on. –  Christophe Sep 7 '11 at 5:35
    
Would the container be the DIVs with the class et-tabrow and et-separator? I've got a span tag that I try to insert into using $('#enableEasyTabs').html($(".et-tabrow").html()); $('.et-tabrow').remove(); –  Alex C Sep 7 '11 at 5:39
1  
Yes, et-tabrow is the container. How about $('.et-tabrow').appendTo('#enableEasyTabs') –  Christophe Sep 7 '11 at 5:55
show 5 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.