This post was most recently updated on August 5th, 2024
Before we go through our actual goal first we discuss about SharePoint versioning.
Within SharePoint list or library, you ability to add column that are type multi-line text field. Within this column setting you have option ‘Append Changes to Existing Text‘.
“You must first turn on versioning in this list before adding or creating columns which append changes to existing text.”
Follow the steps below to enable versioning and column level settings
- Turn on versioning on the list Settings > List Settings > Versioning Settings > Create a version each time you edit an item in this list? Check ‘Yes’
- Change (or add a new) Multiple Lines of Text field and set Append Changes to Existing Text
If you turn on versioning to list and set field is Append only mean SharePoint keep track of updates all items in list on each edit and show versions in form of user name, date time with comment text.
We need to use SP Service “GetVersionCollection” method to read the item data as Rest and CSOM does not support reading the version history of the submitted item
Follow the steps below to read all the version data from comment column.
Steps: Page level
- Create page and add following datatable css and js.
<link rel=”stylesheet” type=”text/css” href=”https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css” />
<script src=”https://code.jquery.com/jquery-1.12.4.js” type=”text/javascript”></script>
<script src=”https://microsoft.sharepoint.com/teams/script/jquery.SPServices-2014.02.js”></script>
<script type=”text/javascript” src=”https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js”></script> - Create table with header according to SharePoint list.
1234567891011<table id="table_id" class="display" role="grid" width="100%" cellspacing="0"><thead><tr><th>ID</th><th>Title</th><th>Adjustment Actual</th><th>Adjustment Requested</th><th>Adjustment Comment</th></tr></thead></table>
Steps: JS Level
- Step 1: We need to get item count of threshold exceed list by GetItemCount () function.
12345678910111213141516function GetItemCount(siteurl, ListName){ //Step 1. get total item count of threshold exceed list.var ItemCount='';$.ajax({url: siteurl+"/_api/web/lists/GetByTitle('"+ListName+"')/ItemCount",method: "GET",async: false,headers: { "Accept": "application/json; odata=verbose" },success: function (data) {ItemCount = data.d.ItemCount;},error: function (data) {console.log(data);}});return ItemCount;}
- Step 2: Next step create rest service url without specifying comment column in string. Here we splitting rest call according to item count of GetItemCount () function. Check item count if item count is above 5000 then we split calling with 1000 item per call top=1000 for better performance. Otherwise we call as usual i.e. top=5000.
12345678910111213function createRestUrl(siteurl, ItemCount, ListName) {//Step 2. create rest service url if item count is above 5000 then we split calling with 1000 item per call top=1000 for better performance. Otherwise we call as usual 5000 items top=5000if(ItemCount<=5000) {//Item count less than 5000 so we limit it as usual 5000var listServiceUrl = siteurl+ "/_api/web/lists/GetByTitle('" + ListName + "')/Items?$select=Title,ID,AdjustmentActual,AdjustmentRequsted$top=5000";} else {//Item count more than 5000 so we split it in 1000 item per callvar listServiceUrl = siteurl+ "/_api/web/lists/GetByTitle('" + ListName + "')/Items?$select=Title,ID,AdjustmentActual,AdjustmentRequsted$top=1000";}//Step 3: Rest call to procerss each items of list$.when(processList(listServiceUrl,ItemCount)).done(function () { });}
- Step 3: In this step we process each item of threshold list by repeatedly calling getJSONDataFromUrl () function. GetJSONDataFromUrl () function gives Ajax json object.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556function processList(nextUrl,ItemCount) { //Step 3: Rest call to procerss each items of listvar dfd = new $.Deferred();if (nextUrl == undefined) {dfd.resolve();return;}//Step 4: Repetative call to getJSONDataFromUrl() to get Ajax Json object.getJSONDataFromUrl(nextUrl).done(function (listItems) {TotalItemCount = TotalItemCount+listItems.d.results.length;var items = listItems.d.results;var next = listItems.d.__next;$.when(getLargeList(next,ItemCount)).done(function (){dfd.resolve();});var tableTdHTML='';//Process each column data for data table object$.each(items, function(index, obj){tableTdHTML +='<tr><td>'+obj.ID+'</td><td>'+obj.Title+'</td><td>'+obj.AdjustmentActual+'</td><td>'+obj.AdjustmentRequested+'</td><td class="ItemIDField_'+obj.ID+'_AdditionalComments"></td></tr>';//Step 4: Call getFieldHistory() to get each item historygetFieldHistory(obj.ID,'AdditionalComments', '');// You can add more such column by calling individual getFieldHistory() function with column name});//Create datatable objectvar table = $('#table_id').DataTable({'iDisplayLength': ItemCount,'lengthMenu': [[10, 25, 50, -1], [10, 25, 50, "All" ]]});//dynamically add tableTdHtml in data table objecttable.rows.add($(tableTdHTML)).draw();});return dfd.promise();}//Step 4: Repetative call to getJSONDataFromUrl() to get Ajax Json object.function getJSONDataFromUrl(endpoint) {return jQuery.ajax({url: endpoint,method: "GET",headers: {"Accept": "application/json; odata=verbose","Content-Type": "application/json; odata=verbose"}});}
- Step 4: At a time of processing we also process each item comment by calling getFieldHistory() function and dynamically append comment to each td.
12345678910111213141516171819202122232425262728293031323334function getFieldHistory (itemId, fieldName, field) { //Get each item version history with comment using SPServicesvar HTML='';var ItemID ="", AdditionalComments= "";var i = 1;$().SPServices({operation: "GetVersionCollection",strlistID: "{A4538568-2FC1-44E2-BAFC-D5DB2C64FF0D}",strlistItemID: itemId,strFieldName: fieldName,completefunc: function (xData, Status) {var xmlDoc = $.parseXML(xData.responseText);$xml = $(xmlDoc);field.history = [];var values = $xml.find("Versions > Version").each(function () {AdditionalComments = $(this).attr(fieldName);var Editor= $(this).attr("Editor");Editor=Editor.substring(0,Editor.indexOf(','));Editor=Editor.split('#')[1];var temp= $(this).attr("Modified");tempModified=temp.split('T')[0];tempModified= new Date(temp);Modified=(tempModified.getMonth() + 1) + '/' + tempModified.getDate() + '/' + tempModified.getFullYear();HTML ='<div>'+Editor+' ('+Modified+'): '+AdditionalComments+' | </div><br/>';$('#table_id .ItemIDField_'+itemId+'_'+fieldName).append(HTML);i++;});}});}
Final Screen shot
Reference: