Wednesday, August 15, 2007

Managing Field Control Visibility - a step towards field level security and much more

Hi all,
Many times I face the same problems with almost all my customers.
In some point it seems they all want more controls over fields in the “edit” and “new” item form.
Some want to hide it from unauthorized users; others want to give a field a default value that changes according to the current user, and even some more interesting things like filtering values in choice fields to answer some complicated logic.
So one way to support all these whims is to develop new field types with field controls to mach – you can find plenty examples for that on the web (like our soon-to-be-released tags field type).
Here I want to show a simpler solution that involves only editing the edit/view form of the list and make use of very simple javascript code to get control over the client-side HTML element of each field.
One more thing – although we can create a custom list form using the SharePoint designer to hide controls there is a major disadvantage in using such a custom list form. If your user will add a new field in the future it will not show automatically in the edited form and you will have to edit these forms every time your user changes the list.
This code I wrote with the help of Sveta (thanks) expects the field display name and look for it in the HTML while it assumes a comment tag with the field name will exist right above the field itself.
Here is the code:
var ctrl = null;
//Place this code right AFTER the list view web part.
//To go into edit mode of the page,
//in case you dont have the edit page menu paste this in the browser's address bar:
//javascript:MSOLayout_ChangeLayoutMode(false)
function foo()
{
var ctrl = null;

var arr = document.getElementsByTagName('!');//get all comments

for(var i=0;i<arr.length;i++)
{
try
{
var html = arr[i].innerHTML;

if(
html.indexOf("field to hide 1") > 0 ||
html.indexOf("field to hide 2") > 0
)
{
ctrl = arr[i].parentElement.parentElement;
ctrl.style.display="none";
}

}
catch(e){alert(e.description);}
}
}
foo();




Doing this allows you to keep the default list form and still get some control of the desired field element. I usually wrap this code in a custom control that analyzes on the server side what needs to be done (hide element, replace with another or filter a combo box) and make use of the code above to complete the job on the client site. For example if I want to achieve a field level security for any SharePoint list field my server control will test the user permissions and will hide the control if the current user does not have enough permissions.
Hope this could help some of you guys,
Shai Petel.

5 comments:

Tsahi said...

Great Blog.
Is any of kwizcom products Sharepoint webparts Support this?

Derek said...

I have a service request list in a WSS 3.0 site (I used the helpdesk template, and added some custom fields), and I am interested in field-level permissions. I use my own custom New and Edit forms (which broke attachment functionality, but I'm not as concerned with that), and while I like that users cannot change the Assigned To field (they are Site Members, so they can't read group membership), I do not like that users can change the priority level of their own ticket.

Ideally, I would like to redirect users to separate New/Edit forms, depending on their group membership, but if that's not possible, is there a way to keep users from being able to modify their ticket priority, while allowing technicians (site owners) to still modify this field?

-Derek

Shai Ben Shooshan said...

Hi Derek.

Sounds to me you have 2 options:
1, much more simple but not so elegant - create a server side control and add it to the list new/edit forms that checks the user's mebership and writes down to javasctipt a line of commands such as:
var HideFields = "priority;assignedto"
var SetValues = "priority=2;assignedto=domain\user";

now, add javascript to the page (using the same control would make it easier) that reads these script values and perform the needed actions: hiding all controls that should be hidden, and setting the values according to the current user.

I believe this could solve your need.

2 - a bit more elegant way but harder to do: create 2,3 or 4 edit + new item forms (as many as you need) for each group.
make the changes you wish to these forms by removing the list form web part and adding a custom list form (using SharePoint Designer of course).
now - create a ASPX file that has a view of that list for each group.

now, in SharePoint Designer - right click the list and select properties. go to supporting files and choose the correct form you created earlier for each of the pages you created now so that each page will redirect to a different form.

I know it is long and may be confusing, but you cna email me for a deeper walkthrough at shai...kwizcom.com

thanks,

geneld said...

is there anyway you can post the entire code for hiding a field based on the users group? You solution sounds like exactly what I need, but I'm not sure how to implement it.

Thanks.

Anonymous said...

Hello,

I developed a feature (SPListDisplaySetting feature) which allowed administrators to set permission for columns for each mode (new, edit and display) for each type of list (but not library). If the user has no right for a field, the field is not display (and not set read only).

You can download this feature from CodePlex to http://www.codeplex.com/SPListDisplaySetting.


Laurent Cotton

www.bewise.fr
MVP SharePoint
Blog : http://sharepoint.over-blog.fr