How to use Sharepoint CSR to conditional hide row
Question
Team,
I've got a list to record a shift roster. I have two Date/Time columns recording (1) Start of the shift and (2) End of the Shift.
I want a view that only shows who is rostered on right now!
I can use OOTB list filters to filter by [today] but not by time - which means it picks up all shifts that either start or end on the same date as "today".
The code below paints any row green if shift start date/time <= to "now" AND if shift end date/time => to "now" and anything that does not match that criteria is painted red (my workaround to the whole inability of filtering by time).
GREAT! - however, rather than paint green or red, I want to show TRUE rows and hide FALSE rows.
I just haven't found the code yet on the 'net that I can scavenge and rejig to do the job. Any help would be appreciated.
Don't care if its a pre or post render. Thought pre-render will probably by better?
<script type="text/javascript">
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function() {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
//OnPreRender: function(ctx) {
OnPostRender: function(ctx) {
var rows = ctx.ListData.Row;
for (var i=0;i<rows.length;i++)
{
// get today's date
var today = new Date();
// get the Start Date and Time
var startDateTime = rows[i]["StartDateTime"]; //static name "StartDateTime" Format: 31/03/2018 7:00 AM
var startDateTimeParts = startDateTime.split(" ");
var startDate = (startDateTimeParts[0]); // date
var startTime = (startDateTimeParts[1]); // time
// Split startDate
var startDateParts = startDate.split("/");
var startDateYear = (startDateParts[2]); // Year
var startDateMonth = (startDateParts[1]); // Month
var startDateDay = (startDateParts[0]); // Day
// Split startTime
var startTimeParts = startTime.split(":");
var startTimeHour = (startTimeParts[0]); // Hour
var startTimeMinutes = (startTimeParts[1]); // Minute
var startTimeSeconds = (startTimeParts[2]); // Seconds
var startDateTimeValue = new Date(startDateYear,startDateMonth-1,startDateDay,startTimeHour,startTimeMinutes,0,0);
// get the End Date and Time
var endDateTime = rows[i]["EndDateTime"]; //static name "EndDateTime" Format: 31/03/2018 7:00 AM
var endDateTimeParts = endDateTime.split(" ");
var endDate = (endDateTimeParts[0]); // date
var endTime = (endDateTimeParts[1]); // time
// Split endDate
var endDateParts = endDate.split("/");
var endDateYear = (endDateParts[2]); // Year
var endDateMonth = (endDateParts[1]); // Month
var endDateDay = (endDateParts[0]); // Day
// Split endTime
var endTimeParts = endTime.split(":");
var endTimeHour = (endTimeParts[0]); // Hour
var endTimeMinutes = (endTimeParts[1]); // Minute
var endTimeSeconds = (endTimeParts[2]); // Seconds
var endDateTimeValue = new Date(endDateYear,endDateMonth-1,endDateDay,endTimeHour,endTimeMinutes,0,0);
var rowId = GenerateIIDForListItem(ctx, rows[i]);
var row = document.getElementById(rowId);
//alert("new start d/t: " + startDateTimeValue);
//alert("new end d/t: " + endDateTimeValue);
if (startDateTimeValue <= today && endDateTimeValue >= today) {
row.style.backgroundColor = '#01DF3A'; //green
//alert("startDateTimeValue: " + startDateTimeValue + " <= today: " + today + " && endDateTimeValue: " + endDateTimeValue);
} else {
row.style.backgroundColor = '#ff4d4d'; //red
//alert("NOT = startDateTimeValue: " + startDateTimeValue + " <= today: " + today + " && endDateTimeValue: " + endDateTimeValue);
}
}
}
});
});
</script>
Regards Michael
Solution
First of all, you definitely don't want pre-render because there are no DOM elements there to hide yet.
I believe you should be able to set the row's display
style setting to "none" right in the code that you have.
Something like this:
SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function (ctx) {
var rows = ctx.ListData.Row;
for (var i = 0; i < rows.length; i++) {
var today = new Date();
// can you not just create the DateTime objects directly from
// the field values? i am certain i have done this before,
// i don't think you need to do all the string splitting
var startDateTimeValue = new Date(rows[i]["StartDateTime"]);
var endDateTimeValue = new Date(rows[i]["EndDateTime"]);
var rowId = GenerateIIDForListItem(ctx, rows[i]);
var row = document.getElementById(rowId);
if (startDateTimeValue <= today && endDateTimeValue >= today) {
row.style.backgroundColor = '#01DF3A'; //green
} else {
row.style.display = 'none'; // hidden
}
}
}
});
});