Thursday, April 09, 2009

How to Emulate User Roles in InfoPath Forms Services to Automatically Switch Views


Many of my SharePoint consulting clients and students express the need to have different users see different views of an InfoPath form. In the InfoPath client, this is easy to handle using the User Roles
functionality which has been well-documented elsewhere. Unfortunately, User Roles are not supported by InfoPath Forms Services for your browser-enabled forms. Here is a work-around that I have been using for quite some time that has worked well for me and my clients and students.

In this post we'll create a simple InfoPath form with two views: one view for most users and another view for administrators only. When the form loads, it will check to see if the current logged in user is an Administrator for that form and if he is it will display the Admin View to the user. If the user is not an administrator for the form, it will display the User View.

Create a Custom List to Store Users and Permission Levels

Although SharePoint exposes a number of web services that reveal security information and information about SharePoint Groups, I've never been able to get them to work reliably with InfoPath, especially without writing code. Since I can't use SharePoint Groups, I create a custom list to store the names of my users who will be administrators.

  1. Create a custom list called My Form Admins.
  2. Change the name of the Title column to Permission Level.
  3. Create a new column named User, of type Person or Group. Set the Showfield to User Name.
  4. Add a couple users.
  5. Your list should look similar to this:

Create a New InfoPath Form with Two Views

Obviously, you'll need an InfoPath form to use this, so launch InfoPath and create a new blank form.

Within this form, create two views. Rename the default view to User View, name the other one Admin View. You don't have to add any fields on these views, but you can if you want. You will want to make them distinct so you know which view you are looking at, but it could be as simple as just putting the text "User View" and "Admin View" on the top of each view; that's what I did for this post.

Add Some Nodes to Store the Decisioning Information

In my form, I created a new group named AdminCheckingNodes, with two nodes both of type Text named Current UserUserName, and CurrentUserPermissionLevel. These will be used to store the User name of the current logged in user and his permission level, if one is set, in the My Form Admins list in SharePoint.

Add a Data Connection to the SharePoint List Containing the Admin Names

The form needs to be able to look at the My Form Admins list in SharePoint to determine the Permission Level of the current user. Create a data connection to this list.

  1. Click on Tools, Data Connections.
  2. Click Add.
  3. Create a new connection to Receive Data
    from a SharePoint Library or List.
  4. Paste in the path to the My Form Admins list.
  5. Select the My Form Admins list.
  6. Select both the Permission Level and User fields.
  7. Accept all the other defaults in the wizard and close the Data Connection window.

Write Rules to Get the Current User's Permission Level

You need to write four rules to fire when the form first loads.

The first rule will store the name of the current user in the CurrentUserUserName
node.

  1. Click on Tools, Form Options.
  2. Select the Open and Save category.
  3. In the Open Behavior section , click on the Rules button.
  4. Click the Add button.
  5. For the Rule Name, enter "Store Name of Current User".
  6. Click the Add Action button.
  7. Select the
    Set a field's value
    action.
  8. For the Field, select the CurrentUserUserName node.
  9. For the Value, click the Data Binding button. Click the Insert Function button, select userName. Click OK, and OK. Your form should look like this:

  10. Click OK. The completed rule will look like this:

  11. Click OK to close the Rules dialog.

Whew! That may have seemed like a lot, but it's only part of what we need to do. You still need to write three more rules. Your Rules for OpeningForms dialog should look like this.


  1. Click the Add button.
  2. For the Rule Name enter, "Clear out the current permission level". You need to do this just to make sure this field is empty in case the current user isn't listed in you're My Form Admins list.
  3. Click the Add Action button.
  4. Select the
    Set a field's value
    action.
  5. For the Field, select the CurrentUserPermisisonLevel node.
  6. For the Value, just leave the field blank. Click OK, and OK. Your form should look like this:


  7. Click OK. The completed rule will look like this:

  8. Click OK to close the Rules dialog.
  9. You should have two rules now. You're half done!


The next rule will look at the SharePoint list and store the permission level of the user, if the user's name is in the list.

  1. Click the Add button.
  2. For the Rule Name enter, "Look up and store the current user's permission level".
  3. Click the Add Action button.
  4. Select the
    Set a field's value
    action.
  5. For the Field, select the CurrentUserPermisisonLevel node.
  6. For the Value, click on the data binding button.
  7. In the Insert Formula dialog, click on the Insert Field or Group button.
  8. Change the Data Source to My Form Admins (Secondary).
  9. Expand out all the nodes and select Permission Level.

  10. Click on the Filter Data… button.
  11. Click the Add button.
  12. In the first drop-down, select Select a field or group….Then select User, then click OK.
  13. Leave the second drop-down with is equal to.
  14. In the third drop-down, select Select a field or group….Then change the Data Source to Main, select the CurrentUserUserName node. Your condition should look lieke this:

  15. Click OK on the next four dialogs. Your form should look like this:

  16. Click OK three more times. Your rules should look like this:

You're almost done!. Just one more rule to write, then you can publish and test your form. The last rule will look at the value stored by the previous rule and will switch views if it contains the word "Admin."

  1. Click the Add button.
  2. For the Rule Name enter, "Switch to admin view if user is an admin".
  3. This rule will have a condition to check the permission level you stored with the previous rule. Click the Set Condition button.
  4. In the first drop-down, select Select a field or group….Then select CurrentUserPermissionLevel, then click OK.
  5. Leave the second drop-down with is equal to.
  6. In the third drop-down, select Type Text….Type the word "Admin" without the quotes; InfoPath will automatically add quotes for you. Your condition should look like this:

  7. Click OK.
  8. Click the Add Action button.
  9. Select the
    Switch Views
    action.
  10. For the view, select the Admin View, and click OK.
  11. Your completed rule will look like this:
  12. Click OK. All four rules should look like this:
  13. Click OK twice to return to your form.

Publish and Test the Form

Now you're ready to test the form! Woohoo! The easiest way to do this is to switch to the User View, then click the Preview button. If you are not listed as an Admin in the My Form Admins table, you shouls see the User View.


Close the form, add yourself as an Admin in the SharePoint list and then preview the form again. You should see the Admin view.


Conclusion

You can do a lot more with this besides just switch views. For example, depending on the permission level you set for the current user, the form may call different web services to populate certain fields of information. You could choose to show or hide different sections using Conditional Formatting. When users with certain permission levels submit the form, you may have a SharePoint Designer workflow check to see if it was submitted by an Administrator, and if it was, do something different than if it was submitted by a regular user. The uses of this are limitless. Let me know in the comments how you plan to make use of this.

26 comments:

Anonymous said...

This is great. I've got multiple uses for this. I'm always getting asked to create forms with hidden sections that only form admins can see. I've been using a complex approach involving an admin sharepoint security group, a hidden section on the form that is only visible to the security group (using if submitter username does not equal viewer username) and turning on approvals so that users can only see the forms they have submitted. Thanks for this.

Anonymous said...

Excellent article! My clients have requested me to this many times but I always figured I would have to take the custom route. You have certainly provided a great workaround with details on each step.
Thanks!

Unknown said...

Thanks for the info, really helped, just one issue, view work 100% except once they are published, it doesn't seam to read the security info in the browser based form and users can see both views regardless of the details in the admin list. any idea's?

Ricky Spears said...

Scwaal - This works fine for me in browser based forms. You may want to make sure you haven't missed anything and you're not displaying the drop-down where users can select a view.

Unknown said...

Hi Ricky, I have checked everything over again, I have disabled the view menu but it still only opens the default view in the browser, works 100% when opening in info path though, any suggestions where else I could check, thanks a million!

Unknown said...

I'm having a similar issue to Scwaal. If I open the form with InfoPath, it works great. However, when I use the browser from from the same InfoPath library, the CurrentUserPermissionLevel text box is blank. But using the InfoPath form, the CurrentUserPermissionLevel text box displays the correct list item.

Anonymous said...

Hi, I also have the same problem as Scwaal and Brian as it works fine within the InfoPath client but does not do the job under Web-enabled forms. Any ideas? Cheers

Anonymous said...

I have an odd result, when using the User Name for the Show Field option in the User column, the users that have user names in AD as JSmith (upper case first initial and first letter of last name) will not switch views. The user that has (jdoe all lower case) seems to work fine. Any ideas or suggestions? This is happening in all three of our environments, dev, qa and production.

Ricky Spears said...

Anonymous - Use the TRANSLATE function to convert the UserName to lowercase before you store it. In step 9 above where you select UserName, change it to the following function:
translate(UserName(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")

This will convert all the upercase letters to lowercase letters.

Anonymous said...

Outstanding work, this is a huge help and regularly requested-I found when creating a demo of this in InfoPath 2010/SharePoint 2010 that the process worked fine, but on the "Look up and store the users permission level", the filter (step 13) had to use "Contain" rather than "Is Equal To" due to the text value.

RogerS1954 said...

This is a simple and elegant solution when a small group needs to see a section that the rest of the world doesn't. One problem: the display view hides the section, regardless of the user. The new and edit views are working correctly, though. Any ideas on why this is happening and what can be done to fix it?
Thanks

Ricky Spears said...

RogerS1954 - It sounds like you've got some error in your logice. I would recommend that you use the Logic Inspector to see all your rules in one place to see why that section is being hid. Good luck!

CRJAngel said...

I can not get this to work. My nodes in the browser 1. You can not create another folder.
2. Selections under list from SP are not displayed the same because of this. I can not get it to pull the permissions either as a few others have stated here. Still no answer from you on this. On SP 2010 Info path 2010 Browser form

CRJAngel said...

First of all in Browser enabled form you can not create another folder:
2. consequently my list data does not look like your screen shot.
3. As others have stated here I can not get this form to pull permissions this way. It is blank
My logic is exactly the same as yours BUT there could be issues between how AD sees the user what is brought in by Profile service and matching names. I believe that is my issue. I can not match the Current Username to the list to pull the permissions. Tried a lot of things. Suggestions are welcome

Abdul Waheed said...

Grate effort i follow all steps all roles done successfully. after publishing form on sharepoint site receiving this error:
The custom code in the form cannot be run. This functionality may be deactivated on the server. For more information, contact the server farm administrator.

maro said...

Please tell me how to create a new group named AdminCheckingNodes in my Fields, I do right click but the new section is not active

Centaur31 said...

Great job about this post,
i was trying to find a solution with userGroups.asmx,

However, how to populate the UserAdmin list every day from another data source. Because, we can't manager all of this lists manually every time a user changes

Benjoe said...

I am following these for an urgent project I am working, using InfoPath 2010 and SharePoint 2010, my urrentUserPermissionLevel is always empty and "@Permission_Level[@User=CurrentUserName]" is different Title[User = CurrentUserName]. Please help me here

num bhaskar said...

It's not working.It always taking the permission level of the user is "Admin" and it is not clearing the permission level, what ever you have explained second Rule.
Thanks,
This is NumBhaskar

Ubi said...

This is all fine for me except for one issue. In the User Roles list, if the user has more than one role only the first is returned. Is that the expected behaviour?

Many thanks.

Ricky Spears said...

Ubi - Once the filter finds the first row for the user, it will return the permission level for that row.

If you want to use this for multiple levels for the same person, you may want to add other columns for the other permission levels, so that you only have one row for each user. Then your rules in InfoPath can use OR to check both columns (eg. PermissionLevel1 is equal to 'Admin' OR PermisionLevel2 is equal to 'Admin').

Grace88 said...

Excellent post! I've been working on a test case of this today. The form works perfectly for me, however, it does not switch views for the other "Admin" users in the custom list. Have I missed something here? Any help would be appreciated. Thanks

Grace88 said...

Following my previous comment, it seems to be working now. I found a work around on the last rule. Instead of CurrentUserPermissionLevel = Admin, I merely used the secondary source set the form to switch when Permission_Level = Admin. I seem to see the logic behind this minor change in that Permission_Level contains Admin and not CurrentUserPermissionLevel, if that makes sense?

Unknown said...

Hi Ricky,

Thanks for the post. A query before I dive in - Is there a limit to the number of groups that can be used? e.g. admin, team1, team2, team3 etc.?

Thanks in advance.

Ricky Spears said...

Kev - Following this method, you could theoretically have as many "Permission Levels" as you wanted.

ggill1970 said...

This is SICK. Love it & works perfectly for me. FOR INFOPATH 2010 USERS: (1) adding CurrentUserUserName and CurrentUserPermissionLevel under MyFields | dataFields as a text field works FINE. i wasn't able to add a Group w/ 2010 or just had some kind of browser-based issue. (2) enter your Rules under Data | Form Load. (3) for the 3rd rule, "Look Up and Store the Current Users Permission Level", i didn't see a way to Filter like in the example (browser-based issue or 2010?). Setting a similar condition before the "Set a field's value" works great.

everything else worked perfect. One additional thing (4) was to UNCHECK "Show on the view menu when filling out this form" under Page Design (tab) View | Properties. i did this for both Admin & (default) Associate Views. this is so there is not odd User experience with them toggling Views or seeing Admin but only able to see Associate.