Introduction

In this article, we will explore how we can attach multiple attachments to the new item on list using JSOM and REST API.

There are dozens of blog posts and articles out there about uploading files to SharePoint, and some of them even mention attachments. But I found that not a single one of the articles provide a step by step guide to create new item and attachments to itself.

So far, I have seen everyone blogging and posting articles, where they follow the approach of hardcoding the item ID and passing it to REST API and Uploading.

But I have come up with another way of implementing the same. Check the step by step guide below.

Steps

The below code snippet will show the Personal Details HTML that has been created for the user to insert data into the list. In HTML, one tag is highlighted to facilitate multi -ile upload control, I am leveraging “jquery.multifile.js” plugin. If we don’t use that plugin, the user will select only one input file for upload.

  1.     “text/javascript” src=“/Script/jquery-1.10.2.js”>
  2.     “text/javascript” src=“/Script/jquery-ui.js”>
  3.     “text/javascript” src=“/_layouts/15/sp.js”>
  4.     “text/javascript” src=“/_layouts/15/sp.runtime.js”>
  5.  “text/javascript” src=“/Script/jquery.multifile.js”>
  6.   <span style=“font-size: 22.0pt;padding-left:20px”>Personal Details<o:p></o:p></span>
  7. <table align=“left” border=“1” cellpadding=“0” cellspacing=“0” class=“MsoTableGrid” width=“0” id=“mytable”>
  8.         <tbody>
  9.             <tr>
  10.                 <td >
  11.                     <table align=“left” border=“1” cellpadding=“0” cellspacing=“0” class=“MsoTableGrid” style=“”><tbody><tr><td style=“” valign=“top” class=“auto-style16”><h3> Name</h3></td>
  12.    <td valign=“top” style=“padding:9px;” class=“auto-style17”>
  13.                                     <input type=“text” value=“” maxlength=“255” id=“Name” title=“Name” style=“width: 96%;” class=“ms-long ms-spellcheck-true”>
  14.                                 </td></tr><tr >
  15.                                 <td class=“auto-style16”><h3> Address</h3>                           </td><td class=“auto-style17”>
  16.                                     <input type=“text” value=“” maxlength=“255” id=” Address” title=“Address” style=“ime-mode :;width: 96%;” class=“ms-long ms-spellcheck-true”></td></tr><tr><td class=“auto-style15”><h3 >City</h3></td>
  17.  <td class=“auto-style4”><input type=“text” value=“” maxlength=“255” id=” City “ title=” City “ style=“;width: 96%;” class=“ms-long ms-spellcheck-true”></td></tr><tr><td class=“auto-style15”><h3 >
  18. Contact Number </h3></td>
  19. <td class=“auto-style5”><input type=“text” value=“” maxlength=“255” id=” ContactNumber “ title=“ContactNumber” style=“ime-mode :;width: 96%;” class=“ms-long ms-spellcheck-true”></td></tr></tbody></table><table ><tbody>
  20. <tr ><td ><span style=“font-family: “ segoe ui” ,sans-serif; color: #444444″>Click here to attach file</span> 
    class=“files” id=“attachFilesHolder “>
  21.   “file_input” type=“file” name=“files[]”>
  22.                                     
  • </td><td></td></tr></tbody></table>
  •                    
    “TEXT-ALIGN: -webkit-center; padding-bottom: 20px; padding-top: 20px; padding-left:190px”>”SaveItem” style=” height: 40px; font-size: 15px;” class=“ms-ButtonHeightWidth” id=” NewSaveItem “ accesskey=“O” onclick=“” type=“button” value=“Click here to submit “ target=“_self”>
  •         </tbody></table>
  • SharePoint

    Step 1

    Navigate to your SharePoint 2013 site.

    Step 2

    From this page, select Site Actions | Edit Page.

    Edit the page. Go to the Insert tab in the ribbon and click Web Part option.

    In Web Parts picker area, go to the Media and Content category, select the Script Editor Web Part, and press the Add button.

    Step 3

    Once the Web part is inserted into the page, you will see an “EDIT SNIPPET” link; click it. You can insert HTML and/or JavaScript, as shown below.

    1. “text/javascript”>
    2.     var oLoader;
    3.     var attcount = 0;
    4.     var arraycount = 0;
    5.         $(document).ready(function ($) {
    6.            $(‘#file_input’).multifile();//For facilitate multi file upload
    7.         $(“#NewSaveItem”).click(function () { formSave() });
    8.     });
    9.     function formSave() {
    10.             oLoader = SP.UI.ModalDialog.showWaitScreenWithNoClose(“Working on it”“Creating New Bank Account…”);
    11.                 var data = [];
    12.                 var fileArray = [];
    13.                 $(“#attachFilesHolder input:file”).each(function () {
    14.                     if ($(this)[0].files[0]) {
    15.                         fileArray.push({ “Attachment”: $(this)[0].files[0] });
    16.                     }
    17.                 });
    18.             arraycount += fileArray.length;
    19.                 data.push({
    20.                     “Name”: $(“input[title=’Name’]”).val(),
    21.                     ” Address “: $(“input[title=’Address’]”).val(),
    22.                     “City”: $(“input[title= City]”).val(),
    23.                     “ContactNumber”: $(“input[title=’ContactNumber’]”).val(),
    24.                     “Files”: fileArray
    25.                 });
    26.                 createNewItemWithAttachments(“BankDetails”, data).then(
    27.                     function () {
    28.                         if (oLoader.close) setTimeout(function () { oLoader.close(); window.location.replace(_spPageContextInfo.siteAbsoluteUrl + “/Lists/BankDetails/AllItems.aspx”); }, 3000);
    29.                     },
    30.                     function (sender, args) {
    31.                         console.log(‘Error occured’ + args.get_message());
    32.                     }
    33.                 )
    34.         }
    35.     var createNewItemWithAttachments = function (listName, listValues) {
    36.         var fileCountCheck = 0;
    37.         var fileNames;
    38.         var context = new SP.ClientContext.get_current();
    39.         var dfd = $.Deferred();
    40.         var targetList = context.get_web().get_lists().getByTitle(listName);
    41.         context.load(targetList);
    42.         var itemCreateInfo = new SP.ListItemCreationInformation();
    43.         var listItem = targetList.addItem(itemCreateInfo);
    44.         listItem.set_item(“Name”, listValues[0].Name);
    45.         listItem.set_item(“Address”, listValues[0]. Address);
    46.         listItem.set_item(“City”, listValues[0].City);
    47.         listItem.set_item(“ContactNumber”, listValues[0].ContactNumber);
    48.         listItem.update();
    49.         context.executeQueryAsync(
    50.             function () {
    51.                 var id = listItem.get_id();
    52.                 if (listValues[0].Files.length != 0) {
    53.                     if (fileCountCheck 
    54.                         loopFileUpload(listName, id, listValues, fileCountCheck).then(
    55.                             function () {
    56.                             },
    57.                             function (sender, args) {
    58.                                 console.log(“Error uploading”);
    59.                                 dfd.reject(sender, args);
    60.                             }
    61.                         );
    62.                     }
    63.                 }
    64.                 else {
    65.                     dfd.resolve(fileCountCheck);
    66.                 }
    67.             },
    68.             function (sender, args) {
    69.                 console.log(‘Error occured’ + args.get_message());
    70.             }
    71.         );
    72.         return dfd.promise();
    73.     }
    74.     function loopFileUpload(listName, id, listValues, fileCountCheck) {
    75.         var dfd = $.Deferred();
    76.         uploadFileHolder(listName, id, listValues[0].Files[fileCountCheck].Attachment).then(
    77.             function (data) {
    78.                 var objcontext = new SP.ClientContext();
    79.                 var targetList = objcontext.get_web().get_lists().getByTitle(listName);
    80.                 var listItem = targetList.getItemById(id);
    81.                 objcontext.load(listItem);
    82.                 objcontext.executeQueryAsync(function () {
    83.                     console.log(“Reload List Item- Success”);
    84.                     fileCountCheck++;
    85.                     if (fileCountCheck 
    86.                         loopFileUpload(listName, id, listValues, fileCountCheck);
    87.                     } else {
    88.                         console.log(fileCountCheck + “: Files uploaded”);
    89.                         attcount += fileCountCheck;
    90.                         if (arraycount == attcount) {
    91.                             if (oLoader.close) setTimeout(function () { oLoader.close(); window.location.replace(_spPageContextInfo.siteAbsoluteUrl + “/Lists/BankDetails/AllItems.aspx”); }, 3000);
    92.                         }
    93.                     }
    94.                 },
    95.                 function (sender, args) {
    96.                     console.log(“Reload List Item- Fail” + args.get_message());
    97.                 });
    98.             },
    99.             function (sender, args) {
    100.                 console.log(“Not uploaded”);
    101.                 dfd.reject(sender, args);
    102.             }
    103.        );
    104.         return dfd.promise();
    105.     }
    106.     function uploadFileHolder(listName, id, file) {
    107.         var deferred = $.Deferred();
    108.         var fileName = file.name;
    109.         getFileBuffer(file).then(
    110.             function (buffer) {
    111.                 var bytes = new Uint8Array(buffer);
    112.                 var binary = ;
    113.                 for (var b = 0; b 
    114.                     binary += String.fromCharCode(bytes[b]);
    115.                 }
    116.                 var scriptbase = _spPageContextInfo.webServerRelativeUrl + “/_layouts/15/”;
    117.                 console.log(‘ File size:’ + bytes.length);
    118.                 $.getScript(scriptbase + “SP.RequestExecutor.js”function () {
    119.                     var createitem = new SP.RequestExecutor(_spPageContextInfo.webServerRelativeUrl);
    120.                     createitem.executeAsync({
    121.                         url: _spPageContextInfo.webServerRelativeUrl + “/_api/web/lists/GetByTitle(‘” + listName + “‘)/items(“ + id + “)/AttachmentFiles/add(FileName='” + file.name + “‘)”,
    122.                         method: “POST”,
    123.                         binaryStringRequestBody: true,
    124.                         body: binary,
    125.                         success: fsucc,
    126.                         error: ferr,
    127.                         state: “Update”
    128.                     });
    129.                     function fsucc(data) {
    130.                         console.log(data + ‘ uploaded successfully’);
    131.                         deferred.resolve(data);
    132.                     }
    133.                     function ferr(data) {
    134.                         console.log(fileName + “not uploaded error”);
    135.                         deferred.reject(data);
    136.                     }
    137.                 });
    138.             },
    139.             function (err) {
    140.                 deferred.reject(err);
    141.             }
    142.         );
    143.         return deferred.promise();
    144.     }
    145.     function getFileBuffer(file) {
    146.         var deferred = $.Deferred();
    147.         var reader = new FileReader();
    148.         reader.onload = function (e) {
    149.             deferred.resolve(e.target.result);
    150.         }
    151.         reader.onerror = function (e) {
    152.             deferred.reject(e.target.error);
    153.         }
    154.         reader.readAsArrayBuffer(file);
    155.         return deferred.promise();
    156.     }

    Final O/P

    SharePoint

    Advertisements

    Scenario

    Create a SharePoint Designer 2013 Workflow associated with the security list and set it to start automatically when a list item is created. Once the user submits his comment, the Workflow will create the list item in the security list with the use of an app step. The initiator does not always have the rights to complete all the actions within the Workflow, for example, when the Workflow needs to create new items. With SharePoint 2013 Workflows, it is possible to use app step action to give the Workflow its own permission set, if the Workflow’s own permission is not set. In such a situation, the Workflow gets Suspended. I noticed the occurrence of this scenario when I used the app step. Looking at the Suspended state, there is an icon, which shows an error when clicked.

    Details

    An unhandled exception occurred during the execution of the Workflow instance. Exception details: System.ApplicationException: HTTP 401 {“error_description”:”The Server was unable to process the request due to an internal error.

    SharePoint

    Solutions

    To allow Workflow to use app permissions

    1. Go to Site settings–>Manage Features

      SharePoint

    2. Activate Workflows can use app permissions.

      SharePoint

    Steps

    1. Go to Site Settings.
    2. In the Users and Permissions section, select Site app permissions.

      SharePoint

    3. Copy the client section of the app identifier. This is the identifier between the last “|” and the “@” sign. Select App Identifier.

      SharePoint

    4. Navigate to the Grant permission to an app page. This must be done by browsing to the appinv.aspx page of the site.
    5. Fill in the App Id and click Lookup.

      SharePoint

    6. The fields Title, App Domain and Redirect URL will be filled in automatically.
    7. Paste XML code given below into Permission Request XLM textbox to the grant the Workflow app step full control.
      1. http: //}hostname}/{the Site Collection}/_layouts/15/appinv.aspx
      2. < AppPermissionRequests > < AppPermissionRequest Scope = http://sharepoint/content/sitecollection/web&#8221;
      3. Right = “FullControl” / > < /AppPermissionRequests>
    8. Click Create and Trust It.
      SharePoint

      Note
      1. There are no placeholders in the Scope value above. It is a literal value. Enter it exactly, as it appears here.
      2. If you are facing any issue, please copy the text given above, which is taken from MSDN article whose link is given below.
    9. Click Create.
    10. You will then be asked to trust the Workflow app. Click Trust It.

    Please follow the MSDN article given below for more reference to configure the app step.

    https://msdn.microsoft.com/en-us/library/office/jj822159.aspx

    Introduction

    Hi, I am a SharePoint front-end developer. As such, it is important to understand the client life cycle in terms of DOM, Browser-engine, etc. We will be talking about the Onload process in this post. There are different techniques used to Provide our custom JavaScript code loaded before / in the middle / alter OnLoad events in SharePoint;

    Here we will see 8 different techniques used for the 0nload process. Below are the specified Techniques.

    Below are the code snippets for each technique in use.

    Sys.Application.PageLoad

    1. Sys.Application.add load(SPLoad);
    2. function SPLoad(){
    3.     console.log(“Sys.Application.PageLoad.Time:” + ((Date.now()) – performance.timing.navigationStart))
    4. }

    Sys.WebForms.PageRequestManager.PageLoaded

    1. Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(SPPageLoaded);
    2. function SPPageLoaded(sender,args){
    3.     console.log(“Sys.Webforms.PageRequestManager.PageLoaded.Time:” + ((Date.now()) – performance.timing.navigationStart))
    4. }

    Document.ready Jquery

    1. jQuery(document).ready(jqueryLoadsSP);
    2. function jqueryLoadSP(){
    3.     console.log(“Document.ready Jquery.Time:” + ((Date.now()) – performance.timing.navigationStart))
    4. }
    5. function ProcessDefaultOnLoad() {
    6.     ProcessPNGImages();
    7.     UpdateAccessibilityUI();
    8.     UpdateAnimationUserControl(false);
    9.     window.setTimeout(‘ProcessImn()’, 10);
    10.     ProcessOnLoadFunctionNames(_spBodyOnLoadFunctionNames);     ProcessOnLoadFunctions(_spBodyOnLoadFunctions);
    11.     if (typeof _spUseDefaultFocus != “undefined”)
    12.         DefaultFocus();
    13. }

    _spBodyOnLoadFunctionNames

    1. _spBodyOnLoadFunctionNames.push(‘OnPageLoad’);
    2. function OnPageLoad(){
    3.     console.log(“_spBodyOnLoadFunctionNames. Time: “ + ((Date.now()) – performance.timing.navigationStart));
    4. }

    _spBodyOnLoadFunctions

    1. _spBodyOnLoadFunctions.push(raiseFunc);
    2. var raiseFunc = function(){
    3.     console.log(“_spBodyOnLoadFunction. Time: “ + ((Date.now()) – performance.timing.navigationStart));
    4. };

    ExecuteOrDelayUntilScriptLoaded:sp.core.js

    1. ExecuteOrDelayUntilScriptLoaded(MyFunction, “sp.core.js”);
    2. function MyFunction(){
    3.     console.log(“ExecuteOrDelayUntilScriptLoaded:sp.core.js. Time: “ + ((Date.now()) – performance.timing.navigationStart));
    4. }

    SP.SOD.executeFunc: sp.js

    1. SP.SOD.executeFunc(‘sp.js’‘SP.ClientContext’, sharePointReady);
    2. function sharePointReady(){
    3.     console.log(“SP.SOD.executeFunc: sp.js. Time: “ + ((Date.now()) – performance.timing.navigationStart));
    4. }

    ExecuteOrDelayUntilBodyLoaded

    1. ExecuteOrDelayUntilBodyLoaded(delayBody);
    2. function delayBody(){
    3.     console.log(“ExecuteOrDelayUntilBodyLoaded. Time from NavStart: “ + ((Date.now()) – performance.timing.navigationStart));
    4. }

    Output

    JavaScript

    Chrome

    Run 1

    JavaScript

    Run 2

    JavaScript

    Run 3

    JavaScript

    IE11

    JavaScript

    Run 1

    JavaScript

    Run 2

    JavaScript

    Run 3

    JavaScript

    As you see the above images of the output of the code snippet run on both chrome and IE11 browsers, here we discover the sequence of execution.

    We will talk about both the sequences,

    Order Chrome IE11
    1 ExecuteOrDelayUntilBodyLoaded document.ready Jquery
    2 Sys.Application.PageLoad. ExecuteOrDelayUntilBodyLoaded
    3 document.ready Jquery Sys.Application.PageLoad.
    4 SP.SOD.executeFunc: sp.js. SP.SOD.executeFunc: sp.js.
    5 _spBodyOnLoadFunctionNames _spBodyOnLoadFunctionNames
    6 _spBodyOnLoadFunction _spBodyOnLoadFunction
    7 ExecuteOrDelayUntilScriptLoaded:sp.core.js ExecuteOrDelayUntilScriptLoaded:sp.core.js
    8 Sys.WebForms.PageRequestManager.PageLoaded Sys.WebForms.PageRequestManager.PageLoaded
    • ExecuteOrDelayUntilBodyLoaded function is always executed first in chrome (but at this stage we cannot access  SP methods). Whereas the document.ready Jquery function is executed first in IE11.
    • This could be useful to execute our custom code at a really early stage in the OnLoad process keeping in mind the order of execution.
    • There are two SharePoint onLoad functions _spBodyOnLoadFunctionNames and _spBodyOnLoadFunction. Always executed in the order. SO, if we want to execute some code after all functions included by us (or other devs) in _spBodyOnLoadFunctionNames, then it is useful to use this one _spBodyOnLoadFunction, because is executed the last.
    • If we want to execute some functions after all functions (SP, after load functions, Yammer, etc.) we can use this function to attach the OnLoad event -> Sys.WebForms.PageRequestManager.PageLoaded.
    • I have referred to an article to implement this particular functionality, check the URL.

    Introduction

    SharePoint 2013 provides a very powerful endpoint, which you can use to retrieve search result and query suggestion.

    The first thing which we have seen is the available search endpoints

    Endpoint
    http://%5Bhost%5D/%5Bsite%5D/_api/search/query
    http://%5Bhost%5D/%5Bsite%5D/_api/search/postquery
    http://%5Bhost%5D/%5Bsite%5D/_api/search/suggest

    The simplest way to run a query against REST API is to pass a keyword query. There are two basic ways to run searches, where one is by sending the search parameters through the RESTful URL and the other by sending them through the query or suggest endpoints. The querytext can be any legal keyword query language construction, including managed properties and operators. So far we’ve just looked at executing a basic query, where the query text is specified. Here are a couple of other common operations, which you might want to do.

    Operation Sample REST URL
    Specify the maximum number of record to return /_api/search/query?querytext=’search term’&rowlimit=100
    Specify a start row (i.e. in paging) /_api/search/query?querytext=’search term’&startrow=11
    Specify a number of results to return /_api/search/query?querytext=’search term’&startrow=11&rowlimit=10 (but note 10 is the default)
    Specifies the list of properties to sort the search results by. /_api/search/query?querytext=’terms’&sortlist= ‘Title:ascending’
    Specify particular (managed) properties to return /_api/search/query?querytext=’search term’&selectproperties=’Author,Path,Title’
    Use a search Result Source (i.e. a scope) /_api/search/query?querytext=’search term’&sourceid=’B09A7990-05EA-4AF9-81EF-EDFAB16C4E31′ (this ex. is to search the ‘People’ result source)

    Below specifies the unique key identifier of the Result Source to use for executing the search queries,

    Result Source ID
    Documents e7ec8cee-ded8-43c9-beb5-436b54b31e84
    Items matching a content type 5dc9f503-801e-4ced-8a2c-5d1237132419
    Items matching a tag e1327b9c-2b8c-4b23-99c9-3730cb29c3f7
    Items related to current user 48fec42e-4a92-48ce-8363-c2703a40e67d
    Items with same keyword as this item 5c069288-1d17-454a-8ac6-9c642a065f48
    Local People Results b09a7990-05ea-4af9-81ef-edfab16c4e31
    Local Reports And Data Results 203fba36-2763-4060-9931-911ac8c0583b
    Local SharePoint Results 8413cd39-2156-4e00-b54d-11efd9abdb89
    Local Video Results 78b793ce-7956-4669-aa3b-451fc5defebf
    Pages 5e34578e-4d08-4edc-8bf3-002acf3cdbcc
    Pictures 38403c8c-3975-41a8-826e-717f2d41568a
    Popular 97c71db1-58ce-4891-8b64-585bc2326c12
    Recently changed items ba63bbae-fa9c-42c0-b027-9a878f16557c
    Recommended Items ec675252-14fa-4fbe-84dd-8d098ed74181
    Wiki 9479bf85-e257-4318-b5a8-81a180f5faa1

    Example

    I wanted to search for the people, the key learning here is that you specify the content sources via its GUID.

    Use the procedure given below to create a sample.

    Step 1

    Navigate to your SharePoint 2013 site.

    Step 2

    From this page, select Site Actions | Edit Page.

    Edit the page, go to the Insert tab in the Ribbon and click Web Part option. In Web Parts picker area, go to the Media and Content category, select the Script Editor Web Part and press the Add button.

    Step 3 

    Once the Web Part is inserted into the page, you will see an “EDIT SNIPPET” link; click it. You can insert HTML and/or JavaScript, as shown below.

    1. “/Scripts/jquery-1.10.1.min.js” type=“text/javascript”>
    2. “text/javascript”>
    3.     $(document).ready(function() {
    4.         $(“#SearchQuery”).click(function() {
    5.             $.ajax({
    6.                 url: window.location.protocol + “//” + window.location.host + “/_api/search/query?querytext='” + $(“#search-input”).val() + “*’&sourceid=’b09a7990-05ea-4af9-81ef-edfab16c4e31’&rowlimit=’100’&selectproperties=’PictureURL, PreferredName, Country'”,
    7.                 headers: {
    8.                     “Accept”“application/json; odata=verbose”
    9.                 },
    10.                 contentType: “application/json; odata=verbose”,
    11.                 success: function(data) {
    12.                     var results;
    13.                     var divHTML = ;
    14.                     var Picurl;
    15.                     if (data.d) {
    16.                         if (data.d.query) var users = newArray();
    17.                         results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
    18.                         for (i = 0; i 
    19.                             var item = results[i];
    20.                             var itemCell = item.Cells;
    21.                             var itemResults = itemCell.results;
    22.                             //Get Values for User
    23.                             var userPic = getValueByKey(“PictureURL”, itemResults);
    24.                             var fullname = getValueByKey(“PreferredName”, itemResults);
    25.                             var CountryName = getValueByKey(“Country”, itemResults);
    26.                             if (userPic != null) {
    27.                                 Picurl = userPic;
    28.                             } else {
    29.                                 Picurl = ‘/Style Library/styles/images/tempPic.png’;
    30.                             }
    31.                             // alert(PicId);
    32.                             divHTML += 
      ‘ + 

      ‘ + 

      ‘ + 

      ‘ + 

      ‘ + 

      ‘ +  + Picurl + ‘”/>’ + 

      ‘ + 

      ‘ + 

      ‘ + 

      ‘ + 

      ‘ + 

       ‘ + fullname + ‘ 

      ‘ + 

      ‘ + CountryName + ‘ 

      ‘ + 

      ‘ + 

      ‘ + 

      ‘ + 

    ‘ + 

    ‘ + 

  •                         }
  •                         $(“#Result”).html(divHTML);
  •                     }
  •                     elseif(data.d.postquery)
  •                     results = data.d.postquery.PrimaryQueryResult.RelevantResults.Table.Rows.results;
  •                     else throw “Results not found”;
  •                 }
  •             });
  •         });
  •         function getValueByKey(key, results) {
  •             var postItem = $.grep(results, function(e) {
  •                 if (e.Key === key) returne;
  •             })[0].Value;
  •             returnpostItem;
  •         }
  •     });
  •  <input type=“text” id=“search-input”> <input type=“button” id=“SearchQuery” value=“Search”>
  • “Result”>