Saturday, February 14, 2015

Better SharePoint Content Authoring – Hide Sections that have no data

Presenting another trick for an improved SharePoint Content Authoring experience. As they say, picture says thousands words, I will present the problem and the solution in picture first:

Consider this page and the problem:

SNAGHTML16daf3

the solution:

SNAGHTML1a0e78

But what about this page in edit mode?

SNAGHTML223795

I know some of you may be thinking that this is so easy to do using JavaScript. Personally, I don’t like that approach because you will have to hide it based on element targeting and DOM manipulation. I think that’s not a robust solution because.. 1) it breaks when the element targeting fails (ID, or class name of DOM element changes 2) If you don’t implement it right, you will see “Description” first and then it  will magically disappear. That’s unacceptable for me.

Let’s talk about a better approach…

Well, my approach is it wrap the field heading (“Description” in this case)  into a Panel control which checks if the provided field has a value. If it has a value show the field heading panel, otherwise hide it.

It’s better because…..

1) It does not have two problems that I described above with JQuery approach

2) Unlike JavaScript approach, this solution is reusable. My favorite reason.

Here is my code for the panel look like:

public class FieldHeadingPanel : Panel, INamingContainer, IParserAccessor
   
{
       
private bool _shouldRender = false;
       
private bool _evaluated = false;

       
public string FieldGuid { get; set; }
       
public bool ShowInEditMode { get; set; }
       
protected override void AddParsedSubObject(object obj)
       
{
           
if (!_evaluated)
           
{
               
_evaluated = true;
               
this.ShouldRender();
           
}

           
if (_shouldRender)
           
{
               
base.AddParsedSubObject(obj);

           
}
       
}

       
private void ShouldRender()
       
{
           
_shouldRender = false;
           
try
           
{
               
if (!PublishingPage.IsPublishingPage(SPContext.Current.ListItem) || string.IsNullOrEmpty(FieldGuid))
               
{

                   
_shouldRender = false;
               
}
               
else
               
{
                   
// check if edit mode
                    if (SPContext.Current.FormContext.FormMode == Microsoft.SharePoint.WebControls.SPControlMode.Edit && ShowInEditMode)
                   
{
                       
_shouldRender = true;
                       
return;
                   
}
                   
SPField field = SPContext.Current.ListItem.Fields[new Guid(FieldGuid)];
                   
_shouldRender = !string.IsNullOrEmpty(field.GetFieldValueAsHtml(SPContext.Current.ListItem[new Guid(FieldGuid)]));


               
}
           
}
           
catch (Exception ex)
           
{
               
AppContext.FromSPContext().Logger.LogException(ex);
               
           
}
          
           

       
}
   
}

Basically, the panel will render content inside it only if the provided field has a value in it. I have tested it with Person, Text, Note and Summary Links field controls and it works. I’ll modify the code if it does not work for certain fields.

This class is part of my SharePoint Reusable Application framework which I use from one project to another.

You will put the following markup in your Page Layout.

   1:  <Framework:PageModePanel runat="server" ShowMode="Display" id="pnlDisplayOnly" >
   2:          <BEX:FieldHeadingPanel runat="server" FieldGuid="9da97a8a-1da5-4a77-98d3-4bc10456e700" ShowInEditMode="true">
   3:          <h2>
   4:              Description
   5:          </h2>
   6:     </Framework:FieldHeadingPanel>



Hope this helped you, feel free to leave comments!

No comments:

Post a Comment