Monday, December 30, 2013

_spBodyOnLoadFunctionNames.push and ExecuteOrDelayUntilScriptLoaded

SharePoint JavaScript Client Object Model: How to Use
 
_spBodyOnLoadFunctionNames.push
 
ExecuteOrDelayUntilScriptLoaded
 
SP.ClientRuntimeContext.executeQueryAsync
 


This is a blog that discusses when and how to use these important SharePoint Javascript calls.

1. _spBodyOnLoadFunctionNames.push() is SharePoint's version of jQuery's $(document).ready() or $(function(){});

It is better to use SharePoint's version than using jQuery's version.

2. _spBodyOnLoadFunctionNames.push() takes the function names as string,

For example, for self-defined function use

_spBodyOnLoadFunctionNames.push('Company.Utility.hideText');

Since the function name passed as string, it is not possible to pass parameters to the function directly. The parameters have to be passed inside the function itself.

3. If your Javascript use SharePoint Client Object Model, you need to use ExecuteOrDelayUntilScriptLoaded to delay your Client Object calls after SharePoint's core Javascript library is loaded. The function name is passed directly as parameter to the function.

ExecuteOrDelayUntilScriptLoaded(Company.Utility.showData"sp.js")

4. To pass parameters to the function calls deplayed by ExecuteOrDelayUntilScriptLoaded.

ExecuteOrDelayUntilScriptLoaded(function () { Company.ReportListView.initListView("<%=ReportName %>") }, "sp.js")

This code also shows the technique to pass server side variable value to the client script.

5. Usually you will need these two functions together to first delay the run of your script after the page is loaded and delay the run of your script after the core SharePoint JavaScript library is loaded.

<script type="text/javascript">
    if (ExecuteOrDelayUntilScriptLoaded && _spBodyOnLoadFunctionNames) {
        _spBodyOnLoadFunctionNames.push(ExecuteOrDelayUntilScriptLoaded(function () { Compnay.ReportListView.initListView("<%=ReportName %>") }, "sp.js"));
    }
</script>

6. To pass parameter to the success function of SP.ClientRuntimeContext.executeQueryAsync

    function initListView(reportName) {
        var context = SP.ClientContext.get_current();
        ... 
        context.load(items);
 
        var sender = { "items": items, "reportName": reportName };
 
        context.executeQueryAsync(function () { succeed(sender); }, failed);
    }
 
    function succeed(sender, args) {
 
         if (sender.items) {
 
            var htmlOutput = "";
            var count = sender.items.get_count();
 
            ...

 

Friday, December 13, 2013


An Easier Way to Provision Publishing Page in SharePoint Solution


When you use SharePoint as a full-fledged publishing portal to do content management, there are scenarios that requires custom page layout.
For example , every article page of your portal requires a sub-title area that end users need to add or edit when they provide the content. The manual steps to create a custom page layout is
1.       Create custom content type that inherits from a OOTB page layout content type. This custom content type will have a new field called “Sub Title”.

2.       Create a page layout that uses the custom content type and then using SharePoint Designer to design the UI. During this process, the “Sub Title” field is added to the UI.

3.       Create the content page in “pages” library that use the custom page layout created in step2.
When creating a SharePoint solution in Visual Studio 2012 to create publishing portal, we tends to follow the same steps to create a publishing page: Create a custom content type, bind the content type to pages library, create custom page layout, and create the page that uses the custom content type and page layout.
However if you think it twice, you will find these are not necessary steps to follow.

First, most pages provisioned though custom SharePoint solution will not have custom content from end users. The layout and contents of the pages are pre-defined in implementation. This means there is no need to create a custom field with a custom content type. The new page could just use any existing page layout template such as “Article Page”.
Second, since we developer have control over the design of the page layout using HTML and XML, we don’t even need to use any field from the layout content type. All the content and layout could be done with HTML, web part zone and web parts.
So the easy way to do this is just two steps
1.       Create the custom page layout (with web part zones).

2.       Create the content page that uses the custom page layout (with web part that use the web part zone).

The content page uses OOTB page layout content type "Article Page"
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="Pages_" List="101" Url="Pages" SetupPath="SiteTemplates\SPS\">
    <File Name="home.aspx" Url="home.aspx" Path="default.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="FALSE" >
      <Property Name="Title" Value="Home" />
      <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/HomePageLayout.aspx, My Homepage Layout" />
      <Property Name="ContentType" Value="Article Page" />
      <Property Name="ContentTypeId" Value="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D00034BC11D88051947AB4A4F809BB04726" />
      <AllUsersWebPart WebPartZoneID="TopLeft" WebPartOrder="0">
        <![CDATA[
    ......
 ]]>
      </AllUsersWebPart>
    </File>
  </Module>
</Elements>