Wednesday, March 16, 2016

Uncaught TypeError: SP.ProxyWebRequestExecutorFactory is not a function

Environment: Office 365, SharePoint Online, Visual Studio 2015, SharePoint JSOM


Scenario: Create a SharePoint hosted app to get the SharePoint list details from the root web.

Error: Uncaught TypeError: SP.ProxyWebRequestExecutorFactory is not a function


Code snippet where the error has occurred is marked in red


   hostwebUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
   appwebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
   context = new SP.ClientContext(appwebUrl);
   factory = new SP.ProxyWebRequestExecutorFactory(appwebUrl);


Troubleshooting: According to this article, SP.ProxyWebRequestExecutorFactory is member of Request Executor(sp.requestexecutor.js). So the script file should be loaded explicitly in order to avoid the error.


Fix: Reference the SP.RequestExecutor.js in the page
<script type="text/javascript" src="/_layouts/15/SP.RequestExecutor.js"></script>






Thursday, February 18, 2016

Deployment to resource group ‘Resource Group Name’ failed in Windows Azure

Environment: Windows Azure

Requirement: Create a SharePoint Server 2013 trial Virtual Machine in Azure.

Error: Deployment to resource group ‘Resource Group Name’ failed.

Issue: The deployment failed with the following an error at event Microsoft.Resources/deployments/write

Deployment failed error

Troubleshooting: From the audit log detail, it is understood that this is an authorization error. The credentials that are provided during Virtual Machine configuration does not have permission to access the virtual machine.

Following is the screenshot of the page that is used to set the credentials while creating virtual machine. The issue was because the user 'prasath' does not below to 'MyAzureGroup' resource group and not granted any permission/role.

Create Virtual Machine

Resolution:
  1. To resolve this issue, from Azure portal home page, select the Resource Groups menu from the quick launch.
  2. Select the appropriate Resource Group
  3. Select Users from the settings panel
  4. Click Add from the Users panel
  5. Click Select a role from Add Access panel
  6. Select Owner from Select a role panel
  7. Select the user name to whom you want to grant permission to login to virtual machine and set them with appropriate role.

Permission Settings

After the above changes, recreated the virtual machine and the deployment when successfully without errors.

Tuesday, February 2, 2016

Develop SharePoint-hosted SharePoint Add-in to get user's permission at the site level

This article is a basic example of developing a SharePoint-hosted SharePoint Add-in and deploying to SharePoint online site

Source Code

Environment: Office 365, SharePoint Online, Visual Studio 2015, JSOM

Prerequisite: Active users are added to the Office 365 site and granted permission to access the SharePoint online.


Requirement: Develop a SharePoint-hosted SharePoint Add-in to get user's permission at the site level

Solution:
Create the add-in project


  1. Start Visual Studio
  2. Choose File > New > New Project.
  3. In the New Project dialog box, expand the Visual C# node, expand the Office/SharePoint node, and then choose Add-ins > Add-in for SharePoint.
  4. Name the project, and then choose OK.


Create SharePoint Add-in using Visual Studio


  1. Specify the Add-in for SharePoint Settings dialog box, provide the full URL of the SharePoint site that you want to use to debug your add-in. This is the URL of the Developer Site. (Use HTTPS, not HTTP in the URL.) Under How do you want to host your SharePoint Add-in, choose SharePoint-hosted. Choose Finish.


Specify the SharePoint Add-in settings.


  1. Provide your subscription administrator's credential if prompted to login to your Developer Site.


Connect to SharePoint


  1. In Specify the target SharePoint version page, select SharePoint Online, and then click Finish button


Specify the target SharePoint version


Code your add-in


Following is the project items created by default template. Refer to this MSDN article for more information about each project item
Solution Explorer


Publish the Add-in


Publish the SharePoint Add-in


Deploy the Add-in to the developer site.


Deploy the SharePoint Add-in to the developer site


Developer Site home page with the Add-ins in Testing list


Developer Site home page with the Add-ins


Run the add-in

Note: User running this app should have appropriate permission to get the permission level for other users. A full control permission is recommended in this case.


Run the add-in


Source Code is available at TechNet gallery.

Sunday, January 31, 2016

A different version of this App is already installed with the same version number. You need to delete the app from the site and the site recycle bin to install this version.

Environment: Office365, SharePoint Online, Visual Studio 2015

Requirement: Re-Deploy an SharePoint Add-in into SharePoint Online Developer site

Approach: The Add-in is build successfully, but was getting an error when it is deployed using Visual Studio or added to Apps list in Developer site.

Issue/Error: A different version of this App is already installed with the same version number.  You need to delete the app from the site and the site recycle bin to install this version.

Resolution: We could not delete the app as it was neither in site recycle bin nor second-stage recycle bin. Clean and Retract the app from Visual Studio. Redeploy it again after successful retraction.

Wednesday, January 6, 2016

Add text or image between suite bar in Ribbon

Environment: SharePoint 2013 Enterprise

Requirement: Add text or image between suite bars

Solution:

Edit the master page using SharePoint Designer and add <div> tags with banner text or images as required. The following code snippet is from the out of the box seattle.master page. Text that are highlighted are inserted between the suite bars.

<div id="suiteBar" class="ms-dialogHidden noindex" >
  <div id="suiteBarLeft">
  <div class="ms-table ms-fullWidth">
     <div class="ms-tableRow">
        <div class="ms-tableCell ms-verticalAlignMiddle">
                <SharePoint:DelegateControl id="ID_SuiteBarBrandingDelegate" ControlId="SuiteBarBrandingDelegate" runat="server"/>
        </div>
        <div class="ms-tableCell ms-verticalAlignMiddle" style="text-align:center;font-weight:bold;color:#FF3300;"> [[[ SOME BANNER IMAGES ]]] </div>
        <SharePoint:AjaxDelta runat="server" id="DeltaSuiteLinks" BlockElement="true" CssClass="ms-core-deltaSuiteLinks">
            <div id="suiteLinksBox">
                <SharePoint:DelegateControl id="ID_SuiteLinksDelegate" ControlId="SuiteLinksDelegate" runat="server" />
            </div>                                                                                                              
         </SharePoint:AjaxDelta>
         <div class="ms-tableCell ms-verticalAlignMiddle" style="text-align:center; font-weight:bold;color:#FF3300;"> [[[ SOME BANNER TEXT ]]] </div>
      </div>
  </div>
</div>
Edit the master page using SharePoint Designer
To insert a row below the Suite bar

<SharePoint:ThemedClusteredHoverImage
                                    runat="server"
                                    ……………………
</span>
</div>
</SharePoint:AjaxDelta>
</div>
</div>
<div id="s4-ribbonrow ms-verticalAlignMiddle" style="text-align:center;font-size:large;font-weight:bold; background-color:#6699FF;">[[ SOME SAMPLE TEXT/BANNER ]]</div>
<div id="ms-hcTest"></div>
<div id="s4-ribbonrow">
<div id="globalNavBox" class="noindex">
<div id="ribbonBox">
  <div id="s4-ribboncont">
  <SharePoint:AjaxDelta id="DeltaSPRibbon" BlockElement="true" runat="server">
                <SharePoint:DelegateControl runat="server" ID="GlobalDelegate0" ControlId="GlobalSiteLink0" />
                  <SharePoint:SPRibbon
                                    runat="server"
                                    PlaceholderElementId="RibbonContainer"
                                    CssFile="" >
                                    <SharePoint:SPRibbonPeripheralContent
                                      runat="server"
                                      CssClass="ms-core-defaultFont ms-dialogHidden"
                                      Location="TabRowLeft">
                                    </SharePoint:SPRibbonPeripheralContent>
Insert a row below the Suite bar
P.S. Create appropriate CSS classes and add to the style sheet.

Tuesday, December 8, 2015

Get next item ID from a SharePoint Document Library using REST

Environment: Using jQuery, REST, SharePoint 2013 Enterprise, knockout JS

Requirement: To get the next item ID from a SharePoint Document Library using REST

Prerequisite: knockout and latest jQuery are defined in the code.

Code:

function getNextSequenceID() {
              
var documentLibraryName = 'DocumentLibraryName';     
               var serverUrl = window.top._spPageContextInfo.webServerRelativeUrl;
              
               //Query the top 1 item sorted in descending order.
               var fileListItemIDUri = serverUrl + "/_api/web/lists/getbytitle('" + documentLibraryName + "')/items?$select=ID&$top=1&$orderby=ID%20desc";
               var sequenceID = 1;
                                            
                              return $.ajax({
                                             url: fileListItemIDUri,
                                             type: "GET",
                                             headers: { "accept": "application/json;odata=verbose" },
                                             success: function (data) {
                                             if(data.d.results.length==1)
                                             {
                                                            var id = data.d.results[0].ID;
                                                            sequenceID = id+1;
                                             }   
alert(“The next item ID is :”+ sequenceID);

        },
        error: function (data) {
        },
        });

};

Create a folder in a document library using REST

Environment: Using jQuery, REST, SharePoint 2013 Enterprise, knockout JS

Requirement: Create a folder in a document library with current year as the folder name using REST. Check if folder exists already, else create a new folder.

Prerequisite: knockout and latest jQuery must be defined.

Code:
var currentYear = ko.observable();
var documentLibraryName = “DocumentLibraryName”;   
var serverUrl = “http://webServerURL”;

//Following code should be executed on page load
self.currentYear = ko.computed(function () {
               currentYear = (new Date).getFullYear();
               return (new Date).getFullYear();
});

//fileUpload method is used to upload a file to a folder in SharePoint document library
self.fileUpload = function () {
self.doesFolderExist();
….
….
…
};

//doesFolderExist method is used to check if the folder already exists in the document library and create a new folder if does not exist.
self.doesFolderExist = function (){
                                            
              
               var fileCollectionEndpoint = serverUrl + "/_api/web/getfolderbyserverrelativeurl('" + documentLibraryName +"/"+currentYear+ "')";
               return $.ajax({
               url: fileCollectionEndpoint,
               type: "GET",                      
               headers: {
                              "accept": "application/json;odata=verbose",
                              "X-RequestDigest": window.top.$("#__REQUESTDIGEST").val()
                              },
                              success: function (data) {
                                             alert("Folder already exists");
                      },
               error: function (data) {
                              //Folder does not exist, so create a new folder
                              self.createFolder();
        }
});
};


//Create a folder in document library
self.createFolder = function ()
{
                             
               var fileCollectionEndpoint = serverUrl + "/_api/web/getfolderbyserverrelativeurl('" + documentLibraryName + "')/folders/add(url=\'" + currentYear + "\')";
                                            
               return $.ajax({
                              url: fileCollectionEndpoint,
                              type: "POST",
                              headers: {
                                             "X-RequestDigest":  window.top.$("#__REQUESTDIGEST").val(),
                                             "accept": "application/json;odata=verbose",
                                             "content-type": "application/json;odata=verbose"
                              },
                              success: function (data) {
                                             //alert(‘Folder created successfully’);
                                             },
                                              error: function (jqXHR, textStatus, errorThrown) {
                                                            //handle error...
                                                            alert('Failed to create folder in library.');
                                             }
                              });
               };

References: