Tabs in SharePoint form

18.01.2011 I have posted a new solution compatible with both SP2007 and SP2010 and fixes the problems with rich text fields and “single lookup with more than 20 items under Internet Explorer – problem”. You find it her


23.01.2010 Updated the code to fix two issues regarding date and time columns. I added a <style> tag to set the font size of “.ms-dtinput” and “.ms-dttimeinput” to 0.7em.

I also added a custom handler to select the right tab on “empty field validation” on a date and time field. These are validated without page reload, and therefore did not work in the previous version.

Thank you all for the feedback and the testing.

15.12.2009 Update to support form validation. On submit – if there are required fields not filled – the tab containing the first required field is selected.


I got this request:

We have a custom list with a lot of fields. I need to divide it into sections and then easily show/hide those sections. I am going to try dividing the form into div tags and then use jQuery to display the sections in either Tabs or an accordion…

And made this demo based on the jQuery UI Widget “Tabs”.

NewForm:
IMG
DispForm:
IMG
DispForm with attachment:
IMG

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

A folder named “jQueryUI” containing the scripts and the “images”-folder for the selected theme:
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.3.2.min. If you download another version, be sure to update the script reference in the sourcecode.

The jQuery UI-library is found here. Find the theme of your choice – mine is “smootness” – and download the files (i have plucked only the necessary files – “UI Core” and “Tabs”).

Add a CEWP below your NewForm, DispForm and EditForm.

Add this code:
[javascript]
<!– Date field text size –>
<style type="text/css">
.ms-dtinput,.ms-dttimeinput{
font-size:0.7em;
}
</style>
<DIV id="tabs">
<UL style="font-size:12px">
<LI><A href="#tabs-1">Tab 1</A></LI>
<LI><A href="#tabs-2">Tab 2</A></LI>
<LI><A href="#tabs-3">Tab 3</A></LI>
<LI><A href="#tabs-4">Attachments</A></LI>
</UL>

<div><table cellpadding="0" cellspacing="0" id="tabs-1"></table></div>
<div><table cellpadding="0" cellspacing="0" id="tabs-2"></table></div>
<div><table cellpadding="0" cellspacing="0" id="tabs-3"></table></div>
<div><table cellpadding="0" cellspacing="0" id="tabs-4"></table></div>
</DIV>

<link type="text/css" href="/test/English/Javascript/jQueryUI/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/jQueryUI/jquery-ui-1.7.2.custom.min.js"></script>
<script type="text/javascript">
// Array of all fields – format: tabID|FieldInternalName
arrTab = [‘1|Title’,’1|Tab1Text’,’1|Tab1Choice’,
‘2|Responsible’,’2|Tab2Text’,’2|Tab2Choice’,’2|Date’,
‘3|Tab3Text’,’3|Tab3Choice’,’3|Tab3MultilinePlain’];

// Initiate all the fields
fields = init_fields();

// Add the "tabs" to the formtable
$("#tabs").insertAfter(‘.ms-formtable’).tabs();
// Loop trough all fields and move them to the right tab
$.each(arrTab,function(idx,item){
var split = item.split(‘|’);
var tabID = split[0];
var fieldName = split[1];
if(fields[fieldName]!=undefined){
currField = $(fields[fieldName]);
currField.appendTo(‘#tabs-‘+tabID);
}
});

// Are there any required fields not filled? – select the tab containing the first field
selectTabOnFormValidation(false);
function selectTabOnFormValidation(preSave){
var formvalidationTab = ”;
// Formvalidation – find the first tab with empty required fields
$.each(arrTab,function(idx,item){
var split = item.split(‘|’);
var tabID = split[0];
var fieldName = split[1];
currField = $(fields[fieldName]);
// Handles DateTimeField (empty field validation is performed without page reload)
if(currField.find("SPAN[ID*=’_DateTimeField_’]").length>0){
if(currField.find(‘input:first’).val()==” && preSave){
formvalidationTab = tabID;
}
}
if(formvalidationTab == ” && currField.find(‘.ms-formbody span.ms-formvalidation’).length>0){
formvalidationTab = tabID;
}
});
// Select the first tab containing an empty required field
if(formvalidationTab!=”){
$(‘#tabs’).tabs(‘select’, formvalidationTab);
}
}

// Move the Attachment’s to the last tab
$("#idAttachmentsRow").appendTo(‘#tabs-4’).find(‘.ms-formlabel’).attr(‘width’,’165px’);

// function – to make "object" of all tr’s in the form
function init_fields(){
var res = {};
$("td.ms-formbody").each(function(){
if($(this).html().indexOf(‘FieldInternalName="’)<0) return;
var start = $(this).html().indexOf(‘FieldInternalName="’)+19;
var stopp = $(this).html().indexOf(‘FieldType="’)-7;
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}

// Catch "empty field validation" on date and time columns
function PreSaveAction(){
selectTabOnFormValidation(true);
return true;
}
</script>
[/javascript]

The only parameters you need to edit in the script is the array of FieldInternalNames. The format of the variable “arrTab” is tabID|FieldInternalName.

In the html above the script, adapt the number’s of tabs – and the tab’s display name. The tabID corresponds with the number in the id attribute of the table to insert the tab content in.

All fields must be added to a tab – if not it looks ugly….

Note: By now i have tested and found that columns of type “Multiple lines of text (Rich text or Enhanced rich text) do not work. What happens is that the tabs script shows some of the fields hidden parts.

I have not done any testing on how to prevent this issue, so feel free to notify me if you find a workaround.

Regards
Alexander

157 thoughts on “Tabs in SharePoint form”

  1. hi Alexander
    as always. gr8 job!!

    it s work gr8 on my NewItem but somehow doesntwork on my DispForm.
    i can see the tabs like in html page (if know waht i ment).
    why?

    gilad

  2. Hi there. I am struggling to find out where in the code in sharepoint designer I am supposed to insert this code?
    I have opened the newfrom,dispfor and editform in sharepoint designer, and added the Insert webpart on NewForm, DispForm or EditForm: from the insert menu. Where is this code going?

    1. Hi,
      Just above the codeblock, you find a link on the text “CEWP”. There you find a description on how to put a CEWP in NewForm, DispForm and EditForm.

      Here it is copied from this description:
      Insert webpart on NewForm, DispForm or EditForm:
      Add “toolpaneview=2″ behind the URL in this format:
      …NewForm.aspx?toolpaneview=2
      …EditForm.aspx?ID=12&toolpaneview=2

      Alexander

  3. Hey A,
    Great job again. I know I am always a pain in the ass asking you questions. With this is there a way to hide/show the tabs based on your script IsInUserGroup ?
    How could this be converted to accordian as opposed to tabs?

  4. I have dowloaded the jquery-1.4.js as you can check in the code, and the multiple lines of text are working in Newform and DispForm pages

    For the Date and Time fields I have deleted previous colums, created new ones and adding in the code

    Below is my code, please adjust the address of the libraries according to yours

    <DIV id="tabs">
    	<UL style="font-size:12px">
    		<LI><A href="#tabs-1">Employee Information</A></LI>
    		<LI><A href="#tabs-2">Reimbursement Information</A></LI>
    		<LI><A href="#tabs-3">Justification</A></LI>
    	</UL>
    
    	<div><table id="tabs-1"></table></div>
    	<div><table id="tabs-2"></table></div>
    	<div><table id="tabs-3"></table></div>
    	<div><table id="tabs-4"></table></div>
    </DIV>
    
    <link type="text/css" href="http://teams3.sharepoint.hp.com/teams/1903/project/Javascript/jQueryUI/jquery-ui-1.7.2.custom.css" rel="stylesheet" />
    
    <script type="text/javascript" src="http://teams3.sharepoint.hp.com/teams/1903/project/Javascript/jquery-1.4.js"></script>
    
    <script type="text/javascript" src="http://teams3.sharepoint.hp.com/teams/1903/project/Javascript/jQueryUI/jquery-ui-1.7.2.custom.min.js"></script>
    
    <script type="text/javascript">
    // Array of all fields - format: tabID|FieldInternalName
    arrTab = ['1|Title','1|Name','1|Organization',
    		   '2|Date','2|Reason','2|Justification','2|Amount','2|CostCenter',
    		  '3|Who','3|When','3|What','3|Why'];
    
    // Initiate all the fields
    fields = init_fields();
    
    // Add the "tabs" to the formtable
    $("#tabs").insertAfter('.ms-formtable').tabs();
    // Loop trough all fields and move them to the right tab
    var formvalidationTab = '';
    $.each(arrTab,function(idx,item){
    	var split = item.split('|');
    	var tabID = split[0];
    	var fieldName = split[1];
    	if(fields[fieldName]!=undefined){
    		currField = $(fields[fieldName]);
    		currField.appendTo('#tabs-'+tabID);
    
    		// Formvalidation - find the first tab with empty required fields
    		if(formvalidationTab == '' && currField.find('.ms-formbody span.ms-formvalidation').length>0){
    			formvalidationTab = tabID;
    		}
    	}
    });
    
    // Are there any required fields not filled? - select the tab containing the first field
    if(formvalidationTab!=''){
    	$('#tabs').tabs('select', formvalidationTab);
    }
    
    // Move the Attachment's to the last tab
    $("#idAttachmentsRow").appendTo('#tabs-4').find('.ms-formlabel').attr('width','165px');
    
    // function - to make "object" of all tr's in the form
    function init_fields(){
      var res = {};
      $("td.ms-formbody").each(function(){
    	  if($(this).html().indexOf('FieldInternalName="')<0) return;
    	  var start = $(this).html().indexOf('FieldInternalName="')+19;
    	  var stopp = $(this).html().indexOf('FieldType="')-7;
    	  var nm = $(this).html().substring(start,stopp);
    	  res[nm] = this.parentNode;
      });
      return res;
    }
    
    </script>
    
    1. The fields What and Why are multiple lines of text, they are working fine in DispForm and NewForm pages

      Try to load them into the lasted jQuery library 😉

    2. Hi,
      With multi line: do you mean plain text or rich text/enhanced rich text?

      Multi line plain text is not a problem, rich text/enhanced rich text are.

      Alexander

  5. Renan: Multiline fields now seems to work fine. How did you fix the date field issue (date fields are not shown correctly)? Another issue i am experiencing is that the tabs are not showing correctly either. Any advice on how to fix this ? Thanks.

  6. I got the tabs working. The only remaining issue is that for the date fields. Another thing i noticed was the function for showing the tabs which contains an empty require field. It seems that if the empty required field is on the first tab, it won’t then show that first tab. I.e. if you have 3 tabs, a, b and c, each containing required fields. Now if you forgot a required fields in tab a, and you are currently in tab c when you hit the “OK” button, then tab a wont get visibily… This is a minor issue, but I hope someone can help give some advice on the date fields. Thanks.

    1. Hi,
      I tested the “empty required field” and the select of the first tab, and i cannot find anything wrong. What kind of required field is it you have in the first tab (field type).

      Alexander

    2. Alexander. First of all, thanks for a great solution 🙂 I have several required fields on the first tab, like several datetime fields, radiobuttons, text boxes, dropdowns, etc. So if someone forgets one of the required fields on the first tab, and is on another tab and hits the “OK” button, then the first tab is not shown, rather it just doesnt seem to respond to it and remains on the same tab.

  7. Ok, I ended up making a small hack for the datetime fields. Put the following code at the end of the init_fields() function:

    var row = res[nm].innerHTML;

    var match = row.match(/<input.*?id=([^s]*?DateTimeField[^s]*?)s/i);

    if( match != null )
    {
    match = match[1].replace(/"/gi,'');
    $("#" + match).css('width','75px');
    $("#" + match).css('height','20px');
    $("#" + match).css('font-size','11px');
    }

    What this code does is that it looks for a datetime input field and gets the id of that field. Later it manipulates the css so that the datetime fields show up correctly.

  8. Alexander,
    I added a lookup column to my list but this column is shown twice (in the correct tab and above in the standard form).

    Do you have the same problem?

    FYI: In my lookup source list are more than 40 items.

    Thanks for your great work!
    Thomas

    1. Hi,
      I have tested with lookup columns like your setup, but cannot replicate this error. Can you give me some more information, and maybe test with another column of the same type?

      By the way – the code is updated to fix the issues with the date and time columns.

      Alexander

  9. Alexander,

    This is getting real good man! 🙂
    I have only 1 more request. On my DispForm, I want the first tab (Summary tab) to show some specific fields chosen from the other tabs. So in a sense to “duplicate” the field twice so I can use it in both the first summary tab and in the other “normal” tab where it belongs. I think I can use the .appenTo method to do that, but I hope that you can help me on this. Thanks in advance and keep doing a great job 🙂

  10. Alexander,

    How can I change the display name of a field using your code? I.e. a field’s label is : “My current home address” and i want to display it as “Current address”… Another question I have is how I can display two fields (and their labels) in the same row? I know I am asking too much. But I really hope you can give me some advice o this. Thanks man.

  11. Howdy guys,

    I am trying to place field columns inside the tabs (reffering to the latest post regarding fields side by side). But the thing is: At the time I create a Web part for the tabs, I cannot pull up the columns to populate them.
    Can you help me?

    Thank you so much =)

    1. Hi,
      I have not done thorough testing on this (tabs and side-by-side), but a quick test shows that you can add a reference to the script FieldsSideBySide.js, and add the side-by-side function calls at the top of the tabs script.

      Alexander

  12. Hi Alexander:
    This is superior work!

    You said earlier, “All fields must be added to a tab – if not it looks ugly….”

    I actually need about 4 fields to show above the tabs (I need it to be ugly!) so that the people editing an item can populate their department’s tab and still see the 4 fields above.

    How can I adjust the order of the “left over” fields?

    Thanks-
    Charlie Epes

    1. Hi,
      This is as easy as not adding them to the array. The order will be the order the fields has in an unmodified list – rearrange the order under list settings.

      Alexander

    2. Hi Alexander:
      I think I lose the ordering ability when I “Manage my Content Types”.

      I have the column order set how I want it but it has no effect on the fields left out of the array. Are you seeing anything different?

      Thanks-

      Charlie Epes

  13. Alexander,

    Fantastic work. I am very close to getting this to be exactly what I want. The only thing is I need subgroupings to expand once you click the tab. So what I am asking for is how can i use tabs and accordion together? I would prefer to have the accordion first and then tabs under it. Or can I use multilayered accordions? I want to be able to break it down twice. I have a huge list and I am trying to make it seem much less intimidating! I have a tight deadline on this so if you can let me know if and how this is possible soon I’d greatly appreciate it! Thanks a ton in advance.

    1. Alexander I am so close! I am missing something simple I just know it. Help me out and take a look. Thanks a ton!

      
      <DIV id="tabs">
      	<UL style="font-size:12px">
      		<LI><A href="#tabs-1">Customer/Prospect Information</A></LI>
      		<LI><A href="#tabs-2">Established DuBois Applications</A></LI>
      		<LI><A href="#tabs-3">Potential Applications</A></LI>
      		<LI><A href="#tabs-4">Attachments</A></LI>
      	</UL>
      
      <div><table cellpadding="0" cellspacing="0" id="tabs-1"></table></div>
      
      	<div id="tabs-2"> <div id="accordion" style="font-size:14px">
      
      <H3><A href="#accordion-0">Surface Finishing</A></H3>
      	<div><table width="100%" id="accTable-0"></table>&nbsp;</div>
      	<H3><A href="#accordion-1">Section 2</A></H3>
      	<div><table width="100%" id="accTable-1"></table>&nbsp;</div>
      	<H3><A href="#accordion-2">Section 3</A></H3>
      	<div><table width="100%" id="accTable-2"></table>&nbsp;</div>
      	<H3><A href="#accordion-3">Attachments</A></H3>
      	<div><table width="100%" id="accTable-3"></table>&nbsp;</div>
      </div>
      
      </div>
      
      	<div><table cellpadding="0" cellspacing="0" id="tabs-3"></table></div>
      	<div><table cellpadding="0" cellspacing="0" id="tabs-4"></table></div>
      
      
      </DIV>
      
      <link type="text/css" href="javascript/jquery-ui-1.8rc3.custom.css" rel="stylesheet" />
      <script type="text/javascript" src="javascript/jquery-1.3.2.min.js"></script>
      <script type="text/javascript" src="javascript/jquery-ui-1.8rc3.custom.min.js"></script>
      <script type="text/javascript">
      
      // Array of all fields - format: tabID|FieldInternalName
      arrTab = ['1|Title','1|Customer_x0020_Status','1|DSP_x0020_Level', '1|DSP_x0020_Level', '1|Sales_x0020_Representative', '1|Manager', '1|SAE_x0020_Partner', '1|Customer_x0020_Number', '1|Shipping_x0020_Address', '1|Billing_x0020_Address_x0020__x00', '1|Contact_x0020_Name_x0020_and_x00', '1|Buying_x0020_Influence_x0020_Mod', '1|Phone_x0020_Number', '1|Email', '1|Contact_x0020_2_x0020_Name_x0020', '1|Contact_x0020_2_x0020_Phone_x002', '1|Contact_x0020_2_x0020_Email', '1|Contact_x0020_3_x0020_Name_x0020', '1|Contact_x0020_3_x0020_Phone_x002', '1|Contact_x0020_3_x0020_Email', '1|Fax', '1|MSDS_x0020_Email', '1|A_x002f_P_x0020_Contact_x0020_In', '1|Delivery_x0020_Method', '1|Price_x0020_Contract', '1|Service_x0020_Frequency',];
      
      
      arrOfFields = ['0|Metalworking_x0020_Competitor','0|Maintenance_x0020_Cleaning_x0020','0|Maintenance_x0020_Cleaning_x00200',];
      
      
      
      
      // Initiate all the fields
      fields = init_fields();
      
      // Add the "tabs" to the formtable
      $("#tabs").insertAfter('.ms-formtable').tabs();
      $("#accordion").accordion({autoHeight: false,animated: false});
      
      
      // Loop trough all fields and move them to the right tab
      $.each(arrTab,function(idx,item){
      	var split = item.split('|');
      	var tabID = split[0];
      	var fieldName = split[1];
      	if(fields[fieldName]!=undefined){
      		currField = $(fields[fieldName]);
      		currField.appendTo('#tabs-'+tabID);
      	}
      });
      
      fValAccID = '';
      $.each(arrOfFields,function(idx,item){
      	var split = item.split('|');
      	var accID = split[0];
      	var fieldName = split[1];
      	if(fields[fieldName]!=undefined){
      		currField = $(fields[fieldName]);
      		currField.appendTo('#accTable-'+accID);
      
      		// Formvalidation - find the first tab with empty required fields
      		if(fValAccID == '' && currField.find('.ms-formbody span.ms-formvalidation').length>0){
      			fValAccID = accID;
      		}
      	}
      });
      
      
      // Are there any required fields not filled? - select the tab containing the first field
      selectTabOnFormValidation(false);
      function selectTabOnFormValidation(preSave){
      var formvalidationTab = '';
      // Formvalidation - find the first tab with empty required fields
      	$.each(arrTab,function(idx,item){
      		var split = item.split('|');
      		var tabID = split[0];
      		var fieldName = split[1];
      		currField = $(fields[fieldName]);
      		// Handles DateTimeField (empty field validation is performed without page reload)
      		if(currField.find("SPAN[ID*='_DateTimeField_']").length>0){
      			if(currField.find('input:first').val()=='' && preSave){
      				formvalidationTab = tabID;
      			}
      		}
      		if(formvalidationTab == '' && currField.find('.ms-formbody span.ms-formvalidation').length>0){
      			formvalidationTab = tabID;
      		}
      	});
      	// Select the first tab containing an empty required field
      	if(formvalidationTab!=''){
      		$('#tabs').tabs('select', formvalidationTab);
      	}
      }
      
      // Move the Attachment's to the last tab
      $("#idAttachmentsRow").appendTo('#tabs-4').find('.ms-formlabel').attr('width','165px');
      
      // function - to make "object" of all tr's in the form
      function init_fields(){
        var res = {};
        $("td.ms-formbody").each(function(){
      	  if($(this).html().indexOf('FieldInternalName="')<0) return;
      	  var start = $(this).html().indexOf('FieldInternalName="')+19;
      	  var stopp = $(this).html().indexOf('FieldType="')-7;
      	  var nm = $(this).html().substring(start,stopp);
      	  res[nm] = this.parentNode;
        });
        return res;
      }
      
      // Catch "empty field validation" on date and time columns
      function PreSaveAction(){
      selectTabOnFormValidation(true);
      return true;
      }
      </script>
      
      
      
    2. Hi,
      Just by looking at the code, i have not had the time to test it, and it may not be important:
      The arrays “arrOfFields” and “arrTabs” ends with a comma. Try to remove those.

      Alexander

    3. Alexander,

      Thanks. I tried that but unfortunately it didn’t make a difference. Any other ideas? It’s frustrating because I can see the accordions but there’s nothing in them.

    4. It looks like you are moving the fields to the tabs rather than to the accordion. If you in the HTML above the script put the accordion inside the tab, you must look at the code from the post Accordion in SharePoint form and move the field to the right accordion.

      Note line 55 in the codeblock in the accordion article.

      Alexander

    5. Alexander,

      Thanks again. I tried to add line 55 but that didn’t do anything. I do have some information I just want on one tab with no accordions, then the second and third tabs I want to have the accordions in. You’ll see I have arrtab and arroffields both. I also tried to add the same information in both arr sections so it would first put it in the tab and then in the accordion but that didn’t work either. Basically when I did this I tried to married both of your tutorials together using the method I found on that other link.

    6. So I am trying the other route of using the “Dynamic expand/collapse fields or array of fields by multi select” link. I can get it to work for the first tab. But for the second tab there is another control and another set of fields that need to be displayed. In the comments on your site you mention using a dynamicdisplay. How do I do this? Or what am I missing? I added a second CEWP for the other tab and recreate the code but it does nothing. You have been very helpful and now again with this approach I near an answer but hit a wall. Thanks a ton!

  14. Hi,

    Thanks Alexander for the great job.

    What about the Rich text field, is the problem resolved? In fact, I have a list form which contains many rich text fields and I want to regroup them by tab.

    Thank you.

    1. Hi,
      Sorry, but i have not done any more work on this issue. I’m kind of busy and cannot promise i will find a solution.

      If you find a solution, please let me know.

      Alexander

  15. How to use this code in a customized sharepoint form? i am not able to get the tabbed results in customized for, but i am able to get results in uncustomized form.

  16. can one or more of the tabs point to a filtered doc lib view? I think I can create ca CC to give me the filter, Just need to figure out how to pull the list into one of the tabs.

    1. hey yes sometimes. I am setting up a requirements tracking system. As documents are added to the library and the intake changes I am trying to setup quick access to the doc lib.
      will the vlookup work on a doc lib?
      can it work on an edit form ?
      Can it be used to pull the version history of an item?

    2. The vLookup is based on a calculated field and therefore is available in DispForm only. It will work against a DocLibrary, just remember the the “Name” field has a FieldInternalName of “FileLeafRef”.

      It can’t pull the version history.

      I do not think putting a document library in a tab between the form fields in EditForm is such a good idea. If a user has made some changes in the EditForm, and then clicks on a document, the EditForm is left without saving the changes.

      Alexander

  17. Hi Alex,

    the script is great but I can not make “Attach file” and “Delete Item” move to the fourth tab. It just stays on top of the list, so far I’ve only tried within editform.aspx.

    Any idea on how I can debug this problem?

    regards
    Chris

    1. This is not part of the original functionality, as these “buttons” are not “fields” and therefore is not addressed by the script.

      If it is a genuine desire to make this happen, it is possible, but what about the other “buttons” in the toolbar?

      Show me what you got this far, and i might help you.

      Alexander

    2. Well, I haven’t changed anything from your code. I created a standard list, applied the code to a CEWP below some input fields, defined the tabs (still using the original four), defined the fields per tab and clicked ok. Worked well for all the fields but not for the attachments. As far as I understand it’s the same attachments that is shown in the first screenshot on this page. It’s a link to ‘javascript:UploadAttachment()’.

      I can find the “idAttachmentsRow” within the source of the page but it seems to be untouched by the script code.

      To move on with my orginial idea I added some other CEWPs, namely the FieldsSidebySide, BuildHeadingsFromArray, a Color Changer, a HideField and a ChangeOkToSave. All playing well with each other so far 🙂

      What info can I provide to help with debugging?

      Chris

    3. Are you sure you have attachments enabled for your list? Also note that the screenshots are from DispForm. The Attachments tab is empty until you add an attachment.

      Alexander

    4. Hi,

      > The Attachments tab is empty until you add an attachment.

      that’s it. It’s not that the buttons are moved into the attachments tab, it’s the attachments themselves. Silly me. I was to happy that everything worked together – see above – that I didn’t realize that it’s not about the buttons.

      Thanks for clarification.
      Chris

  18. I am trying to use this code with enhanced multiple lines of text fields, and I have seen in your post that they don’t work together. Would it be possible to not include these in the tabs but in place of making them appear over the tabs to make them appear under them. Since they would not be in tabs, they should render properly, and in our case it would work.
    Thank you

  19. Hi Alexander,

    Great tool this is!!

    I have a strange issue with lookup drop-downs though, when you click the drop down (the drop down button is in the jqueryUI theme i chose for some reason?) the entries appear at the bottom of the form! Not directly below the drop down where you’d expect them to appear. Any ideas? I’m using your most recent code from this article.

    Many thanks!

    1. Hi,
      Do you have multiple lookup columns in the same form with more than 20 items? (it then renders in a different way).

      There may be an issue with the “item container” as it is shared between all lookup columns in the same form.

      Alexander

  20. Hi there,

    Yes – one more lookup field that’s allowing multiple selections, so isn’t a drop down box. This does have more than 20 items to select from yes.

    As for the lookup drop down that’s displaying oddly, it has well over 20, more like 80 items…

    Thanks!
    Ben

  21. Hi

    Alexander, I’ve been busy with your code for several weeks now. I have to make a calendar list, with loads of fields. So, I have to order those fields in different tabs.

    I’ve done so, but each time i’m testing the code by pressing ‘OK’, Internet Explorer tells me there is an error : “‘undefined’ is null or not an object”.
    in URL: http://home/…/Newform.aspx” Line: 1342

    if i look at the source of the page, it should be in this line:

    var split = item.split(‘|’);

    what could be the problem?

    1. Just a quick guess, have you double checked the array for the tab definition (Line 26 from the original code)? Maybe you’ve missed an apostroph or comma somewhere?

  22. indeed,

    there was a comma after the last value

    thx a lot

    P.

    // Array of all fields – format: tabID|FieldInternalName
    arrTab = [
    ‘1|Title’,
    ‘1|Trefwoord’,
    ‘1|Soort’,
    ‘1|Dossierbeheerder’,
    ‘1|Begintijd’,
    ‘1|Eindtijd’,
    ‘1|Locatie’,
    ‘1|Straat’,
    ‘1|Huisnummer’,
    ‘1|Deelgemeente’,
    ‘1|Organisator’,
    ‘1|Contactnummer’,
    ‘1|Op_x0020_openbaar_x0020_domein’,
    ‘2|Sirene’,
    ‘2|Beschrijving’,
    ‘3|Startvergadering_x0020_datum’,
    ‘3|Startvergadering_x0020_verslag’,
    ‘3|Vergadering1_x0020_datum’,
    ‘3|Vergadering1_x0020_verslag’,
    ‘3|Vergadering2_x0020_datum’,
    ‘3|Vergadering2_x0020_verslag’,
    ‘3|Evaluatievergadering_x0020_datum’,
    ‘3|Evaluatievergadering_x0020_versl’,
    ‘4|Advies_x0020_Politie_x0020_nodig’,
    ‘4|Advies_x0020_korpschef’,
    ‘4|Advies_x0020_brandweer_x0020_nod’,
    ‘4|Advies_x0020_cultuur_x0020_nodig’,
    ‘4|Advies_x0020_wegen_x0020_en_x002’,
    ‘4|Adviezen_x0020_wegen_x0020_en_x0’,
    ‘4|Advies_x0020_de_x0020_Lijn_x0020’,
    ‘5|Status’,
    ‘5|Opmerkingen_x00200_datum’,
    ‘5|Categorie’,

    ];

  23. Hi, this is an awesome solution! I have implemented it successfully on my NewFrom and DispForm but there is one problem I can’t solve. On my DispForm I can’t get my html calculated columns to display in the tabs, they always stay above the tabs. Everything else works great. Do you know how I can move those onto the tabs?

    1. Sorry, I figured it out as soon as I posted this comment. I need to move the HTML calculated column web part after yours so it would render in the right order. Thanks!

  24. Hi Alexander,

    I’m loving the script. This is bringing “life” to the standard forms.

    I do have a question. I am able to run the script successfully on all three form pages (new, edit, display). However, I tried running the script on a MOSS site with the publishing feature turned on. The script works fine on the new and display pages. It doesn’t work so well on the edit page. When in edit mode, the script treats the editform.aspx page like a publishing page. It will display the publishing page menu.

    Is there any workaround for the editform.aspx page with the publishing feature turned on?

    Thanks.

  25. Hi Alexander,

    I’ve copied your most recent code and am using j-query 1.8.1 css and 1.4.2 js, but I’m having a problem with how it deals with if not all the required fields are filled in IF there are required fields in more than one tab. E.g. if I have req’d fields in tab 1 and tab 1 only and I dont fill them in, it works! Returns me to the page showing what fields are empty. But if I have req’d fields in tab 1 and 4, it does not work, the page doesn’t submit and I get an error in IE…

    Line: 3010
    Char: 3
    Error: Object doesn’t support this property or method
    Code: 0

    Line 3010 is var tabID = split[0];, similar to Pieter’s problem above, but I have checked what Pieter said was causing their problem, which was having a comma after the last value, but I do not have a comma after the last value. All the commas are in the correct place, see below… (I don’t expect you to read through this code, I have checked it and it always follows ‘2|Field’,’3|Field’ format)

    arrTab = [‘1|Goals_x0020_for_x0020_event’,’1|Start_x0020_Time’,’1|End_x0020_Time’,’1|Physical_x0020_Location’,’1|Local_x0020_Time_x0020_Zone’,’1|Virtual_x0020_Location_x0020__x0′,’1|Official_x0020_Event_x0020_Title’,’1|Event_x0020_Description’,’1|School_x0028_s_x0029_’,’1|Discipline’,’1|Target_x0020_Text_x0028_s_x0029_’,’1|Pre_x0020_or_x0020_Post_x002d_Ad’,’1|Opportunity_x0020_Units_x0020__x’,’1|Will_x0020_there_x0020_be_x0020_’,’2|Event_x0020_Host’,’2|Rep_x0020_Name’,’2|District_x0020_Manager’,’2|NPC’,’2|WileyPLUS_x0020_Account_x0020_Ma’,’2|SSC’,’2|District_x0020_Expense_x0020_Cod’,’3|Would_x0020_you_x0020_like_x0020′,’3|Preferred_x0020_Mentor’,’3|Mentor_x0020_Virtual_x0020_or_x0′,’3|Presentation_x0020_Details_x0020′,’3|Mentor_x0020_Confirmed’,’4|Pre_x002d_Event’,’4|Day_x0020_of_x0020_Event’,’4|Number_x0020_of_x0020_Attendees_’,’4|Other_x0020_Materials’,’4|Equipment’,’4|Post_x0020_Event’,’4|Online_x0020_Evaluation_x0020_Li’,’5|Marketing_x0020_Promotional_x002′,’6|Shipping_x0020_Address’,’6|Need_x0020_Materials_x0020_by’,’7|Feedback’];

    Any ideas please?

    Many thanks in advance,
    Ben

    1. Ah – it seems the it was happening because I was using fields-side-by-side as well, but in a different web part, so if you add the reference to the side-by-side js file and add your code into the web part for the tabs it works a treat 🙂 worth knowing!

  26. I don’t have other scripts in the page.
    the form also contains cascading dropdowns and calculated colums.
    do you need more details?
    does IE8 has problems with the css?

    Jan

    1. I have no problems with IE8 – have you modified the CSS?

      You mention cascading dropdowns – is it “my script”? if so, try to remove this script and see if they interfere with each other.

      Alexander

  27. i haven’t modified the css.
    without the script the dropdowns work fine.
    but with the script ie8 says in the statusbar at the bottom that there is a problem on the page and it doesn’t reload the page and the dropdowns.

    jan

  28. Hi,

    it’s a normal cascading dropdown you can add in list options.
    but i don’t think there is a problem with the dropdown.
    i will try some other themes tomorrow. maybe css is the problem.

    Jan

  29. Hi, thx for script))

    But i got problem with dropdown with more than 20 items. Items list appears not under dropdown but much lower on page 🙁

    Im using Sharepoint Foundation.

    Thanks))

    1. Hi,
      The issue with the dropdowns has to do with the strange way the control renders when there are more than 20 items. The control changes from a <select> to an <input> and the dropdown is created using a <div>. This <div> is rendered using the position the control had BEFORE the tabs where rendered.

      Another thing is that this <div> is SHARED between all lookup columns with more then 20 items in the same form.

      To overcome this issue you must “grab” the <div> when it renders and move it to the correct position…

      Look here for a similar issue regarding the controls in a rich text field

      Alexander

    1. Yes it works with SP 2010/Foundation well.
      Also works great with my custom controls ( with complex editor area ), multivalue controls. Haven’t tested with rich-edit yet.

      The only thing that i cant understand is whats going on with dropdowns… i’ve got this error again … dropdown list shows lower than it should… now not too low ( about 1 row lower ).

      Tabs are empty because :
      1. No existing fields added to fields array.
      2. Field display name used in array but field internal name needed.

  30. Hey, it’s me again, I have a new problem ! :s

    in my page list (allitem.aspx)
    I add a a ModifForm Element.
    This code doesn’t work now.

    I notice that It hasn’t table with class=”ms-formtable”
    So i Had the class element, but It doesn’t work again.

    If you have a solution …

    Thanking you

    1. Hi,
      This code is intended used i a standard list form. For any other use you have to do your own customization as each and every custom form will be different…

      Alexander

    2. Hi,

      first of all Happy New Year from Germany.

      I have the same problem. I moved from SP 2007 tp SF 2010. Now my CEWP seems not to work.

      I copied the links for the jquery script files to the v4.master and add the CEWP under the Listform WP.

      I debuged it with different alert´s and they all were hit but the Tabs didn´t show up.

      Also is the ms-formtable not on that site. Maybe this could be the error. But it is a standard SF list.

      Showing the tabs and also the hide and show Script did´t work. In 2007 they all worked.

    3. Hi,
      I have not yet ported this solutions to SP2010. I’m doing some investigation on the rich text fields and the “lookup with more than 20 items” problems, but i cannot promise anything. If i get it working, a dual (2007 and 2010) solution will be posted.

      Alexander

  31. Hi Alexander,

    We’re trying this on SharePoint Foundation and can’t get it to work as expected. We placed the links to the jQuery scripts in the v4.master page and removed it from the CEWP and it seems to pick it up fine without any javascript errors in the browser.

    The problem is that the tab list is showing as a list in CEWP below the rest of the form so I’m guess its an issue while looking for the .ms-formtable. I’ve searched through the HTML using SharePoint Designer 2010 and it doesn’t find it.

    Any suggestions?

  32. Can I use the ‘Tab’ form jquery and the Side-By-Side feature on the same form? I got the Tab piece working, then I tried to add side-by-side underneath (and above!) the tab CEWP and I don’t have the side-by-side or tabs working any more.

    Thanks in advance!

    1. Hi,
      All these scripts may interfere with each other – the two you have picked are the ones that messes the most with the form and i do not recommend using those together. If you do, you will have to dive into it, understanding what the scripts do and make the required modifications. I cannot make a generic solution as the combinations would be to many.

      Alexander

  33. Hello Alexander,

    We opened the page in Safari and discovered that the tabs are not working correctly. The fields are not rendered in the tabs.
    Do you have a solution?

    Kind regards,
    Mario

  34. Hello Alexander,

    We solved the Safari issue by replacing the following code snippet. If you have a better solution please advise.

    function init_fields(){
    var res = {};
    var b = “hello world”;
    $(“td.ms-formbody”).each(function(){
    var Original = $(this).html();
    if(Original.indexOf(‘FieldInternalName=”‘)<0) return;
    var nm = Original.substr(Original.indexOf('FieldInternalName='));
    nm = nm.substr(nm.indexOf('"')+1);
    nm = nm.substring(0,nm.indexOf('"'));
    res[nm] = this.parentNode;
    });
    return res;
    }

    Kind regards,
    Mario

  35. Hi,
    New problem …

    For example we have two lookup fields on unmodified form, first lookup on tab1, another on tab2. If we click for dropdown on lookup at any tab all will be fine, but on another tab it wont show up anymore. No errors in browser.

    1. Checked with clear list – same thing.
      Checked with another (custom)loookup field – same error.

      Seems like something wrong whith ShowDropdown func when it called by controls from different tables …

    2. Hi,
      There are some issues wit single lookup columns with more than 20 item (in IE only) and with rich text fields. I have no generic way to fix these issues, sorry

      Alexander

    3. :((
      Mabye this give You some idea of whats going on :

      I’ve placed to buttons, first calls ShowDropdown for lookup in tab1, second in tab2.

      So what i got : First button show dropdown as it should, second shows dropdown on the top of the page (just the end of dropdown visible because it appears under ribbon ). So dropdowns appears, but in wrong position ( seems like they even in right tab )

      Also another solution could be alternative way to build tabs – not moving them to another table, but to show/hide them depending on what tab is clicked … but im too weak in java script to perform this :'(

    4. Ok, we got 3 functions :
      1. ShowDropdown ( error appears at last line when target control must be focused )
      2. EnsureSelectElement
      3. FilterChoice

      FilterChoice sets position and z-order of our listbox, so here we can change it to our needs.

      But i cant understand how to override FilterChoice so control use our modified version of this function. Any suggestions?

      Idea is to place overrided version in CWEP in forms where tabs used to save original version.

  36. One more question :
    My page contains custom fields which refreshes page in some cases.
    When page refresh active tab becomes first one. Is there any solution for this?

    Thx))

    1. Ok… so … we can restore tab ID from cookie by adding something like this :
      $tabs.tabs(‘select’, Number($.cookie(“tabNumber”)));

      But how to ‘catch’ when tab clicked to save its id in cookies?

  37. Ooookkk… Thats was not easy but…

    We got core function FilterChoice and the only way i found to override it is to modify master page ( v4 for SP2k10 ).
    Its not the way i want it to be, but for now its the only way i found ( any ideas how to fully load core.js without modifying master page are more than welcome!! )

    So, modifying master page :
    1. Looking for SharePoint:ScriptLink language=”javascript” name=”core.js”
    2. Modifying to OnDemand=”False” Defer=”False”

    Now we easily can override our FilterChoice to our own in CWEP.

    Ill try to “correct” original FilterChoice and post here, but still hope someone help me, because all this sharepoint stuff totally blowing up my brains and im not js programmer at all 🙁

    1. For now i really need some help 🙂

      Visually it looks like listbox shows only on tab on which it was called for a first time, but i cant get where this happening …

      function FilterChoice(opt, ctrl, strVal, filterVal)
      {ULSsa6:;
      	var i;
      	var cOpt=0;
      	var bSelected=false;
      	var strHtml="";
      	var strId=opt.id;
      	var strName=opt.name;
      	var strMatch="";
      	var strMatchVal="";
      	var strOpts=ctrl.choices;
      	var rgopt=strOpts.split("|");
      	var x=AbsLeft(ctrl);
      	var y=AbsTop(ctrl)+ctrl.offsetHeight;
      	var elmWorkspace=document.getElementById("s4-workspace");
      	if(elmWorkspace)
      		y -=AbsTop(elmWorkspace);
      	var strHidden=ctrl.optHid;
      	var iMac=rgopt.length - 1;
      	var iMatch=-1;
      	var unlimitedLength=false;
      	var strSelectedLower="";
      	if (opt !=null && opt.selectedIndex >=0)
      	{
      		bSelected=true;
      		strSelectedLower=opt.options[opt.selectedIndex].innerText;
      	}
      	for (i=0; i < rgopt.length; i=i+2)
      	{
      		var strOpt=rgopt[i];
      		while (i < iMac - 1 && rgopt[i+1].length==0)
      		{
      			strOpt=strOpt+"|";
      			i++;
      			if (i < iMac - 1)
      			{
      				strOpt=strOpt+rgopt[i+1];
      			}
      			i++;
      		}
      		var strValue=rgopt[i+1];
      		var strLowerOpt=strOpt.toLocaleLowerCase();
      		var strLowerVal=strVal.toLocaleLowerCase();
      		if (filterVal.length !=0)
      			bSelected=true;
      		if (strLowerOpt.indexOf(strLowerVal)==0)
      		{
      			var strLowerFilterVal=filterVal.toLocaleLowerCase();
      			if ((strLowerFilterVal.length !=0) && (strLowerOpt.indexOf(strLowerFilterVal)==0) && (strMatch.length==0))
      				bSelected=false;
      			if (strLowerOpt.length > 20)
      			{
      				unlimitedLength=true;
      			}
      			if (!bSelected || strLowerOpt==strSelectedLower)
      			{
      				strHtml+="<option selected value=""+strValue+"">"+STSHtmlEncode(strOpt)+"</option>";
      				bSelected=true;
      				strMatch=strOpt;
      				strMatchVal=strValue;
      				iMatch=i;
      			}
      			else
      			{
      				strHtml+="<option value=""+strValue+"">"+STSHtmlEncode(strOpt)+"</option>";
      			}
      			cOpt++;
      		}
      	}
      	var strHandler=" ondblclick="HandleOptDblClick()" onkeydown="HandleOptKeyDown()"";
      	var strOptHtml="";
      	if (unlimitedLength)
      	{
      		strOptHtml="<select tabIndex="-1" ctrl=""+ctrl.id+"" name=""+strName+"" id=""+strId+"""+strHandler;
      	}
      	else
      	{
      		strOptHtml="<select class="ms-lookuptypeindropdown" tabIndex="-1" ctrl=""+ctrl.id+"" name=""+strName+"" id=""+strId+"""+strHandler;
      	}
      	if (cOpt==0)
      	{
      		strOptHtml+=" style="display:none;position:absolute;z-index:2;left:"+x+			"px;top:"+y+			"px" onfocusout="OptLoseFocus(this)"></select>";
      	}
      	else
      	{
      		strOptHtml+=" style="position:absolute;z-index:2;left:"+x+			"px;top:"+y+			"px""+			" size=""+(cOpt <=8 ? cOpt : 8)+"""+			(cOpt==1 ? "multiple="true"" : "")+			" onfocusout="OptLoseFocus(this)">"+			strHtml+			"</select>";
      	}
      	opt.outerHTML=strOptHtml;
      	var hid=document.getElementById(strHidden);
      	if (iMatch !=0 || rgopt[1] !="0" )
      		hid.value=strMatchVal;
      	else
      		hid.value="0";
      	if (iMatch !=0 || rgopt[1] !="0" )
      		return strMatch;
      	else return "";
      }
      
    2. Another func that can help :
      function EnsureSelectElement(ctrl, strId)
      {ULSsa6:;
      var select=document.getElementById(strId);
      if (select==null)
      {
      select=document.createElement(“SELECT”);
      ctrl.parentNode.appendChild(select);
      select.outerHTML=””;
      FilterChoice(select, ctrl, ctrl.value, “”);
      }
      return document.getElementById(strId);;
      }

    3. Well, some progress :

      I’ve override two functions ( only one need to solve problem with
      “disappearing” lookup element )

      First :
      EnsureSelectElement
      add $(select).appendTo(ctrl.parentNode); right before return select;

      This works, but still got problem : first called dropdown in tab table will not hide on click event. Any ideas? And one more thing, i’ve removed name tag in outerHTML of select object, i have no idea why, but if it is used then in browser it will get “WPQ4” variable, which i dont know where and what is it …

      Second :
      FilterChice
      add – 30 to y variable.

      Well, this fixes vertical position problem. But i use constant value so the question is how to get tabs area height dynamically?

    4. Hi,
      I finally got to look at this one. I have located the “fix” and will post another “version” of this article within a week. This article will address the “lookup with more than 20 items” and Rich text fields problems.

      For now you can fix the lookup problem by adding one line to the function “EnsureSelectElement” and include it in your existing code (do NOT edit it in core.js):

      function EnsureSelectElement(ctrl, strId){
      $("#"+strId).remove();
      	var select=document.getElementById(strId);
      	if (select==null)
      	{
      		select=document.createElement("SELECT");
      		ctrl.parentNode.appendChild(select);
      		select.outerHTML="<select id=""+strId+"" ctrl=""+ctrl.id+"" class="ms-lookuptypeindropdown" name=""+strId+"" style="display:none" onfocusout="OptLoseFocus(this)"></select>";
      		FilterChoice(select, ctrl, ctrl.value, "");
      	}
      	return document.getElementById(strId);;
      }
      

      Line 02 is added to force the recreateion of the “_Select” each time it is used.

      Stay tuned for the updated version which no longer needs to load jQueryUI-library.

      Alexander

  38. I simply chose to override FilterChoice like ian suggested and this worked:

    function FilterChoice(opt, ctrl, strVal, filterVal) {
                    ...	
                    var offSet = $(ctrl).position();
    	var x = offSet.left;
    	var y = offSet.top+15;
                    ...
    }
    

    This will fix the list box with more than 20 items moving. I haven’t looked into the other issues as this hasn’t affected me.

    1. Greate! Works on SP 2010 🙂

      If someone got problem in EnsureControls – just remove name tag.

      Still little problem : some fields not getting focus, so dropdown not hiding on lose focus .. will try to see whats the problem is ..

  39. Hi Alexander. Is there any way to combine this solution with your Fields Side by Side solution? I tried to put both scripts on my DispForm and it “worked” but with undesireable results.

    For example: the side by side fields picked up strange styles, and they appear on every tab instead of just after the single appended field that I specified in the CEWP.

    For me it would be the ultimate in control over these form pages.

    1. Hi,

      I’ve successfully implemented the TabsInForm and SideBySide Scripts on a number of pages and so far have only discovered two minor problems, first when you have a mandatory field you have to click “OK” twice to save the form, secondly, when you have a large lookup field the dropdown will open outside the side by side frame.

      You can even combine these scripts with the “BuildHeadingsFromArray” but that is not very reliable and sometimes fails for reasons I have not yet understood.

      The trick to get this working is:

      – TabsInForm comes first
      – FieldsSideBySide is second
      – Create “dummy” fields depending on the number of your tabs

      Assign the fields to your tabs in “TabsInForm” and then attach the fields with “FieldsSideBySide” to the dummy fields, making them the topmost fields per tab.

      A single field, e.g. standard input field, will define the width of the box, short fields will not always expand to the full width, that’s were you might experience messed up styles.

      If you feel the style is too messed up insert a standard field to force the other ones to expand, I haven’t tried it but I think even a hidden field will do the trick.

      If you have more questions feel free to ask.

      Chris

    2. Thanks Chris, I need to try that out soon. By “dummy field” do you mean create an actual column?

      Do you ever have fields that you’ve specified on one tab repeat on multiple tabs?

    3. Yes, “dummy fields” refer to actual columns that I hide with a small “hide field” script. Regarding the fields, no, I only use them once and have never found them to repeat on other tabs.

      Chris

  40. Alexander, in the new solution, can you turn off the Attachments field somehow? I’ve tried commenting out the lines, deleting the lines, renaming the tab, etc. but I can’t successfully remove it. Thanks!

  41. HI guys,

    I am not sure if i am posting here would help me or need to post somewhere else..
    i need a help i am new to sharepoint and have taken a initiative to build a form for handling a project requests
    a kind of tab form similar to an example above,
    1st Tab has RDD form
    2nd Tab with TDD form
    3rd Tab with Testing Form
    4th Tab with Project feedback form
    and once they enter all the detials it should be stored in a repository where i could go look out for…

    Needed you help guys……

    thanks in advance

  42. I followed the same steps but fields are not hiding after clicking the tabs .its showing all the fields if i am clicking on any tab

    Nees help on this!

  43. Here is my code

    .ms-dtinput {
    FONT-SIZE: 0.7em
    }
    .ms-dttimeinput {
    FONT-SIZE: 0.7em
    }Tab 1
    Tab 2
    Tab 3
    Attachments

    // Array of all fields – format: tabID|FieldInternalName
    arrTab = [‘1|Title’,’1|field1′,’1|field2′,
    ‘2|field3′,’2|field4’,
    ‘3|field5′,’3|field6’];

    // Initiate all the fields
    fields = init_fields();

    // Add the “tabs” to the formtable
    $(“#tabs”).insertAfter(‘.ms-formtable’).tabs();
    // Loop trough all fields and move them to the right tab
    $.each(arrTab,function(idx,item){
    var split = item.split(‘|’);
    var tabID = split[0];
    var fieldName = split[1];
    if(fields[fieldName]!=undefined){
    currField = $(fields[fieldName]);
    currField.appendTo(‘#tabs-‘+tabID);
    }
    });

    // Are there any required fields not filled? – select the tab containing the first field
    selectTabOnFormValidation(false);
    function selectTabOnFormValidation(preSave){
    var formvalidationTab = ”;
    // Formvalidation – find the first tab with empty required fields
    $.each(arrTab,function(idx,item){
    var split = item.split(‘|’);
    var tabID = split[0];
    var fieldName = split[1];
    currField = $(fields[fieldName]);
    // Handles DateTimeField (empty field validation is performed without page reload)
    if(currField.find(“SPAN[ID*=’_DateTimeField_’]”).length>0){
    if(currField.find(‘input:first’).val()==” && preSave){
    formvalidationTab = tabID;
    }
    }
    if(formvalidationTab == ” && currField.find(‘.ms-formbody span.ms-formvalidation’).length>0){
    formvalidationTab = tabID;
    }
    });
    // Select the first tab containing an empty required field
    if(formvalidationTab!=”){
    $(‘#tabs’).tabs(‘select’, formvalidationTab);
    }
    }

    // Move the Attachment’s to the last tab
    $(“#idAttachmentsRow”).appendTo(‘#tabs-4’).find(‘.ms-formlabel’).attr(‘width’,’165px’);

    // function – to make “object” of all tr’s in the form
    function init_fields(){
    var res = {};
    $(“td.ms-formbody”).each(function(){
    if($(this).html().indexOf(‘FieldInternalName=”‘)<0) return;
    var start = $(this).html().indexOf('FieldInternalName="')+19;
    var stopp = $(this).html().indexOf('FieldType="')-7;
    var nm = $(this).html().substring(start,stopp);
    res[nm] = this.parentNode;
    });
    return res;
    }

    // Catch "empty field validation" on date and time columns
    function PreSaveAction(){
    selectTabOnFormValidation(true);
    return true;
    }

  44. Hi
    I am getting error at the place where it refers to “ms-formtable”. Kindly let me knowif this is part of any library you have included or default SharePoint element.

    1. It is a completely new solution that also gives you tabs in forms. I cannot guarantee that this will fix your problem, but this current tabs in SharePoint forms is more or less abandoned.

      If you go with the DFFS solution (latest version) you are more likely to get help.

      Alexander

  45. Hi Alex,
    First of all your blog is amazing.

    I followed your steps,
    1. Created a CEWP at the end and added your code using SP designer. I stored TabsForSharePointForms.js file in Site Assets library.

    But somehow the tabs are not showing up.

    I am trying out tabs in a small list before implementing on a larger scale.

    My list has following columns.
    Title, PID, Release, App, Disposition, App Status,LPM and APM

    <![CDATA[​

    var tabConstructor = {tabs:[
    {name:’General’,fields:[
    ‘PID’,’App_x0020_Status’,
    ‘Title’],mouseOver:’This is the first tab’,tabStyle:”,clickFunction:”},

    {name:’Release’,fields:[
    ‘Release’,
    ‘App’],mouseOver:’This is the second tab’,tabStyle:”,clickFunction:’secondTabClick(this)’},

    {name:’Disposition’,fields:[
    ‘Title’],mouseOver:’This is the third 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); ]]>

    Thanks again
    John

Leave a Reply