Tabs for SharePoint forms v2.0

26.11.2011 I have updated the script to v2.4 to attempt to fix some problems withe overlapping tabs in IE7. I have moved the files to another server. Follow the link under the “How to use this solution” section below. I have added one new “attibute” under the settings section in the CEWP code: “baseTabColor”. See below for details.


24.03.2011 Updated the script to fix an issue with the attachments. They now appear at the bottom of every tab – like in a unmodified form. If there are no attachments, the field is hidden.

In the CEWP-code the example-tab containing the attachments has been removed.


19.03.2011 v2.1 adds the ability to call a function after the tab has expanded. You can specify a shared function that will be called on every tab, and/or a function that is called on one specific tab.


This solution has previously been published over at NothingButSharePoint


This solution is used to “tab” SharePoint forms. If you have a long form, you can group fields together and present them in tabs for a better overview.
IMG

Features

  • Full SP2007 and SP2010 support for both lists and document libraries
  • Works for all standard field types (Custom field types are not guaranteed to work)
  • A field can be used in multiple tabs
  • You can have a tab displaying all fields
  • You can have a tab catching all orphans (fields that are not displayed in any other tab). Useful if one adds columns to a list without updating the script call.
  • Highlights tab if a field fails validation upon save
  • Use a URL query string parameter to expand a specific tab

Browser compatibility tested in:

  • IE6 (Works in SP2007 only due to SP2010 incompatibility with IE6)
  • IE7
  • IE8
  • Firefox 3.6.13
  • Google Chrome 8.0.552.237
  • Safari 5.0.2

How to use this solution

Download the code for the file “TabsForSharePointForms.js” from this location

Upload the file to your script repository. This can be a shared document library in the site where you will be using the solution (ensure ALL users have read access).

For each of the forms (NewForm.aspx, DispForm.aspx and EditForm.aspx) add a Content Editor Web Part (CEWP) below the form.

For SharePoint 2007

To put the page in edit mode, modify the URL like this:
/Lists/Tabs/NewForm.aspx?toolpaneview=2
/Lists/Tabs/DispForm.aspx?ID=1&toolpaneview=2
/Lists/Tabs/EditForm.aspx?ID=1&toolpaneview=2

For SharePoint 2010

IMG

Add this code block to the CEWP:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/Tabs/TabsForSharePointForms.js"></script>
<script type="text/javascript">

var tabConstructor = {tabs:[{name:'First Tab',fields:['InMultipleTabs','Column1','Column2'],mouseOver:'This is the first tab',tabStyle:'',clickFunction:''},
							{name:'Second Tab',fields:['InMultipleTabs','Column3','Column4','Lookup1','MyMultiLookup'],mouseOver:'This is the second tab',tabStyle:'',clickFunction:'secondTabClick(this)'},
							{name:'Third Tab',fields:['InMultipleTabs','Title'],mouseOver:'This is the third tab',tabStyle:'',clickFunction:''},
							{name:'Forth Tab',fields:['Column5','Column6','MyPeoplePicker'],mouseOver:'This is the forth tab',tabStyle:'',clickFunction:''}],
					  settings:{viewAllFields:{show:true,name:'All fields',mouseOver:'This tab shows all fields',tabStyle:'',clickFunction:''},
					  orphanFields:{show:true,name:'...',mouseOver:'All orphan fields',tabStyle:'',clickFunction:''},
					  breakTabRowAt:null,
					  baseTabColor:'#F5F5F5',
					  hoverTabColor:'#FFF68F',
					  selectedTabColor:'#B9D3EE',
					  formBgColor:'#C6E2FF'},
					  clickFunctionShared:'clickFunctionShared(this)'};

function clickFunctionShared(elm){
	var tab = $(elm);
	// This code is run on click on any tab
}

function secondTabClick(elm){
	var tab = $(elm);
	var arrOfFields = tab.attr('fields').split(',');
	alert("The fields included in the second tab is these:n"+arrOfFields);
}

init_buildTabbedForm(tabConstructor);
</script>

This is explained in detail below.
You must change the “src” to “TabsForSharePointForms.js” to match your local file. If you like to use a local instance of jQuery, change that as well.

You must also change this example to match your columns FieldInternalName.

The call to the function “init_buildTabbedForm” takes two parameters:
tabConstructor: The object constructed in “var tabConstructor”.
selectedTab: Integer that specifies which tab to preselect.

Variable “tabConstructor” explained:

IMG

New in v2.4:

baseTabColor: Set the default background color for the tabs. See CEWP code for example.

Attachments

I have changed the attachment handling in v2.2. Now attachments are left untouched and they will display at the bottom of all tabs. If there are no attachments, the field is hidden.

How to find the FieldInternalName

Go to your list. Open one existing list element in DispForm.aspx. Right click and select “View source”. Search for “FieldInternalName”. All fields should be found in this format:
IMG

Link directly to a tab:

Specify the tab to preselect in the URL like this:
http://*************/Lists/Tabs/NewForm.aspx?sTab=3

Note:

This is true only for unmodified forms. If you have modified the form in SharePoint designer, you will have to look at the function “init_fields_v2()” in the code to adapt it to your custom form. You will find a bit more information here.

Overriding native SharePoint functions

To overcome some issues with rich text fields I had to override one function: RTE_OnFocus.
I have added one line to the bottom of the function:
g_elemRTELastTextAreaConverted=document.getElementById(strBaseElementID);

To catch “empty field validation” on date and time columns “pre save”, I had to override the function “PreSaveItem”. I have added one line to the top of the function:
preSaveHighlightTabOnValidation();

This will not interfere with the use of the function “PreSaveAction” often used to “do stuff” before save.

Finale notes

The solution is licensed under the MIT X11 license. You find the license agreement by clicking the little (c) to the right of the tabs.

I have set the initial release to v2.0 as I have previously posted a similar solution.

Ask if anything is unclear
Alexander

115 thoughts on “Tabs for SharePoint forms v2.0”

  1. I am experiencing a small bug. I have 10 tabs. with about 100 fields. If I set breakTabRowAt:null it works fine, but the layout seems to go of the right side of the page. you have to scroll to see all the tabs. the active tabs or active tab row is at the top.

    when I set breakTabRowAt:4, the active tab row is on the bottom. all tabs in the first row work perfectly. when I get the the second row I lose the first row tabs. when I click a second item of the second row, all tabs vanish. There are no other scripts in use at this time and I am on MOSS.

    Any ideas?

    1. Hi,
      When you click on a tab in the top row, the rows switch place and the row with the active tab will always be at the bottom.

      Does your tab rows switch place?

      Which browser are you using?

      I tried to add more tabs and break them like you describe, but everything works as expected here.

      If possible, send me some screenshots.

      Alexander

    2. For the life of me I have not been able to figure this out. I have been able to identify the differences between the 2 sites. For the working site I have over 250 fields and 15 tabs. Works perfectly, no issues. This site is internal to my company. The non working site hace about 150 fields and 10 tabs. Something with the second row on click has the issue, this site is accessed differently. Almost like I have to go through a vpn or firewall. It is still internal to my company, but because of a company merger, this site is actually part of the other companies internal websites and requires different credentials to access. Is it possible this may have an impact on the functionality? If not I dont see a way of making it work. I do not want to take anything from this script. As I said first It is producing perfectly on another site.

    3. I need your help now. I have set the breakrow to Null, but there are still 15 tabs. They wrap and when they wrap they over lap to the point you can barely read the top row. I have changed height and margins all over but I can not get the alignment ti change. can you think, off the top of your head, what needs to be changed so the tabs rows will not over lap when breakrow is set to null?

      thanks

  2. Hi there, in the new version I lost the ability to sort the fields using the array. It seems like the column order in the List Settings is overriding the script. Has anyone else noticed that?

    On my DispForm I have this script, Alexander’s vLookup script and Christophe’s html calculate column. I also used Alexander’s Edit SP Field Properties utility to make some fields hidden.

    1. Hi,
      Yes, the order of the fields are given from the list settings. The reason for not rearrange them has to do with the rich text fields being corrupted if you do.

      It is possible to rearrange the fields, but only the ones not being rich text. If this is “in demand”, i will publish an updated version.

      Alexander

  3. Hi Alexander,

    I just did a quick test with v2.1, it worked fine on Firefox but not on IE 7. I’ll double check my settings, but I wanted to let you know, just in case…

    Christophe

    1. Hi Christophe,
      Could you please send me some screenshots of the error? – i have tested it in IE7.0.5730.13 with no errors, but i know Larry did have some issues with a list with a large number of fields.

      His errors are described in his post above.

      Alexander

    1. Update: it worked when I added the attachments field. I had removed it initially because I was working on a list where attachments were disabled.
      Apparently Firefox doesn’t care if you omit some fields (which is good, as you may want to keep some fields always hidden).

      That’s an impressive piece of code you’ve written here, especially with all the tweaks to accomodate the native SharePoint functions.

    2. Thanks Alexander. I would have one more request: the copyright sign is cute (I actually didn’t know what it was the first time I clicked on it), but maybe not something to show to the average site contributor. Would it be possible to have it removed, or placed somewhere else than on the tabs row?

    3. Hi,
      I have updated the script to address the attachment issue. They now appear at the bottom of every tab – like in a unmodified form. If there are no attachments, the field is hidden.

      I have also moved the “About” link below the form.

      If you find anything else, please let me know.

      Regards
      Alexander

  4. » Highlights tab if a field fails validation upon save

    Hi, this function doesn’t work for me. My form just freezes up and I have to close the browser. Is anyone else having this issue?

    I am using MOSS 2007 and all my users are on IE7 or IE8.

    1. Hi,
      Sounds strange – what kind of field is not filled when this happens? Do you have this issue with other lists using the tabs script?

      Alexander

    2. Thanks for the reply! Its a multiple lines of text field with rich text. I just tried testing it with a single line of text field and got the same result.

    3. Could it be some other code interfering?

      I did a quick test here and it works as expected:
      When clicking “OK”, the form does “postback” and the page refreshes with a red marking on the first tab containing the field that did not pass the “empty field validation”.

      Alexander

    1. Hi, Have you put the CEWP below the form webpart?

      If you still have trouble you can send me some screenshots of the page in edit mode, and the contents of the CEWP.

      Alexander

  5. Hi Chris,

    Great job!!!
    I would like to add the jquery function to enlarge a lookup column in your tab.

    $().SPServices.SPSetMultiSelectSizes({
    multiSelectColumn: “”,
    minWidth: 0,
    maxWidth: 0
    });
    I try to put this code in your clickFunction but it takes a long time to execute. (I have to wait for 5 seconds).

    Can you please help me to implement this functionality in your tabs?

    Thanks again.

    Regards

  6. I need to validate fields on each tab separately. No problem there. However, the “input field names” are encoded and not the actual field names. Is there a way to validate fields using JavaScript?

  7. Hi Alexander,

    Is it possible for you to update the code to modify the non-selected tabs (color, font color, font size), and the selected tabs Font, font size and font color)

  8. Thanks for sharing tabs for form.

    I have 8 tabs,
    some have 12-15 fields,
    one have 40 fields and couple of them have 4 fields.

    Problem here is variable size of dialog.
    For 12-15 fields tab it looks fine, for 40 it expands, for 4 fields tab it shrinks too much.

    Can we make pop-up dialog fixed size ?
    Thanks

  9. When I change a display name on a calculated field, the tab display does not update with new name (1 addlt word). Still showing previous display name. Any suggestions?

    1. Hi,
      I cannot see any reason for this behavior, sorry. Try disabling the script to verify that the field name is correct outside the “tabs”.

      Alexander

    1. Hi,
      This solution does not use jQuery UI, but you could look at the CSS embedded in the function “init_buildTabbedForm” in the file “TabsForSharePointForms.js”.

      Alexander

  10. Working with your code and I have run into a cosmetic problem. I have all the tabs displaying and breaking correctly, but the second row overlaps the first row. Where do I change the code so that I see all of the tabs without any overlap?

    I also noticed that when I add the following code, the tabs repeat beneathe themselves… just an interesting feature:

    //$(“table.ms-formtable”).css({‘top’:’75px’})
    // .before(tBuffer.join(”))
    // .after(aBuffer.join(”));

  11. Hi, I just realized that the field descriptions are not displayed on my NewForm and EditForm. I was planning to use that to insert instructional content. Did I miss a setting or is that expected behavior?

    1. I am using a plain old SP2007 List with uncustomized forms. The NewForm and EditForm pages have your Tabs and People Picker webparts on the page, and the DispForm has Christophe’s Text to HTML. I do have rich text fields on several tabs. My company uses a custom theme.

      I can’t think of anything else that would be relevant… but please let me know if you need more information or a screen shot. Thanks!

  12. Alex,

    I have implemented a redirect CEWP on the New and Edit forms in addition to your code. I have noticed that when I click through the tabs, the redirect code becomes inoperable. Is there a postback issue that is causing this? How can I fix this?

    1. I have answered your email request, but will add the answer here as well – for others with the same problem.

      ***********************
      This most likely have to do with the function “PreSaveItem” in the Tabs solution, and the “PreSaveAction” in the redirect solution. Try moving the line “preSaveHighlightTabOnValidation();” from the “PreSaveItem” function to the “PreSaveAction”. Then comment out or remove the function ” PreSaveItem”.

      This will be a problem when combining multiple solutions – especially when the function “PreSaveAction” is used.

      Let me know if this helps.

      1. Actually, I kind of figured it out and hodgepodged the scripts together… They could do with some refinement probably, but they meet my needs. I combined the Form Tabs, Hiding Fields, and Redirect javascripts, See below:

        var tabConstructor = {tabs:[{name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ,
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:”},
        {name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ],
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:”},
        {name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ],
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:’secondTabClick(this)’},
        {name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ],
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:”},
        {name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ],
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:”},
        {name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ],
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:”},
        {name:'[YOUR TAB NAME HERE]’,fields:[‘InMultipleTabs’,
        [YOUR FIELDS HERE]
        ],
        mouseOver:'[YOUR TAB NAME HERE]’,tabStyle:”,clickFunction:”}],
        settings:{viewAllFields:{show:false,name:’All fields’,mouseOver:’This tab shows all fields’,tabStyle:”,clickFunction:”},
        orphanFields:{show:false,name:’…’,mouseOver:’All orphan fields’,tabStyle:”,clickFunction:”},
        breakTabRowAt:’Null’,
        hoverTabColor:’#FFF68F’,
        selectedTabColor:’#B9D3EE’,
        formBgColor:’#C6E2FF’},
        clickFunctionShared:’clickFunctionShared(this)’};

        init_buildTabbedForm(tabConstructor);

        var scriptVersion = ‘2.0 (17.01.2011)’;

        //###########################################################################################
        // FORM TABS CODE
        //###########################################################################################
        //———————————————————————————-

        /* Tabs for SharePoint Forms
        * ———————————————
        * Created by Alexander Bautz
        * Modified by Jayson Fisher
        * alexander.bautz@gmail.com
        * https://spjsblog.com
        * Copyright (c) 2010 Alexander Bautz (Licensed under the MIT X11 License)
        * ———————————————
        * Include reference to:
        * jquery – http://jquery.com
        * ———————————————
        */

        function clickFunctionShared(elm){
        var tab = $(elm);
        // This code is run on click on any tab

        //##################### Hide Fields ##########################
        ChangeTabs_Click();
        }

        function secondTabClick(elm){
        var tab = $(elm);
        var arrOfFields = tab.attr(‘fields’).split(‘,’);
        alert(“The fields included in the second tab is these:n”+arrOfFields);
        }

        function dynResizeDialog(){
        var pWh,wpd,dlgBorder,dlgTitle,dlgTH,dlgFrame,dlgContent,formH,cField,top;
        //pWh = $(window.parent.document).height()-172;
        pWh = $(window.parent.document).height();
        wpd = $(window.parent.document);
        dlgBorder = wpd.find(“div.ms-dlgBorder”);
        dlgTitle = wpd.find(“div.ms-dlgTitle”);
        dlgTH = dlgTitle.height();
        dlgFrame = wpd.find(“iframe[id^=’DlgFrame’]”);
        dlgContent = dlgFrame.parent().parent().parent();
        if(dlgContent.attr(‘DragBehavior’)!==null&&dlgContent.css(‘left’)!==’20px’){
        formH = 265+dlgTH;
        formH+=$(“#tabOuterWrap”).height();
        if($(“#aboutTabsSolution”).css(‘display’)!==’none’){
        formH+=$(“#aboutTabsSolution”).height();
        }
        $.each(fields,function(fin){
        cField = $(fields[fin]);
        if(cField.css(‘display’)!==’none’){
        formH += cField.height();
        }
        });
        if(formH>pWh){
        formH = pWh;
        }
        if(pWh!==formH){
        top = (pWh-formH)/2;
        if(top700){
        dlgTitle.css({width:(dlgTitleWidth)+’px’});
        dlgContent.css({width:(dlgTitleWidth)+’px’});
        dlgBorder.css({width:(dlgTitleWidth)+’px’});
        dlgFrame.css({width:(dlgTitleWidth)+’px’});
        }
        if(parseInt(dlgTitle.css(‘width’),10)0){
        ct = $(“#tab_”+fieldTR.attr(‘tabid’));
        if(!ct.hasClass(‘tabFormValidation’)){
        ct.addClass(‘tabFormValidation’);
        }
        }
        // UserField validation error
        if(fieldTR.attr(‘FieldType’).match(‘SPFieldUser’)!==null){
        if(fieldTR.html().match(“IsResolved=”False””)!==null||fieldTR.find(‘td.ms-error’).length>0){
        ct = $(“#tab_”+fieldTR.attr(‘tabid’));
        if(!ct.hasClass(‘tabFormValidation’)){
        ct.addClass(‘tabFormValidation’);
        }
        }
        }
        }
        });
        }
        }
        if(!onload && _isV4Dlg){
        //ChangeTabs_Click();
        dynResizeDialog();
        }

        //##################### Hide Fields ##########################
        ChangeTabs_Click();

        }

        //###########################################################################################
        function buildTabbedForm(argObj,selectedTab){
        var cFields,tBuffer,tabRow,orphans,cTab,wrapTabs,aBuffer,cBuffer;

        if(typeof(selectedTab)===’undefined’||selectedTab===”||selectedTab===’0′){
        selectedTab=1;
        }
        cFields = [];
        tBuffer = [];
        tabRow = 0;
        tBuffer.push(“”);
        tBuffer.push(“”);
        wrapTabs = (argObj.settings.breakTabRowAt!==”&&argObj.settings.breakTabRowAt!==0&&argObj.settings.breakTabRowAt!==null)?true:false;
        if(wrapTabs){
        tBuffer.push(“”);
        tabRow = 1;
        }
        $.each(argObj.tabs,function(i,obj){
        $.each(obj.fields,function(idx,fin){
        cFields.push(fin);
        if($(fields[fin]).attr(‘tabid’)===undefined){
        $(fields[fin]).attr(‘tabid’,(i+1));
        }
        });
        tBuffer.push(“”);
        tBuffer.push(“”+obj.name+””);
        tBuffer.push(“”);

        if(wrapTabs&&argObj.settings.breakTabRowAt===(i+1)){
        tBuffer.push(“”);
        tabRow = 2;
        }

        });

        if(argObj.settings.viewAllFields.show){
        tBuffer.push(“”);
        tBuffer.push(“”+argObj.settings.viewAllFields.name+””);
        tBuffer.push(“”);
        }
        if(argObj.settings.orphanFields.show){
        orphans = [];
        $.each(fields,function(fin){
        if($.inArray(fin,cFields)===-1){
        $(fields[fin]).attr(‘tabid’,’allFields’);
        orphans.push(fin);
        }
        });
        if(orphans.length>0){
        tBuffer.push(“”);
        tBuffer.push(“”+argObj.settings.orphanFields.name+””);
        tBuffer.push(“”);
        }
        }

        // About
        tBuffer.push(“”);
        tBuffer.push(“(c)”);
        tBuffer.push(“”);
        if(wrapTabs){
        tBuffer.push(“”);
        }
        tBuffer.push(“”);
        tBuffer.push(“”);

        // About
        cBuffer = [];
        cBuffer.push(“”);
        cBuffer.push(“Copyright (c) 2011 Alexander Bautz”);
        cBuffer.push(“”);
        cBuffer.push(“Permission is hereby granted, free of charge, to any person obtaining a copy”);
        cBuffer.push(“of this software and associated documentation files (the “Software”), to deal”);
        cBuffer.push(“in the Software without restriction, including without limitation the rights”);
        cBuffer.push(“to use, copy, modify, merge, publish, distribute, sublicense, and/or sell”);
        cBuffer.push(“copies of the Software, and to permit persons to whom the Software is”);
        cBuffer.push(“furnished to do so, subject to the following conditions:”);
        cBuffer.push(“”);
        cBuffer.push(“The above copyright notice and this permission notice shall be included in”);
        cBuffer.push(“all copies or substantial portions of the Software.”);
        cBuffer.push(“”);
        cBuffer.push(“THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR”);
        cBuffer.push(“IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,”);
        cBuffer.push(“FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE”);
        cBuffer.push(“AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER”);
        cBuffer.push(“LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,”);
        cBuffer.push(“OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN”);
        cBuffer.push(“THE SOFTWARE.”);
        aBuffer = [];
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“Tabs for SharePoint forms”);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“by Alexander Bautz“);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“v”+scriptVersion+””);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“SharePoint JavaScripts“);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“”+cBuffer.join(”)+””);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“”);
        aBuffer.push(“”);

        // Insert tabs before the formtable
        $(“table.ms-formtable”).css({‘border-top’:’1px blue solid’})
        .before(tBuffer.join(”))
        .after(aBuffer.join(”));
        //$(“table.ms-formtable”).css({‘top’:’75px’})
        // .before(tBuffer.join(”))
        // .after(aBuffer.join(”));

        // Select tab
        cTab = GetUrlKeyValue(‘sTab’);
        if(cTab!==null&&cTab!==”&&$(“#tab_”+cTab).length!==0){
        selectedTab = cTab;
        }
        // Select tab
        selectTab($(“#tab_”+selectedTab),true);

        }

        //###########################################################################################
        function init_buildTabbedForm(argObj,selectedTab){

        var styleBuffer = [];
        styleBuffer.push(“”);
        styleBuffer.push(“span.tabMasterStyle{“);
        styleBuffer.push(“border:1px silver solid;”);
        styleBuffer.push(“font-size:x-small;”);
        styleBuffer.push(“padding:5px;”);
        styleBuffer.push(“background-color:#ffffff;”);
        styleBuffer.push(“}”);
        styleBuffer.push(“span.tabHover{“);
        styleBuffer.push(“background-color:”+argObj.settings.hoverTabColor+”;”);
        styleBuffer.push(“cursor:pointer;”);
        styleBuffer.push(“}”);
        styleBuffer.push(“span.tabSelected{“);
        styleBuffer.push(“background-color:”+argObj.settings.selectedTabColor+”;”);
        styleBuffer.push(“border-color:gray;”);
        styleBuffer.push(“border-bottom:1px transparent solid;”);
        styleBuffer.push(“padding:7px 5px 8px 5px;”);
        styleBuffer.push(“}”);
        styleBuffer.push(“span.tabFormValidation{“);
        styleBuffer.push(“color:red;”);
        styleBuffer.push(“border-color:red;”);
        styleBuffer.push(“}”);
        styleBuffer.push(“div.tabWrappedTop{“);
        styleBuffer.push(“padding-bottom:12px;”);
        styleBuffer.push(“}”);
        styleBuffer.push(“div.tabWrappedBottom{“);
        styleBuffer.push(“”);
        styleBuffer.push(“}”);
        styleBuffer.push(“”);
        document.write(styleBuffer.join(”));

        if(typeof(fields)===’undefined’){
        fields=init_fields_v2();
        }
        if($(“#idAttachmentsRow”).length>0){
        fields.attachments=$(“#idAttachmentsRow”).attr(‘FieldType’,’attachments’);
        }
        if(GetUrlKeyValue(‘IsDlg’)===’1′){
        _isV4Dlg = true;
        $(document).ready(function(){
        buildTabbedForm(argObj,selectedTab);
        });
        }else{
        _isV4Dlg = false;
        buildTabbedForm(argObj,selectedTab);
        }

        }

        //###########################################################################################
        // Catch validation on empty DateAndTime-fields
        function preSaveHighlightTabOnValidation(){
        var fieldTR,ct;
        $.each(fields,function(fin){
        fieldTR = $(fields[fin]);
        if(fieldTR.attr(‘FieldType’)===’SPFieldDateTime’){
        if(fieldTR.find(“td.ms-formbody span[controltovalidate][display!=’none’]”).length>0&&fieldTR.find(‘input:first’).val()===”){
        ct = $(“#tab_”+fieldTR.attr(‘tabid’));
        if(!ct.hasClass(‘tabFormValidation’)){
        ct.addClass(‘tabFormValidation’);
        }
        }
        }
        });
        }

        //###########################################################################################
        function init_fields_v2(){
        var res,myMatch,disp,fin,type;
        res = {};
        $(“td.ms-formbody”).each(function(){
        myMatch = $(this).html().match(/FieldName=”(.+)”s+FieldInternalName=”(.+)”s+FieldType=”(.+)”s+/);
        if(myMatch!==null){
        // Display name
        disp = myMatch[1];
        // FieldInternalName
        fin = myMatch[2];
        // FieldType
        type = myMatch[3];
        if(type===’SPFieldNote’){
        if($(this).find(‘script’).length>0){
        type=type+”_HTML”;
        }
        }
        if(type===’SPFieldLookup’){
        if($(this).find(‘input’).length>0){
        type=type+”_Input”;
        }
        }
        // Build object
        res[fin] = this.parentNode;
        res[fin].FieldDispName = disp;
        res[fin].FieldType = type;
        }
        });
        return res;
        }

        //###########################################################################################
        // Native SharePoint function – last line added
        function RTE_OnFocus(strBaseElementID){
        g_strRTETextEditorWithTheFocus=strBaseElementID;
        RTE_GetEditorDocument(strBaseElementID).body.contentEditable=true;
        if((g_strRTEPrevTextEditor!=null)&&(g_strRTEPrevTextEditor.length>0)&&(g_strRTEPrevTextEditor!=strBaseElementID)){
        RTE_DisableToolBar(g_strRTEPrevTextEditor);
        }
        RTE_StartResetToolBarTimer(strBaseElementID);
        // Select current RTE
        g_elemRTELastTextAreaConverted=document.getElementById(strBaseElementID);

        }

        //###########################################################################################
        // Native SharePoint function – first line added
        function PreSaveItem(){
        preSaveHighlightTabOnValidation();
        if(“function”==typeof(PreSaveAction)){
        return PreSaveAction();
        }

        return true;
        }

        //###########################################################################################
        // Edit the form-action attribute to add the tab and source as the user clicks through tabs
        function addSelectedTabToFormAction(tabID,redirURL){
        var ca = $(“#aspnetForm”).attr(‘action’);
        if(ca.indexOf(‘sTab=’)>0){
        ca = ca.substring(0,ca.indexOf(‘sTab=’)-1);
        }
        if(ca.indexOf(‘?’)>0){
        $(“#aspnetForm”).attr(‘action’,ca+”&sTab=”+tabID+ “&Source=” + redirURL);
        }else{
        $(“#aspnetForm”).attr(‘action’,ca+”?sTab=”+tabID+ “&Source=” + redirURL);
        }

        }

        //###########################################################################################
        // CHANGE TABS CODE
        //###########################################################################################
        function ChangeTabs_Click()
        {

        // Hide fields
        hideFieldsOnStart();

        /*
        // Redirect code
        goToWhenSaved = ‘[YOUR /SITE HERE]’;

        // Edit the redirect on the Save-button’s for every input with the id containing ‘SaveItem’
        $(‘.ms-ButtonHeightWidth[id$.indexOf(“SaveItem”) != -1]’).each(function(){
        $(this).click(function(){
        PreSaveAction();
        })
        });
        */

        }

        //###########################################################################################
        // DYNAMIC REDIRECT CODE ON LOAD
        //###########################################################################################
        // Edit the form-action attribute to add the source=yourCustomRedirectPage on initial load
        function setOnSubmitRedir(redirURL){
        //addSelectedTabToFormAction(1,redirURL)

        // Capture the http header as ACTION
        var action = $(“#aspnetForm”).attr(‘action’);

        if(action.indexOf(‘?Source=’)>0){
        action = action.substring(0,action.indexOf(‘Source=’)-1);
        }

        // set END to ACTION if ACTION has an ‘&’
        var end = action.indexOf(‘&’);

        // if ACTION does not have an ‘&’, rewrite the ACTION to include SOURCE, otherwise append SOURCE to the ACTION
        if(action.indexOf(‘&’)<0){
        newAction = action + "?Source=" + redirURL;
        }else{
        newAction = action.substring(0,end) + "&Source=" + redirURL;
        }

        // apply the new ACTION to the header
        $("#aspnetForm").attr('action',newAction);

        }

        //###########################################################################################
        // Use this function to add a dynamic URL for the OnSubmit-redirect. This function is automatically executed before save item.
        function PreSaveAction(){

        // Pass a dynamic redirect URL to the function by setting it here,
        // for example based on certain selections made in the form fields like this:
        //var mySelectVal = $(fields['MySelect']).find(':radio:checked').next().text();
        //if(mySelectVal=='Option one'){
        // var dynamicRedirect = '../..'; ///test/English/YouSelectedOptionOne.aspx';
        //}else if(mySelectVal=='Option two'){
        // var dynamicRedirect = '../..'; ///test/English/YouSelectedOptionTwo.aspx';
        //}

        var dynamicRedirect = '[YOUR /SITE HERE]';

        // Call the function and set the redirect URL in the form-action attribute
        setOnSubmitRedir(dynamicRedirect);

        // This function must return true for the save item to happen
        return true;
        }

        //###########################################################################################
        // HIDE FIELDS CODE
        //###########################################################################################

        /*
        SharePoint Field Type identifier tagName
        ———————————————————————–
        Single Line of Text TextField input
        Multiple Lines of Text TextField input
        Number TextField input
        Currency TextField input
        Choice (dropdown) DropDownChoice select
        Lookup (single)* Lookup select
        Lookup (multiple) SelectCandidate; SelectResult select
        Yes/No BooleanField input
        */

        //###########################################################################################
        function hideFieldsOnStart() {

        //hide the control at start
        var control = getTagFromIdentifierAndTitle("select","DropDownChoice","[YOUR DROPDOWN HERE]");

        //control.parentNode.parentNode.parentNode.style.display="none";
        //control.enabled="false";
        ChangeEvent();

        //add an onchange event to the dropdown
        getTagFromIdentifierAndTitle("select","DropDownChoice","[YOUR DROPDOWN HERE]").onchange = function() {ChangeEvent()};

        }

        //###########################################################################################
        function ChangeEvent()
        {

        //get the dropdown
        var dropDown = getTagFromIdentifierAndTitle("select","DropDownChoice","[YOUR DROPDOWN HERE]");

        //get the selected value
        var option = dropDown.options[dropDown.selectedIndex].text;

        //get the control
        var control = getTagFromIdentifierAndTitle("select","DropDownChoice","[YOUR DROPDOWN HERE]");

        //show hide based on your condition
        if(option == "Data Match")
        {
        //alert(control.parentNode.parentNode.parentNode.nodeName);
        //alert(control.parentNode.parentNode.nodeName);
        //alert(control);
        //control.style.display="";
        control.parentNode.parentNode.parentNode.style.display="";
        }
        else
        {
        //alert(control.parentNode.parentNode.parentNode.nodeName);
        //alert(control.parentNode.parentNode.nodeName);
        //alert(control);
        //control.style.display="none";
        control.parentNode.parentNode.parentNode.style.display="none";
        }

        }

        //###########################################################################################
        //this gets the field based on title identifier and tagname
        function getTagFromIdentifierAndTitle(tagName, identifier, title) {
        var len = identifier.length;
        var tags = document.getElementsByTagName(tagName);
        for (var i=0; i < tags.length; i++) {
        var tempString = tags[i].id;
        if (tags[i].title == title && (identifier == "" || tempString.indexOf(identifier) == tempString.length – len)) {
        return tags[i];
        }
        }
        return null;
        }

  13. Love this and use it all the time. Client has a request, and want to see if there is a simple way to accomodate. A particular form has approximately 12 tabs with about 7-8 fields on each tab. Is there a way to:
    – keep a tab highlighted that has been visited, or alternately,
    – highlight any tabs where any field has been populated (check box checked, text field not empty, etc)

    Thanks – I love the site and will be buying you a beer!!

    1. Hi,
      Thank you for the beer 🙂

      Look at v2.5 BETA and read the “ChangeLog” for instructions.

      I’m heading of for a short Christmas holiday so i cannot answer any questions until the 27th.

      Alexander

    2. I forgot one thing:
      If the page reloads due to failed validation on some fields, the marking will persist only if you have the form in a dialog.

      Alexander

  14. Hello ALexander,

    I’m trying to implement this with Office365 using IE8 but I’m getting the following error…

    HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)
    Line: 0
    Char: 0
    Code: 0

    I tried using defer=true and $(document).ready but then I get the following error..

    Message: ‘null’ is null or not an object
    Line: 289 (Sometimes this error is on Line: 214)
    Char: 2
    Code: 0
    URI: TabsForSharePointForms.js (2.4)

    This works fine in Firefox but I’m required to use IE.

    Do you know how I can fix this?

    Regards,
    Ken

    1. Hi,
      I have never had this error and therefore do not have a fix for it., There are multiple users who experience the same error in different scripts, so if you could try to dig into it and find the cause it would be very nice.

      Can you try first to comment out line 29 in the script – the call to the function “init_buildTabbedForm(tabConstructor);”

      Of course the script will not work, but do the error go away?

      If the error goes away, try commenting out line 255
      “document.write(styleBuffer.join(”));”

      If this helps, you can try to put the styles pushed into the “styleBuffer” in a regular style-tag in the cewp code.

      Alexander

  15. I have a couple of fields which are links. They are on my first tab. However, they then show up at the top of each subsequent tab. Any way to fix? Below is the calculation for one of the links – both are essentially the same – =IF(PID=”TBD”,””,”“&PID&”“)

  16. I am using 2.4 — working great with one issue. Need to hide a column/field based on a condition. Works fine using $(fields[‘Account’].hide(0); in the clickfunction for the tab as long as it is not the first tab. The first tab works also but not on initial page load only when you go to some other tab and then back to the first tab.

    Tried putting the same hide code in other places before and after the init_buildTabbedForm(tabConstructor); but neither one works on initial page load. So I was forced to move the field I want hidden to the second tab — not the ideal solution as it logically belongs on the first tab.

  17. Alexander,

    Thank you so much! Though I have known about Tabs for SharePoint Forms for quite a while, my first opportunity came just recently, and now I am on my second application.

    Question: I spent a little time modifying the colors of the tabs to match our (current) 2007 environment and tweeking the fonts, etc., however could not make a perfect match to my site style… I have in the past used Christophe’s (Path to SharePoint) Easy-Tabs, and admired his use SharePoint’s default CSS to make Easy-Tabs abide by the template of the site, etc.

    Do you think that using SharePoint’s CSS could be a future feature for Tabs for SharePoint Forms?

    Again, many thanks!

  18. Hi Alexander,

    Have used your code in a number of solutions since coming across it about a year ago and find it very useful for large custom lists.

    However I’ve had a bit of an odd output in my latest use, Version 2.4, where two of the ‘fields’ on my fourth tab (and an all fields tab) are showing the column ‘Description’ in the input field area rather that directly below. This can be overtyped when completing the form but looks odd. All the other field in all the other tabs – there are a total of 6 tabs each with around 10 fields – display the fields and descriptions properly.

    1. Hi, Could you provide a few screenshots and information about which browser you are using? – if you could test it in another browser to see if the problem persists it would be very helpful.

      Alexander

    2. Hi Alexander,

      I can send you some screen shots if you can email me your email address to attach them too.

      I’m using IE8 into MOSS2007 and will see what result I get with FireFox and send you screen shots from both.

      Regards,

      David

    3. Alexander,

      Please ignore my supposed problem, it was down to me. Seems I’d managed to paste the description for the two fields in question into the ‘Default Value’ not the ‘Description’ field when creating the columns!! I need to take more care.

      Thanks for following up. Regards, David

  19. When testing with Safari 5.0 the dropdowns render horizontally and not vertically. And only 4 or so will render horizontally. Is this a known problem or is there some configuration setting I am missing. Works fine in IE.

  20. Rendering with Safari on IPAD fails with Display form but not with edit or new form. The display form renders with copyright (2.4) at the top of the dialog form and then all white space below and no way to scroll up to see the real form. Works fine with Safari on non-IPAD devices (could be same issue on Iphone did not test that).

    1. Hi,
      Sorry for the late answer. I have not tested this code on an iPad. If you find a fix, please let me know.

      Alexander

  21. Great feature. Have it working fine, but one question. Is there a way to suppress the pop window when you click a tab. In may case it pops up when I click the 2nd tab, has message “The fields included in the second tab is these:….”. I see where the function is that triggers this but not sure what purpose this serves or how to turn it off, also didnt see any thing is question/response area addressing this. Thank you, Mark

    1. Hi,
      This was added as an example on how to trigger a specific function when clicking on a tab.

      Look at the CEWP code – find the configuration for the second tab, and you will see this code:
      clickFunction:’secondTabClick(this)’

      change it to:
      clickFunction:”

      Alexander

  22. Alexander,

    Tabs for SharePoint Forms has changed my life for the better! I am using the latest version (2.4) in a SharePoint 2010 environment, but am running into two small problems:

    1) I can’t seem to find a way to hide a field – there are many JQuery snippets on the Internet to hide a field in EditForm, but none that I have found seem to work in conjunction with Tabs for SharePoint Forms — do you have a recommendation?

    2) Field order — I find that if I have a field displayed with Tabs for SharePoint Forms in a different order then they are ordered in the list, the results often follow the list vs. the Tabs for SharePoint Forms configuration. This happens most when a field appears on multiple tabs (a wonderful feature!), and in this case, the field-order of the list itself seems to take presidence over the TfSF configuration.

    Many, many thanks for sharing you wonderful work! I hope you can help me.

    R’grds – Ben.

    1. Ben, I also rely heavily on this script in my Sharepoint!

      For your first question check out Alexander’s amazing post here:

      https://spjsblog.com/2010/03/30/edit-sharepoint-field-properties-including-lookup-column-list-association-with-client-side-code-only/

      For your second question, I’ve found that once you have rich text multiple lines of text fields you have to control the field display order using both Column Ordering in the List Settings and the configuration in the script itself.

      1. DCH,

        Thank you, I too am amazed by Alexander’s Edit List and Field Properties solution! From my question, I see that I was not clear enough…

        Actually, what I am doing is performing some Javascript manipulation, getting field values, performing a little math, and placing the result into a field — and it is this “results” field that I want to “hide” or not to display (very much like the behaviour of a Calculated Column, which does not display on an EditForm).

        Using Alexander’s Edit List and Field Properties solution seems to more than “hide” or ihibit the field display, it seems to “remove” it as effectively as Content Types remove — making the “result” field unavailable to Javascript as well.

        So, I guess I am asking for a way to inhibit the display of a field while leaving it available Javascript to receive my computed result.

        On column ordering, I do have more than one multiple-lines-of-text fields, but they are all plain text, no rich-text — not sure if that makes a difference. Are you saying that once multiple-lines-of-text fields are introduced, the display sort is affected for all fields? In my case, it not the multiple-lines-of-text fields that are placed out of requested order, but other fields.

        Again, thank you for interest!

        R’grds – Ben.

    2. I think the Edit List and Field properties does most of what you are looking for… I use it for that all the time. The field is still available to calculated columns, workflows, etc. Not sure about javascript references to it though. Maybe it won’t work for you if that’s what you mean.

      Yes, the column ordering is affected for all the fields, not just the multiple lines of text fields once there is one present in the form. It might include the plain text type too.

  23. Hi, Alexander,

    I would like to have more then one field in one row.
    Like Title, Description and State or first name and last name.=> defined as
    …(‘Title’, ‘#’, ‘Description’,’#’,’State’) or (‘FirstName’,’#’,’LastName’).
    using ‘#’ as an indicator for three or two Columns.
    The field label must be shown above the field in this case.

    Can you give me some hints how to solve this requirement.
    Best regards
    Rudolf

  24. Hi Alexander,

    I have been trying to implement your solution in my SharePoint 2010 environment for a couple of days now but with no luck. I get to see the 4 tabs as expected but for me, all the fields appear in all the tabs. I have around 8 fields and even though I have added 2 fields per tab, they are all appearing in all the tabs.

    Any thoughts.

    Best Regards,
    Nick

  25. Alexander,

    I have tried to implement the changes you described for tabs in SharePoint 2010 without luck. When I click to add a new item to the list, the form is not tabbed at all and below the form it displays all the code I added in the CEWP ( I can actually click on the src links from the displayed form )

  26. I have some lengthy column names in my list. Using the tabs in forms doesn’t seem to allow for the form to auto adjust its width, resulting in a horizontal scroll bar at the bottom. Is there a way to have tabs in forms and auto-adjusting form widths?

  27. We are having an issue with Line 90 of the tabsforsharepointforms.js file where we get attr(…) is null or not an object. We have a site working perfectly with the same code. Can you assist?

  28. I’ve tired using this solution in a document set edit form but could not get it to work. I wondering if you have tried it get tabs on a document set edit form to work?

  29. Hello,

    the solution works fine, but now i try to add more than 4 tabs to my form.
    What i supposed to do? Where can i change the settings for “tabs-limit”? i’m very thankful for every answer.

    Tiac

  30. Hello, first of all let me tell you that your code is fantastic. However I have the same problem related by Ken: HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917.

    I look at your answer but I don’t understand what you mean by “If this helps, you can try to put the styles pushed into the “styleBuffer” in a regular style-tag in the cewp code”. I comment out line 255
    “document.write(styleBuffer.join(”));” and the error goes awat b ut the script does not work.

    Please help.

    Regards

  31. Hi,

    how can I customize the tabstyle css?

    I can’t find it anywhere in the code block imbedded in the CEWP.

    Imagine that I wanted, for exemple, to change the color of the field names.
    How would I do it?

    Thanks!
    Susana

  32. Hi,
    another question.

    At the top of this page, you state: “24.03.2011 Updated the script to fix an issue with the attachments. They now appear at the bottom of every tab – like in a unmodified form. If there are no attachments, the field is hidden.”

    Now, what if I want to show the attachments field but only in a specific tab, for exemple, the first tab?

    Would that be very hard to do?

    Thank you
    Susana

  33. Hi,
    yes I’m trying. I’ve posted a doubt about that (because of the var I have to include since I’m working with SP2007)on your Dynamic Forms page.

    Hope you can help me.
    Thanks
    Susana

  34. Hi I followed the same and its not working fro me.

    My CEWP code is as follows.

    var tabConstructor = {tabs:[{name:’First Tab’,fields:[‘Title’,’C_No’],mouseOver:’This is the first tab’,tabStyle:”},

    {name:’Second Tab’,fields:[‘C_Name’,’C_Date’],mouseOver:’This is the second tab’,tabStyle:”},

    settings:{

    viewAllFields:{show:true,name:’All fields’,mouseOver:’This tab shows all fields’,tabStyle:”},

    orphanFields:{show:true,name:’…’,mouseOver:’All orphan fields’,tabStyle:”},

    breakTabRowAt:null,

    hoverTabColor:’#FFF68F’,

    selectedTabColor:’#B9D3EE’}};

    init_buildTabbedForm(tabConstructor,1);

    Please help me out on this.

    Any video on this for our reference will be helpful.

    Thanks in advance.

  35. Hi, Is there a way I can hide tabs conditionally in Display form depending on the selection made in Choice field. Eg. I want to display “Other” tab if a particular column is set to “Yes”.

    Thanks,
    Pavan

  36. Hi!

    This is a fantastic script. However, one thing I’m not able to do is to display tabs “on demand”, ie being able to toggle between the standard Sharepoint view to the tabbed view using this script.

    I tried calling the init_buildTabbedForm(tabConstructor) function from a button on the page instead of loading it with the page, but the only thing it does is making the whole page blank when I click on it.

    Any idea how to fix this?

  37. Is there a way to add a spacer or blank line? Sort of like an tag? We have a couple of tabs that have several fields and we want to break them up a bit but keep them on the same tabs. It would be ideal if we could put some sort of header text in there as well, but just being able to display a line would be great.

    I tried adding ‘ ‘ , etc to the list of fields in tabConstructor but it was ignored.

    I don’t really know much JavaScript so didn’t want to mess with the .js file.

    Thanks!

  38. i do have additonal js to show/hide fields in the form.
    when i load the page the js kicks in and hides the fields, when i switch to another tab and come back to old tab the fields are showing. , this happnes only i switch between tabs. is there a fix for it ?

  39. Great tool. I have deployed this and is working fine except for one aspect. In my list I have a lookup field and I am also bringing in some “additional columns” from that other list that lookup is pulling from. I tried using internal name of those “additional columns” to get them to display on the tabs but I don’t see them.

  40. Alexander,

    We have had this tabs on a 2010 site for years. We were recently pushed to 2013 and everything worked fine until IT pushed out changes to the master pages to bring up compatibility for 2016 sharepoint. Can you confirm that this solution works on 2013, and if so, what changes might be required?

    I’m happy to go into more details, but wanted to start more generically first.

    Thanks,
    -Aaron

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.