Using "EditModePanel" To Show/Hide Webparts In Edit/Display Mode in Sharepoint 2007/2010

Posted by Ahmed Tarek Hasan on 12/23/2012 08:37:00 PM with No comments
While working on Sharepoint pagelayouts I needed to control whether an element will appear on edit/display mode. I specifically needed a webpart zone to appear in the edit mode but not appear in the display mode.

So, after searching, I found an OOTB control called "EditModePanel" which has an attribute to decide the mode in which the control children will be rendered. So, if this attribute -which is called "PageDisplayMode" by the way- is set to "Display", then the control contents will be rendered in the display mode of the page. While, if it is set to "Edit", then the control contents will be rendered in the edit mode of the page.

Then, I thought that I found what I need. But, after using this control, I figured out a problem with it. In the days of Sharepoint 2007, this control would have done exactly what I needed, but the case is different with Sharepoint 2010.

In Sharepoint 2010, Microsoft decided to introduce a security change to this control which I really can't understand till now. Microsoft added a part to this control which checks for the privilege of the logged in user. If this user has edit privilege on the page, then everything is ok and the control works as supposed to. But, if the user doesn't have edit privilege on the page, the control will never render its children whatever its display mode is set to.

So, to imagine the whole thing;

In Sharepoint 2007
<PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Display">
 <!-- content here will be rendered in page display mode -->
</PublishingWebControls:EditModePanel>

<PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Edit">
 <!-- content here will be rendered in page edit mode -->
</PublishingWebControls:EditModePanel>

In Sharepoint 2010
<PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Display">
 <!-- if user has edit privilege, content here will be rendered in page display mode -->
</PublishingWebControls:EditModePanel>

<PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Edit">
 <!-- if user has edit privilege, content here will be rendered in page edit mode -->
</PublishingWebControls:EditModePanel>

So, this didn't help me achieve what I needed for my case. So, after searching, I found some other ways to do it using a combination between the "EditModePanel" and "AuthoringContainer". The "AuthoringContainer" is a panel which also has the two modes but I didn't like this solution cause it has its limitations beside it is somehow complex.

This lead me to another idea, let's reflect the "EditModePanel" to find the newly introduced security change then inherit from the control and override this method. So, I reflected the control and found the line which causes the problem. The method I need to override is called "CalculateShouldRender" and the line causing me troubles is like the following
if (!ConsoleUtilities.CheckPermissions(SPBasePermissions.EditListItems))
{
 this.shouldRender = false;
}

This is good, I can now override this method. But, I noticed that the control is sealed which means I can't inherit from it, so, I had to make one extra step. I copied the same code of the control as it is except for the "CalculateShouldRender" method, I removed the security check.

This was the hard part. I started using my new control and used it to wrap the webpart zone which I wanted to display only into the edit mode. Then I started testing my work, I opened the page into edit mode, found the zone, added a webpart to the zone, crossed my fingers and switched to display mode. What?!!!!

I found that the zone itself is not displayed into the display mode, but, the webpart -which was located into the zone- is moved to another zone on the page and it is displayed!!!!!

So, after some searching, I figured out that Sharepoint is somehow sensitive against webparts that are found on the page but will not be displayed. In such occasion, Sharepoint decides to move this webpart to the nearest visible zone. Why meeeeeeeeee.......

So, I decided to take another approach, instead of wraping the zone inside my control, I will leave the zone as it is and I will write some css to hide my webpart and locate this css inside the control while setting the control to display mode. So, now, in the display mode, the css will be rendered and the webpart will disappear. For sure I know that the webpart actually exists on the page and its code will be running but in my case this is enough.


Wish you find this helpful.
Bye.


 

Categories: ,