Presentation is loading. Please wait.

Presentation is loading. Please wait.

Nick Hadlee and Gary Payne

Similar presentations


Presentation on theme: "Nick Hadlee and Gary Payne"— Presentation transcript:

1 Nick Hadlee and Gary Payne
JS in SP – Why, What & How Nick Hadlee and Gary Payne

2 WHY JavaScript…

3 …you can do some Cool Things!
Expectations of users and BAs/designers!

4 ...can’t touch the server Light-touch or no-touch server deployments, especially in the cloud Server-side code is *not* allowed in a SharePoint-hosted app, so all SharePoint code is CSOM or REST (in addition to the HTML, CSS and JavaScript elements). Remote hosting of applications SharePoint apps have no access to server-side API, so must access SharePoint via the various client APIs or via OData

5 …because it’s easy now (really?)
Released Jan 2006 by John Resig, now used in over 30% of top site on the web. It helped relaunch JavaScript as a powerful tool for web development by making page enhancement intuitive, browser-agnostic and fast – JavaScript has become cool! Danger – do not use client-side for pulling down and processing large wads of data (even if you can!) Official MS support for jQuery, cross-browser woes, great things about jQuery (selectors, chaining) Usage of jQuery: Select some elements on a page Do stuff to those elements

6 HOW to add JavaScript?

7 In the Masterpage <SharePoint:ScriptLink language="javascript" name="menu.js" OnDemand="false" runat="server" Localizable="false" /> true" <script type="text/javascript"> // <![CDATA[ document.write(‘<script type= "text/javascript" src="/_layouts/menu.js"></’ + ‘script>’); // ]]> </script> <script type="text/javascript">RegisterSod("menu.js", “\u002f_layouts\u002f15\u002fmenu.js?rev=pcr83s11QGFA2kLt5rDQ1g\u00253D\u00253D");</script> Scriptlink GOOD as it: adds a version parameter to the rendered code Ensures the file only loads once Allows for files to be loaded only if actually required by other script on page Custom masterpage needs to be incorporated in a solution for deployment Ensures that the script is loaded only once  Files have to be in the layouts folder 

8 Control Delegate <SharePoint:DelegateControl runat="server" ControlId="AdditionalPageHead" AllowMultipleControls="true" /> <?xml version="1.0" encoding="utf-8"?> <Elements xmlns=" <Control Id="AdditionalPageHead" Sequence="50" ControlSrc="~/_CONTROLTEMPLATES/SPC/jQueryControl.ascx" /> </Control> </Elements> Content – code from a control delegate Discussion Associate with the AdditionalPageHead placeholder Possible activation scopes

9 A Custom Action <?xml version="1.0" encoding="utf-8"?>
<Elements xmlns=" <CustomAction ScriptSrc="~SiteCollection/SiteAssets/jquery min.js" Location="ScriptLink" Sequence="10"> </CustomAction> </Elements> Adds as a document.write line Sandbox solutions are still supported in 2013, but are deprecated for Apps

10 Straight in the page

11 HOW to use JS in SP?

12 OData – What is it? OData is an open standard for querying and updating data that relies on common web standard HTTP. Built on standard web technologies & standards so easy to use(HTTP, JSON, ATOM PUB) Achieve data interactions via HTTP GETS, POSTS, PUTS and DELETES Better as: easier interaction that SOAP in web services, smaller returned payload of data as can retrieve as JSON (which is easier to work in JavaScript) Firewalls usually block HTTP verbs other than GET and POST. Fortunately, OData supports verb tunneling where PUT, MERGE and DELETE are submitted as POST requests and X-HTTPMehod header carries the actual verb. The path /_vti_bin/client.svc is abstracted as _api in SharePoint 2013 SOAP was using same URL and request was transmitted in the SOAP header, REST simplified the request process by having separate URL for different queries or operations you want to execute REST Results can be cached by proxy servers because you no longer expect different results & run two different queries using same URL Read operations mapped to HTTP GET Insert operations mapped to HTTP POST Update operations mapped to HTTP PUT or HTTP MERGE – Difference between PUT or MERGE is – e.g. if you have 20 columns in SharePoint list and you want to update only 3 columns, PUT will update 3 columns and reset other 17 columns to it’s default value while MERGE will update 3 columns leaving other 17 columns as it is with existing values Delete operations mapped to HTTP DELETE

13 OData demo – Get some data
GetByTitle('Towns')/items?$select=Title OData Demo (browsing to _api locations) api/web alias for _vti_bin/client.svc/web which is the WCF endpoint for CSOM interactions (not accessible in 2010). ListData.svc exists for backwards compatibility!! Show in browser: With Fiddler running. Then use the Fiddler response builder to change the ACCEPT header to application/json;odata=verbose; REQUIREMENT – need flddler and the JSON add-in installed on demo machine!! Usage of navigation operations, e.g. /web/lists/getByTitle(‘title’) Search web service deprecated in 2013 and will be removed in next version

14 OData demo - AutoComplete
Show AutoComplete action in text box, explore the simple JS and discuss use of jQuery + jQuery UI

15 TIP!!! Getting internal name of list fields
getbytitle('Events')/Fields ?$select=Title,InternalName,ID

16 CSOM & JSOM

17 JSOM – What is it? Purpose is to enable rich remote interaction with SharePoint elements and data Run under credentials of current user Actions are batched into an async call Wasn’t widely used in SP2010 as offered only a subset of functionality available in the server API

18 Typical JSOM Pattern var clientContext = SP.ClientContext.get_current(); var web = clientContext.get_web(); var list = web.get_lists().getByTitle("Rooms"); var floorChoiceField = clientContext.castTo( list.get_fields().getByInternalNameOrTitle("Floor"), SP.FieldChoice ); clientContext.load(floorChoiceField); clientContext.executeQueryAsync( Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) Behind the scenes, commands are batched and sent to _api

19 Typical JSOM Pattern var clientContext = SP.ClientContext.get_current(); var web = clientContext.get_web(); var list = web.get_lists().getByTitle("Rooms"); var floorChoiceField = clientContext.castTo( list.get_fields().getByInternalNameOrTitle("Floor"), SP.FieldChoice ); clientContext.load(floorChoiceField); clientContext.executeQueryAsync( Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) Behind the scenes, commands are batched and sent to _api

20 Typical JSOM Pattern var clientContext = SP.ClientContext.get_current(); var web = clientContext.get_web(); var list = web.get_lists().getByTitle("Rooms"); var floorChoiceField = clientContext.castTo( list.get_fields().getByInternalNameOrTitle("Floor"), SP.FieldChoice ); clientContext.load(floorChoiceField); clientContext.executeQueryAsync( Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) Behind the scenes, commands are batched and sent to _api

21 Typical JSOM Pattern var clientContext = SP.ClientContext.get_current(); var web = clientContext.get_web(); var list = web.get_lists().getByTitle("Rooms"); var floorChoiceField = clientContext.castTo( list.get_fields().getByInternalNameOrTitle("Floor"), SP.FieldChoice ); clientContext.load(floorChoiceField); clientContext.executeQueryAsync( Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) Behind the scenes, commands are batched and sent to _api

22 Demo – Reading and writing
Show operation of this panel Discuss the use of the JSOM pattern to get and write data Show data over HTTP in Fiddler

23 TIP!!! You can only work with files up to 1.5 MB by using the JavaScript object model. To upload larger files, use REST.

24 Client Side Rendering

25 Enhancing data displays
Image – screenshot from Nick’s demo of CSR Discuss – introduce CSR and other JS drawing libraries

26 Client Side Rendering Method of changing how areas of SharePoint’s UI via JS micro templates “Display Templates” JSLink or JS Link Search

27 JSLink Fields Views Xslt List View Web Parts Forms
View(s) templates "View" Forms templates "DisplayForm" "EditForm" "NewForm" Views The entire view via an “Item” template or “Body” template A field in a view via a “View” template Can also limit to a specific view and/or list template Xslt List View Web Parts Forms Can be applied at a global level for fields Display logic is maintained within the view – just override the UI Can be debugged

28 JSLink The JavaScript template pattern: (function () {
// Initialize the variable that store the objects. var overrideCtx = {}; overrideCtx.Templates = {}; // Do the template bits here // <-- Overidden rendering is added here --> // Register the template overrides. SPClientTemplates.TemplateManager .RegisterTemplateOverrides(overrideCtx); })(); Starts with an self executing anonymous function – many people will want to use a namespace too Define an override context variable with a Templates property Decide which parts of the template you want to override Register your templates via the TemplateManager

29 JSLink (function () { // Initialize the variable that store the objects. var overrideCtx = {}; overrideCtx.Templates = {}; // A field template. Can be static text or a function overrideCtx.Fields = { LinkTitle = { "View" : "No problem here!" } } // Register the template overrides. SPClientTemplates.TemplateManager .RegisterTemplateOverrides(overrideCtx); })();

30 JSLink (function () { // Initialize the variable that store the objects. var overrideCtx = {}; overrideCtx.Templates = {}; // A field template. Can be static text or a function overrideCtx.Fields = { LinkTitle = { "View" : titleFieldFunction } } // Register the template overrides. SPClientTemplates.TemplateManager .RegisterTemplateOverrides(overrideCtx); })();

31 JSLink function titleFieldFunction (ctx) {
// Craft the html to be returned by the function var returnHtml = ""; returnHtml += "<b>"; returnHtml += ctx.CurrentItem.Title; returnHtml += "</b>"; return returnHtml; }

32 CSR demos Show CSR to change a field and a XsltListView

33 TIP!!! _spPageContextInfo is a JS object on every SP page
_spPageContextInfo.webServerRelativeUrl =9 javascript-current-page-context-info.html

34 _spPageContextInfo

35 Contact Details Nick Hadlee @nickhadlee Gary Payne
@nickhadlee

36 Code – create towns list
Markup and js in notes for this slide <script src="/spconf/SiteAssets/jquery js"></script> <script type="text/ecmascript"> var actionTownsName; $(function() { $('#btnCreateTownsList').click(createTownList); }); function createTownList() { var clientContext = new SP.ClientContext.get_current(); var web = clientContext.get_web(); var listCreationInfo = new SP.ListCreationInformation(); // List name listCreationInfo.set_title('Towns'); // List description listCreationInfo.set_description('Towns for OData autocomplete demo'); // List type listCreationInfo.set_templateType(SP.ListTemplateType.genericList); web.get_lists().add(listCreationInfo); actionTownsName = 'creating the Towns list'; clientContext.executeQueryAsync( Function.createDelegate(this, onCreateTownListQuerySucceeded), Function.createDelegate(this, onQueryTownFailed) ); } function addTownListItems() { var list = web.get_lists().getByTitle('Towns'); var itemCreateInfo = new SP.ListItemCreationInformation(); var item10 = list.addItem(itemCreateInfo); item10.set_item('Title', 'Auckland') item10.update(); var item11 = list.addItem(itemCreateInfo); item11.set_item('Title', 'Christchurch') item11.update(); var item12 = list.addItem(itemCreateInfo); item12.set_item('Title', 'Hamilton') item12.update(); var item20 = list.addItem(itemCreateInfo); item20.set_item('Title', 'Hanmer') item20.update(); var item21 = list.addItem(itemCreateInfo); item21.set_item('Title', 'Hastings') item21.update(); var item22 = list.addItem(itemCreateInfo); item22.set_item('Title', 'Napier') item22.update(); var item23 = list.addItem(itemCreateInfo); item23.set_item('Title', 'Wellington') item23.update(); var item24 = list.addItem(itemCreateInfo); item24.set_item('Title', 'Dunedin') item24.update(); var item30 = list.addItem(itemCreateInfo); item30.set_item('Title', 'New Plymouth') item30.update(); var item31 = list.addItem(itemCreateInfo); item31.set_item('Title', 'Taupo') item31.update(); var item32 = list.addItem(itemCreateInfo); item32.set_item('Title', 'Tauaranga') item32.update(); clientContext.load(item10); clientContext.load(item11); clientContext.load(item12); clientContext.load(item20); clientContext.load(item21); clientContext.load(item22); clientContext.load(item23); clientContext.load(item24); clientContext.load(item30); clientContext.load(item31); clientContext.load(item32); actionTownsName = 'adding items to the Towns list'; Function.createDelegate(this, this.onQueryTownsSucceeded), Function.createDelegate(this, this.onQueryTownFailed) function onCreateTownListQuerySucceeded() { var $resultText = $('<div>Success ' + actionTownsName + '</div>'); $('#townsListResult').append($resultText); addTownListItems(); function onQueryTownsSucceeded() { function onQueryTownFailed(sender, args) { var $resultText = $('<div>Failed ' + actionTownsName + '</div>'); </script> <input type="button" value="Create Towns List" id="btnCreateTownsList" /> <div id="townsListResult"></div>

37 Code- autocomplete Markup and code in notes of this slide
<link href="/spconf/SiteAssets/jquery-ui.css" rel="stylesheet" /> <link href="/spconf/SiteAssets/style.css" rel="stylesheet" /> <script src="/spconf/SiteAssets/jquery js"></script> <script src="/spconf/SiteAssets/jquery-ui.js"></script> <script> $(function() { function log( message ) { $('#chosenTown').text(message); } $( "#city" ).focus().autocomplete({ minLength: 2, source: function( request, response ) { var townName = $('#city').val(); $.ajax({ url: " '" + townName + "')&$select=Title", type: 'GET', headers: { "ACCEPT": "application/json;odata=verbose" }, success: function( data ) { response( $.map( data.d.results, function(item) { return { label: item.Title, value: item.Title } })); }); }, select: function( event, ui ) { log( ui.item ? "You selected " + ui.item.label : "Nothing selected, input was " + this.value); </script> <style> #autocompleteDemo { background-color:#f7f3f7;border: 1px solid #0071c6;border-radius:5px;font-size:14px;height:200px;padding: px;width:220px } .ui-autocomplete-loading { background: white url('/spconf/SiteAssets/ui-anim_basic_16x16.gif') right center no-repeat; } #city { width: 25em; } </style> <div id="autocompleteDemo"> <h1>Autocomplete</h1> <div class="ui-widget"> <label for="city">Select a town: </label> <input id="city" style="width:150px;" /> </div> <div style="margin-top:15px;font-size:14px;"><span id="chosenTown"></span></div>

38 Code – create rooms list
Markup and code in notes for this slide <script src="/spconf/SiteAssets/jquery js"></script> <script type="text/ecmascript"> var actionName; $(function() { $('#btnCreateRoomsList').click(createAndPopulateRoomList); }); function createAndPopulateRoomList() { createRoomList(); } function createRoomList() { var clientContext = new SP.ClientContext.get_current(); var web = clientContext.get_web(); var listCreationInfo = new SP.ListCreationInformation(); // List name listCreationInfo.set_title('Rooms'); // List description listCreationInfo.set_description('Room availability for JSOM demo'); // List type listCreationInfo.set_templateType(SP.ListTemplateType.genericList); web.get_lists().add(listCreationInfo); actionName = 'creating the rooms list'; clientContext.executeQueryAsync( Function.createDelegate(this, this.onCreateListQuerySucceeded),// when success Function.createDelegate(this, this.onQueryFailed) // when failed ); function addRoomListFields() { var list = web.get_lists().getByTitle('Rooms'); var fields = list.get_fields(); var fieldFloorDef = fields.addFieldAsXml('<Field Type="Choice" DisplayName="Floor" Name="Floor" />', true, SP.AddFieldOptions.addToDefaultContentType); var fieldFloor = clientContext.castTo(fieldFloorDef, SP.FieldChoice); var floorChoices = Array('Floor 1','Floor 2','Floor 3'); fieldFloor.set_choices(floorChoices); fieldFloor.update(); var availableFloorDef = fields.addFieldAsXml('<Field Type="Boolean" DisplayName="Available" Name="Available" />', true, SP.AddFieldOptions.addToDefaultContentType); actionName = 'adding fields to the rooms list'; Function.createDelegate(this, this.onAddFieldsQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) function addRoomListItems() { var itemCreateInfo = new SP.ListItemCreationInformation(); var item10 = list.addItem(itemCreateInfo); item10.set_item('Title', 'Room 10') item10.set_item('Floor', 'Floor 1') item10.set_item('Available',1); item10.update(); var item11 = list.addItem(itemCreateInfo); item11.set_item('Title', 'Room 11') item11.set_item('Floor', 'Floor 1') item11.set_item('Available',0); item11.update(); var item12 = list.addItem(itemCreateInfo); item12.set_item('Title', 'Room 12') item12.set_item('Floor', 'Floor 1') item12.set_item('Available',1); item12.update(); var item20 = list.addItem(itemCreateInfo); item20.set_item('Title', 'Room 20') item20.set_item('Floor', 'Floor 2') item20.set_item('Available',1); item20.update(); var item21 = list.addItem(itemCreateInfo); item21.set_item('Title', 'Room 21') item21.set_item('Floor', 'Floor 2') item21.set_item('Available',1); item21.update(); var item22 = list.addItem(itemCreateInfo); item22.set_item('Title', 'Room 22') item22.set_item('Floor', 'Floor 2') item22.set_item('Available',0); item22.update(); var item23 = list.addItem(itemCreateInfo); item23.set_item('Title', 'Room 23') item23.set_item('Floor', 'Floor 2') item23.set_item('Available',0); item23.update(); var item24 = list.addItem(itemCreateInfo); item24.set_item('Title', 'Room 24') item24.set_item('Floor', 'Floor 2') item24.set_item('Available',1); item24.update(); var item30 = list.addItem(itemCreateInfo); item30.set_item('Title', 'Room 30') item30.set_item('Floor', 'Floor 3') item30.set_item('Available',1); item30.update(); var item31 = list.addItem(itemCreateInfo); item31.set_item('Title', 'Room 31') item31.set_item('Floor', 'Floor 3') item31.set_item('Available',0); item31.update(); var item32 = list.addItem(itemCreateInfo); item32.set_item('Title', 'Room 32') item32.set_item('Floor', 'Floor 3') item32.set_item('Available',1); item32.update(); var item33 = list.addItem(itemCreateInfo); item33.set_item('Title', 'Room 33') item33.set_item('Floor', 'Floor 3') item33.set_item('Available',1); item33.update(); var item34 = list.addItem(itemCreateInfo); item34.set_item('Title', 'Room 34') item34.set_item('Floor', 'Floor 3') item34.set_item('Available',0); item34.update(); var item35 = list.addItem(itemCreateInfo); item35.set_item('Title', 'Room 35') item35.set_item('Floor', 'Floor 3') item35.set_item('Available',0); item35.update(); clientContext.load(item10); clientContext.load(item11); clientContext.load(item12); clientContext.load(item20); clientContext.load(item21); clientContext.load(item22); clientContext.load(item23); clientContext.load(item24); clientContext.load(item30); clientContext.load(item31); clientContext.load(item32); clientContext.load(item33); clientContext.load(item34); clientContext.load(item35); actionName = 'adding items to the rooms list'; Function.createDelegate(this, this.onQuerySucceeded),// when success function onCreateListQuerySucceeded() { var $resultText = $('<div>Success ' + actionName + '</div>'); $('#roomsListResult').append($resultText); addRoomListFields(); function onAddFieldsQuerySucceeded() { addRoomListItems(); function onQuerySucceeded() { function onQueryFailed(sender, args) { var $resultText = $('<div>Failed ' + actionName + '</div>'); </script> <input type="button" value="Create Rooms List" id="btnCreateRoomsList" /> <div id="roomsListResult"></div>

39 Code – room availability panel
Markup and code in notes for this slide <script src="/spconf/SiteAssets/jquery js"></script> <script type="text/ecmascript"> var actionName; SP.SOD.executeOrDelayUntilScriptLoaded(PopulateFloors, "SP.js"); var floorChoiceField, floorListItems; function PopulateFloors() { var clientContext = new SP.ClientContext.get_current(); var web = clientContext.get_web(); var list = web.get_lists().getByTitle('Rooms'); floorChoiceField = clientContext.castTo(list.get_fields().getByInternalNameOrTitle("Floor"),SP.FieldChoice); clientContext.load(floorChoiceField); clientContext.executeQueryAsync( Function.createDelegate(this, this.onGetFloorsQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) ); } function onGetFloorsQuerySucceeded() { var $floorSelect = $('<select id="floorSelect"><option>Select a floor...</option></select>'); var floorChoices = floorChoiceField.get_choices(); for (var i = 0; i < floorChoices.length;i++) { var $floorOption = $('<option>' + floorChoices[i] + '</option>'); $floorSelect.append($floorOption) $('#floors').append($floorSelect); $('#floorSelect').change(function() { showRoomsOnFloor(); }); function showRoomsOnFloor() { var selectedFloor = $('#floorSelect').val(); var camlQuery = new SP.CamlQuery(); var queryText = '<View><Query><Where><Eq><FieldRef Name="Floor" /><Value Type="Text">' + selectedFloor + '</Value></Eq></Where><OrderBy><FieldRef Name="Title" /></OrderBy></Query></View>' camlQuery.set_viewXml(queryText); floorListItems = list.getItems(camlQuery); clientContext.load(floorListItems); Function.createDelegate(this, this.onGetRoomsQuerySucceeded), function onGetRoomsQuerySucceeded(sender, args) { var $rooms = $('<div id="roomsAvailability">Room availability:</div>'); var listItemEnumerator = floorListItems.getEnumerator(); while(listItemEnumerator.moveNext()) { var listItem = listItemEnumerator.get_current(); var isAvailable = listItem.get_item('Available'); var className = ((isAvailable) ? 'available' : 'booked'); var itemId = 'roomItem' + listItem.get_id(); $rooms.append('<div id="' + itemId + '" class="' + className + '">' + listItem.get_item('Title') + '</div>') $rooms.find('#' + itemId).click(function() { AdjustRoomStatus($(this).attr('id')); }); $('#rooms').empty().append($rooms); function onQueryFailed(sender, args) { alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); function AdjustRoomStatus(roomElementId) { var id = roomElementId.replace('roomItem',''); var listItem = list.getItemById(new Number(id)); if ($('#' + roomElementId).is('.available')) listItem.set_item('Available', 0); else listItem.set_item('Available', 1); listItem.update() $('#' + roomElementId).attr('class','updating'); Function.createDelegate(this, this.onUpdateRoomQuerySucceeded), function onUpdateRoomQuerySucceeded() { showRoomsOnFloor(); </script> <style type='text/css'> .available { background: -ms-linear-gradient(top, #c7e5c7 0%,#a1d5a1 17%,#7cc47c 33%,#00e400 67%,#00be00 83%,# %); /* IE10+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c7e5c7', endColorstr='#009600',GradientType=0 ); /* IE6-8 */ display: block; text-decoration: none; color: #fff; font-weight: bold; background-color: #538fbe; padding: 20px 70px; font-size: 14px; border: 1px solid #299a0b; border-radius: 5px; text-shadow: 0px -1px 0px rgba(0,0,0,.5); box-shadow: 0px 3px 0px #299a0b, 0px 3px 15px rgba(0,0,0,.4), inset 0px 1px 0px rgba(255,255,255,.3), inset 0px 0px 3px rgba(255,255,255,.5); .booked { background: -ms-linear-gradient(top, #ff3019 0%,#cf %); /* IE10+ */ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff3019', endColorstr='#cf0404',GradientType=0 ); /* IE6-8 */ background-color: #ff3019; /*border: 1px solid #299a0b;*/ box-shadow: 0px 3px 0px #ff3019, 0px 3px 15px rgba(0,0,0,.4), inset 0px 1px 0px rgba(255,255,255,.3), inset 0px 0px 3px rgba(255,255,255,.5); .updating { background-color:#d86c00; } #roomsAvailabilityDemo { background-color:#f7f3f7;border: 1px solid #0071c6;border-radius:5px;font-size:14px;height:350px;padding: px;width:200px } #roomsAvailability>div { margin:5px 0 0 0;padding:5px;text-align:center;width:150px; } #floorSelect { width:160px; } #floors { margin-top:10px;vertical-align:middle; } #rooms { margin-top:10px; } </style> <div id="roomsAvailabilityDemo"> <h1>JSOM Demo</h1> <div id="floors">Select a floor:<br/></div> <div id="rooms"></div> </div>

40 Code – task list creation (CSOM)
Markup and code in notes for this slide <script src="/_layouts/15/SPC2013/jquery min.js"></script> <script type="text/javascript"> var finalInstructions = "A task list has been created with some default tasks in it at. The JSLink property of the '% Completed' field needs to be updated to use a custom JSLink template so go and grab that other demo code and switch out the JSLink property!"; var actionName; var list; var view; $(function () { $('#btnCreateTaskList').click(createAndPopulateTaskList); }); function createAndPopulateTaskList() { $('#taskListResult').append('Trying to create a task list...'); createTaskList(); } function createTaskList() { var clientContext = new SP.ClientContext.get_current(); var web = clientContext.get_web(); var listCreationInfo = new SP.ListCreationInformation(); // List name listCreationInfo.set_title('Tasks'); // List description listCreationInfo.set_description('An task list to hold tasks for the Client Side Rendering demo'); // List type listCreationInfo.set_templateType(SP.ListTemplateType.tasks); web.get_lists().add(listCreationInfo); actionName = 'creating the task list'; clientContext.executeQueryAsync( Function.createDelegate(this, this.onCreateListQuerySucceeded),// when success Function.createDelegate(this, this.onQueryFailed) // when failed ); function addTaskListItems() { var list = web.get_lists().getByTitle('Tasks'); var itemCreateInfo = new SP.ListItemCreationInformation(); var item1 = list.addItem(itemCreateInfo); item1.set_item('Title', 'Learn JavaScript'); item1.set_item('PercentComplete', 0.25); item1.set_item('Body', 'The fact that you are looking at this demo means you are well on the way...'); item1.update(); var item2 = list.addItem(itemCreateInfo); item2.set_item('Title', 'Master JavaScript'); item2.set_item('PercentComplete', 0.05); item2.set_item('Body', 'This could take a while but keep on it!'); item2.update(); var item3 = list.addItem(itemCreateInfo); item3.set_item('Title', 'Love SharePoint '); item3.set_item('PercentComplete', 0.85); item3.set_item('Body', 'This is an obvious one and everyone already does right?'); item3.update(); clientContext.load(item1); clientContext.load(item2); clientContext.load(item3); actionName = 'adding items to the task list'; Function.createDelegate(this, this.onQuerySucceeded),// when success function onCreateListQuerySucceeded() { var $resultText = $('<div>Success ' + actionName + '</div>'); $('#taskListResult').append($resultText); addTaskListItems(); function onQuerySucceeded() { // Final instructions $('#taskListResult').html('<div> DONE! ' + finalInstructions + '</div>'); function onQueryFailed(sender, args) { var $resultText = $('<div>Failed ' + actionName + '</div>'); </script> <input type="button" value="Create Task List" id="btnCreateTaskList" /> <div id="taskListResult"></div>

41 Code – ‘% Complete’ field (JSLink)
Markup and code in notes for this slide The markup will need to be copied into a .JS file and deployed to a document library, the master page gallery or the _layouts directory on the server. This file is ‘referenced’ in the JSLink update script on the next slide // /_layouts/15/SPC2013/jslink-fielddemo.js (function () { /* * Initialize the variable that store the overrides objects. */ var overrideCtx = {}; overrideCtx.Templates = {}; overrideCtx.Templates.Fields = { 'PercentComplete': { 'View': ViewField } }; // Register the template overrides. SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx); })(); function ViewField(ctx) { if (ctx == null) return ''; var percentAsBarChart = ''; // the html to return will be built up here var _value = ctx.CurrentItem.PercentComplete != null ? ctx.CurrentItem.PercentComplete : ''; // get the value of the field safely if (_value.length > 0) { var percentageValue = _value.indexOf(" ") > -1 ? _value.replace(" ","") : "0%"; // remove the whitespace in the % value so we can use it in CSS percentAsBarChart += "<div style='background-color: rgba(156, 206, 240, 0.5); width: 100%; position: relative;'><div style='background-color: #0072C6; width: " + percentageValue + "'> </div><span style='position: absolute; top: 0%; right: 0%;'>" + _value + "</span></div>"; } return percentAsBarChart;

42 Code – change ‘% Complete’ field Jsink property (CSOM)
Markup and code in notes for this slide <script type="text/javascript" src="/_layouts/15/SPC2013/jquery min.js"></script> <script type="text/javascript"> var currentJSLink = ''; var defaultJSLink = 'clienttemplates.js'; var customJLink = '/_layouts/15/SPC2013/jslink-fielddemo.js'; var actionName; var field; $(function () { $('#btnUpdateLink').click(updateLink); $('#btnGetLink').click(getLink); }); function updateLink() { updateJSLink(); } function getLink() { getJSLink(); function updateJSLink() { var clientContext = new SP.ClientContext.get_current(); var web = clientContext.get_web(); var list = web.get_lists().getByTitle('Tasks'); var fields = list.get_fields(); field = fields.getByTitle('% Complete'); if (currentJSLink == defaultJSLink || currentJSLink == '') { field.set_jsLink(customJLink) if (currentJSLink == customJLink) { field.set_jsLink(defaultJSLink) field.update(); clientContext.load(field); clientContext.executeQueryAsync( Function.createDelegate(this, this.onLinkUpdateQuerySucceeded), Function.createDelegate(this, this.onQueryFailed) ); function getJSLink() { Function.createDelegate(this, this.onLinkQuerySucceeded), function onLinkQuerySucceeded() { currentJSLink = field.get_jsLink(); actionName = 'found field with JSLink ' + currentJSLink; var $resultText = $('<div>Success ' + actionName + '</div>'); $('#fieldResult').append($resultText); function onLinkUpdateQuerySucceeded() { actionName = 'JSLink property was set to ' + currentJSLink; function onQuerySucceeded() { function onQueryFailed(sender, args) { var $resultText = $('<div>Failed ' + actionName + '</div>'); </script> <input type="button" value="Get JS Link" id="btnGetLink" /> <input type="button" value="Update JS Link" id="btnUpdateLink" /> <div id="fieldResult"></div>

43 Code – news list creation (CSOM)
Markup and code in notes for this slide <script src="/_layouts/15/SPC2013/jquery min.js"></script> <script type="text/javascript"> var finalInstructions = "An announcements list has been created with some default items in it at. The JS Link property of the XSLT List View Web Part for this list needs to be updated to use a custom JS Link template. Go and add the 'News' list web part to a page, edit the web part properties and change the JS Link property!"; var actionName; var list; var view; $(function () { $('#btnCreateNewsList').click(createAndPopulateNewsList); }); function createAndPopulateNewsList() { createNewsList(); } function createNewsList() { var clientContext = new SP.ClientContext.get_current(); var web = clientContext.get_web(); var listCreationInfo = new SP.ListCreationInformation(); // List name listCreationInfo.set_title('News'); // List description listCreationInfo.set_description('An announcements list to hold news for the Client Side Rendering demo'); // List type listCreationInfo.set_templateType(SP.ListTemplateType.announcements); web.get_lists().add(listCreationInfo); actionName = 'creating the news list'; clientContext.executeQueryAsync( Function.createDelegate(this, this.onCreateListQuerySucceeded),// when success Function.createDelegate(this, this.onQueryFailed) // when failed ); function addViewToList() { // onAddItemsQuerySucceeded var list = web.get_lists().getByTitle('News'); var view = list.get_defaultView(); var viewFields = view.get_viewFields(); viewFields.removeAll(); viewFields.add('LinkTitle'); viewFields.add('Body'); view.update(); actionName = 'updating the default view of the news list'; Function.createDelegate(this, this.onQuerySucceeded),// when success function addNewsListItems() { var itemCreateInfo = new SP.ListItemCreationInformation(); var item1 = list.addItem(itemCreateInfo); item1.set_item('Title', 'CSR = Client Side Rendering') item1.set_item('Body', 'And CSR is one of the new ways that we can customise how content is rendered.') item1.update(); var item2 = list.addItem(itemCreateInfo); item2.set_item('Title', 'Client Side Rendering is JavaScript Based') item2.set_item('Body', 'So if you love XSL this might not be the news you were hoping for.​') item2.update(); var item3 = list.addItem(itemCreateInfo); item3.set_item('Title', 'There is no design view in SharePoint Designer 2013') item3.set_item('Body', 'So now we either have to be really good at hand crafting XSL and HTML or we have to use different techniques to achieve what we want from SharePoint.') item3.update(); clientContext.load(item1); clientContext.load(item2); clientContext.load(item3); actionName = 'adding items to the news list'; Function.createDelegate(this, this.onAddItemsQuerySucceeded),// when success function onCreateListQuerySucceeded() { var $resultText = $('<div>Success ' + actionName + '</div>'); $('#newsListResult').append($resultText); addNewsListItems(); function onAddItemsQuerySucceeded() { addViewToList(); function onQuerySucceeded() { // Final instructions $('#newsListResult').html('<div> DONE! ' + finalInstructions + '</div>'); function onQueryFailed(sender, args) { var $resultText = $('<div>Failed ' + actionName + '</div>'); </script> <input type="button" value="Create News List" id="btnCreateNewsList" /> <div id="newsListResult"></div>

44 Code – ‘News’ XSLT List View (JSLink)
Markup and code in notes for this slide The markup will need to be copied into a .JS file and deployed to a document library, the master page gallery or the _layouts directory on the server. // /_layouts/15/SPC2013/jslink-carouseldemo.js (function () { /* * Initialize the variable that store the overrides objects. */ var overrideCtx = {}; overrideCtx.Templates = {}; // Assign functions or plain html strings to the template objects: overrideCtx.Templates.Header = " "; // Custom header is empty so it shows nothing; // Custom Body/Item you need to override the header otherwise there will be the OOTB LV elements on the page overrideCtx.Templates.Body = CustomBody; // Other templates we can override overrideCtx.Templates.View = {}; overrideCtx.Templates.Footer = {}; overrideCtx.Templates.Group = {}; overrideCtx.Templates.Item = {}; overrideCtx.Templates.Fields = {}; // We can also have functions called before and after our rendering overrideCtx.Templates.OnPreRender = PreRender; overrideCtx.Templates.OnPostRender = PostRender; // Register the template overrides. SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx); })(); // This function builds the output for the item template. Uses the Context object to access announcement data. function CustomBody(ctx) { // debugger; var returnHtml = ""; returnHtml += "<div id='news-carousel'>"; returnHtml += "<input type='button' class='buttons prev' value='Previous'>"; returnHtml += "<div class='viewport'>"; returnHtml += "<ul class='overview'>"; // Access objects from the context that was passed with the template var listItems = ctx.ListData[ctx.ListDataJSONItemsKey]; // Loop through all the items being shown and output something for (var i = 0; i < listItems.length; i++) { var listItem = listItems[i]; returnHtml = returnHtml + "<li><h1>" + listItem.Title + "</h1><p>" + listItem.Body + "</p></li>"; } returnHtml += "</ul>"; returnHtml += "</div>"; returnHtml += "<input type='button' class='buttons next' value='Next'>"; return returnHtml; function PreRender() { /*SP.SOD.registerSod("jquery min.js", "/_layouts/15/SPC2013/jquery min.js"); SP.SOD.registerSod("jquery.tinycarousel.min.js", "/_layouts/15/SPC2013/jquery.tinycarousel.min.js"); SP.SOD.registerSodDep("jquery.tinycarousel.min.js", "jquery min.js");*/ // LoadSodByKey("jquery.tinycarousel.min.js"); function PostRender() { /*LoadSodByKey("jquery.tinycarousel.min.js", function () { jQuery(document).ready(function () { jQuery('head').append('<link rel="stylesheet" href="/_layouts/15/SPC2013/carousel.css?rev=2" type="text/css" />'); jQuery('#news-carousel').tinycarousel(); }); });*/

45 Code – ‘News’ XSLT List View (JS and CSS)
Markup and code in notes for this slide Add the ‘News’ XSLT List View Web Part to the page and change the JS Link property Add this code to a Script Editor web part This carousel demo uses <script type="text/javascript" src="/_layouts/15/SPC2013/jquery min.js"></script> <script type="text/javascript" src="/_layouts/15/SPC2013/jquery.tinycarousel.min.js"></script> <script type="text/javascript"> jQuery(document).ready(function () { jQuery('head').append('<link rel="stylesheet" href="/_layouts/15/SPC2013/carousel.css" type="text/css" />'); jQuery('#news-carousel').tinycarousel(); }); </script>

46


Download ppt "Nick Hadlee and Gary Payne"

Similar presentations


Ads by Google