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

05.07.2012 An updated version can be found here


This article describes how to show or hide a form field based upon membership or not membership in a SharePoint group.

This solution uses the script created in this article to access the user info on the current user. It is a precondition that you read the previous article before continuing with this one.

As always we begin 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 subsite named “test” with a subsite named “English” with a document library named “Javascript”):
IMG

I use some code (”interaction.js” and stringBuffer.js”) created by Erucy and published on codeplex.

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 file “AccessUserProfileInWSS.js” is created in the previous article.

The sourcecode for the IsUserInGroup.js” looks like this:

/* isUserInGroup - Used to check if a user is in a spesific SharePoint-group
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * LastMod: 20.09.2009
 * ---------------------------------------------

Use:
 * userId : Only supplied if the user to query is not the logged in user.
 * groupId : ID of the group to check membership in
 * returnGroupName (true) : Returns the groupName of the group if the user is in it - returns false if user is not in the group.
 * returnGroupName (false) : Returns "true" or "false"
 *
 * Refer these scripts:
 *  interaction.js // Erucy - http://spjslib.codeplex.com
 *  stringBuffer.js // Erucy - http://spjslib.codeplex.com
 *  jQuery // http://jQuery.com
 *  AccessUserProfileInWSS.js // https://spjsblog.com/2009/09/20/accessing-user-profile-information-in-wss-3-0-with-javascript/
*/

function isUserInGroup(UserId,groupId,returnGroupName){
if(UserId=='')UserId = _spUserId;
var ui = getUserInfo(UserId); 
var userLoginName = ui['Name'];
var ug = getGroupCollectionFromUser(userLoginName);
	for(i=0;i<ug.length;i++){
	var id = ug[i].split('|');
		if(id[0]==groupId){
			if(returnGroupName){
				return id[1];
			}else{
				return true;
			}				
		}
	}
return false;
}

function getGroupCollectionFromUser(userLoginName){
	var result = [];
	innerPost(wsBaseUrl + '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($(itemData).attr('ID') + "|" + $(itemData).attr('Name'));
			});
		});
	return result;
}

function init_fields(){ // Modified version og the function created by Erucy - http://spjslib.codeplex.com/
  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;
}

Save this as a text file and rename to “IsUserInGroup.js”, then upload to the library as shown above.

Then you add a CEWP below the list form in NewForm (and if you like – DispForm and EditForm) with this sourceCode:
IMG

CEWP sourcecode:

<script type="text/javascript" src="/test/English/Javascript/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/interaction.js"></script>
<script type="text/javascript" src="/test/English/Javascript/stringBuffer.js"></script>
<script type="text/javascript" src="/test/English/Javascript/AccessUserProfileInWSS.js"></script>
<script type="text/javascript" src="/test/English/Javascript/IsUserInGroup.js"></script>
<script type="text/javascript">
fields = init_fields();
var arrToShowOnlyForOwnerGroup = ['OnlyForOwnerGroup1','OnlyForOwnerGroup2']; // FieldInternalNames
var isInGroup = isUserInGroup('',38,false)
if(!isInGroup){
	for(i=0;i<arrToShowOnlyForOwnerGroup.length;i++){
		$(fields[arrToShowOnlyForOwnerGroup[i]]).hide();
	}
}
</script>

The variable “arrToShowOnlyForOwnerGroup” is an array of “FieldInternalNames” of the fields to hide for “non owners”. Look here for a quick guide for obtaining the “FieldInternalName” of your fields.

“38” is the ID of the group “Owners”. You find your group ID by looking at the URL under Site Actions > Site settings > People and Groups > your group – look at the URL:
/_layouts/people.aspx?MembershipGroupId=38.

For group members the NewForm looks like this:
IMG

For all others the NewForm looks like this:
IMG

Just remember not to set the field as required from SharePoint UI – if the user cannot see the field he can not fill it! To learn how to add dynamic required fields – se fieldutility.js from Erucy on codeplex.

Alexander

65 thoughts on “Showing or hiding list fields based on membership in a SharePoint group”

  1. I don’t know If I said it already but …This blog rocks! I gotta say, that I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say I’m glad I found your blog. Thanks, 🙂

    A definite great read..Jim Bean

  2. I have been able to hide some fields in my forms successfully based on membership.

    How would I go about using similar code to make the fields read only based on membership?

    Thank you, and keep up the good work!

  3. Figured out how to disable fields based on membership.

    I replaced the line in your code that hid the field

    $(fields[arrToShowOnlyForOwnerGroup[i]]).hide();

    with a line that disabled the field, based on information that I found on the jQuery site.

    $(fields[arrToShowOnlyForOwnerGroup[i]]).attr(“disabled”,”disabled”);

  4. I am just learning JavaScript, so forgive me for my basic questions. I uploaded all of the js files, changes the “listname” and added the js include files to my CEWP. I was then interested in using your code to either show/hide an entire HTML table on a page. My goal is to show the table only for an administrator, so I added the following code in the CEWP:

    $(document).ready(function(){
    $(‘.ms-test’).hide();
    var isInGroup = isUserInGroup(”,5,false)
    if(isInGroup){
    $(‘.ms-test’).show();
    }
    });
    

    Then added the following HTML later in the page:

    Hello World

    When I log in as an administrator (Group = 5) then the table appears correctly. However, when I log in as someone with “Read Only” access, the user name and password prompt appears 4 times. If I select “OK” 4 times, then I can eventually access the site. The HTML table is then hidden.

    Do you have any suggestions why the login prompt keeps reappearing for someone with “Read Only” access?
    Thanks so much.

    1. Hi,
      This may have to do with them not having permission to browse the “user information list”, but I’m not sure. Can you check the permission level for the “reader” if the “Browse User Information – View information about users of the Web site.” is checked?

      Also you can try to alert the “isInGroup” and see if it returns any value (true or false).

      Alexander

      PS:I moved your comments to the correct article.

  5. The above post coverted my HTML to “Hello World”. Basically, here’s my HTML, without the

    <table style="width: 100%" class="ms-test">
     <tr>
      <td>Hello World</td>
     </tr>
    </table>
    
  6. Hi, this may seem like a simple question, but I’ve tried to use the code above with little success. I pass in what seems to be the right list guid but no matter who I log in as, it says that the user is not a member of the group (I put in alerts in the scripts).

    Can someone point me in the right direction as to how to get the right guid?

  7. I’m having problems getting this to work. When I run it and I try to return ui.Name from the isUserInGroup I get an error “User with ID undefined not found”. It appears that the UserID cannot find _spUserId, or anything hard coded into it.

    Thoughts?

  8. Hi I’m having problems getting this to work as well.
    I’ve used alerts to determine that the group membership is definately working. The script seems to work right up to the point where it needs to hide the fields. It just won’t hide them. I’ve definately used the correct FieldInternalNames. I just can’t figure out why this won’t work. I’ve also only used the default Form and haven’t customized the form. What else can I check that might stop it from actually hiding the fields?

    Thanks.

  9. Hi,

    I have it work for 2 columns and one group.

    Tis is what I have for the first group:

    fields = init_fields();

    var arrToShowOnlyForOwnerGroup = [‘HR’,’Finance’]; // FieldInternalNames

    var isInGroup = isUserInGroup(”,3,false) //Find Groupnumber to show the Field to

    if(!isInGroup){

    for(i=0;i<arrToShowOnlyForOwnerGroup.length;i++){

    $(fields[arrToShowOnlyForOwnerGroup[i]]).hide();

    }

    }

    But I would like to hide several columns for different groups.
    So for example:

    What do I need to only show field 'Status' to group 6, and hide it for everyone else?

    1. Hi,
      Add this code to your CEWP, replacing the code you have there now:

      var arrAll = getArrOfAllGroups();
      if($.inArray('3',arrAll)>-1){
      	// Do something
      	alert("Is in group 3");
      }
      
      if($.inArray('146',arrAll)>-1){
      	// Do something
      	alert("Is in group 146");
      }
      
      
      function getArrOfAllGroups(){
      var arrOfAllGroups = [];
      	var ui = getUserInfo(_spUserId); 
      	var userLoginName = ui['Name'];
      	var ug = getGroupCollectionFromUser(userLoginName);
      	$.each(ug,function(i,val){
      		var groupId = val.split('|')[0];
      		arrOfAllGroups.push(groupId);	
      	});
      	return arrOfAllGroups;
      }
      

      Note that the group id is passed as string in the $.inArray-function.

      Alexander

    1. Like this:

      if($.inArray('3',arrAll)==-1){
      	// Do something
      	$(fields['PutTheFieldInternalNameHere']).hide();
      }
      

      Note the modification in line 1: ==-1
      This requires that the fields = init_fields() function is called above.

      Alexander

  10. I’ve tried several things, but I can’t get is to work.
    The column disappears for everyone.

    To bad, because I liked this option.
    I quess I did something wrong.

  11. Thanks for the change. It seems to work.
    Unfortunately when you upload a document directly from MS Word, you get to see the hidden field.
    Apparently with this way the user groups residing on sharepoint are not used when directly uploading to it.

    1. Hi,
      When uploading files, you enter the EditForm.aspx. It should not be any problem applying this code to this form.

      Please provide some more details.

      Alexander

  12. I would like to hide several field for different groups.
    So for example:

    1)hide same field (4) for different groups.
    2) and another 3 filed for another different groups.
    3) other field for other groups.

  13. Hi,

    I have a problem, the function init_fields(). When I make an alert on one field , I have “undefined”.

    ex:

    <script type="text/javascript" src="/SI/javascript/IsUserInGroup.js"></script>
    <script type="text/javascript">
    
    	var fields = init_fields();
    alert(fields[2]);
    </script>
    

    I try with a internalname of field too. same problem.. have you got a solution ? maybe its because i use script jquery 1.4.3 ?
    thanks

  14. Hi Alexander,

    I’ve uploaded all of the scripts to my document library and changed the source links, column names and group ID in the CEWP. It’s not working though. Are you able to tell where I am messing up?

    Thanks!
    Katie

    fields = init_fields();
    var arrToShowOnlyForOwnerGroup = [‘Student Name’,’Student ID’]; // FieldInternalNames
    var isInGroup = isUserInGroup(”,7711,false)
    if(!isInGroup){
    for(i=0;i<arrToShowOnlyForOwnerGroup.length;i++){
    $(fields[arrToShowOnlyForOwnerGroup[i]]).hide();
    }
    }

  15. Hi Alexander, Sorry — I did use the internal names by viewing the newform.aspx source. I do have another CEWP with a script on the page to hide a couple of fields. Would multiple scripts conflict?

  16. I love this solution and have used it a few times. Now what I would like to do with it is:
    If “ChoiceField” = Choice 1, then hide OtherFields from Group 1

    How would I do that?

  17. My choice field is actually a checkbox/multi-select. I saw your other post regarding on the multi-select, but I haven’t been able to piece the 2 together. Can you help with the code? I need to show 2 fields to a group if only the “DEV” option is selected. Any other combination of selections, the 2 fields need to be hidden. Thanks!

    1. Hi,
      If you in line 30 in the codeblock from this link wrap it like this:

      var isInGroup = isUserInGroup('',38,false);
      if(isInGroup){
      arrToShow = arrToShow.concat(arrRed);
      }else{
      arrToHide = arrToHide.concat(arrRed);
      }
      

      You will of course have to include references to the scripts from this article to have all the “infrastructure” in place.

      Alexander

  18. Forgive me, I am fairly new to Javascript and so far, I’ve been able to use your code mostly as is with only small modifications. This one however, has got me.

    I have your original post (dynamic display with multi-select) working perfectly and I’m working off it until I get it perfected to meet my needs. I’ve also got the code from this post working perfectly (hiding fields based on membership). As soon as I try to combine, I start having issues. This is as far as I have gotten with combining without it breaking:
    var isInGroup = isUserInGroup(”,96,false);
    if(objChecked[‘Red’]){
    if(isInGroup)
    {
    arrToShow = arrToShow.concat(arrRed);
    }
    }
    else{
    arrToHide = arrToHide.concat(arrRed);
    }

    I’m hoping to accomplish this:
    If Red is selected AND i AM in group 96, I can see arrRed (Approval fields)… If Red is selected and I am NOT in group 96, I cannot see arrRed. That is not working with the code above. Can you help me?

    1. Sorry, but i get a lot of questions and cannot quite manage to follow up on all…

      It looks like a simple syntax error – try it like this:

      if(objChecked['Red']){
      	if(isInGroup){
      		arrToShow = arrToShow.concat(arrRed);
      	}else{
      		arrToHide = arrToHide.concat(arrRed);
      	}
      }
      

      Alexander

    1. Hi,
      This solution uses some libraries that are not created by me. In interaction.js you have to change all occurrences of

      $('z\:row', data)
      // and
      $('rs\:data', data)
      

      like this:

      $(data).find("[nodeName='z:row']")
      // and
      $(data).find("[nodeName='rs:data']")
      

      This has to do with Forefox not recognizing these as proper “DOM-elements”.

      Alexander

  19. Alexander,

    I very much appreciate the quick reply. As jQuery is not my strongest language, I believe I have done as suggested without any change in FireFox. The code does still work in IE. For example, I’ve done my substitutions as such:

    ORIGINAL LINE:
    $(‘z\:row’, data).each(function(idx, itemData){

    SUBSTITUTED LINE:
    $(data).find(“[nodeName=’z:row’]”).each(function(idx, itemData){

  20. I’ve read through all the older comments posted here, and I did not see anything about modifying the SharePoint alert to have equivalent permissions. From preliminary research, that does not look like it will be as elegant of a solution if it is even possible. Has anyone modified SharePoint alerts in accordance with the fields they’ve hidden on the GUI using this awesome script solution?

  21. Hi Master,

    You mentioned
    innerPost(wsBaseUrl + ‘usergroup.asmx’,
    ‘http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromUser’,
    ” + userLoginName + ”,

    So, While we copy this code, should we need to change with our sharepoint site or related url ? or we no need to change anything except the javascript file path ?

    Please let me know master…. 🙂

  22. Hi Master,
    I have checked by adding your script file and code. but i am getting like i am not in that group. even though i have checked the group id through http://doccell:1000/personal/brijeshm_shah/_layouts/people.aspx?MembershipGroupId=10 and passed 10 where my name is listed.

    my code is somewhat like

    fields = init_fields();
    var isInGroup = isUserInGroup(”,10,false)
    if(!isInGroup)
    {
    alert(“Not in Group”);

    var arrOfMenuItemsToHide = [‘_EditInGridButton’,’_AddView’,’_AddColumn’,’_ListSettings’];
    $.each(arrOfMenuItemsToHide,function(idx,item){
    $(“*[id$='” + item + “‘]”).next().andSelf().remove();});
    var arrOfViewsToHide = [‘_ModifyView’, ‘All Documents’, ‘All Forms’, ‘Explorer View’, ‘Brij View’, ‘All Items’];
    $.each(arrOfViewsToHide,function(idx,item){
    $.each($(“*[id$=’_ViewSelectorMenu’]”).children(),function(){if($(this).attr(‘id’).match(item) || $(this).attr(‘text’)==item){$(this).next().andSelf().remove();}});});

    $(“.ms-menutoolbar”).find(‘menu’).each(function(){if($(this).children().length==0){$(this).parents(‘td.ms-toolbar:first’).prev().andSelf().remove();}});
    }
    else
    {
    alert(“in Group”);
    }

    Is there anything wrong i have done or missed ?
    Please it’s really urgent sir … if you have any idea..

  23. Hi Master,

    Now i have one issue with New form. I mean Add Form there i don’t have Edit Page Option While I have that option available in List where All Items displayed in grid.
    But from there we have option Add Item and gives add item page there i don’t have that edit option available.

    So, How can i add that CEWP and Javascript on that Page ? Through Sharepoint Designer ? Then in which Content Place Holder or Webpartzone ?

    1. Hi,

      Moreover can you tell me what field i should take in place of ‘OnlyForOwnerGroup1′,’OnlyForOwnerGroup2’ ? is that textbox id ?
      Because in my sharepoint desginer it display
      <SharePoint:FormField runat="server" id="ff1{$Pos}"
      <SharePoint:FieldDescription runat="server" id="ff1description{$Pos}"
      Like this…
      Can you help me out ?

  24. Good day to you. I trying to add in SP2010, but it is not working. The field hides all the time. IU have tried differnt groups and group IDs but I cannot not make it dynamic hide based on the group. any instruction would help.

    1. Hi,
      Ensure you get the “userLoginName” – try inserting an alert after line 25 like this:
      alert(userLoginName);

      Do you get an alert with tour login name?

      Alexander

  25. Hey Alexander, I got everything working great in terms of hiding the fields, but not coming up right on showing them for the appropriate users. When I add alerting it says my userid is a different shortname (jjflynn) even though I am signed on as bwolf. For the fun of it I added jjflynn to the usergroup and still no luck.

    Have you or anyone heard of something like this?

Leave a Reply

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