Sivarajan's Blog

SharePoint | Office 365 | Azure | JavaScript

Client WebPart Starter Project for SharePoint On-Premise / Online using AngularJs with Gulp

Overview SharePoint Framework is completely a client side development model and Microsoft is going to release it soon. As per their notes, this will support only SharePoint Online and SharePoint 2016. This post is mainly who is currently working with SharePoint 2010/2013. Instead of developing a Visual/Standard WebPart, you can build the entire development using front-end technologies (AngularJs, ReactJs or KnockoutJs) and later you can easily convert it into SharePoint Framework easily. Tools and Frameworks I have used the following tools and frameworks for build the starter project. Visual Studio Code and JavaScript IntelliSense This is an open source and cross-platform IDE. Here you can find more details about VS Code and why I used for client side development. Similarly, you can find that how to enable the JavaScript IntelliSense for your project. Node.Js and NPM I have used Node.Js for build and deployment and NPM for install the node packages (AngularJs, Gulp, etc.). Here you can find more details about Node.Js and NPM Gulp This is a build automation tool.  Here you can find more details about Gulp Office UI Fabric This is UI framework for Office 365 and SharePoint, similar to Bootstrap. You can ignore if you are not familiar with this. Setup the Project in Local Machine Please make sure that you installed and configured Visual Studio Code, NodeJs and Gulp properly. If everything is working properly then, you can continue further. You can download the starter project from GitHub location and extract zip file in your local machine. Open the folder in VS code. Package.json file Open the package.json and you can find the two attributes dependencies and devDependencies. { "name": "spo-ng-officeuifabric-gulp", "version": "1.0.0", "description": "SharePoint Angular Office UI Fabric Starter App with Gulp", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Sivarajan Raju", "license": "MIT", "dependencies": { "angular": "^1.5.8", "angular-router": "0.0.2", "ng-office-ui-fabric": "^0.12.2", "office-ui-fabric": "^2.6.1" }, "devDependencies": { "gulp": "^3.9.1", "gulp-changed": "^1.3.1", "gulp-concat": "^2.6.0", "gulp-notify": "^2.2.0", "gulp-sourcemaps": "^1.6.0", "gulp-spsync": "wictorwilen/gulp-spsync", "gulp-uglify": "^1.5.4", "gulp-watch": "^4.3.9" } } Open the extracted file location in the command prompt and run the below command. > npm install Now all the dependencies will be installed in your local machine and you can see the modules under node_modules folder. Gulpfile.js file The next important file is Gulpfile.js file. Open this file and you can find the multiple tasks. Lets see in detail below. This is a list of gulp related plug-ins I used.var gulp = require('gulp'); var uglify = require('gulp-uglify'); var concat = require('gulp-concat'); var notify = require('gulp-notify'); var sourcemaps = require('gulp-sourcemaps'); var changed = require('gulp-changed'); var sp = require('gulp-spsync'); var watch = require('gulp-watch'); //Change your project name here var PROJECT_NAME = 'spo-ng-officeuifabric-gulp'; Authentication Settings I have used gulp-spsync plug-in for for synchronizing local files with a SharePoint library. We need to create security token for SharePoint authentication. Please follow this link to create the client_id ad client_secret and update settings section. var settings = { "client_id":"your here client", "client_secret":"your here client code secret", "realm" : "", "site" : "https://your tenent.sharepoint.com/", "verbose": "true" }; Task : build-app //Combine all the JavaScript files (Controllers and Services) under the App folder and create 'combined.js' file for upload to SharePoint. //with sourcemaps for debugging gulp.task('build-app', function () { console.log('start - dev task'); return gulp.src(SOURCE_APP_SCRIPT_PATH) .pipe(sourcemaps.init()) .pipe(concat('combined.js')) .pipe(sourcemaps.write()) .pipe(gulp.dest(DEST_APP_SCRIPT_PATH)); }); Task : spupload-app //Call the build-app task and then upload the combined.js to SharePoint gulp.task('spupload-app',['build-app'], function() { console.log('starting spupload-app'); return gulp.src('content/**/scripts/*.*') .pipe(sp(settings)) }); Task : spupload-views //upload the HTML templates from content/_catalogs/masterpage/spo-ng-officeuifabric-gulp/views folder to SharePoint gulp.task('spupload-views', function() { return gulp.src('content/**/views/*.*') .pipe(changed('_build')) .pipe(sp(settings)) .pipe(gulp.dest('_build')) }); Task: watch //Whenever we modify the JavaScript files or HTML templates, this task will help to upload the modified file to SharePoint immediately. gulp.task('watch', function() { gulp.watch('content/**/views/*.*', ['spupload-views']); gulp.watch('app/**/*.js', ['spupload-app']); }); Task: copy-npmjs //Each npm packages will have a minified and unminified JavaScript files with documentations. //But we need only minified versions and run this task to copy the mentioned js files to our content folder gulp.task('copy-npmjs', function () { console.log('starting external-scripts task'); return gulp.src([ /* JS Files */ 'node_modules/angular/angular.min.js', 'node_modules/ng-office-ui-fabric/ngOfficeUiFabric.min.js' ]).pipe(gulp.dest(DEST_EXTERNAL_SCRIPTS_PATH)); }); Task: copy-npmcss //Each npm packages will have a minified and unminified CSS files with documentations. //But we need only minified versions and run this task to copy the mentioned css files to our content folder gulp.task('copy-npmcss', function () { console.log('starting external-scripts task'); return gulp.src([ /* CSS Files */ 'node_modules/office-ui-fabric/dist/css/fabric.css', 'node_modules/office-ui-fabric/dist/css/fabric.components.css' ]).pipe(gulp.dest(DEST_EXTERNAL_CSS_PATH)); }); Task: spupload //Upload all the files from content folder to SharePoint including external JavaScripts gulp.task('spupload', function() { return gulp.src('content/**/*.*') .pipe(sp(settings)) .pipe(gulp.dest('_build')) }); Run the gulp task. > gulp <task name> >gulp spupload Now all your files under content folder will be uploaded to SharePoint master page gallery. https://<your tenent>.sharepoint.com/_catalogs/masterpage/Forms/AllItems.aspx   Use the following gulp task for incremental uploads, > gulp watch View the Results We can view the results by using Script/Content Editor. I have used content editor webpart. Add the two content editor webpart in your SharePoint page and set the content link to /_catalogs/masterpage/spo-ng-officeuifabric-gulp/views/include-script.html and /_catalogs/masterpage/spo-ng-officeuifabric-gulp/views/main.html respectively. Summary The advantages of the approach is, while you are working in your local machine, the latest changes will be combined and minified and will be uploaded silently to SharePoint. You can see the latest changes by simply refresh your SharePoint page. I tested this starter project against SharePoint online. For SharePoint On-premises, you need to include the following gulp plug-in additionally. https://github.com/estruyf/gulp-spsync-creds Please let me know if you are facing any issues. Download Source

How to automate the Content Types provision in SharePoint Online using Client Object Model – Part 2

This post is a continuation of the previous post. We have discussed that how to automate the Site Columns creation using Client Object Model. Now we will see that how to automate the Content Types creation. 1. Download and open the “SiteProvising” solution. 2. Once you create the site columns as I mentioned in part 1, we are ready to create the content type. 3. Right click the “Contoso.IntranetAssets” project and add the new folder “Content Types”. 4. Right click the “Content Types” folder and add the new item “Content Type” and name it as “Employee” and leave the base content type as “Item”. 5. Now select the site columns “Employee Name”, “Employee Age” and “Employee Address”. 6. Now run the “SiteProvisioning” project and select the option “Content Types”. 7. All the site columns will be created in the associated site collection. Here is a source code for Content Type automation. You can create the multiple content types under the folder “Content Types”. The above code will collect all the content types’ elements files and provision in the associated site collection. I have detailed blog here why I choose this approach.

How to automate the Site Columns provision in SharePoint Online using Client Object Model – Part 1

In SharePoint on-premises, we can connect site collection directly with Visual Studio and can able to provision the site columns using element files. But Visual Studio does not support the same operations for SharePoint Online and will support only for Add-Ins / SharePoint Apps (Provider/hosted). Here are the alternative options for creating the site columns directly with site collections in SharePoint Online. 1. SharePoint User Interface through browser. 2. SharePoint Designer 3. SharePoint Online Client Object Model 4. SharePoint Online PowerShell + Client Object Model From Vesa Juvonen blog, you can find the sample for creating the Site Columns, Content Types using SharePoint Online Client Object Model http://blogs.msdn.com/b/vesku/archive/2014/03/20/office365-multilingual-content-types-site-columns-and-site-other-elements.aspx http://www.microsoft.com/en-us/download/details.aspx?id=42038 We need to write a lot of coding for provisioning the Site Assets using the Client Object Model. To overcome this issue, I wrote a small utility for that. In SharePoint on-premises, we can connect site collection directly with Visual Studio and can able to provision the site columns using element files. But Visual Studio does not support the same operations for SharePoint Online and will support only for Add-Ins / SharePoint Apps (Provider/hosted). Here are the alternative options for creating the site columns directly with site collections in SharePoint Online. 1. SharePoint User Interface through browser. 2. SharePoint Designer 3. SharePoint Online Client Object Model 4. SharePoint Online PowerShell + Client Object Model From Vesa Juvonen blog, you can find the sample for creating the Site Columns, Content Types using SharePoint Online Client Object Model http://blogs.msdn.com/b/vesku/archive/2014/03/20/office365-multilingual-content-types-site-columns-and-site-other-elements.aspx http://www.microsoft.com/en-us/download/details.aspx?id=42038 We need to write a lot of coding for provisioning the Site Assets using the Client Object Model. To overcome this issue, I wrote a small utility for that. Instead of developing a user interface for provisioning this site assets, I thought to reuse the Visual Studio capabilities here. Let’s go step by step. 1. Download and open the SiteProvisioning Visual Studio solution. Download Source Code 2. Right click the “SiteProvisioning” solution. Click “Add” and then “New Project”. 3. Select the “App for SharePoint” under the Office/SharePoint in the “Add New Project” dialog 4. In the “New app for SharePoint” dialog, provide the debug URL and select the “SharePoint hosted” option. 5. Enter the credential to connect with your SharePoint Online. 6. Now we can see that the new project “Contoso.IntranetAssets” will be added with the existing project “SiteProvisioning”. Note : I created this SharePoint hosted App is only for utilizing the Visual Studio user interface for creating the Site Columns, Site Content Types, Pages, etc.,) and we won’t deploy the SharePoint hosted App anywhere. 7. Right click the solution “Contoso.IntranetAssets” and add the new folder “Site Columns”. 8. Right click the “Site Columns” folder and add the new item. 9. Select the “Site Column” template under “Office/SharePoint” and enter the name as “Employee Registration. 10. Open the “Elements.xml” file under the “Employee Registration” site column folder and the columns “Employee Name”, “Employee Age” and Employee Address”. 11. Similarly, we can create the multiple site columns under the “Site Columns” folder. 12. Here is the code snippets for creating the site columns using client object model. 13. Run the SiteProvisioning project and then provide the site collection credentials. 14. On clicking the “Provision” button, all the site columns related elements files will be located from Contoso.IntranetAssets project location and then site columns will provisioned in the site collection. 15. By changing the site collection URL, we can easily provision the site collection in DEV, QA or Production site. In the next post, we will see that how to automate the Content Types provisions.

Portals Development Challenges in SharePoint Online

I had an opportunities to work with SharePoint Online and Windows Azure related implementations for the last one year. Initially I was struggled a lot to setup a proper development process in SharePoint Online like SharePoint on-premises. We can find a lot of code samples in Office PnP for SharePoint Online development. For the same implementation, we can find the multiple approaches in Office PnP. Even though we don’t have a proper Application Lifecycle Management process for SharePoint Online development. If we want to setup a proper development setup for SharePoint Online like On-premises, we should know that what we are missing in SharePoint Online comparing with on-premises. Let’s take an intranet portal development scenario and recap how we did the same implementation in SharePoint on-premises. How we implement an Intranet Portals in SharePoint on-premises? Here are the list of activities we will follow in SharePoint on-premises for implementing a portal. 1. Setup the environments (Development, QA and Production). 2. Build the SharePoint solutions (WSP) using Visual Studio. Each WSP files may have the following items, a. Modules - Which contains the Master Pages, Site Pages, Page Layouts, Branding Assets ( CSS Style sheets, JavaScript files, 3rd party libraries) b. Site Columns c. Content Types d. List and Library schemas e. Visual and Standard Web Parts (using server side C# or VB.NET code) f. Application Pages g. Visual Studio based Workflow h. BDC model files for Business connectivity Services. i. Feature activation or deactivation code block and event receivers. j. Custom Timer Jobs 3. Deployment PowerShell scripts. 4. If everything is working well in DEV environment then, deploy the same WSP solutions in QA and then production environment. Comparing the Licensing model between SharePoint on-premises and SharePoint Online. Understanding the licensing model is important factor for setup the environments. Let’s assume we are planning an intranet portal for 1000 employees in Contoso Inc., SharePoint on-premises Here the license model will be the combination of SharePoint instances and the number of users count. So we will buy a SharePoint Server licenses for DEV, QA and PROD environments and also a user CAL licenses for 1000 users. SharePoint Online Here the license approach is different and there is not instance based license model. So will buy a licenses based on user counts and not server instance basis. Here are the few licensing options. For setup a full blown environments like on-premises (DEV, QA and PROD), we need to buy a three different domains like contoso.dev, contoso.qa and contoso.prod with 1000 user’s licenses for each domain. This approach is too expensive. Alternatively, buy the single domain with 1000 user’s licenses. We can create and use the multiple site collections for DEV, QA and PROD for intranet portal implementation. But the main challenges are with shared services like Content hub, Taxonomy and Search. This is a cost effective option also. Available Development Approaches in SharePoint Online Let’s see the available development approaches for SharePoint Online development 1. SharePoint Add-Ins based development (or Apps) As my experience, we can develop a multiple isolated modules like leave requests, meeting requests, and employee directory using Add-Ins approach and cannot develop or provision a full blown Intranet Portals using SharePoint Add-Ins. Because each app is loading inside an iframe and have lot of challenges in sharing and presenting the data. Already we have a lot analysis regarding the traditional SharePoint solution development vs. Add-Ins (App) and I am not going to write here the same again. 2. PnP provisioning Engine Customizing the sites using browser and/or SharePoint designer and then use PnP provisioning Engine for moving the customizations from DEV to QA/PROD. Office PnP team has recently released this option for moving customization from one site collection to another. Still the framework is in development and not production ready. 3. Remote Provisioning using Client Object Model Office PnP team has released the SharePoint Online Client SDK and we can provision the customization programmatically. For more information about the remote provisioning http://www.sharepoint-reference.com/Blog/Code%20Samples/Introducing%20the%20PnP%20Provisioning%20Engine.pdf SharePoint Online PowerShell. PowerShell support has enabled for SharePoint Online recently and we cannot provision all the options like SharePoint on-premises. By using the combination of above features, we can build the portals in SharePoint Online. Common Development Activities in SharePoint We can divide an entire portal development activities into three main categories, · Provisioning · Customizing the Out of box features · Custom implementation/development Provisioning As we discussed above, we have multiple options are available for site provisioning in SharePoint Online. But I prefer the remote provisioning using SharePoint Online Client Object. Initially it will required a lot of efforts for building the framework. But the deployment will easier and controllable by developer at any time. 1. How to automate the Site Columns provision in SharePoint Online using Client Object Model – Part 1 2. How to automate the Content Types provision in SharePoint Online using Client Object Model – Part 2 3. How to automate the Lists and Libraries provision in SharePoint Online using Client Object Model – Part 3 4. How to automate the Site Pages provision and embedding the Web Parts in SharePoint Online using Client Object Model – Part 4 5. How to automate the Pages Layouts provision in SharePoint Online using Client Object Model – Part 5 6. Feature Stapling in SharePoint Online using Client Object Model – Part 6 7. Managing the Roles and Site Permissions in SharePoint Online using Client Object Model – Part 7 8. Provisioning the current and global navigations in SharePoint Online using Client Object Model – Part 8 The next series of post, I will cover the OOB customization and custom development.

Generic List Helpers for .NET Client object model in SharePoint 2013/Office 365

Overview We are using lot of helper methods in day to day activities for manipulating the SharePoint list data. In this post, we will see that how to play with Choice and Lookup Field. Retrieving data using Choice Field (Multiple items) In the choice field, we can add the list of string values or numeric values. But always it will return as object and then we will convert the value to array of object or string. public static string GetChoiceValues(object values) { List<string> results = new List<string>(); if (values != null) { string[] arr = ((IEnumerable)values).Cast<object>() .Select(x => x.ToString()) .ToArray(); foreach (string value in arr) { results.Add(value); } return string.Join(";", results.ToArray()); } return string.Empty; }   Alternative Approach : Retrieving data using Choice Field (Multiple items) Now we will write the same code in different way to retrieve the values using Generic type. So here we can avoid explicit type casting on each and every time. public static List<T> GetChoiceFieldValue<T>(object itemValue) { if (itemValue != null) { return ((IEnumerable)itemValue).Cast<object>() .Select(x => (T)Convert.ChangeType(x, typeof(T))) .ToList<T>(); } return null; }   Usage: List<double> values = ListHelper.GetChoiceFieldValue<double>(item["value1"]); So we can use the same helper method for any data types. Sometime, we may require the selected choice field values as string (comma separated), we will use the following code for that, public static string GetChoiceFieldMultiValue(object itemValue, string delimiter)         {             if (itemValue != null)             {                 List<string> values = GetChoiceFieldValue<string>(itemValue);                 if (values != null && values.Count() > 0)                 {                     return string.Join(delimiter, values.ToArray());                 }                 return null;                            }             return null;         } Usage: string value = ListHelper.GetChoiceFieldMultiValue(item["value1"], ";");  Retrieving data using Choice Field (Single item) If the choice field has created with display option either Radio or Dropdown, we can use the following code to retrieve the selected single value from that. public static T GetChoiceFieldSingleValue<T>(object itemValue)         {             if (itemValue != null)             {                 return (T)Convert.ChangeType(itemValue, typeof(T));             }             return default(T);         } Retrieving data using Lookup Field (Allow Multiple Items) Similarly, we will see how to retrieve the values from Lookup column if the lookup has created with multiple value selection option.         public static List<T> GetLookupFieldValue<T>(object itemValue)         {             if (itemValue != null)             {                 var itemValueArray = itemValue as Microsoft.SharePoint.Client.FieldLookupValue[];                 if (itemValueArray != null && itemValueArray.Count() > 0)                 {                                        return ((IEnumerable)itemValue).Cast<FieldLookupValue>()                                  .Select(x => (T)Convert.ChangeType(x.LookupValue, typeof(T)))                                  .ToList<T>();                 }             }             return null;         } Note: Always the LookupValue attribute will return the value as string. Usage: List<string> values = ListHelper.GetLookupFieldValue<string>(item["Value2"]); We can also use the following method, suppose if we want to retrieve the values with keys.        public static Dictionary<int, T> GetLookupFieldUserIdValue<T>(object itemValue)         {             List<string> results = new List<string>();             if (itemValue != null)             {                 var itemValueArray = itemValue as Microsoft.SharePoint.Client.FieldLookupValue[];                 if (itemValueArray != null && itemValueArray.Count() > 0)                 {                     return ((IEnumerable)itemValue).Cast<FieldLookupValue>()                         .ToDictionary(                                     x => x.LookupId,                                     x => (T)Convert.ChangeType(x.LookupValue, typeof(T)));                                                }             }             return null;         } Usage: Dictionary<int,string> values = ListHelper.GetLookupFieldKeyValue<string>(item["Value2"]); Summary We can use the same approach in Office 365 provider hosted App and will see how to work with other fields (Date, Managed Mata data, etc.) in the next post. Download Source Code