Introduction to Client Side Dev in SharePoint Workshop


Published on

Slides from my full day workshop on Client Side Dev in SharePoint.

Published in: Technology
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Introduction to Client Side Dev in SharePoint Workshop

  1. 1. SharePointintersection POSTCON06 Introduction to Client Side Development in SharePoint Workshop Mark Rackley
  2. 2. About Mark Rackley • • • • • • • 18+ years software architecture and development experience SharePoint Junkie since 2007 Event Organizer Blogger, Writer, Speaker Bacon aficionado @mrackley 2 © DEVintersection. All rights reserved.
  3. 3. Introduction to Client Side Dev Agenda          Story time - What’s and Why’s What are we going to build today? Deploying & Referencing Scripts jQuery Primer How to debug effectively Modifying Default SharePoint Forms REST / CSOM / SPServices Third Party Libraries SPA’s and SharePoint Hosted Apps All links from this session Code Samples Available at 3 © DEVintersection. All rights reserved.
  4. 4. Client Side Development? Why Bother?      Stay off the server Deployment and maintenance can be easier Upgrades can be painless You don’t have to be a development guru You don’t need expensive tools like Visual Studio… well you don’t NEED any tools at all. 4 © DEVintersection. All rights reserved.
  5. 5. Why is JavaScript development so painful?  It’s not compiled  Simple errors can be hard to track down  It’s difficult to debug       Error messages are usually not helpful There’s a lot of ways to do the exact same thing Performance can be an issue Inconsistent Results on Different Browsers Non-developers are doing it It can harm you farm! 5 © DEVintersection. All rights reserved.
  6. 6. Why is JavaScript development so painful? var car = { var car = {};  It’s not compiled  Simple errors can be hard to trackcar.color = “red”; down color: “red”,  It’s difficult to debug make: “Jeep”, car.make = “Jeep”;  Error messages are usually not helpful model: “wrangler” car.model=“wranger”;  There’s a lot of ways to do the exact same thing }  Performance can be an issue var car = {};  Inconsistent Results on Different“red”; car[“color”] = Browsers  Non-developers are doing it = “Jeep”; car[“make”]  It can harm you farm! car[“model”] =“wranger”; 6 © DEVintersection. All rights reserved.
  7. 7. Oh yeah… so, what can’t you do?  Event Receivers  Timer Jobs  Elevate Privileges  This is a good thing  Write to the file system 7 © DEVintersection. All rights reserved.
  8. 8. Yadda Yadda Yadda and other Gobbledygook  Privileges  Scripts run with same permissions as currently logged in user  Cache busting   Stop caching of scripts by applying an inremental query string parameter http://urltoscript/myScript.js?rev=001  Eval  It‟s not as evil as everyone says  Async Processing  You are going to hate it with the passion of 1,000,000 burning suns  setTimeout  It feels like a hack because it usually is (but sometimes you might not have a choice) 8 © DEVintersection. All rights reserved.
  9. 9. How about some best practices?       Avoid global variables Write scripts in small digestible chunks Code with performance in mind Minify files, but make updates in un-minified files Be consistent in structure and syntax ESPECIALLY if developing as part of a team Document what you’ve done 9 © DEVintersection. All rights reserved.
  10. 10. Development Tools  Visual Studio Express Web (You don’t have to buy it)   TypeScript   Web Essentials (Does not work with VS Express )      Napa SharePoint Designer (yes… really) Notepad++ 10 © DEVintersection. All rights reserved.
  11. 11. Demo Building a simple Contract Management Solution Let‟s pull this pre-baked one out of the oven
  12. 12. Deployment Scripts  Document Library     Can use metadata to enhance maintainability Integrates well with SPD for development Can be on different Site or Site Collection Make sure users have read access  File System   Not an option in the cloud Arguably faster than Document Library  Content Delivery Network (CDN)   Hosted by a third party Not recommended for on-Premises Intranets 12 © DEVintersection. All rights reserved.
  13. 13. Document Library 13 © DEVintersection. All rights reserved.
  14. 14. Referencing Scripts  ScriptLink  Need Visual Studio or SPD  Custom Action   Create feature in Visual Studio Deploys Script across entire section colleciton  Content Editor Web Part      Deploys script to specific page Quick and simple Easily removable Ideal for editing default pages NEVER put scripts directly in CEWP  ORDER MATTERS! 14 © DEVintersection. All rights reserved.
  15. 15. Custom Action (Deploy jQuery across Site Collection) <?xml version="1.0" encoding="utf-8"?> <Elements xmlns=""> <CustomAction ScriptSrc="~sitecollection/SiteAssets/jquery.min.j s" Location="ScriptLink" Sequence="100" > </CustomAction> </Elements> 15 © DEVintersection. All rights reserved.
  16. 16. Demo Getting Started Deploying and referencing Scripts
  17. 17. jQuery Primer  JavaScript Utility Library     jQuery() or $() Allows interaction and manipulation of the DOM after page is rendered Can interact with other systems using Web Services Supported by Microsoft 17 © DEVintersection. All rights reserved.
  18. 18. jQuery Primer script type="text/javascript"> $(document).ready(function($){ //this script executes after the page is loaded //if you need to interact with the DOM put script here }) //Script placed here would execute before the page is finished loading. </script> 18 © DEVintersection. All rights reserved.
  19. 19. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> 19 © DEVintersection. All rights reserved.
  20. 20. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> //Retrieve the element by ID: $(‚#myID‛); 20 © DEVintersection. All rights reserved.
  21. 21. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> //Retrieve the element by attribute: $(‚div[attribute=‘myAttribute’]‛); 21 © DEVintersection. All rights reserved.
  22. 22. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> //Retrieve every div on the page $(‚div‛).each(function() { //‛this‛ is the current element in each loop $(this).method(); }); //Hide all divs on the page $(‚div‛).hide(); 22 © DEVintersection. All rights reserved.
  23. 23. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> //Retrieve every div of a specific class $(‚div.myClass‛).each(function() { //‛this‛ is the current element in each loop $(this).method(); }); //Hide all divs of a specific class on the page $(‚div.myClass‛).hide(); //Hide all elements of a specific class on the page $(‚.myClass‛).hide(); 23 © DEVintersection. All rights reserved.
  24. 24. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> //Retrieve the div that contains content ‚World‛ $(‚div:contains(‘World’)‛).each(function() { //‛this‛ is the current element in each loop $(this).method(); }); 24 © DEVintersection. All rights reserved.
  25. 25. jQuery Primer <div id=“myID” attribute=“myAttribute” class=“myClass” ><b>Hello World</b></div> //Retrieve the formatted HTML for an element $(‚#myID‛).html(); //returns <b>Hello World</b> //Set the formatted HTML for an element $(‚#myID‛).html(‚<b>Hello Nurse</b>‛); //Retrieve the text with HTML formatting stripped out $(‚#myID‛).text(); //returns Hello World //Set the unformatted text of an element $(‚#myID‛).text(‚Hello Nurse‛); 25 © DEVintersection. All rights reserved.
  26. 26. jQuery Primer Interacting with SharePoint Form Fields //get input / select values $(‚#id‛).val(); //set input / select values $(‚#id‛).val(‚value‛); //check a check box $(‚#id").attr('checked','checked'); //uncheck a check box $(‚#id").removeAttr('checked'); //is a check box checked? if ($(‚#id‛).is(':checked')) 26 © DEVintersection. All rights reserved.
  27. 27. jQuery Primer <tr id=„myRow‟><td><div id=„myElement‟></div><div id=„myOtherElement‟></div></td></tr> 27 © DEVintersection. All rights reserved.
  28. 28. jQuery Primer <tr id=„myRow‟><td><div id=„myElement‟></div><div id=„myOtherElement‟></div></td></tr> //get the row that contains the div ‚myElement‛ $(‚#myElement‛).closest(‚tr‛); //get the cell that contains the div ‚myElement‛ $(‚#myElement‛).closest(‚td‛); Or $(‚#myElement‛).parent(); 28 © DEVintersection. All rights reserved.
  29. 29. jQuery Primer <tr id=„myRow‟><td><div id=„myElement‟></div><div id=„myOtherElement‟></div></td></tr> //get the div AFTER myElement $(‚#myElement‛).next(‚div‛); Or $(‚#myElement‛).next(); //get the div BEFORE myOtherelement $(‚#myOtherElement‛).prev(‚div‛); Or $(‚#myOtherElement‛).prev(); 29 © DEVintersection. All rights reserved.
  30. 30. jQuery Primer - Chaining //find the input element that has the ‚title‛ attribute equal to ‚Name‛ //then find it’s parent cell’s previous cell. Then find the ‚h3‛ element and replace the HTML $("input[title='Name']").closest("td").prev("td").find("h3").html("File Name <font color='red'>*</font>"); //In English: Find the label for the field ‚Name‛ and change it to ‚File Name‛ and add a red astrisk //find the input element that has the ‚title‛ attribute equal to ‚City‛ //then hide the entire row that contains the input $(‚input[title=‘City’]‛).closest(‚tr‛).hide(); //In English: Hide the SharePoint Form Field and label for the field with the Display //name ‚City‛ 30 © DEVintersection. All rights reserved.
  31. 31. jQuery Primer – Promises The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended. var call = $.ajax({ … }); call.done(function (data,textStatus, jqXHR){ alert(‚Success‛); }); (jqXHR,textStatus,errorThrown){ alert("Error‛); }); Using the When...Done Pattern with Promises in SharePoint 2013 Apps 31 © DEVintersection. All rights reserved.
  32. 32. Essential jQuery Libraries  jQuery (It’s just JavaScript)   jQuery UI (Make it prettier and more interactive)   jQuery.cookie.js (because it works)  32 © DEVintersection. All rights reserved.
  33. 33. How About Some jQuery Best Practices?      Use the Element’s ID when possible Reduce DOM searches Re-use code / Good coding practices Use animations to hide slow performance Delay loading of data until you need the data 33 © DEVintersection. All rights reserved.
  34. 34. jQueryUI   jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice. 34 © DEVintersection. All rights reserved.
  35. 35. jQueryUI– Basic Usage - Tabs <div id="tabs"> <ul> <li><a href="#tabs-1">Tab 1 title</a></li> <li><a href="#tabs-2">Tab 2 title</a></li> <li><a href="#tabs-3">Tab 3 title</a></li> </ul> <div id="tabs-1"> <p>content in tab 1</p> </div> <div id="tabs-2"> <p>content in tab 2</p> </div> <div id="tabs-3"> <p>content in tab 3</p> </div> </div> <script> $(function() { $( "#tabs" ).tabs(); }); </script> 35 © DEVintersection. All rights reserved.
  36. 36. Demo jQuery Primer Let‟s see some simple jQuery in Action
  37. 37. Debugging Basics  Alerts   Quick sanity checks Are your scripts getting executed?  Developer Tools   Setting breakpoints Evaluating expressions  Fiddler  Is the data I‟m expecting coming across the wire? 37 © DEVintersection. All rights reserved.
  38. 38. Debugging Tools  IE and Chrome Developer Tools (It’s like real debugging)  Fiddler (Essential when you need to see what’s really going on)   jsLint & jsHint     Syntax / Quality Checking Can be more frustrating than helpful 38 © DEVintersection. All rights reserved.
  39. 39. Common issues Issue Sympton Script not loaded “Object doesn’t support property or method” Script loaded more than once / Different versions of same library Sporadic errors, sometimes it works, sometimes it doesn’t. Missing quotes, semicolons, commas, other syntax errors “Expected <char>” (not always the right character) or Syntax Error. Mismatched variable names (foo vs Foo) or use of initialized variables. Unable to get property ‘x’ of undefined or null reference. ‘x’ is undefined No error, but unexpected results. Timing / Async issues Script errors, unexpected results Conflicting jQuery libraries Script errors, unexpected results Changes to script not taking effect Script cached, use cache busting technique of incrementing a rev number on your script. <script type="text/javascript" src="../../SiteAssets/jquery.min.js?rev=1.0"></script> 39 © DEVintersection. All rights reserved.
  40. 40. Demo Modifying Default SharePoint Forms You mean I don‟t need InfoPath??
  41. 41. REST, CSOM, and SPServices Rob Windsor - SharePoint 2013 Development: Client Object Model and REST API. -2013-client-object-model-rest Kirk Evans - What Every Developer Needs to Know About SharePoint Apps, CSOM, and Anonymous Publishing Sites 41 © DEVintersection. All rights reserved.
  42. 42. REST API Coverage      Sites, Webs, Features, Event Receivers, Site Collections Lists, List Items, Fields, Content Types, Views, Forms, IRM Files, Folders Users, Roles, Groups, User Profiles, Feeds Search 42 © DEVintersection. All rights reserved.
  43. 43. REST Get List Items Query var call = $.ajax({ url: _spPageContextInfo.webAbsoluteUrl + "/_api/Web/Lists/GetByTitle('ListName')/items", type: "GET", dataType: "json", headers: { Accept: "application/json;odata=verbose" } }); call.done(function (data,textStatus, jqXHR){ var options = "<option value='0'>(None)</option>"; for (index in data.d.results) { options += "<option value='"+ data.d.results[index].Id +"'>"+data.d.results[index].Title+"</option>"; } $("select[title='<Field Display Name>']").append(options); }); (jqXHR,textStatus,errorThrown){ alert("Error retrieving Tasks: " + jqXHR.responseText); }); 43 © DEVintersection. All rights reserved.
  44. 44. Client Object Model Coverage             Sites, Webs, Features, Event Receivers, Site Collections Lists, List Item s, Fields, Content Types, Views, Forms Files, Folders Users, Roles, Groups, User Profiles, Feeds Web Parts Search Taxonomy Workflow IRM E-Discovery Analytics Business Data 44 © DEVintersection. All rights reserved.
  45. 45. Client Side Object Model (CSOM) Get List Items Query context = SP.ClientContext.get_current(); var speakerList = context.get_web().get_lists().getByTitle("Vendors"); var camlQuery = SP.CamlQuery.createAllItemsQuery(); this.listItems = speakerList.getItems(camlQuery); context.load(listItems); context.executeQueryAsync(ReadListItemSucceeded, ReadListItemFailed); function ReadListItemSucceeded(sender, args) { var enumerator = listItems.getEnumerator(); var options = "<option value='0'>(None)</option>"; while (enumerator.moveNext()) { var listItem = enumerator.get_current(); var Vendor = listItem.get_item('Vendor'); var ID = listItem.get_id(); options += "<option value='"+ ID +"'>"+Vendor+"</option>"; } $("select[title='<Field Display Name>']").append(options); } function ReadListItemFailed(sender, args) { alert('Request failed. ' + args.get_message() + 'n' + args.get_stackTrace()); } 45 © DEVintersection. All rights reserved.
  46. 46. SPServices jQuery library that wraps SharePoint’s .asmx Web Services in easy to call methods  Pros     Shorter learning curve for those already comfortable with jQuery Works well with anonymous access Cross site access Works in SharePoint 2007  Cons   .asmx web services have been deprecated Results returned as XML that must be manually parsed 46 © DEVintersection. All rights reserved.
  47. 47. SPServices Get List Items Query $().SPServices({ operation: "GetListItems", async: true, listName: "Vendors", CAMLViewFields: "<ViewFields><FieldRef Name='Vendor' /></ViewFields>", CAMLQuery: "<Query><Where><Neq><FieldRef Name='ID' /><Value Type='Number'>0</Value></Neq></Where></Query>";,completefunc: function(xData, Status) { var options = "<option value='0'>(None)</option>"; $(xData.responseXML).SPFilterNode("z:row").each(function() { var Vendor = ($(this).attr("ows_Vendor")); var ID = $(this).attr("ows_ID"); options += "<option value='"+ ID +"'>"+Vendor+"</option>"; }); $("select[title='<Field Display Name>']").append(options); }}); 47 © DEVintersection. All rights reserved.
  48. 48. Storing List Data  Storing data in arrays and JSON objects var objArray = [ {ID: 1, Title: {ID: 2, Title: {ID: 3, Title: {ID: 4, Title: ]; "Title "Title "Title "Title 1"}, 2"}, 3"}, 4"}, for (index in objArray) { var thisTitle = objArray[index].Title; } 48 © DEVintersection. All rights reserved.
  49. 49. Reading / Storing List Data  Storing data in JSON objects var objects = {}; objects[1] = {Title: "Title 1"}; objects[2] = {Title: "Title 2"}; objects[3] = {Title: "Title 3"}; for (id in objects) { var thisTitle = objects[id].Title; } 49 © DEVintersection. All rights reserved.
  50. 50. Demo REST, CSOM, and SPServices Oh my…
  51. 51. Third Party Libraries  Pros    Saves development time Hopefully written by someone smarter than me Thoroughly tested  Cons   Library could become unsupported in the future May not “work” in SharePoint  Free (jQueryUI) versus Paid (Kendo UI)   Community support vs. paid support Paid generally has more consistent rendering 51 © DEVintersection. All rights reserved.
  52. 52. Using Third Party Libraries      Look for actively supported libraries Test in target browsers before implementing Duplicate file structure Test “vanilla” in SharePoint first Agree on a set of core libraries. 52 © DEVintersection. All rights reserved.
  53. 53. DataTables   DataTables is a plug-in for the jQuery Javascript library. It is a highly flexible tool, based upon the foundations of progressive enhancement, which will add advanced interaction controls to any HTML table. 53 © DEVintersection. All rights reserved.
  54. 54. DataTables – Basic Usage //array of arrays $('#example').dataTable( { "aaData": [ ["row 1","value"], ["row 2","value 2"], ], "aoColumns": [ //field count must match column count { "sTitle": "Column Name" }, { "sTitle": "Column Name 2" } ] }); //array of objects $('#example').dataTable({ "bProcessing": true, "aaData": vendors, //array of objects "aoColumns": [ { "mData": "Vendor" } ] }); 54 © DEVintersection. All rights reserved.
  55. 55. Using SharePoint REST DataTables demo
  56. 56. FullCalendar   FullCalendar is a jQuery plugin that provides a full-sized, drag & drop calendar like the one below. It uses AJAX to fetch events on-the-fly for each month and is easily configured to use your own feed format (an extension is provided for Google Calendar). It is visually customizable and exposes hooks for user-triggered events (like clicking or dragging an event). 56 © DEVintersection. All rights reserved.
  57. 57. FullCalendar – Basic Usage $('#calendar').fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,basicWeek,basicDay' }, editable: false, events: function(start, end, callback) { //data query goes here } }); <div id='calendar'></div> 57 © DEVintersection. All rights reserved.
  58. 58. You mean I can have more than one date on a list? Fullcalendar demo
  59. 59. Bluff Charts   Bluff is a JavaScript port of the Gruff graphing library for Ruby. It is designed to support all the features of Gruff with minimal dependencies; the only third-party scripts you need to run it are a copy of JS.Class (2.6kB gzipped) and a copy of Google’s ExCanvas to support canvas in Internet Explorer. Both these scripts are supplied with the Bluff download. Bluff itself is around 11kB gzipped. 59 © DEVintersection. All rights reserved.
  60. 60. Bluff Charts – Basic Usage var g = new Bluff.Bar('LineBarChart', '800x400'); g.title = 'Tasks By User'; g.tooltips = true; g.theme_37signals(); for (index in tasks) {[index].name, [tasks[index].Completed, tasks[index].Deferred,tasks[index].NotStarted, tasks[index].InProgress,tasks[index].Waitingonsomeoneelse]); } g.labels = {0: 'Completed', 1: 'Deferred', 2: 'Not Started', 3: 'In Progress', 4: 'Waiting'}; g.draw(); 60 © DEVintersection. All rights reserved.
  61. 61. Quick and dirty charts Bluff demo
  62. 62. SharePoint Hosted Apps and SPA’s  SharePoint Hosted App  SPA = Single Page Application Andrew Connell – SharePoint Hosted Apps in 2013 as Single Page Apps 62 © DEVintersection. All rights reserved.
  63. 63. Patterns and Practices  Bringing JavaScript / Client Side development into the 21st century  MV* Patterns   Adds badly needed structure and consistency Separate display, business, and data retrieval logic  Data Binding  No need to keep track of objects at a granular level 63 © DEVintersection. All rights reserved.
  64. 64. Growing number of libraries  Knockout   Durandal   AngularJS   Ember   Breeze  64 © DEVintersection. All rights reserved.
  65. 65. AngularJS   Open-source JavaScript framework, maintained by Google, that assists with running single-page applications (SPA’s). Its goal is to augment browser-based applications with model–view–controller (MVC) capability, in an effort to make both development and testing easier. 65 © DEVintersection. All rights reserved.
  66. 66. AngularJS          Data Binding MVC Routing Testing jqLite Templates History Factories Animations 66 © DEVintersection. All rights reserved.
  67. 67. AngularJS * *Thanks Dan Wahlin 67 © DEVintersection. All rights reserved.
  68. 68. Finally we open Visual Studio SPA Demo
  69. 69. TypeScript  TypeScript is a language for application-scale JavaScript development.      TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. Any browser. Any host. Any OS. Open Source. 69 © DEVintersection. All rights reserved.
  70. 70. Demo TypeScript JavaScript development for .NET developers
  71. 71. Final Review         How to Deploy and Reference Scripts How to effectively use jQuery and search the DOM How to debug and find out what’s really going on How to create highly stylized forms without InfoPath or expense form tools How to interact with SharePoint using REST, CSOM, and SPServices How to use Third Party Libraries to do a lot of the heavy lifting How to get started with SPA’s and SharePoint Hosted Apps What TypeScript is and how to get started using it How to go into the office on Monday and get stuff done! 71 © DEVintersection. All rights reserved.
  72. 72. Questions? Don’t forget to enter your evaluation of this session using EventBoard! Thank you!