Showing or hiding form fields based on membership in a SharePoint group

This solution will let you control the visibility of individual fields in NewForm, DispForm and EditForm based on membership in a specific SharePoint group.

This is an updated version of this post.

I have updated it to support newer versions of jQuery, and to use spjs-utility.js.

Note:
If you plan to hide empty fields in NewForm or EditForm, these fields cannot be required to contains information as the user would not be able to save the form – and as the field is invisible, the user will not see the empty field validation message.
How to set up this solution:
  • Download the latest version of spjs-utility.js, and save it locally. You can put it in a folder created using SharePoint designer, or in a shared document library where all users have read permission.
  • If you prefer to use a local version of jQuery, get it here and save it alongside the file above.
  • Add the below code to a CEWP or a HTML form web part, and update the script src to reflect your local copy of spjs-utility.js and jQuery.

[javascript]
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="http://spjsfiles.com/SharePoint%20JavaScripts/spjs-utility/07.03.2012/spjs-utility.js"></script>
<script type="text/javascript">

var fields = init_fields_v2();
// The group ID
var groupId = 146; // This number must be changed to match your local group ID
// Show this array for members in the above group
var arrToShowForMembersInTheGroup = [‘Title’,’ForOwnersOnly’];
// And this array for everybody else
var arrToShowForEverybodyElse = [‘Title’];

var isInGroup = isCurrentUserInGroup(groupId,false);
if(isInGroup){
hideAllButThese(arrToShowForMembersInTheGroup);
}else{
hideAllButThese(arrToShowForEverybodyElse);
}

/************************************
Do not edit below this line
************************************/
function isCurrentUserInGroup(groupId,returnGroupName){
var ui, userLoginName, ug, result;
ui = getUserInfo_v2(_spUserId);
userLoginName = ui[‘Name’];
ug = getGroupCollectionFromUser(userLoginName);
result = false;
$.each(ug,function(i,obj){
if(obj.groupId===groupId){
if(returnGroupName){
result = obj.groupName;
}else{
result = true;
}
return false;
}
});
return result;
}

function getGroupCollectionFromUser(userLoginName,userListBaseUrl){
if(userListBaseUrl===undefined){
userListBaseUrl = L_Menu_BaseUrl;
}
var result = [];
spjs_wrapSoapRequest(userListBaseUrl + ‘/_vti_bin/usergroup.asmx’,
‘http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromUser’,
‘<GetGroupCollectionFromUser xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/"><userLoginName>’ + userLoginName + ‘</userLoginName></GetGroupCollectionFromUser>’,
function(data){
$(‘Group’, data).each(function(idx, itemData){
result.push({"groupId":parseInt($(itemData).attr(‘ID’),10),"groupName":$(itemData).attr(‘Name’)});
});
});
return result;
}

function hideAllButThese(arrToShow){
$.each(fields,function(fin){
if($.inArray(fin,arrToShow)===-1){
$(fields[fin]).hide();
}else{
$(fields[fin]).show();
}
});
}
</script>
[/javascript]

How to configure the solution

Find the group ID of the group you want to use by going to Site Settings > People and Groups, select your group and look at the URL:
http://www.contoso.com/_layouts/people.aspx?MembershipGroupId=6

Change the FieldInternalNames in the array “arrToShowForMembersInTheGroup” and “arrToShowForEverybodyElse” to match your setup.

Look here to learn how to manually retrieve FieldInternalNames, or here to find a solution that shows you all in one go.

If you have trouble, post a comment below.

Alexander

33 thoughts on “Showing or hiding form fields based on membership in a SharePoint group”

  1. Alexandar, as always you amaze me with your tips and tricks, what a truely excellant way to hide sections, thanks for this it will come in great for future 🙂

  2. Now if the same could be done for showing or hiding views based on membership that would be great.

    I realize neither hiding fields nor hiding views is a particularly good security mechanism – but it is an easy way to stop the wrong people from making a mistake or editing what they are not supposed to.

  3. Carlos, here’s what I’m doing to solve the problem regarding limiting views.
    Our situation is that we have one list of all relevant data but would prefer to show only those parts of the list to folks who belong to relevant groups. So, System=1 items would only be shown to GroupA, System=2 items to GroupB, etc.
    I construct a querystring parameter that lists all the groups to which the current user belongs, then correlate those groups to a similar array of systems, to construct the final URL:
    …your site…/AuditTest.aspx?FilterName=System&FilterMultiValue=CSSx;GFMSx
    That would show only items where system is either ‘CSSx’ or ‘GFMSx’.

  4. Alexander, this works perfectly – I love it.

    I’ve been playing around to see if I could make the code support three group – not just two (in the group, or not in the group).

    I have a list with 10 items, where Group1 should see all 10 items, Group2 see 5 items and Group3 see 1 items. Having the trouble with Group3. 🙂 Any solution based on your java-code?

  5. Hello Alexander. The suggestion you provided for 3 groups and the show hide option is for sharepoint 2010. Do you have a solution using this posting and multiple GroupID’s? I am using SharePoint 2007 and this works great for us, we just need to expand and provide multiple groupID functionality.

    1. This would be a great enhancement if this can handle multiple IDs. Where there would be a case statement depending on the ID of the membership. I was wondering if this is possible? I’m using SharePoint 2010.

  6. Hello Adam, look at Jacob’s post above mine. Alexander responded to his question and the link provided to Jacob reflects Sharepoint 2010. It may just resolve your issue. I hope Alexander will have a solution for us 2007 users.

  7. Hi Alex, excellent solution here. Quick question, is there a way specify a group to be able to view all fields (and not manually enter each field especially if you have more than 50 fields)? So for instance group 1 has access only to certain fields but group 2 can have access to all fields.

  8. Will this work with a SharePoint calendar? I am trying to hide certain unrequired fields I’ve added for events for certain groups on the NewForm.aspx and EditForm.aspx in Designer.

  9. Hi, this is fine solution for developer, I used similar approach many times. But if user is less qualified than developer, it is difficult to implement such behavior. That is why we developed our SharePoint Forms Designer (http://spform.com), it allows easily create custom forms just with drag&drop for specific SharePoint groups, so different groups works with different form presentations.

  10. Hi, I have trouble because, i don’t have the permissions to capture the profile of a user. Can you tell me how to obtain the information without permission?

  11. Because, with the function getUserInfo_v2 I have successful to capture my user info, but the only thing i can’t get is the group

    Thanks for the supporting, this blog is awsome.

  12. This looks like it’s exactly what I’m looking for, but jsut doesn’t work for me. I configured with my environment-specific details as described above, but the specified fields aren’t shown/hidden.

    Throwing in some debug code, I can see that the following line is reached, but nothing thereafter. Any ideas?

    $.each(fields,function(fin){

  13. Alex – Finally go this solution working, thanks for posting this as the other jquery solutions I looked at I couldn’t get to work. Question is how to make this work for multiple Groups. I looked at the link you put to the tabbed solution but I’m still working with 2007. I need to have Field1 and Field2 visible for GroupID 1 or GroupID2 membership, but only Field1 visible for all others. I tried setting new variables and and a new array but couldn’t get it to work. Any help is appreciated.

    1. Sorry for the late reply, if you are still looking for a solution, try this (not testes – written freehand here):

      // Format = {groupId1 : array of fields, groupId2 : array of fields}
      var showFieldsByGroupObj = {"1":["Field1","Field2","Field3"],"2":["Field4","Field5","Field6"]}
      var userInfo = getUserInfo_v2(_spUserId);
      var groupCollection = getGroupCollectionFromUser(userInfo.Name);
      
      $.each(groupCollection,function(i,obj){
      	if(showFieldsByGroupObj[obj.groupId] !== undefined){
      		$.each(showFieldsByGroupObj[obj.groupId],function(i,fin){
      			$(fields[fin]).show();
      		});
      	}else{
      		$.each(showFieldsByGroupObj[obj.groupId],function(i,fin){
      			$(fields[fin]).hide();
      		});		
      	}
      });

      Alexander

  14. Hi Alexander

    My SharePoint foundation 2010 site is using Custom Master Page. On the top navigation bar, it is showing all the sites link even though user does not have access to that site. Once user clicks on the site link, it is giving “Access Denied” error. If user doesn’t have access to a site then he should not see this link. How can I make these top navigation links permission driven?

    Thanks,
    Sam

    1. Hi,
      SP 2013 is more asynchronous than SP 2010 was. I have not had the time to write about it yet, but you must wait for the form to properly render before running the code. You can try wrapping the code in a “timeout” like this:

      setTimeout(function(){
         // Add the code here
      },100);
      

      Alexander

  15. Hi Alexander,

    Is it possible to alter the script so that it recognizes members within a nested group? We manage most of our groups in Active Directory and either grant permissions to the group directly or nest them within another SharePoint group. With this script, the user is only recognized as a member of the group if they are added individually to the SharePoint group.

    Thanks in advance for any guidance you can provide!

    Michelle

  16. Alexander, (and a warning to others)

    We’ve been using a similar technique to hide some fields from some users. Our mechanism is different in that it checks whether the user is one of a particular list (based on _spUserId), though I’m going to transition to your group-base approach. However, we recently ran in to a problem which took days to get to the bottom of and I thought I’d share it to avoid any pain for others.

    Having Javascript at the client (browser) end hide fields is great but if the field in question is mandatory, then SharePoint doesn’t “know” that the field is hidden. If you don’t give the field a default value (and the user can’t enter a value because the field is hidden) then, when the form is submitted, SharePoint will reject the submission and attempt to display an error message to the user. However the user won’t be able to see the error message because it is written in the HTML as a child element of the field and therefore gets hidden when the form is redisplayed after the post.

    Usually you would pick this up during your initial development and testing and ensure that the field has a default value. However we ran into a situation where something unexpected changed in a production system and the field no longer had a default value. The submission failed and all the end user saw was the same for spat back at them with all there data in it but no explanation as to why SharePoint would not accept it.

    Since it had worked for years and we couldn’t identify anything that had changed, it took days for us to realise that the cause was this hidden field and the lack of a default value. Trap for young players!!

    In case you’re wondering what changed for us, it was this:

    The field in question was a combobox filled with lookup items from another SharePoint list. It turns out that for Internet Explorer only, if the lookup list has more than 20 items (may be 20 or more … not sure) in it then SharePoint uses an INPUT element rather than a SELECT element in the HTML. As a SELECT element, all browsers automatically select the first item in the list as the default value and we have no problem. But, as an INPUT element, Internet Explorer does NOT select a default value. As a consequence, users who could not see the field could no longer submit the form.

    As you can imagine, tying this back to someone having added a couple of extra items to a lookup list took forever.

    Watch out!!

  17. Hi Alex,

    I have been trying to get a solution to work in SP2013 for a couple weeks now. I have combined a solution for the SP2013 timeout issue that you provided in a different conversation along with the above code and now ALL referenced fields are hidden for all permission groups. All of my other efforts failed and all fields were still available for editing to all permission groups. The timeout solution mentioned above included.

    Would you mind looking at the code below and let me know what is wrong please? Since this script produced a change (just not the change I wanted), I figured I must be close. Thank you so much!

    .ms-RadioText label{
    white-space:nowrap;
    }
    function init_sp2013FormReady(){
    if($(“td.ms-formbody span[id*='”+_spPageContextInfo.pageListId.replace(/\{|\}/g,””)+”‘]”).length>0){
    setTimeout(function(){
    init_sp2013FormReady();
    },10);
    return;
    }else{
    sp2013FormReady();

    }
    }

    function sp2013FormReady(){
    // The form is ready – add the code here
    }

    var fields = init_fields_v2();
    // The group ID
    var groupId = 763; // This number must be changed to match your local group ID
    // Show this array for members in the above group
    var arrToShowForMembersInTheGroup = [‘Title’,’Check%5Fx0020%5FBox’,‘ColumnText’];
    // And this array for everybody else
    var arrToShowForEverybodyElse = [‘Title’,‘ColumnText’];
    var isInGroup = isCurrentUserInGroup(groupId,false);
    if(isInGroup){
    hideAllButThese(arrToShowForMembersInTheGroup);
    }else{
    hideAllButThese(arrToShowForEverybodyElse);

    /************************************
    Do not edit below this line
    ************************************/
    function isCurrentUserInGroup(groupId,returnGroupName){
    var ui, userLoginName, ug, result;
    ui = getUserInfo_v2(_spUserId);
    userLoginName = ui[‘Name’];
    ug = getGroupCollectionFromUser(userLoginName);
    result = false;
    $.each(ug,function(i,obj){
    if(obj.groupId===groupId){
    if(returnGroupName){
    result = obj.groupName;
    }else{
    result = true;
    }
    return false;
    }
    });
    return result;
    }
    function getGroupCollectionFromUser(userLoginName,userListBaseUrl){
    if(userListBaseUrl===undefined){
    userListBaseUrl = L_Menu_BaseUrl;
    }
    var result = [];
    spjs_wrapSoapRequest(userListBaseUrl + ‘/_vti_bin/usergroup.asmx’,
    ‘http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromUser’,
    ‘’ + userLoginName + ‘’,
    function(data){
    $(‘Group’, data).each(function(idx, itemData){
    result.push({“groupId”:parseInt($(itemData).attr(‘ID’),10),”groupName”:$(itemData).attr(‘Name’)});
    });
    });
    return result;
    }
    function hideAllButThese(arrToShow){
    $.each(fields,function(fin){
    if($.inArray(fin,arrToShow)===-1){
    $(fields[fin]).hide();
    }else{
    $(fields[fin]).show();
    }
    });
    }

    init_sp2013FormReady();

  18. Hi Alexander –

    Thank you for your quick reply!

    I’ve updated the internal field so there are no spaces and verified it is correct in the code, but it is still not working.

    Before my previous comment, I uploaded the js files to a document library and referenced them in the code (I changed the verbiage on my example above to remove any reference to our company) and I placed this code in a ScriptEditor as the last object, so I don’t believe these are the issues, but maybe there is something wrong here?

    And since your reply, I updated the quotes of the internal field names to be ‘ and ‘ (opened and closed vs most of them were closed) and still nothing.

    Since the result is that ALL fields are hidden including the version, created by and modified by fields being empty, mean there could be something wrong with the form coding piece or placement of the embedded code within the timeout code?

    Any further ideas would be greatly appreciated!!!

    Once this is working, I will be utilizing this feature with linked forms and wondering if the ScriptEditor needs to be placed between the two linked form webparts or that it should always be at the end.

    Thanks again,

    Chris

Leave a Reply