Methods
    
    
       (
source code)
      
      
          Add items into a Sharepoint List
               note: A Date must be provided as "YYYY-MM-DD" (only date comparison) or "YYYY-MM-DD hh:mm:ss" (date AND time comparison), or you can use $SP().toSPDate(new Date())
               note: A person must be provided as "-1;#email" (e.g. "-1;#foo@bar.com") OR NT login with double \ (eg "-1;#europe\\foo_bar") OR the user ID as a number
               note SP2013: If "-1;#" doesn't work on Sharepoint 2013, then try with "i:0#.w|" (e.g. "i:0#.w|europe\\foo_bar") ("i:0#.w|" may vary based on your authentification system -- see https://social.technet.microsoft.com/wiki/contents/articles/13921.sharepoint-20102013-claims-encoding.aspx)
               note: A lookup value must be provided as "X;#value", with X the ID of the value from the lookup list.
                     --> it should also be possible to not pass the value but only the ID, e.g.: "X;#" or the ID as a number without anything else
               note: A URL field must be provided as "http://www.website.com, Name"
               note: A multiple selection of People/Users must be provided as "userID1;#email1;#userID2;#email2;#userID3;#email3", with "userID" that could be "-1" if you don't know it, and "email" that could also be an NT Login; if you know the correct userID then nothing else is required (e.g. "158;#;#27655;#" will add the users with ID 158 and 27655)
               note: A multiple selection must be provided as ";#choice 1;#choice 2;#", or just pass an array as the value and it will do the trick
               note: A multiple selection of Lookup must be provided as ";#X;#Choice 1;#Y;#Choice 2;#" (with X the ID for "Choice 1", and "Y" for "Choice 2")
                     --> it should also be possible to not pass the values but only the ID, e.g.: ";#X;#;#Y;#;#"
               note: A Yes/No checkbox must be provided as "1" (for TRUE) or "0" (for "False")
               note: A Term / Taxonomy / Managed Metadata field must be provided as "0;#|UniqueIdentifier" for the special hidden related column (see https://github.com/Aymkdn/SharepointPlus/wiki/ to know more)
               note: You cannot change the Approval Status when adding, you need to use the $SP().moderate function
          
          
            Parameters:
            
              Object|Array
  items 
  List of items (e.g. [{Field_x0020_Name: "Value", OtherField: "new value"}, {Field_x0020_Name: "Value2", OtherField: "new value2"}])
   Object
  options Optional
  Options (see below)
   Number
  options.packetsize Optional, Default: 30
  If you have too many items to add, then we use `packetsize` to cut them into several requests (because Sharepoint cannot handle too many items at once)
   Function
  options.progress Optional
  (current,max) If you provide more than 'packetsize' items then they will be treated by packets and you can use "progress" to know more about the steps
   Boolean
  options.breakOnFailure Optional, Default: false
  If you add more than `packetsize` items, then they will be added by packet; by setting `breakOnFailure=true` it will cause the process to stop if at least one item from a packet has failed
   Boolean
  options.escapeChar Optional, Default: true
  Determines if we want to escape the special chars that will cause an error (for example '&' will be automatically converted to '&')
   String
  options.rootFolder Optional, Default: ''
  When dealing with Discussion Board you need to provide the rootFolder of the Message when you post a reply
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({passed, failed}), reject(error)
             
           
          
          
          Example:
          
          // to add 1 item
  $SP().list("My List").add({Title:"Ok"});
  // to add several items
  $SP().list("List Name").add([{Title:"Ok"}, {Title:"Good"}]).then(function(items) { alert("Done!"); });
  $SP().list("My List","http://my.sharepoi.nt/dir/").add({Title:"Ok"}).then(function(items) {
    if (items.failed.length > 0) {
      for (let i=0; i < items.failed.length; i++) console.log("Error '"+items.failed[i].errorMessage+"' with:"+items.failed[i].Title); // the 'errorMessage' attribute is added to the object
    }
    if (items.passed.length > 0) {
      for (let i=0; i < items.passed.length; i++) console.log("Success for:"+items.passed[i].Title+" (ID:"+items.passed[i].ID+")");
    }
  });
  // different ways to add John and Tom into the table
  $SP().list("List Name").add({Title:"John is the Tom's Manager",Manager:"-1;#john@compagny.com",Report:"-1;#tom@compagny.com"}); // if you don't know the ID
  $SP().list("My List").add({Title:"John is the Tom's Manager",Manager:"157",Report:"874"}); // if you know the Lookup ID
  // Calendar events:
  //   - you must define "EventDate" and "EndDate"
  //   - for a full day event you have to define "fAllDayEvent" to "1"
  //   - for recurrent events you have to define "RecurrenceData" and you can either provide an already formatted XML string or the recurrence object that will then be converted with $SP().parseRecurrence()
  // EXAMPLE: event occurs every week on monday and friday, until December 31, 2019, between 10am and 11am, starting from December 20, 2018
  // EventDate is the StartTime and must be the same as EndDate (except for the Time)
  $SP().list("My Calendar").add({
    Title:"Team Meeting",
    EventDate:"2018-12-20 10:00:00", // the Date part is when the recurrent event starts, and the Time part will be used for each event
    EndDate:"2019-12-31 11:00:00", // it must be the last Date/Time for the meeting, then the Time is used as an end time for each event
    RecurrenceData: {
      "type":"weekly",
      "frequency":1,
      "on":{
        "monday":true,
        "friday":true
      },
      "endDate":new Date(2019,11,31,11,0,0) // December 31, 2019, at 11am
    }
  })
  // for Discussion Board, please refer to https://github.com/Aymkdn/SharepointPlus/wiki/Sharepoint-Discussion-Board
          
          
         
      
    
    
    
       (
source code)
      
      
          Add an attachment to a Sharepoint List Item
          
          
            Parameters:
            
              Object
  setup 
  Options (see below)
   Number
  setup.ID 
  The item ID to attach the file
   String
  setup.filename 
  The name of the file
   String
  setup.attachment 
  An array buffer of the file content
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(fileURL), reject()
             
           
          
          
          Example:
          
          $SP().list("My List").addAttachment({
    ID:1,
    filename:"helloworld.txt",
    attachment:"*ArrayBuffer*"
  }).then(function(fileURL) {
    alert(fileURL)
  });
  // to read a file and send it
  // with something like: <input type="file" onchange="addAttachment(event)">
  function addAttachment(event) {
    let files = event.target.files;
    let fileReader = new FileReader();
    fileReader.onloadend = function(e) {
      let content = e.target.result;
      $SP().list("MyList").addAttachment({
        ID:itemID,
        filename:files[0].name,
        attachment:content
      })
      .then(function(url) {
        console.log({url})
      })
      .catch(function(err) {
        console.log(err)
      })
    }
    fileReader.onerror = function(e) {
      alert('Unexpected error: '+e.target.error);
    }
    fileReader.readAsArrayBuffer(files[0]);
  }
          
          
         
      
    
    
    
       (
source code)
      
      
        cleanResult(str, separator)
           
          clean a string returned by a GET (remove ";#" and "string;#" and null becomes "")
          
          
            Parameters:
            
              String
  str 
  The string to clean
   String
  separator Optional, Default: ";"
  When it's a list we may want to have a different output (see examples)
 
           
          
          
          
          
          
          Example:
          
          $SP().cleanResult("15;#Paul"); // -> "Paul"
  $SP().cleanResult("string;#Paul"); // -> "Paul"
  $SP().cleanResult("string;#"); // -> ""
  $SP().cleanResult(";#Paul;#Jacques;#Aymeric;#"); // -> "Paul;Jacques;Aymeric"
  $SP().cleanResult(";#Paul;#Jacques;#Aymeric;#", ", "); // -> "Paul, Jacques, Aymeric"
  $SP().cleanResult("2022-01-19 00:00:00"); // -> "2022-01-19"
          
          
         
      
    
    
    
       (
source code)
      
      
          Get the content of the list based on different criteria (by default the default view is used)
          
          
            Parameters:
            
              Object
  options Optional
  Options (see below)
   String
  options.fields Optional, Default: ""
  The fields you want to grab (be sure to add "Attachments" as a field if you want to know the direct link to an attachment)
   String
  options.view Optional, Default: ""
  If you specify a viewID or a viewName that exists for that list, then the fields/where/order settings for this view will be used in addition to the FIELDS/WHERE/ORDERBY you have defined (the user settings will be used first)
   String
  options.viewCache Optional, Default: true
  If several calls are done using option 'view', then the view's details are put in cache by default
   Boolean
  options.json Optional, Default: false
  When TRUE then the data returned will be an array of JSON
   String|Array
  options.where Optional, Default: ""
  The query string (like SQL syntax) (you'll need to use double \\ before the inside ' -- see example below); you can use an array that will make the sequential requests but it will return all the data into one array (useful for the Sharepoint 2010 throttling limit)
   Boolean
  options.whereCAML Optional, Default: false
  If you want to pass a WHERE clause that is with CAML Syntax only instead of SQL-like syntax -- see $SP().parse() for more info
   Boolean
  options.whereEscapeChar Optional, Default: true
  Determines if we want to escape the special chars that will cause an error (for example '&' will be automatically converted to '&') -- this is applied to the WHERE clause only
   Function
  options.whereFct Optional, Default: function(w){return w}
  Permits to apply your own function on the WHERE clause after conversion to CAML (can be useful also when you use the "view" parameter)
   Function
  options.progress Optional
  When using an array for the WHERE or the PAGING option then you can call the progress function (see the example); one parameter when PAGING that is the number of total items already loaded; two parameters when WHERE as an array that are the number of requests done and the total number of requests that will be sent
   String
  options.orderby Optional, Default: ""
  The field used to sort the list result (you can also add "ASC" -default- or "DESC")
   String
  options.groupby Optional, Default: ""
  The field used to group by the list result; NOTE: it's an option provided by Sharepoint WebService, but it doesn't really do anything special on the results...
   Integer
  options.rowlimit Optional, Default: 0
  You can define the number of rows you want to receive back (0 is infinite)
   Boolean
  options.paging Optional, Default: false
  If you have defined the 'rowlimit' then you can use 'paging' to cut by packets your full request -- this is useful when there is a list view threshold (attention: we cannot use "WHERE" or "ORDERBY" with this option)
   Integer
  options.page Optional, Default: infinite
  When you use the `paging` option, several requests will be done until we get all the data, but using the `page` option you can define the number of requests/pages you want to get
   String
  options.listItemCollectionPositionNext Optional, Default: ""
  When doing paging, this is the index used by Sharepoint to get the next/previous page
   Boolean
  options.useIndexForOrderBy Optional, Default: false
     Boolean
  options.expandUserField Optional, Default: false
  When you get a user field, you can have more information (like name,email,sip,...) by switching this to TRUE
   Boolean
  options.dateInUTC Optional, Default: false
  TRUE to return dates in Coordinated Universal Time (UTC) format. FALSE to return dates in ISO format.
   Boolean
  options.showListInAttribute Optional, Default: false
  When we call a single list, it permits to add the ListName in the attribute (see example)
   String
  options.alias Optional, Default: listName
  In case of a "join" or when "showListInAttribute" is true, we can use a different name for the list to be shown
   Array
  options.merge Optional
  Permits to merge several lists together and return only one dataset; obviously it makes more sense to use this option when you have tables in different locations, but with the same columns. It must be an array of the same settings as $SP().list().get(). Each row of the dataset will have an extra `Source` parameter to know from where the data is coming from (see an example below)
   Object
  options.folderOptions Optional
  Permits to read the content of a Document Library (see below)
   String
  options.folderOptions.path Optional, Default: ""
  Relative path of the folders we want to explore (by default it's the root of the document library)
   String
  options.folderOptions.show Optional, Default: "FilesAndFolders_InFolder"
  Four values: "FilesOnly_Recursive" that lists all the files recursively from the provided path (and its children); "FilesAndFolders_Recursive" that lists all the files and folders recursively from the provided path (and its children); "FilesOnly_InFolder" that lists all the files from the provided path; "FilesAndFolders_InFolder" that lists all the files and folders from the provided path
   String
  options.folderOptions.rootFolder Optional, Default: ""
  It's the full URL to the document library; if not provided, it will be automatically retrieved
   Boolean
  options.queryOptions Optional
     Object
  options.join Optional
  Permits to create a JOIN closure between the current list and another one: it will be the same syntax than a regular GET (see the example below)
   String
  options.join.list Optional
  Permits to establish the link between two lists (see the example below)
   String
  options.join.url Optional, Default: 'current website'
  The website url (if different than the current website)
   String
  options.join.on Optional
  Permits to establish the link between two lists (only between the direct parent list and its child, not with the grand parent) (see the example below)
   String
  options.join.onLookup Optional
  Permits to establish the link between two lists based on a lookup field... it's more optimized than the simple `join.on` (see the example below)
   Boolean
  options.join.outer Optional, Default: false
  If you want to do an outer join (you can also directly use "outerjoin" instead of "join")
   Boolean
  options.calendar Optional, Default: false
  If you want to get the events from a Calendar List
   Object
  options.calendarOptions Optional
  Options that will be used when "calendar:true" (see the example to know how to use it)
   Boolean
  options.calendarOptions.splitRecurrence Optional, Default: true
  By default we split the events with a recurrence (so 1 item = 1 day of the recurrence)
   String|Date
  options.calendarOptions.referenceDate Optional, Default: today
  This is the date used to retrieve the events -- that can be a JS Date object or a SP Date (String) [attention: if 'splitRecurrence' is FALSE, then Sharepoint will ignore this 'referenceDate'...]
   String
  options.calendarOptions.range Optional, Default: "Month"
   
           
          
          
          
            Returns:
            
            
              Promise
resolve(data returned by the server), reject(error from $SP().ajax())
             
           
          
          
          Example:
          
          $SP().list("List Name").get().then(function(data) {
    for (var i=0; i<data.length; i++) console.log(data[i].getAttribute("Title"));
  });
  // with some fields and an orderby command
  $SP().list("ListName","http://www.mysharepoint.com/mydir/").get({
    fields:"Title,Organization",
    orderby:"Title DESC,Test_x0020_Date ASC"
  }).then(function(data) {
    for (var i=0; i<data.length; i++) console.log(data[i].getAttribute("Title"));
  });
  // handle the errors
  $SP().list("List Name").get().then(function(data) {
    for (var i=0; i<data.length; i++) console.log(data[i].getAttribute("Title"));
  }).catch(function(err) {
    console.log("Error => ",err)
  });
  // the WHERE clause must be SQL-like
  // the field names must be the internal names used by Sharepoint
  // ATTENTION - note that here we open the WHERE string with simple quotes (') and that should be your default behavior each time you use WHERE
  var name = "O'Sullivan, James";
  $SP().list("My List").get({
    fields:"Title",
    where:'Fiscal_x0020_Week > 30 AND Fiscal_x0020_Week < 50 AND Name = "'+name+'"'
  }).then(function(row) {
    for (var i=row.length;i--;) console.log(row[i].getAttribute("Title"));
  });
  // Same example but this time we write the name directly inside the query...
  // So make sure to use a single backslash (\) if you have a simple quote ' inside your WHERE with a double quotes (") to open/close the string
  $SP().list("My List").get({
    fields:"Title",
    where:'Fiscal_x0020_Week > 30 AND Fiscal_x0020_Week < 50 AND Name = "O\'Sullivan, James"'
  }).then(function(row) {
    for (var i=row.length;i--;) console.log(row[i].getAttribute("Title"));
  });
  // Or to use a double backslash (\\) if you have a simple quote ' inside your WHERE with a simple quote (') to open/close the string
  $SP().list("My List").get({
    fields:"Title",
    where:"Fiscal_x0020_Week > 30 AND Fiscal_x0020_Week < 50 AND Name = 'O\\'Sullivan, James'"
  }).then(function(row) {
    for (var i=row.length;i--;) console.log(row[i].getAttribute("Title"));
  });
  // also in the WHERE clause you can use '[Me]' to filter by the current user,
  $SP().list("My List").get({
    fields:"Title",
    where:"Author = '[Me]'"
  }).then(function(row) {
    console.log(row[0].getAttribute("Title"));
  });
  // also in the WHERE clause you can use '[Today]' or '[Today-X]' with 'X' a number,
  // Here it will return the records done yesterday
  $SP().list("My List").get({
    fields:"Title",
    where:"Created = '[Today-1]'"
  }).then(function(row) {
    console.log(row[0].getAttribute("Title"));
  });
  // Since 3.0.8, if you do a WHERE on a Date with the Time included, then it will compare with the time
  // see http://blogs.syrinx.com/blogs/sharepoint/archive/2008/08/05/caml-queries-with-dates.aspx
  // here it will only show the items created at 2PM exactly -- if you want to check only the today, then use "Created = '2014-03-12'"
  $SP().list("My List").get({
    fields:"Title",
    where:"Created = '2014-03-12 14:00:00'"
  }).then(function(row) {
    console.log(row[0].getAttribute("Title"));
  });
  // We have a list called "My List" with a view already set that is called "Marketing View" with some FIELDS and a WHERE clause
  // so the function will grab the view information and will get the data from the list with "Author = '[Me]'" and adding the view's WHERE clause too
  $SP().list("My List","http://my.sharepoint.com/my/site/").get({
    view:"Marketing View",
    where:"Author = '[Me]'"
  }).then(function(data) {
    for (var i=data.length; i--;) console.log(data[i].getAttribute("Title") + " by " + data[i].getAttribute("Author"));
  });
  // use the paging option for the large list to avoid the message "the attempted operation is prohibited because it exceeds the list view threshold enforced by the administrator"
  // ATTENTION: if you use the WHERE option then it could return the "view threshold" error message because the packet from the WHERE is too big and SharePoint is too stupid...
  $SP().list("My List").get({
    fields:"ID,Title",
    rowlimit:5000,
    paging:true,
    progress:function progress(nbItemsLoaded) {
      // for each new page this function will be called
      console.log("It's still loading... already "+nbItemsLoaded+" items have been loaded!");
    }
  }).then(function(data) {
    console.log(data.length); // -> 23587
  })
  // add the `page` option to stop after a number of requests/pages
  // for example you only want the last record from a list that has more than 5,000 items
  $SP().list("My List").get({fields:"ID",orderby:"ID DESC",rowlimit:1,paging:true,page:1}).then(function(data) {
    console.log("last ID : "+data[0].getAttribute("ID"));
  })
  // use `listItemCollectionPositionNext` to start from this index
  $SP().list("My List").get({
    fields:"ID",
    orderby:"ID DESC",
    rowlimit:10,
    paging:true,
    page:1
  }).then(function(data) {
    // "data" is our first page of data
    // get the next block
    return $SP().list("My List").get({fields:"ID",orderby:"ID DESC",rowlimit:10,paging:true,page:1,listItemCollectionPositionNext:data.NextPage})
  }).then(function(data) {
    // here "data" is the 2nd block of data
    // If you want to access to the previous page, you can use:
    // listItemCollectionPositionNext:"Paged=TRUE&PagedPrev=True&p_ID="+ID
    // with ID the first/smallest ID of the current set.
    // reference: https://social.technet.microsoft.com/wiki/contents/articles/18606.sharepoint-2013-paging-with-sharepoint-client-object-model.aspx
  })
  // We can also find the files from a Document Shared Library
  $SP().list("Shared Documents","http://my.share.point.com/my_site/").get({
    fields:"FileLeafRef,File_x0020_Size",
  }).then(function(data) {
    for (var i=0; i<<data.length; i++) console.log("FileName:"+data[i].getAttribute("FileLeafRef"),"FileSize:"+data[i].getAttribute("File_x0020_Size"));
  });
  // We can join two or more lists together based on a condition
  // ATTENTION: in that case the DATA passed to the callback will return a value for "LIST NAME.FIELD_x0020_NAME" and not directly "FIELD_x0020_NAME"
  // ATTENTION: you need to make sure to call the 'fields' that will be used in the 'on' clause
  $SP().list("Finance and Expense","http://my.sharepoint.com/my_sub/dir/").get({
    fields:"Expense_x0020_Type",
    where:"Finance_x0020_Category = 'Supplies'",
    join:{
      list:"Purchasing List",
      fields:"Region,Year,Expense_x0020_Type,Finance_x0020_Category,Cost",
      where:"Region = 'EMEA' AND Year = 2012",
      orderby:"Expense_x0020_Type,Finance_x0020_Category",
      on:"'Purchasing List'.Expense_x0020_Type = 'Finance and Expense'.Expense_x0020_Type",
      join:{
        list:"Financial Static Data",
        fields:"Region,Year,Expense_x0020_Type,Finance_x0020_Category,Forecast",
        where:"Region = 'EMEA' AND Year = 2012",
        on:"'Purchasing List'.Region = 'Financial Static Data'.Region AND 'Purchasing List'.Expense_x0020_Type = 'Financial Static Data'.Expense_x0020_Type"
      }
    }
  }).then(function(data) {
    for (var i=0; i<data.length; i++) {
      console.log(data[i].getAttribute("Purchasing List.Region")+" | "+data[i].getAttribute("Purchasing List.Year")+" | "+data[i].getAttribute("Purchasing List.Expense_x0020_Type")+" | "+data[i].getAttribute("Purchasing List.Cost"));
    }
  });
  // By default "join" is an "inner join", but you can also do an "outerjoin"
  // ATTENTION: in that case the DATA passed to the callback will return a value for "LIST NAME.FIELD_x0020_NAME" and not directly "FIELD_x0020_NAME"
  // ATTENTION: you need to make sure to call the 'fields' that will be used in the 'on' clause
  $SP().list("Finance and Expense","http://my.sharepoint.com/my_sub/dir/").get({
    fields:"Expense_x0020_Type",
    where:"Finance_x0020_Category = 'Supplies'",
    join:{
      list:"Purchasing List",
      fields:"Region,Year,Expense_x0020_Type,Finance_x0020_Category,Cost",
      where:"Region = 'EMEA' AND Year = 2012",
      orderby:"Expense_x0020_Type,Finance_x0020_Category",
      on:"'Purchasing List'.Expense_x0020_Type = 'Finance and Expense'.Expense_x0020_Type",
      outerjoin:{
        list:"Financial Static Data",
        fields:"Region,Year,Expense_x0020_Type,Finance_x0020_Category,Forecast",
        where:"Region = 'EMEA' AND Year = 2012",
        on:"'Purchasing List'.Region = 'Financial Static Data'.Region AND 'Purchasing List'.Expense_x0020_Type = 'Financial Static Data'.Expense_x0020_Type"
      }
    }
  }).then(function(data) {
    for (var i=0; i<data.length; i++)
      console.log(data[i].getAttribute("Purchasing List.Region")+" | "+data[i].getAttribute("Purchasing List.Year")+" | "+data[i].getAttribute("Purchasing List.Expense_x0020_Type")+" | "+data[i].getAttribute("Purchasing List.Cost"));
  })
  // Another example of "outerjoin", but this time with fields tied to a Lookup ID
  // Here 1 Project can have several Deliverables based on field "Project ID", and 1 Deliverable can have several team members based on "Deliverable ID"
  $SP().list("Projects").get({
    fields:"ID,Project_x0020_Name",
    where:"Status = 'In Progress'",
    outerjoin:{
      list:"Deliverables",
      fields:"ID,Name",
      onLookup:"Project_x0020_ID",
      outerjoin:{
        list:"Team Members",
        fields:"ID,Deliverable_x0020_ID,Name",
        onLookup:"Deliverable_x0020_ID"
      }
    }
  }).then(function(data) {
    var html = '<table class="table default"><thead><tr><th>Project ID</th><th>Project Name</th><th>Deliverable ID</th><th>Deliverable Name</th><th>Team ID</th><th>Member Name</th></tr></thead><tbody>'
    for (var i=0;i<data.length; i++) {
      html += '<tr><td>'+data[i].getAttribute("Projects.ID")+'</td><td>'+data[i].getAttribute("Projects.Project_x0020_Name")+'</td><td>'+data[i].getAttribute("Deliverables.ID")+'</td><td>'+data[i].getAttribute("Deliverables.Name")+'</td><td>'+data[i].getAttribute("Team Members.ID")+'</td><td>'+data[i].getAttribute("Team Members.Name")+'</td></tr>'
    }
    html += '</tbody></table>';
    $('#part1').html(html);
  })
  // With Sharepoint 2010 we are limited due to the throttling limit (see here for some very interesting information http://www.glynblogs.com/2011/03/sharepoint-2010-list-view-throttling-and-custom-caml-queries.html)
  // So for example if I do WHERE:'Fiscal_x0020_Year = 2012' it will return an error because I have 6,500 items
  // So I'll do several requests for each Fiscal_x0020_Week into this Fiscal Year
  var query=[],q=[];
  for (var i=1; i<54; i++) {
    q.push("Fiscal_x0020_Week = "+i);
    if (i%8==0 || i == 53) {
      query.push("("+q.join(" OR ")+") AND Fiscal_x0020_Year = 2012");
      q=[]
    }
  }
  // it returns :
  // [
  //   "(Fiscal_x0020_Week = 1 OR Fiscal_x0020_Week = 2 OR Fiscal_x0020_Week = 3 OR Fiscal_x0020_Week = 4 OR Fiscal_x0020_Week = 5 OR Fiscal_x0020_Week = 6 OR Fiscal_x0020_Week = 7 OR Fiscal_x0020_Week = 8) AND Fiscal_x0020_Year = 2012",
  //   ...
  //   "(Fiscal_x0020_Week = 49 OR Fiscal_x0020_Week = 50 OR Fiscal_x0020_Week = 51 OR Fiscal_x0020_Week = 52 OR Fiscal_x0020_Week = 53) AND Fiscal_x0020_Year = 2012"
  // ]
  $SP().list("Sessions").get({
    fields:"Title,Score",
    where:query,
    progress:function progress(current,max) {
      // when we use an array for the WHERE clause we are able to provide `current` and `max`
      console.log("Progress: "+current+" / "+max);
    }
  }).then(function(data) {
    console.log(data.length); // -> 6,523
  });
  // also regarding the throttling limit, you can query a list on a user column in using the User ID
  // For example if John Doe is recorded as "328;#Doe, John" then you'll have to use the special operator "~="
  $SP().list("Sessions").get({
    fields:"Title",
    where:"User ~= 328"
  }).then(function(data) {
    console.log(data.length);
  });
  // if you want to list only the files visible into a folder for a Document Library
  $SP().list("My Shared Documents").get({
    fields:"BaseName,FileRef,FSObjType", // "BaseName" is the name of the file/folder; "FileRef" is the full path of the file/folder; "FSObjType" is 0 for a file and 1 for a folder (you need to apply $SP().cleanResult()), "File_x0020_Size" the filesize in bytes
    folderOptions:{
      path:"My Folder/Sub Folder/",
      show:"FilesOnly_InFolder"
    }
  });
  // if you want to list all the files and folders for a Document Library
  // Let's say the original name for this library was "Documents Library", but then it has been renamed to "My Different Shared Documents"
  $SP().list("My Different Shared Documents").get({
    fields:"BaseName,FileRef,FSObjType", // "BaseName" is the name of the file/folder; "FileRef" is the full path of the file/folder; "FSObjType" is 0 for a file and 1 for a folder (you need to apply $SP().cleanResult())
    folderOptions:{
      show:"FilesAndFolders_Recursive",
      rootFolder:"https://www.mysite.com/sites/Team/Documents Library/" // this is optional as the tool will otherwise automatically retrieve this full path
    }
  });
  // How to retrieve the events from a Calendar List
  // NOTE -- when "calendar:true" we automatically get some fields: "Title", "EventDate" -- the Start Date --, "EndDate", "RecurrenceData", "Duration", "fAllDayEvent", "fRecurrence", "ID", "EventType", "UID" and "MasterSeriesItemID"
  $SP().list("My Calendar").get({
    fields:"Description",
    calendar:true,
    calendarOptions:{
      referenceDate:new Date(2012,4,4),
      range: "Week"
    },
    where:"Category = 'Yellow'"
  }).then(function(data) {
    var events=[];
    for (var i=0; i<data.length; i++) {
      // several information are available -- see below
      events.push({
        Title:         data[i].getAttribute("Title"),
        StartDateTime: data[i].getAttribute("EventDate"), // you can use $SP().toDate() to have a JS Date
        EndDateTime:   data[i].getAttribute("EndDate"), // you can use $SP().toDate() to have a JS Date
        Recurrence:    (data[i].getAttribute("fRecurrence") == 1 ? true : false),
        AllDayEvent:   (data[i].getAttribute("fAllDayEvent") == 1 ? true : false),
        RecurrenceEnd: (data[i].getAttribute("RecurrenceData")||"").replace(/.+([^<]+)<\/windowEnd>.+/,"$1"), // see the NOTE below
        ID:            data[i].getAttribute("ID"), // the ID for the recurrence events is special but can be also passed to "Display.aspx?ID="
        Duration:      1*data[i].getAttribute("Duration") // Duration is in SECONDS
      })
      // NOTE: with data[i].getAttribute("RecurrenceData") you'll find more info about the recurrence (like the end date for the serie, and much more),
      // but because there are a lot of scenario, I won't handle the different cases.
      // e.g. for a daily recurrence you can find the end date of the serie with: data[i].getAttribute("RecurrenceData").replace(/.+([^<]+)<\/windowEnd>.+/,"$1")
      // --> it will return a SP Date
    }
  })
  // if we want to merge two tables
  $SP().list("Requests").get({
    fields:"ID",
    where:"User_x0020_Name ~= 16358",
    merge:[{
      list:"Requests Archive",
      fields:"ID",
      where:"User_x0020_Name ~= 16358"
    }]
  })
  .then(function(data) {
    data.forEach(function(d) { console.log(d.Source.list, d.Source.url, d.getAttribute("ID")) })
  })
  // Use of "showListInAttribute"
  // In normal case you'll have:
  $SP().list("My List").get({fields:"Title", where:"ID = 1"})
  .then(function(data) {
    console.log("Title = "+data[0].getAttribute("Title"))
  });
  // With "showListInAttribute" you'll have to use the listname to get the field's value:
  $SP().list("My List").get({fields:"Title", where:"ID = 1", showListInAttribute:true})
  .then(function(data) {
    console.log("Title = "+data[0].getAttribute("My List.Title")); // here we have to specifiy "My List"
  });
  // With "json:true" you'll get an array of JSON
  $SP().list("My List").get({fields:"Title", json:true})
  .then(function(data) {
    data.forEach(function(d) {
      console.log("Title = "+d["Title"]);
    })
  });
  // for Discussion Board, please refer to https://github.com/Aymkdn/SharepointPlus/wiki/Sharepoint-Discussion-Board
  // [It doesn't work with Sharepoint 2013 anymore, only for SP2010]
  // You can use `useIndexForOrderBy:true` to override the list view threshold -- see https://spservices.codeplex.com/discussions/280642
  // To make it to work, you need :
  // 1) to have "ID > 0 AND Another_Index_Column_Filtered" in the WHERE Clause (so at least two filters), and then we can add some other WHERE (even the not indexed columns)
  // 2) To use `orderby`, with an indexed column
  // 3) To use `useIndexForOrderBy:true`
  // see the below example with Trainer an indexed column, and Equipment a column not indexed
  // NOTE: you need to test your WHERE to see if it works or not, because it's vary a lot depending of the kind of WHERE clause you'll use
  $SP().list("Calendar",'http://intranet.dell.com/services/Educate/Toolbox/scheduling_tool/').get({
    fields:"Trainer",
    where:'ID > 0 AND Trainer <> "" AND Equipment LIKE "Box"',
    orderby:'Trainer',
    useIndexForOrderBy:true
  }).then(function(d) {
    console.log(d.length)
  })
          
          
         
      
    
    
    
       (
source code)
      
      
          Get the attachment(s) for an item
          
          
            Parameters:
            
              String|Number
  itemID 
  The item ID
 
           
          
          
          
            Returns:
            
            
              Promise
resolve([results])
             
           
          
          
          Example:
          
          $SP().list("My List","http://my.site.com/mydir/").getAttachment(1).then(function(attachments) {
    for (var i=0; i<attachments.length; i++) console.log(attachments[i]); -> "https://my.site.com/site/Lists/Something/Attachments/46/helloworld.txt"
  });
  // you can also use $SP().list().get() using the "Attachments" field
          
          
         
      
    
    
    
       (
source code)
      
      
        getContentTypeInfo(contentType, options)
           
          Get the Content Type Info for a Content Type into the list
          
          
            Parameters:
            
              String
  contentType 
  The Name or the ID (from $SP().list.getContentTypes) of the Content Type
   Boolean
  options.cache Optional, Default: true
  Do we use the cache?
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(fields), reject(error)
             
           
          
          
          Example:
          
          $SP().list("List Name").getContentTypeInfo("Item").then(function(fields) {
    for (var i=0; i<fields.length; i++) console.log(fields[i]["DisplayName"]+ ": "+fields[i]["Description"]);
  });
  $SP().list("List Name").getContentTypeInfo("0x01009C5212B2D8FF564EBE4873A01C57D0F9001").then(function(fields) {
    for (var i=0; i<fields.length; i++) console.log(fields[i]["DisplayName"]+ ": "+fields[i]["Description"]);
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Get the Content Types for the list (returns Name, ID and Description)
          
          
            Parameters:
            
              Boolean
  options.cache Optional, Default: true
  Do we want to use the cache on recall for this function?
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(contentTypes), reject(error)
             
           
          
          
          Example:
          
          $SP().list("List Name").getContentTypes().then(function(contentTypes) {
    for (var i=0; i<contentTypes.length; i++) console.log(contentTypes[i].Name, contentTypes[i].ID, contentTypes[i].Description);
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          When versionning is activated on a list, you can use this function to get the different versions of a list item
          
          
          
          
          
            Returns:
            
            
              Promise
resolve(arrayOfVersions)
             
           
          
          
          Example:
          
          $SP().list("My List").getVersions(1234).then(function(versions) {
    versions.forEach(function(version) {
      console.log(version);
    })
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Find the WorkflowID for a workflow, and some other related info
          
          
            Parameters:
            
              Number
  setup.ID 
  The item ID that is tied to the workflow
   String
  setup.workflowName 
  The name of the workflow
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({workflowID, fileRef, description, instances}), reject(error)
             
           
          
          
          Example:
          
          $SP().list("List Name").getWorkflowID({ID:15, workflowName:"Workflow for List Name (manual)"}).then(function(params) {
  alert("Workflow ID:"+params.workflowID+" and the FileRef is: "+params.fileRef);
});
          
          
         
      
    
    
    
       (
source code)
      
      
          This function permits to check if the current user has a specific permission for a list/library
          
          
          
          
          
            Returns:
            
            
              Promise
A promise with a boolean (TRUE/FALSE) if the requested perm was a string, or an object ({perm1:BOOLEAN, perm2:BOOLEAN}) if it was an array
             
           
          
          
          Example:
          
          // check permissions for list 'Travels'
  $SP().list('Travels').hasPermission('deleteListItems').then(function(hasPerm) {
    console.log('Can the user delete an item on Travels? ', hasPerm) // hasPerm is TRUE or FALSE
  })
  $SP().list('Travels').hasPermission(['addListItems','editListItems']).then(function(hasPerm) {
    console.log('Can the user add an item in Travels? ', hasPerm.addListItems);
    console.log('Can the user edit an item in Travels? ', hasPerm.editListItems);
  })
          
          
         
      
    
    
    
       (
source code)
      
      
          When versioning is an active option for your list, then you can use this function to find the previous values for a field
          
          
            Parameters:
            
              String|Number
  params.ID 
  The item ID
   String
  params.Name 
  The field name
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(data), reject(error)
             
           
          
          
          Example:
          
          $SP().list("My List").history({ID:1981, Name:"Critical_x0020_Comments"}).then(function(data) {
    for (var i=0,len=data.length; i<len; i++) {
      console.log("Date: "+data[i].getAttribute("Modified")); // you can use $SP().toDate() to convert it to a JavaScript Date object
      console.log("Editor: "+data[i].getAttribute("Editor")); // it's the long format type, so the result looks like that "328;#Doe,, John,#DOMAIN\john_doe,#John_Doe@example.com,#,#Doe,, John"
      console.log("Content: "+data[i].getAttribute("Critical_x0020_Comments")); // use the field name here
    }
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Get the columns' information/metadata, and the list's details
          
          
          
            Returns:
            
            
              Promise
resolve(infos), reject(error)
             
           
          
          
          Example:
          
          $SP().list("List Name").info().then(function(infos) {
    // for columns' details:
    for (var i=0; i<infos.length; i++) console.log(infos[i]["DisplayName"]+ ": => ",infos[i]);
    // for list's details:
    console.log(infos._List)
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Get all the lists from the site
          
          
            Parameters:
            
              Object
  setup Optional
  Options (see below)
   String
  setup.url Optional, Default: 'current website'
  The website url
   Boolean
  setup.cache Optional, Default: true
  To get the result from the cache when available
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({ID, Name, Description, Url, .....}), reject(error)
             
           
          
          
          Example:
          
          $SP().lists().then(function(lists) {
    for (var i=0; i<lists.length; i++) console.log("List #"+i+": "+lists[i].Name);
  });
          
          
         
      
    
    
    
       (
source code)
      
      
        moderate(approval, setup)
           
          Moderate items from a Sharepoint List
          
          
            Parameters:
            
              Array
  approval 
  List of items and ApprovalStatus (e.g. [{ID:1, ApprovalStatus:"Approved"}, {ID:22, ApprovalStatus:"Pending"}])
   Object
  setup Optional
  Options (see below)
   Number
  setup.packetsize Optional, Default: 15
  If you have too many items to moderate, then we use `packetsize` to cut them into several requests (because Sharepoint cannot handle too many items at once)
   Function
  setup.progress Optional
  Two parameters: 'current' and 'max' -- if you provide more than `packetsize` ID then they will be treated by packets and you can use "progress" to know more about the steps
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({passed, failed}), reject(error)
             
           
          
          
          Example:
          
          $SP().list("My List").moderate({ID:1, ApprovalStatus:"Rejected"}); // you must always provide the ID
  $SP().list("Other List").moderate([{ID:5, ApprovalStatus:"Pending"}, {ID: 15, ApprovalStatus:"Approved"}]).then(function(items) {
    for (var i=0; i < items.failed.length; i++) console.log("Error with:"+items.failed[i].ID);
    for (var i=0; i < items.passed.length; i++) console.log("Success with:"+items.passed[i].getAttribute("Title"));
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Use a WHERE sentence to transform it into a CAML Syntax sentence
          
          
            Parameters:
            
              String
  where 
  The WHERE sentence to change
   String
  escapeChar Optional, Default: true
  Determines if we want to escape the special chars that will cause an error (for example '&' will be automatically converted to '&')
 
           
          
          
          
          Example:
          
          $SP().parse('ContentType = "My Content Type" OR Description <> null AND Fiscal_x0020_Week >= 43 AND Result_x0020_Date < "2012-02-03"');
  // -> return <And><And><Or><Eq><FieldRef Name="ContentType" /><Value Type="Text">My Content Type</Value></Eq><IsNotNull><FieldRef Name="Description" /></IsNotNull></Or><Geq><FieldRef Name="Fiscal_x0020_Week" /><Value Type="Number">43</Value></Geq></And><Lt><FieldRef Name="Result_x0020_Date" /><Value Type="DateTime">2012-02-03</Value></Lt></And>
  // available operators :
  // "<" : less than
  // "<=" : less than or equal to
  // ">" : greater than
  // ">=" : greater than or equal to
  // "<>" : different
  // "~=" : this must be only used when comparing to a number that represents a User or List ID (e.g. 'User ~= 328') - that permits to query a list with indexed lookup column
  // "~<>" : same as before, except that we exclude the value (e.g. 'User ~<> 328')
  // " AND "
  // " OR "
  // " LIKE " : for example 'Title LIKE "foo"' will return "foobar" "foo" "barfoobar" "barfoo" and so on
  // " IN " : for example 'Location IN ["Los Angeles","San Francisco","New York"]', equivalent to 'Location = "Los Angeles" OR Location = "San Francisco" OR Location = "New York"' — SP2013 limits each IN to 60 items. If you want to check Lookup IDs instead of text you can use '~' followed by the ID, for example 'Location IN ["~23", "~26", "~30"]'
  // special words:
  // '[Me]' : for the current user
  // '[Today]' : to use the today date
  // '[Today+X]' : to use today + X days
  // Null : for the Null value
  // TRUE : for the Yes/No columns
  // FALSE : for the Yes/No columns
  // in the below example, on the "&" will be escaped
  var bar="Bob & Marley";
  var foo="O'Conney";
  $SP().parse('Bar = "'+bar+'" AND Foo = "'+foo+'"'); // -> <And><Eq><FieldRef Name="Bar" /><Value Type="Text">Bob & Marley</Value></Eq><Eq><FieldRef Name="Foo" /><Value Type="Text">O'Conney</Value></Eq></And>
  $SP().parse("Bar = '"+bar+"' AND Foo = '"+foo+"'"); // don't put the simple and double quotes this way because it'll cause an issue with O'Conney
          
          
         
      
    
    
    
       (
source code)
      
      
          Transform a RecurrenceData XML string to a recurrence object, and transform a recurrence object to a RecurrenceData XML string (for calendar events)
          
          
            Parameters:
            
              String|Object
  data 
  The RecurrenceData XML or a recurrence object
 
           
          
          
          
          
          
          Example:
          
          // from RecurrenceData XML to object
  $SP().parseRecurrence('<recurrence><rule><firstDayOfWeek>mo</firstDayOfWeek><repeat><monthlyByDay weekday="TRUE" weekdayOfMonth="last" monthFrequency="1" /></repeat><windowEnd>2019-01-19T16:00:00Z</windowEnd></rule></recurrence>');
  // it will return the below object
  {
    "type":"monthlyByDay",
    "firstDayOfWeek":"monday",
    "on":{
      "weekday":"last"
    },
    "frequency":1,
    "endDate":"2019-01-19T16:00:00.000Z"
  }
  // from recurrence object to RecurrenceData XML string
  $SP().parseRecurrence({"type":"weekly","frequency":1,"on":{"monday":true,"tuesday":true,"wednesday":true},"endDate":new Date("2007-05-31T22:00:00.000Z")}); // -> <recurrence><rule><firstDayOfWeek>mo</firstDayOfWeek><repeat><weekly mo="TRUE" tu="TRUE" we="TRUE" weekFrequency="1" /></repeat><windowEnd>2007-05-31T22:00:00Z</windowEnd></rule></recurrence>
  // recurrence object examples:
  // Every weekday
  {
    "type":"daily",
    "firstDayOfWeek":"monday",
    "on":{
      "weekday":true
    }
  }
  // Every X days
  {
    "type":"daily",
    "firstDayOfWeek":"monday",
    "frequency":X
  }
  // Every week on Monday and Wednesday
  {
    "type":"weekly",
    "firstDayOfWeek":"monday",
    "on":{
      "monday":true,
      "wednesday":true
    },
    "frequency":1
  }
  // Every day 10 of every 2 months
  {
    "type":"monthly",
    "firstDayOfWeek":"monday",
    "on":{
      "day":10
    },
    "frequency":2
  }
  // Every second tuesday of every 6 months
  {
    "type":"monthlyByDay",
    "firstDayOfWeek":"monday",
    "on":{
      "tuesday":"second"
    },
    "frequency":6
  }
  // Every December 25
  {
    "type":"yearly",
    "firstDayOfWeek":"monday",
    "on":{
      "month":12,
      "day":25
    },
    "frequency":1
  }
  // The third weekday of September
  {
    "type":"yearlyByDay",
    "firstDayOfWeek":"monday",
    "on":{
      "month":9,
      "weekday":"third"
    },
    "frequency":1
  }
          
          
         
      
    
    
    
       (
source code)
      
      
          Delete items from a Sharepoint List
          
          
            Parameters:
            
              Objet|Array
  itemsID Optional
  List of items ID (e.g. [{ID:1}, {ID:22}]) | ATTENTION if you want to delete a file you have to add the "FileRef" e.g. {ID:2,FileRef:"path/to/the/file.ext"}
   Object
  options Optional
  Options (see below)
   String
  options.where Optional
  If you don't specify the itemsID (first param) then you have to use a `where` clause - it will search for the list of items ID based on the `where` and it will then delete all of them
   Number
  options.packetsize Optional, Default: 30
  If you have too many items to delete, then we use `packetsize` to cut them into several requests (because Sharepoint cannot handle too many items at once)
   Function
  options.progress Optional
  Two parameters: 'current' and 'max' -- If you provide more than 'packetsize' ID then they will be treated by packets and you can use "progress" to know more about the steps
   Boolean
  options.breakOnFailure Optional, Default: false
  If you add more than `packetsize` items, then they will be removed by packet; by setting `breakOnFailure=true` it will cause the process to stop if at least one item from a packet has failed
   String|Date
  options.event Optional
  If you want to delete an occurrence of a recurrent event from a calendar (see the below example)
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({passed, failed}), reject(error)
             
           
          
          
          Example:
          
          $SP().list("My List").remove({ID:1});
  // we can use the WHERE clause instead providing the ID
  $SP().list("My List").remove({where:"Title = 'OK'",progress:function(current,max) {
    console.log(current+"/"+max);
  }});
  // delete several items
  $SP().list("List Name", "http://my.sharepoint.com/sub/dir/").remove([{ID:5}, {ID:7}]);
  $SP().list("List").remove({ID:43, Title:"My title"}).then(function(items) {
    for (var i=0; i < items.failed.length; i++) console.log("Error with:"+items.failed[i].ID+" ("+items.failed[i].errorMessage+")"); // only .ID and .errorMessage are available
  });
  // example for deleting a file/folder
  $SP().list("My Shared Documents").remove({ID:4,FileRef:"site/subsite/My Shared Documents/something.xls"});
  // or use {where} (that only works with files, but not folders)
  $SP().list("My Shared Documents").remove({where:"ID = 4"});
  // if you want to delete one occurrence of a recurrent event you must use option "event"
  // e.g. you have an event #1589 that occurs every weekday, from 9am to 10am, but you want to delete the one on December 17, 2018
  $SP().list("Calendar").remove({
    where:'ID = 1589', // the criteria that permits to identify your master recurrent event -- IT IS REQUIRED
    event:new Date(2018,11,17) // date of the event that needs to be deleted, it can be the "RecurrenceID"
  })
          
          
         
      
    
    
    
       (
source code)
      
      
          Remove an attachment from a Sharepoint List Item
          
          
            Parameters:
            
              Object
  setup 
  Options (see below)
   Number
  setup.ID 
  The item ID where the file will be removed
   String
  setup.fileURL 
  The full path to the file
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(true), reject()
             
           
          
          
          Example:
          
          $SP().list("My List").removeAttachment({
    ID:1,
    fileURL:"https://mysite.share.point.com/Toolbox/Lists/Tasks/Attachments/2305/image1.png"
  })
          
          
         
      
    
    
    
       (
source code)
      
      
          When versionning is activated on a list, you can use this function to restore another version label/number for a list item
          
          
            Parameters:
            
              Object
  setup Optional
  Options (see below)
   Number
  setup.ID 
  The item ID
   Number
  setup.VersionID 
  The version ID from $SP().list().getVersions()
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(true), reject(errorMessage)
             
           
          
          
          Example:
          
          $SP().list("My List").restoreVersion({
    ID:1,
    VersionID:3849
  })
          
          
         
      
    
    
    
       (
source code)
      
      
        setReadOnly(fieldID, readonly)
           
          Permits to change a readonly column (like "Created By", "Created","Modified" or "Modified By") to become editable... ATTENTION: it's not recommanded to edit a READONLY column, and it could have unexpected consequences on your list
          
          
            Parameters:
            
              String
  fieldID 
  The internal field name (e.g. "Author", or "Modified"); The supported columns are: "Author", "Created", "Editor" and "Modified". You can also provide an XML string if you want to deal with another column (e.g. <'Field ID="{8c06beca-0777-48f7-91c7-6da68bc07b69}" Name="Created" SourceID="
http://schemas.microsoft.com/sharepoint/v3" StaticName="Created" Group="_Hidden" ColName="tp_Created" RowOrdinal="0" ReadOnly="TRUE" Type="DateTime" DisplayName="Created" StorageTZ="TRUE"/>')
   Boolean
  readonly 
  To define the readonly status of the column
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(contentTypes), reject(error)
             
           
          
          
          Example:
          
          // make "Created" column an editable column
  $SP().list("List Name").setReadOnly('Created', false)
  .then(function() {
    $SP().list("List Name").update({ID:1, Created:'2019-01-19'})
  })
          
          
         
      
    
    
    
       (
source code)
      
      
          Manually start a workflow (that has been set to be manually started) (for "Sharepoint 2010 workflow" as the platform type)
          
          
            Parameters:
            
              String
  setup.workflowName 
  The name of the workflow
   Number
  setup.ID Optional
  The item ID that tied to the workflow
   Array|Object
  setup.parameters Optional
  An array of object with {name:"Name of the parameter", value:"Value of the parameter"}
   String
  setup.fileRef Optional
  Optional: you can provide the fileRef to avoid calling the $SP().list().getWorkflowID()
   String
  setup.workflowID Optional
  Optional: you can provide the workflowID to avoid calling the $SP().list().getWorkflowID()
 
           
          
          
          
            Returns:
            
            
              Promise
resolve() if it's started, reject(error)
             
           
          
          
          Example:
          
          // if you want to call a Site Workflow, just leave the list name empty and don't provide an item ID, e.g.:
  $SP().list("").startWorkflow({workflowName:"My Site Workflow"});
  // to start a workflow for a list item
  $SP().list("List Name").startWorkflow({ID:15, workflowName:"Workflow for List Name (manual)", parameters:{name:"Message",value:"Welcome here!"}).then(function() {
    alert("Worflow Started!")
  }).catch(function(error) {
      console.log("Error: ",error);
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Manually start a work (that has been set to be manually started) (for "Sharepoint 2013 workflow" as the platform type)
          
          
            Parameters:
            
              Number
  setup.ID Optional
  The item ID that tied to the workflow
   String
  setup.workflowName 
  The name of the workflow
   Array|Object
  setup.parameters Optional
  An array of object with {name:"Name of the parameter", value:"Value of the parameter"}
 
           
          
          
          
            Returns:
            
            
              Promise
resolve() when started, reject(error)
             
           
          
          
          Example:
          
          // if you want to call a Site Workflow, just leave the list name empty and don't provide an item ID, e.g.:
  $SP().list("").startWorkflow2013({workflowName:"My Site Workflow"});
  // to start a workflow for a list item
  $SP().list("List Name").startWorkflow2013({ID:15, workflowName:"Workflow for List Name (manual)", parameters:{name:"Message",value:"Welcome here!"}).then(function() {
    console.log("workflow started")
  }, function(error) {
    console.log("Error: ",error);
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Stop/Terminate a Workflow 2010 instance (this is only for Workflow 2010)
          
          
            Parameters:
            
              Number
  setup.ID 
  The item ID that is tied to the workflow
   String
  setup.workflowName 
  The name of the workflow
 
           
          
          
          
            Returns:
            
            
              Promise
resolve(), reject(error)
             
           
          
          
          Example:
          
          $SP().list("List Name").stopWorkflow({ID:42, workflowName:"My workflow"});
          
          
         
      
    
    
    
       (
source code)
      
      
          Update items from a Sharepoint List
          
          
            Parameters:
            
              Array
  items 
  List of items (e.g. [{ID: 1, Field_x0020_Name: "Value", OtherField: "new value"}, {ID:22, Field_x0020_Name: "Value2", OtherField: "new value2"}])
   Object
  options Optional
  Options (see below)
   String
  options.where Optional, Default: ""
  You can define a WHERE clause
   Number
  options.packetsize Optional, Default: 30
  If you have too many items to update, then we use `packetsize` to cut them into several requests (because Sharepoint cannot handle too many items at once)
   Function
  options.progress Optional
  Two parameters: 'current' and 'max' -- if you provide more than 'packetsize' ID then they will be treated by packets and you can use "progress" to know more about the steps
   Boolean
  options.breakOnFailure Optional, Default: false
  If you add more than `packetsize` items, then they will be updated by packet; by setting `breakOnFailure=true` it will cause the process to stop if at least one item from a packet has failed
   Boolean
  options.escapeChar Optional, Default: true
  Determines if we want to escape the special chars that will cause an error (for example '&' will be automatically converted to '&')
   String|Date
  options.event Optional
  If you want to create an exception occurrence for a recurrent event you must define the "event" option using the date of the occurence to change (see the below example)
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({passed, failed}), reject(error)
             
           
          
          
          Example:
          
          // to update 1 item
  $SP().list("My List").update({ID:1, Title:"Ok"});
  // if you use the WHERE then you must not provide the item ID:
  $SP().list("List Name").update({Title:"Ok"},{where:"Status = 'Complete'"});
  // to update several items with a known ID
  $SP().list("My List","http://sharepoint.org/mydir/").update([{ID:5, Title:"Ok"}, {ID: 15, Title:"Good"}]);
  $SP().list("List Name").update({ID:43, Title:"Ok"}).then(function(items) {
    for (var i=0; i < items.failed.length; i++) console.log("Error '"+items.failed[i].errorMessage+"' with:"+items.failed[i].Title);
    var len=items.passed.length;
    console.log(len+(len>1?" items have been successfully added":" item has been successfully added"))
  });
  // For recurrent calendar events, you can edit one of the occurrence using the `event` option; it will procure a new separate event
  // e.g. you have an event #1589 that occurs every weekday, from 9am to 10am, but you want to update the one on December 17, 2018 to be from 2pm to 3pm
  $SP().list("Calendar").update({
    Title:'Special Team Meeting', // if you want to change the event's title
    EventDate:$SP().toSPDate(new Date(2018,11,17,14,0,0), true), // the new start date for the meeting (2pm)
    EndDate:$SP().toSPDate(new Date(2018,11,17,15,0,0), true) // the new end date for the meeting (3pm)
  }, {
    where:'ID = 1589', // the criteria that permits to identify your master recurrent event -- IT IS REQUIRED
    event:new Date(2018,11,17) // date of the event that needs to be changed... if the event ID is "5274.0.2019-01-07T15:00:00Z", then you can use "2019-01-07T15:00:00Z"
  })
  // Note: if you update a complete serie for a recurrent event, then all the exception occurrences will be automatically deleted and replace with the full serie of events
          
          
         
      
    
    
    
       (
source code)
      
      
          Get the view's details (like selected fields, order by, where, ....)
          
          
            Parameters:
            
              String
  viewID Optional, Default: "The default view"
  The view ID or view Name
   Object
  options Optional
  (see below)
   Boolean
  options.cache Optional, Default: true
  Get the view's info from the cache
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({DefaultView, Name, ID, Type, Url, OrderBy, Fields, RowLimit, WhereCAML}), reject(error)
             
           
          
          
          Example:
          
          $SP().list("List Name").view("All Items").then(function(res) {
    for (var i=0; i<res.Fields.length; i++) console.log("Column "+i+": "+res.Fields[i]);
    console.log("And the GUI for this view is :"+res.ID);
  });
          
          
         
      
    
    
    
       (
source code)
      
      
          Get the views' info for a List
          
          
            Parameters:
            
              Boolean
  options.cache Optional, Default: true
  Get the info from the cache
 
           
          
          
          
            Returns:
            
            
              Promise
resolve({DefaultView, Name, ID, Type, Url}), reject(error)
             
           
          
          
          Example:
          
          $SP().list("My List").views().then(function(view) {
    for (var i=0; i<view.length; i++) {
      console.log("View #"+i+": "+view[i].Name);
    }
  });