java script helper

Measure loading time of the page:
var loadTime = window.performance.timing.domContentLoadedEventEnd-window.performance.timing.navigationStart;
loadTime
function toCamel(o, khet=false) {
  var newO, origKey, newKey, value
  if (o instanceof Array) {
    return o.map(function(value) {
        if (typeof value === "object") {
          value = toCamel(value)
        }
        return value
    })
  } else {
    newO = {}
    for (origKey in o) {
      if (o.hasOwnProperty(origKey)) {
        newKey = (origKey.charAt(0).toLowerCase() + origKey.slice(1) || origKey).toString()
        value = o[origKey]
        if (value instanceof Array || (value !== null && value.constructor === Object)) {
          value = toCamel(value)
        }
        newO[newKey] = value
      }
    }
  }
  return newO
}

 

Add a custom javascript file to SharePoint library using csom

var list = Ctx.Site.GetCatalog((int)ListTemplateType.MasterPageCatalog);
Ctx.Load(list);
Ctx.ExecuteQuery();

var rootFolder = list.RootFolder;
Ctx.Load(rootFolder);
Ctx.ExecuteQuery();

bool displayTemplateExists = DisplayTemplateExists(Ctx, list, ProjectStatusAll.Title);
string destFileName = rootFolder.ServerRelativeUrl + “/Display Templates/Content Web Parts/” + “Item_ProjectStatusAll.js”;
string content = ProjectStatusAll.Content;
string ctId = “0x0101002039C03B61C64EC4A04F5361F38510660500E478F12A266BD24B842D0B2128BDDAAB”;

var fields = new List<KeyValuePair<string, string>>();

fields.Add(new KeyValuePair<string, string>(“Title”, ProjectStatusAll.Title));
fields.Add(new KeyValuePair<string, string>(“TargetControlType”, ProjectStatusAll.TargetControlType));
fields.Add(new KeyValuePair<string, string>(“DisplayTemplateLevel”, ProjectStatusAll.DisplayTemplateLevel));
fields.Add(new KeyValuePair<string, string>(“TemplateHidden”, ProjectStatusAll.TemplateHidden));
fields.Add(new KeyValuePair<string, string>(“ManagedPropertyMapping”, ProjectStatusAll.ManagedPropertyMapping));

if (!displayTemplateExists)
{
CreateFile(Ctx, list, content, Encoding.UTF8, destFileName, ctId, fields, false);
}

 

public File CreateFile(ClientContext Ctx, List list, string content, Encoding encoding, string destFileName, string ctId, List<KeyValuePair<string, string>> fields, bool overwrite)
{
// Verify encoding
if (encoding == null)
{
throw new ArgumentNullException(“encoding”);
}

if (list == null)
{
throw new ArgumentNullException(“list”);
}

FileCreationInformation fileCreateInfo = new FileCreationInformation();
fileCreateInfo.Url = destFileName;
fileCreateInfo.Content = encoding.GetBytes(content);
fileCreateInfo.Overwrite = overwrite;

File createdFile = list.RootFolder.Files.Add(fileCreateInfo);
Ctx.Load(createdFile);
Ctx.ExecuteQuery();

ListItem item = createdFile.ListItemAllFields;

item[“ContentTypeId”] = ctId;

foreach (var field in fields)
{
item[field.Key] = field.Value;
}

item.Update();
Ctx.ExecuteQuery();

return createdFile;
}

Get SharePoint site/subsites template using javascript

var siteCollections = [
https://forvaltningdev.sharepoint.com&#8221;
];

siteCollections.forEach(function (site) {
var webCollection = null;
function getWebTemplate() {
var context = new SP.ClientContext(site);
//var context = SP.ClientContext.get_current();
var web = context.get_web();
context.load(web);
context.executeQueryAsync(
function () {
var webTemplate = web.get_webTemplate();
var configuration = web.get_configuration();

var templateName = webTemplate + “#” + configuration;
var isTeamSite = templateName === “STS#0”;

console.log(site + “,” + templateName + “,,” + (isTeamSite? “Classic Team Site”: “”));

$.ajax({
url: site + “/_api/web/webs/?$select=title,ServerRelativeUrl,Created,webTemplate,configuration”,
method: “GET”,
headers: {
“Accept”: “application/json; odata=verbose”
},
success: function (data) {
$.each(data.d.results, function (index, item) {
templateName = item.WebTemplate + “#” + (item.Configuration + 1);
isTeamSite = templateName === “STS#0”;

console.log(site + item.ServerRelativeUrl + “,” + templateName + “,,” + (isTeamSite ? “Classic Team Site” : “”));
});
},
error: function (data) {
//console.log(site + “,,Unable to get sub sites”);
}
});

},
function (sender, args) {
//console.log(site + “,,Unable to check the site template”);
}
);
}
getWebTemplate();
});

Build your first project with angularjs and typescript in Visual Studio

1. Create new ASP.Net Web Application, remember to select the empty template

2. Open Command Line window and go to your project folder

3.

npm init

4.

npm install typescript --save-dev

5.

npm install @types/angular --save

6.

npm install angular

7. Create a tsconfig.json like this:

{
        “compileOnSave”: true,
        “compilerOptions”: {
                  “noImplicitAny”: false,
                  “noEmitOnError”: true,
                  “removeComments”: true,
                  “sourceMap”: true,
                  “target”: “es5”
         },
         “include”: [
                  “Scripts/*”
         ]
}

8. Create a file “Index.html” in your root folder

<!DOCTYPE html>
<html>

<head>
         < script src=”/node_modules/angular/angular.js”></script>
         < script src=”scripts/script.js”></script>
</head>

<body>
         <myangularjs></myangularjs>
</body>

</html>

9. Create a folder “Scripts” and add a new ts file “script.ts” in it

var module = angular.module(“myAwesomeApp”, []);

module.component(“myangularjs”, {
         template: “This is my template”,
         controller: function myAngularJSController() { },
         controllerAs: “$ctrl”
});

angular.element(document).ready(function () {
         angular.bootstrap(document, [“myAwesomeApp”]);
});

Here is the completed structure, please press F5 to see what happen:

CompleteStructure.png

 

Access SharePoint Online using Javascript

Thanks SHANTHA KUMAR for his really nice post: http://www.ktskumar.com/2017/01/access-sharepoint-online-using-postman/

What I need here is just convert it to using Javascript:

function connectingToSP() {
(function () {
var cors_api_host = ‘cors-anywhere.herokuapp.com’;
var cors_api_url = ‘https://&#8217; + cors_api_host + ‘/’;
var slice = [].slice;
var origin = window.location.protocol + ‘//’ + window.location.host;
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function () {
var args = slice.call(arguments);
var targetOrigin = /^https?:\/\/([^\/]+)/i.exec(args[1]);
if (targetOrigin && targetOrigin[0].toLowerCase() !== origin &&
targetOrigin[1] !== cors_api_host) {
args[1] = cors_api_url + args[1];
}
return open.apply(this, args);
};
})();

var spURL = “https://ideasportal.sharepoint.com&#8221;;

function getWWWAuthentication() {
var dfd = $.Deferred();

$.ajax({
url: spURL,
data: null,
type: “GET”,
beforeSend: function (xhr) { xhr.setRequestHeader(‘Authorization’, ‘Bearer’); },
success: function () {
dfd.resolve(“ERROR”);
},
error: function (jqXHR, status) {
dfd.resolve(jqXHR.getResponseHeader(“www-authenticate”));
}
});

return dfd.promise();
}

function generateAccessToken(wwwAuthenticate) {
var dfd = $.Deferred();

if (wwwAuthenticate.indexOf(“realm”) >= 0) {
var wwwAuthenticateInfo = wwwAuthenticate.split(“,”);
var realm = wwwAuthenticateInfo[0].split(“=”)[1].replace(‘”‘, ”).replace(‘”‘, ”);
var client_id = wwwAuthenticateInfo[1].split(“=”)[1].replace(‘”‘, ”).replace(‘”‘, ”);

var appClientId = “6982a6e1-4df4-48e1-a745-94ba99bd4901”;
var appClientSecret = “2Oz3HMthr+hzi9gTFgIZTv3Fwe+Y9n/L8VUg1XzOCIk=”;

var tenantId = realm;
var grant_type = “client_credentials”;
var newClientId = appClientId + “@” + tenantId;
var client_secret = appClientSecret;
var resource = client_id + “/” + spURL.replace(“https://&#8221;, “”) + “@” + tenantId;

var details = {
‘grant_type’: grant_type,
‘client_id’: newClientId,
‘client_secret’: client_secret,
‘resource’: resource
};

var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + “=” + encodedValue);
}
var strFormBody = formBody.join(“&”);

$.ajax({
url: “https://accounts.accesscontrol.windows.net/&#8221; + tenantId + “/tokens/OAuth/2”,
type: “POST”,
headers: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’
},
data: strFormBody,
processData: false,
success: function (response) {
var authorizationToken = response.token_type + ” ” + response.access_token;
dfd.resolve(authorizationToken);
},
error: function (jqXHR, status) {
dfd.resolve(“ERROR”);
}
});

} else {
dfd.resolve(“ERROR”);
}

return dfd.promise();
}

function accessSPResource(authorizationToken) {
var dfd = $.Deferred();

$.ajax({
url: spURL + “/_api/web?$select=Title”,
data: null,
type: “POST”,
beforeSend: function (xhr) {
xhr.setRequestHeader(‘Accept’, ‘application/json;odata=verbose’);
xhr.setRequestHeader(‘Authorization’, authorizationToken);
},
success: function (spResponse) {
dfd.resolve(spResponse.d);
},
error: function (jqXHR, status) {
dfd.resolve(“ERROR”);
}
});

return dfd.promise();
}

function handleSPResource(spResponse) {
console.log(spResponse.Title);
}

getWWWAuthentication()
.then(generateAccessToken)
.then(accessSPResource)
.then(handleSPResource);
}

connectingToSP();

 

How to get SPAppToken in Office 365 and use it in your Provider-Hosted app?

When you log in to your SharePoint site in Office 365, the site will generate a SPAppToken  and cache it somewhere for you to use in App. So, you need this token to open the ClientContext in your Provider-hosted app. When you add an app to your page, it will go to the appredirect.aspx with some parameters:

redirect_uri: App url with the formatting like this:

1:  https://yourproviderhosted.cloudapp.net/ProjectSite?SPHostUrl=https://youroffice365.sharepoint.com/sites/yoursitecollection&SPHostTitle=Your SharePoint Site Title&SPAppWebUrl=”&SPLanguage=en-US&SPClientTag=1&SPProductNumber=16.0.2016.1224&SenderId=E73DC26C0  

client_id: This is an app principle id with the formatting like this:

1:  i:0i.t|ms.sp.ext|48384dfb-52f9-4f04-9a53-dfad0028cbf2@dad0be63-dbfb-4bb2-ab26-ce292a09cff8  

But the problem here is the App only exist at the site where you add it, if you want to use this app again in sub site, you must add it again. In my scenario, I want to add an app only one time at root site collection, and can use it every where in this site collection, include sub site. How I do this?

Step 1: You need to know an app instance id via app product id. You can see the ProductId at the AppManifest.xml of App project, keep this id to javascript variable.

1. Declare some variables to store your context

1:  var clientContext = {};  
2:  var rootWeb = {};  
3:  var appInstance = {};  
4:  var yourAppProductId = '6d510a27-38f7-4d0f-9e67-dac426cc5a3d';

2. Load the root web in your site collection

1:  function loadRootWeb() {  
2:    clientContext = SP.ClientContext.get_current();  
3:    var site = clientContext.get_site();  
4:    clientContext.load(site);  
5:    rootWeb = site.get_rootWeb();  
6:    clientContext.load(rootWeb);  
7:    clientContext.executeQueryAsync(loadRootWebSuccessed, loadRootWebFailed);  
8:  };  

3. In the function “loadRootWebSuccessed”, get appPrincipalId by your AppProductId

1:  function loadRootWebSuccessed() {  
2:    appInstance = rootWeb.getAppInstancesByProductId('{' + yourAppProductId + '}');  
3:    clientContext.load(appInstance);  
4:    clientContext.executeQueryAsync(loadAppRedirect, errorHandler);  
5:  };  

4. Get appInstanceId and load appredirect.aspx with that instanceId

1:  function loadAppRedirect() {  
2:    var appEnumerator = appInstance.getEnumerator();  
3:    var hasNext = appEnumerator.moveNext();  
4:    if (hasNext) {  
5:      var oApp = appEnumerator.get_current();  
6:      var appInstanceId = oApp.get_id().toString();//     "6c2ca931-e661-4cff-bb71-66be022e1763"     String  
7:      var appPrincipalId = oApp.get_appPrincipalId().toString();//     "i:0i.t|ms.sp.ext|48384dfb-52f9-4f04-9a53-dfad0028cbf2@dad0be63-dbfb-4bb2-ab26-ce292a09cff8"     String  
8:      var hostWebUrl = _spPageContextInfo.siteAbsoluteUrl;  
9:      var iframeAppRedirectId = 'appRedirectFrame';  
10:      var iframeAppRedirectSrc = hostWebUrl + "/_layouts/15/appredirect.aspx?instance_id=" + appInstanceId;  
11:      $('body').append('

‘); 12: $(“#” + iframeAppRedirectId).load(iframeAppRedirectSrc + ” #frmRedirect”, function () { 13: getAppInformation(); 14: }); 15: } 16: }

Step 2: Get all needed information of an app in function getAppInformation, include SPAppToken

1:  function getAppInformation() {  
2:    var inputSPAppToken = $('#frmRedirect').find('input[name="SPAppToken"]')[0];  
3:    var formAction = inputSPAppToken.form.action;  
4:    var spAppToken = inputSPAppToken.value;  
5:    var spLanguage = getQuerystringParamValue(formAction, "SPLanguage");  
6:    var spHostUrl = _spPageContextInfo.webAbsoluteUrl;//getQuerystringParamValue(formAction, "SPHostUrl");  
7:    var spClientTag = getQuerystringParamValue(formAction, "SPClientTag");  
8:    var spProductNumber = getQuerystringParamValue(formAction, "SPProductNumber");  
9:    var appUrl = getAppUrlByAction(formAction);  
10:  }  
1:    function getQuerystringParamValue(url, paramName) {  
2:      paramName = paramName.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");  
3:      var regex = new RegExp("[\\?&]" + paramName + "=([^&#]*)"),  
4:        results = regex.exec(url);  
5:      return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));  
6:    };  
1:    function getAppUrlByAction(url) {  
2:      return getRootUrl(url.split('?')[0]);  
3:    };  

That’s all!

Calling a WCF Service using jQuery in SharePoint

Wictor Wilén have a nice post for this article here. But I want to show you my way to create a WCF service for SharePoint

1. Add SharePoint mapped folder “ISAPI” to your project
2. In “ISAPI”, create new folder with the same name with your project name
3. Add new Web.config file into the new folder with some very basic configuration

1:  <?xml version="1.0" encoding="utf-8"?>  
2:  <configuration>  
3:   <system.serviceModel>  
4:    <behaviors>  
5:     <serviceBehaviors>  
6:     </serviceBehaviors>  
7:    </behaviors>  
8:    <bindings>  
9:    </bindings>  
10:    <services>  
11:    </services>  
12:   </system.serviceModel>  
13:  </configuration>  

4. Add new svc file with the content like this”:

1:  <%@ ServiceHost   
2:    Language="C#"   
3:    Service="My.Services.Client.NewsArticleServices, My.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=393b1a9faf7ecfca"   
4:    Factory="Microsoft.SharePoint.Client.Services.MultipleBaseAddressWebServiceHostFactory, Microsoft.SharePoint.Client.ServerRuntime, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>  

5. In service dll, add new class named “NewsArticleServices” with content like this:

1:  using System;  
2:  using System.Collections.Generic;  
3:  using System.Linq;  
4:  using System.Text;  
5:  using System.ServiceModel;  
6:  using System.ServiceModel.Activation;  
7:  using System.ServiceModel.Web;  
8:  using Microsoft.SharePoint;  
9:  using Microsoft.SharePoint.Taxonomy;  
10:  using System.Globalization;  
11:  using System.Web;  
12:  using Microsoft.SharePoint.Utilities;  
13:  using Microsoft.SharePoint.Client.Services;  
14:  using System.Runtime.Serialization;  
15:  namespace My.Services.Client  
16:  {  
17:    [BasicHttpBindingServiceMetadataExchangeEndpointAttribute]  
18:    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]  
19:    [ServiceContract]  
20:    public class NewsArticleServices  
21:    {  
22:      [OperationContract]  
23:      [WebGet(BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]  
24:      public Model.Client.News GetLatestNewsArticle()  
25:      {  
26:        Logger.LogVerbose(this, LayerNames.Services, "GetLatestNewsArticle", "Enter -->");  
27:        var result = new Model.Client.News();  
28:        try  
29:        {  
30:          var webUrl = SPContext.Current.Web.Url;  
31:          SPSecurity.RunWithElevatedPrivileges(() =>  
32:          {  
33:            using (var elevSite = new SPSite(webUrl))  
34:            {  
35:              using (var web = elevSite.OpenWeb())  
36:              {  
37:                Services.NewsArticleServices service = new Services.NewsArticleServices(web);  
38:                result = service.GetLatestNewsArticle();  
39:              }  
40:            }  
41:          });  
42:        }  
43:        catch (Exception ex)  
44:        {  
45:          Logger.LogError(this, LayerNames.Services, "GetLastedNewsArticle", "Can't get latest news article.", ex);  
46:        }  
47:        finally  
48:        {  
49:          Logger.LogVerbose(this, LayerNames.Services, "GetLatestNewsArticle", "Exit -->");  
50:        }  
51:        return result;  
52:      }  
53:    }  
54:  }  

6. Add javascript file to layouts folder with the function:

1:    function getLatestNewsArticle() {  
2:      $.ajax({  
3:        type: "GET",  
4:        url: L_Menu_BaseUrl + '/_vti_bin/YourProjectName/ClientNewsArticleServices.svc/GetLatestNewsArticle',  
5:        contentType: "application/json; charset=utf-8",  
6:        dataType: "json",  
7:        data: getParams(L_Menu_BaseUrl),  
8:        success: function (data) {  
9:          alert('Successed!');  
10:        },  
11:        error: function (err) {  
12:          alert('Failed');  
13:        }  
14:      });  
15:    }  

That’s all!