Showing posts with label JSOM. Show all posts
Showing posts with label JSOM. Show all posts

June 16, 2017

Create a subsite programmatically using Custom Site Template through SharePoint JavaScript Object Model and REST API

Here, I'll explain you in detail how to create SharePoint sub-site programmatically using custom Site Templates through JSOM and REST API.
 
Implementation Approach: First, we need to identify Web Template Id for our custom template. programmatically. And then, we will a create sub-site using the Web Template Id.

Let's go through the code snippet, now. We have two functions in code snippet:

1. CreateSubsiteByTemplateName(title, description, webUrl, templateTitle) 
- This function will create a sub-site by Template Name. First of all, it will find out the Template Id from Template Name, and then, will call another function to create the sub-site.
Parameters Information:
    1. title= name of sub-site which you want to create Ex: "subsite1"
    2. description = description for sub-site
    3. weburl = URL for sub-site Ex: "subsite1"
    4. templateTitle= Name of custom template Ex: "Physicians"

2. CreateSubsiteByTemplateId(title, description, webUrl, templateId)
- This function will create a sub-site by Template Id.
Parameters Information:
    1. title= name of sub-site which you want to create Ex: "subsite1"
    2. description = description for sub-site.
    3. weburl = URL for sub-site Ex: "subsite1"
    4. templateId= Id of custom template Ex: "{D5729655-B3D8-4DED-B5E9-3EE09934FC80}#Physicians"

Code Snippet 1:
 function CreateSubsiteByTemplateName(title, description, webUrl, templateTitle) {   
   var context = new SP.ClientContext.get_current();   
   var web = context.get_web();   
   context.load(web);   
   var webTemplates = web.getAvailableWebTemplates(1033, false);   
   context.load(webTemplates);   
   context.executeQueryAsync(function () {   
    var enumerator = webTemplates.getEnumerator();   
    var templateId = "STS#0";   
    while (enumerator.moveNext()) {   
     var webTemplate = enumerator.get_current();   
     var webTitle = webTemplate.get_title();   
     if (webTitle == templateTitle) {   
      templateId = webTemplate.get_name();  
      break;   
     }   
    }   
    CreateSubsiteByTemplateId(title, description, webUrl, templateId);   
   },   
    function (sender, args) {   
     alert(args.get_message())   
    }   
   );   
  }  

Code Snippet 2:
 function CreateSubsiteByTemplateId(title, description, webUrl, templateId) {    
   var restAPIURL = "/_api/web/webinfos/add";    
   var newSiteData = JSON.stringify(    
   {    
   'parameters': {    
    '__metadata': {    
    'type': 'SP.WebInfoCreationInformation'    
    },    
    'Url': webUrl,    
    'Description': 'Subsite created from REST API',    
    'Title': title,    
    'Language': 1033,    
    'WebTemplate': templateId,    
    'UseUniquePermissions': true    
   }    
   });    
   $.ajax    
   ({    
   url: restAPIURL,    
   type: "POST",    
   async: false,    
   data: newSiteData,    
   headers: {    
    "accept": "application/json;odata=verbose",    
    "content-type": "application/json;odata=verbose",    
    "X-RequestDigest": $('#__REQUESTDIGEST').val()    
   },    
   success: function (data) {    
    console.log('site created');    
   },    
   error: function (data) {    
    console.log('Error creating site');    
   }    
   });    
  }    

If you have any questions you can reach out our SharePoint Consulting team here.

September 8, 2016

Injecting Javascript file through SharePoint Hosted App

A requirement came across was to execute a JavaScript on all the pages of SharePoint Site. Here, option of achieving the functionality by developing custom master page was eliminated as we were dealing with a SharePoint Hosted App. It is also easy to achieve through server side but need to find solution on client side as SharePoint Hosted App has everything on client side. Finally, we found a solution to inject the JavaScript using Custom Action.

JavaScript Object Model (JSOM) allows us to programmatically register Custom Action with Host Web in a way similar to declarative approach used with Farm or Sandboxed Solution. In order to register a Custom Action using JSOM, your app requires the Full Control permission on the Site/Site Collection where you want to register it.

To achieve this, we need to perform two steps as below:
  1. Provisioning the JavaScript file from App web to Host web
  2. Registering the Custom action with the file path referring to that JavaScript file in the Host web.

1. Provisioning the JavaScript file from app web to host web:

function uploadFileToHostWebViaCSOM(serverRelativeUrl, filename, contents) {      
        var executor = new SP.RequestExecutor(window.appWebUrl);
        executor.executeAsync(
                {
                    url: window.appWebUrl + "/_api/SP.AppContextSite(@target)/web/GetFolderByServerRelativeUrl('" + serverRelativeUrl + "')/Files?@target='" + window.hostWebUrl + "'",
                    method: "GET",
                    headers: { "Accept": "application/json; odata=verbose" },
                    success: function (data) {
                        var jsonObject = JSON.parse(data.body);
                        var createInfo = new SP.FileCreationInformation();
                        createInfo.set_content(new SP.Base64EncodedByteArray());
                        for (var i = 0; i < contents.length; i++) {
                            createInfo.get_content().append(contents.charCodeAt(i));
                        }
                       createInfo.set_url(filename);
                       createInfo.set_overwrite(true);
                       var files = hostWebContext.get_web().getFolderByServerRelativeUrl(serverRelativeUrl).get_files();
                       var isexist = false;
                        jsonObject.d.results.forEach(function (item, index) {
                            if (item.Name == filename)
                                isexist = true;
                        });
                        if (isexist)
                            files.getByUrl(filename).checkOut();
                        var file = files.add(createInfo);
                        file.checkIn('Add-in deployment.');
                        file.publish('Add-in deployment.');

                        appWebContext.load(file);
                        appWebContext.executeQueryAsync(success, function (sender, args) {
                            alert(args.get_message());
                        });
                    },
                    error: function (data, errorCode, errorMessage) {
                        console.log("error");
                    }
                });
    };


Here, we are first fetching the file from app web and checking that whether it exists in host web or not. If the file exists then we will update the existing file, check in and publish it. If the file does not exist then we just add the file, check in and publish it.

2. Registering the custom action with the file path:

var context = web.get_context();
var webs = web.get_webs();
var actions = web.get_userCustomActions();
context.load(actions);
context.load(webs, 'Include(Title,Webs)');
context.executeQueryAsync(function () {

  var newAction = actions.add();
  // the 'description' is what we'll use to uniquely identify our custom action
  newAction.set_description(actionDescription);
  newAction.set_location('ScriptLink');
  newAction.set_scriptBlock(getScripts(window.hostWebUrl + '/Style Library/EasyNav/Scripts/tinysort.min.js'));
  newAction.set_sequence(1004);
  newAction.update();

  context.executeQueryAsync(function () { }, fail);
}, fail);

The above code adds a custom action on a web object in Host web. Wherein,
set_location specifies it is a script registration action,
set_scriptBlock indicates the JavaScript file's path in host web,
set_sequence specifies the sequence in which the files are to be loaded if there is more than one.

Once above code will be executed through custom action, we can see all JavaScript files loaded on all the pages of the SharePoint Site.

If you have any questions you can reach out our SharePoint Consulting team here.

July 28, 2016

Client Side People Picker with JSOM in Office 365/SharePoint 2013

Requirement:
In one of the project, I had a requirement to use people picker in Client side HTML which should have same features as SharePoint OOTB people picker provides.

PeoplePicker.png

Approach/Solution:
Follow below steps to achieve client side people picker functionality using JSOM.

1. Below mentioned JS files are required to load client side people picker using JSOM. All
JS
files are OOTB SharePoint JS files which are available under "_layouts/15" folder in
SharePoint.
- clienttemplates.js
- clientforms.js
- clientpeoplepicker.js
- autofill.js
- sp.js
- sp.runtime.js
- sp.core.js
2. Put reference of all JS files into HTML file for which you want to create Client Side People
Picker.
3. Add below Div tag in your HTML file.
<div id="peoplePickerDiv"></div>
4. Add below code in your custom JS file (custompeoplepicker.js) and also put reference of this file into HTML file.
        // Initialize People Picker.   
 $(document).ready(function() {  
 // Specify the unique ID of the DOM element where the  
 // picker will render.  
 initializePeoplePicker('peoplePickerDiv');  
  });  
 // Render and initialize the client-side People Picker.  
 function initializePeoplePicker(peoplePickerElementId) {  
  // Create a schema to store picker properties, and set the properties.  
  var schema = {};  
  schema['PrincipalAccountType'] = 'User,DL,SecGroup,SPGroup';  
  //This value specifies where you would want to search for the valid values
  schema['SearchPrincipalSource'] = 15;             
  //This value specifies where you would want to resolve for the valid values
  schema['ResolvePrincipalSource'] = 15;  
schema['AllowMultipleValues'] = true;  
  schema['MaximumEntitySuggestions'] = 50;  
  schema['Width'] = '280px';  
  // Render and initialize the picker.  
// Pass the ID of the DOM element that contains the picker, an array of initial   
// PickerEntity objects to set the picker value, and a schema that defines  
// picker properties.    
this.SPClientPeoplePicker_InitStandaloneControlWrapper(
peoplePickerElementId, null, schema);  
                        }
                         // Get user information from client side people picker.
  // Query the picker for user information.

 function getUserInfo() {
  // Get the people picker object from the page.
  var peoplePicker = this.SPClientPeoplePicker.SPClientPeoplePickerDict.peoplePickerDiv_TopSpan;
// Get information about all users.
var users = peoplePicker.GetAllUserInfo();
var userInfo = '';
for (var i = 0; i < users.length; i++) {
var user = users[i];
for (var userProperty in user) {
userInfo += userProperty + ':  ' + user[userProperty] + '<br>';
}
}
// Get user keys.
var keys = peoplePicker.GetAllUserKeys();
// Get the first user's ID by using the login name.
getUserId(users[0].Key);
}
// Get the user ID.
function getUserId(loginName) {
var context = new SP.ClientContext.get_current();
this.user = context.get_web().ensureUser(loginName);
context.load(this.user);
context.executeQueryAsync(
Function.createDelegate(null, ensureUserSuccess),
Function.createDelegate(null, onFail)
);
}
function ensureUserSuccess() {
console.log(this.user.get_id());
}
function onFail(sender, args) {
alert('Query failed. Error: ' + args.get_message());
}

// Below code sets values into client side people picker.
var divPeople = SPClientPeoplePicker.SPClientPeoplePickerDict.PeoplePickerDiv_TopSpan;
PeoplePickerDiv_TopSpan - Specify the unique ID of the DOM element where the picker will render.
var userObj = { 'Key': "sample@sample.com" };
divPeople.AddUnresolvedUser(userObj, true);

If you have any questions you can reach out our SharePoint Consulting team here.