This is entirely possible to do with Client Side Rendering. One way to do it would be to add a column to the list called "Days Overdue", and then use a list view override for that field to do the calculations and display your red text message. However, then you have added a column to your list that you are not actually using to store any data.
As it turns out though, you don't even need to add a column to the list, we can use the CSR framework to insert a fake column to display the "XX days overdue" message in the list view.
var DEC = DEC || {};
DEC.DaysOverdueField = (function () {
function addTemporaryField(ctx) {
// make sure we haven't added the field already,
// in case OnPreRender fires twice
if (ctx.ListSchema.Field.filter(function (fld) {
return fld.Name == 'DaysOverdueField';
}).length == 0) {
// create the field schema object to insert
var daysOverdueFieldObj = {
AllowGridEditing: 'FALSE',
DisplayName: 'Days Overdue',
RealFieldName: 'DaysOverdueField',
Name: 'DaysOverdueField',
FieldType: 'Text',
Type: 'Text',
Filterable: 'FALSE',
Sortable: 'FALSE',
ReadOnly: 'TRUE',
};
// find the index of the field to insert next to,
// based on that field's DISPLAY name.
// in this case i am assuming you want to show the "XX days overdue"
// message directly next to your due date field,
// but really you can use this to insert the fake column
// next to any field you want.
var insertIdx = ctx.ListSchema.Field.map(function (fld) {
return fld.DisplayName;
}).indexOf('Your Due Date Field');
// if you want to insert *before* the due date field do not add anything
// but, if you want to insert *after* the due date field, add 1
insertIdx++;
// insert your fake field schema object into the list schema
ctx.ListSchema.Field.splice(insertIdx, 0, daysOverdueFieldObj);
}
}
function calculateOverdueDays(ctx) {
// get the index of the "Days Overdue" column in the table
// so we know where to insert the ovedue days message
var colIndex = 0;
var headers = document.querySelectorAll('.ms-listviewtable th');
var len = headers.length;
for (var idx = 0; idx < len; idx++) {
if (headers[idx].innerHTML.indexOf('Days Overdue') != -1) {
colIndex = idx;
}
};
// go through the rows and display an overdue message if it is overdue
ctx.ListData.Row.forEach(function (listItem) {
// get the due date
// NOTE: this is based on your due date field's INTERNAL name
var duedate = new Date(listItem.YourDueDateField);
// use the built in GetDaysAfterToday function to calculate
// how many days overdue an item is. if it is truly overdue,
// this function will return a negative number.
var overdueDays = GetDaysAfterToday(duedate);
if (overdueDays < 0) {
// change the negative to a positive
overdueDays = Math.abs(overdueDays);
// find the row in the table that corresponds to this list item
var iid = GenerateIIDForListItem(ctx, listItem);
var row = document.getElementById(iid);
// insert the overdue message in the <td> element in
// our temporary "Days Overdue" column
row.children[colIndex].innerHTML = '<span style="color:red;">' + overdueDays + ' days overdue</span>';
}
});
}
return {
render: function () {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPreRender: addTemporaryField,
OnPostRender: calculateOverdueDays
});
}
}
})();
RegisterModuleInit(SPClientTemplates.Utility.ReplaceUrlTokens("~site/SiteAssets/Scripts/ShowDaysOverdue.js"), DEC.DaysOverdueField.render);
DEC.DaysOverdueField.render();
If you save this script in a file called ShowDaysOverdue.js, upload it somewhere on your SharePoint site (make sure you edit the path in the second to last line of the script to reflect the place where you plan to upload the file to), you can then edit the list view web part and link to the script using the view's JSLink property.