Thursday, June 28, 2012

Hide something from the SharePoint Dialog Box

Today I went onto a SharePoint site to Upload A file and saw this in the Dialog Box to upload a file.

Notice the Support Div That is floating on the Right of the page but then is also on the Dialog Box.


SharePoint uses the same Master Page for Dialog Boxes as it does for your site so if you add something to the master page it will most likely show up in your dialog boxes as well.


To resolve this issue you need to know about a "special" CSS class SharePoint uses.


It is s4-notdlg Any item in the master page that has this class is stripped out of the dialog boxes automatically by SharePoint.


So instead of like this:

 <div title="Support" class="supportTab " id="supportTab">  
 Support  
 </div>  

It should be like this:

 <div title="Support" class="supportTab s4-notdlg" id="supportTab">  
 Support  
 </div>  

Extra credit if you add the noindex so search doesn't find the word Support on every page in your Site:

 <div title="Support" class="supportTab s4-notdlg noindex" id="supportTab">  
 Support  
 </div>  

Wednesday, June 27, 2012

list.Fields["Internal Name"] does not exist

Got a quick and dirty one for you.

A co-worker of mine came to me with a simple but weird issue.
This chunk of code wasn't working:

 string property = "DocumentSetDescription";  
 if (list.Fields.ContainsField(property))  
 {  
   if (list.Fields[property].Type == SPFieldType.Invalid)  
   {  
     //Code Here  
   }  
 }  

But it was throwing an error on the second 'if' statement basically saying the Field did not exist.

So you would think that if the first if statement was true then the second must be OK as well but it wasn't.

Come to find out it has to do with the way that the SPList.Fields Property looks up fields.

if you use .Fields.ContainsField(value) it looks it up by the internal name of the field (which were had) but if you use .Fields[value] it tries to look it up by either the GUID, DisplayName or the iIndex.

So if you try to look up a column by the Internal Name and it isn't the same as the Display Name then it will fail.

In order to avoid this we refined the if statement to be more like this:

 string property = "DocumentSetDescription";  
 if (list.Fields.ContainsField(property))  
 {  
   if (list.Fields.GetFieldByInternalName(property).Type == SPFieldType.Invalid)  
   {  
     //Code Here  
   }  
 }  

You learn something new every day...

Thursday, June 14, 2012

Use SharePoint 2010 JavaScript (ECMAScript) Client Object Model to check current users permissions

The JavaScript Object Model is a very powerful tool to a SharePoint Developer if you know how to use it properly. Unfortunately there isn't that much information out there about it and searching for examples often leads you to C# style SharePoint Object Model code which is similar but not the same...

If you are new to it and want to learn more or play around with some working examples check these out!

I struggled to get this to work for longer than I would like to admit so I thought I would post it here to alleviate future headaches and in hopes that it helps someone else.

My requirement was to check the permission of the current user using The JavaScript Client Object Model and do "something"

So here is what I ended up with.

 <script type='text/javascript'>  
  ExecuteOrDelayUntilScriptLoaded(checkifUserHasEditListItems, "sp.js");  
 function checkifUserHasEditListItems ()   
 {  
  context = new SP.ClientContext.get_current();  
  web = context.get_web();  
  this._currentUser = web.get_currentUser();  
  context.load(this._currentUser);  
  context.load(web,'EffectiveBasePermissions');  
  context.executeQueryAsync(Function.createDelegate(this, this.onSuccessMethod), Function.createDelegate(this, this.onFailureMethod));  
 }  
 function onSuccessMethod(sender, args)   
 {  
  if (web.get_effectiveBasePermissions().has(SP.PermissionKind.editListItems))  
  alert('User has editListItems');  
  else  
  alert('no dice');  
 }  
 </script>  


You can dump this in a CEWP or include it in a .js file that you already have...either way it will prompt you with an alert (obviously the alert is just a placeholder for wonderful things to come)

Tuesday, June 12, 2012

Visual Studio Post-Build GacUtil.exe with error handling

If you have ever had to deploy a solution to the GAC then you will love this Post-Build Command.


I found the original here by Dave Chestnutt and made it work for me:



echo POSTBUILDSTEP for $(ProjectName)
xcopy "$(TargetPath)" "$(SolutionDir)$(OutDir)" /i /d /y
if errorlevel 1 goto BuildEventFailed
xcopy "$(TargetDir)$(TargetName).pdb" "$(SolutionDir)$(OutDir)" /i /d /y
if errorlevel 1 goto BuildEventFailed 
echo GAC of: "$(SolutionDir)$(OutDir)$(TargetFileName)"
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\x64\gacutil.exe" /i $(TargetPath)"
if errorlevel 1 goto BuildEventFailed 
REM Exit properly because the build will not fail 
REM unless the final step exits with an error code
goto BuildEventOK
:BuildEventFailed
echo POSTBUILDSTEP for $(ProjectName) FAILED
exit 1
:BuildEventOK
echo POSTBUILDSTEP for $(ProjectName) COMPLETED OK

Friday, June 8, 2012

Debugging and Troubleshooting the Search UI

Here is a great article by Agnes Molnar that would have helped me out today had I known about it earlier! This article goes into great detail about the moving parts to a SharePoint 2010 Search Results page and how to make it your own.

Thursday, June 7, 2012

Add Search Refinement Item Count

A quick and impressive enhancement to the SharePoint Search Refinement Panel is to allow it to show the item count next to each of the refiners.
You can follow this TechNet article on how to achieve this solution.
This is what you will end up with:



SharePoint 2010 Custom Search Refiner for Contentclass

My client pointed out Yaroslav Pentsarskyy's post on Search Refiners last week and asked me to look into it.
So I implemented his solution and although it worked well, my client and I wanted more granularity for this search refiner, so I got to thinking that one thing that would work well would be the ContentClass property that holds such values as STS_Site and STS_ListItem_Announcement etc.


So I dusted off my XML Editor, cracked open the FilterCategories from the Refinement Panel (don't forget to un-check use default configuration, and went to work and here is what I ended up with:
<Category
   Title="Content Class"
   Description="Filter by contentclass"
   Type="Microsoft.Office.Server.Search.WebControls.ManagedPropertyFilterGenerator"
   MetadataThreshold="0"
   NumberOfFiltersToDisplay="2"
   MaxNumberOfFilters="0"
   SortBy="Custom"
   ShowMoreLink="True"
   MappedProperty="contentclass"
   MoreLinkText="show more"
   LessLinkText="show fewer" >
   <CustomFilters MappingType="ValueMapping"
     DataType="String"
     ValueReference="Absolute"
     ShowAllInMore="False">
     <CustomFilter CustomValue="Web Pages">
       <OriginalValue>STS_ListItem_WebPageLibrary</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Announcements">
       <OriginalValue>STS_ListItem_Announcements</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Contacts">
       <OriginalValue>STS_ListItem_Contacts</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Disucssions">
       <OriginalValue>STS_ListItem_DiscussionBoard</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Documents">
       <OriginalValue>STS_ListItem_DocumentLibrary</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Events">
       <OriginalValue>STS_ListItem_Events</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Gantt Tasks">
       <OriginalValue>STS_ListItem_GanttTasks</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="List Items">
       <OriginalValue>STS_ListItem_GenericList</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Links">
       <OriginalValue>STS_ListItem_Links</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Pictures">
       <OriginalValue>STS_ListItem_PictureLibrary</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Surveys">
       <OriginalValue>STS_ListItem_Survey</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Tasks">
       <OriginalValue>STS_ListItem_Tasks</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="XML Forms">
       <OriginalValue>STS_ListItem_XMLForm</OriginalValue>
     </CustomFilter>
     <CustomFilter CustomValue="Sites">
       <OriginalValue>STS_Web</OriginalValue>
     </CustomFilter>
   </CustomFilters>
 </Category>
Note: if you are concerned about Multilingualism then know that by telling the Refinement Panel Web Part to not use the default configuration you are hard-wiring a bunch of words that are used here (like 'show more' and 'show less') so keep that in mind.


Thanks again to Yaroslav Pentsarskyy for the mention on his new post about my resolution after I sent it to him.

Welcome to my blog

Hello All, Welcome to my blog.

I am a SharePoint Developer who lives in Ottawa, Ontario Canada.  I work for StoneShare, we are a SharePoint consulting company specializing in SharePoint and only SharePoint.

I have been riding the SharePoint rollercoster since the SPS 2003 days and loving every bit of it.

Most of my posts will be contextual to what I am currently working on but I am open to suggestions on future posts.

You can follow me on twitter at sharebrad