1

I've tried my best not to ask for help, but I'm stuck, even after I learned a bit of JS, MomentJS and Client Side Rendering on SP.

The code below returns undefined in date column. If you know why, please let me know.

// JavaScript Document
(function () {
var condFieldCtx = {};
// Define template variable  
condFieldCtx.Templates = {};
// Define your required fields and functions to call in each case.
// In our case the field is Progress
// Override Function is PatientProgressViewTemplate
condFieldCtx.Templates.Fields = {
    "Priority": {"View": PriorityFormat},
    "PercentComplete": {"View": PercentCompleteFormat},
    "b05o": {"View": CreateDateFormat}     
};
//conditional formatting for a complete row comes here
condFieldCtx.OnPostRender = [HighlightRowOverride];
// Register the template override with SP2013 
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(condFieldCtx);
})();

function CreateDateFormat(ctx)
{
var date = new Date();
var CreateDate = moment(ctx.CurrentItem.CreateDate).format('DD/MM/YYYY');
var now = moment().format('DD/MM/YYYY');
//Compare and react
if(now > CreateDate)
{
return "<span><font style='background-
color:red;display:block;'>"+ctx.CurrentItem.CreateDate+"</font>";
}
else if(now == CreateDate)
{
return "<span><font style='background-
color:yellow;display:block;'>"+ctx.CurrentItem.CreateDate+"</font></span>";
}
else
{
return ctx.CurrentItem.CreateDate;
}
}

Everything else works fine, as you can see below on the screenshot. It's just the dates I'm struggling with.

Please tell me what am I doing wrong.

enter image description here




Edit1:

OK, thanks to Danny, I finally got it sorted. I hope.

Below is the working code; ctx.CurrentItem.ColumnName reference had to be changed to the internal name b05o, some tweaking here and there..

function CreateDateFormat(ctx)
{
var CreateDate = moment(ctx.CurrentItem.b05o).format('DD/MM/YYYY');
var now = moment(date, "L", 'en-GB', true).format('DD/MM/YYYY');
//Compare and react
if(CreateDate == 'undefined' || !CreateDate)
{
return ctx.CurrentItem.b05o;
}
else if(now > CreateDate)
{
return "<span><font style='color:white;background-color:red;display:block;'>"+ctx.CurrentItem.b05o+"</font>";
}
else if(now == CreateDate)
{
return "<span><font style='background-color:yellow;display:block;'>"+ctx.CurrentItem.b05o+"</font></span>";
}
else if(now < CreateDate)
{
return "<span><font style='color:white;background-color:green;display:block;'>"+ctx.CurrentItem.b05o+"</font></span>";
}
else
{
return ctx.CurrentItem.b05o;
}
}  

...and here's the result and working date formatting.

enter image description here

The only worry I have is the format of the date displayed in debugging:

enter image description here

The date entered in Item 6 is 31/12/2017 and as you can see it's formatted as green on the list, which is correct, but console.log shows it as 12/07/2019. Below, 05/06/2017 and 06/05/2017

console.log(now > CreateDate);

is displayed as true in debugger. Possibly not a big deal, but I'm worried that something is still nor right and it might cause issues in future.

Last problem I have is when I Stop editing the list I get the following error:

enter image description here

Not sure what to do with this :]

Edit2:

Danny showed me great and simple way for authoring the views live, but date 31/12/2017 still seems to be causing issues. It returns invalid date, probably because 12/31/2017 is invalid.

enter image description here

Edit3:

I had to fiddle with dates a bit to get it working, and here's what I did:

  "b05o": {
 View: function (ctx) {
 var valueU = ctx.CurrentItem[this.Name].split("/");
 var valueY = valueU[1] + "/" + valueU[0] + "/" +valueU[2];
 var valueM = moment(valueY).format('DD/MM/YYYY');
 var valueT = new Date(valueY);
 var daysDiff = GetDaysAfterToday(valueT);
 var color = '#ff6600';            // today dark orange
 if (daysDiff > 0) color = 'green';    // future green
 if (daysDiff < 0) color = 'red';  // past red
 if (daysDiff > 0 && daysDiff < 30) color = '#ffad33'; //next 30 days turns orange
 return String.format('<span style=background:{0};color:white>{1:d}</span>',color,ctx.CurrentItem[this.Name]);
}

And this is what I get:

enter image description here

  • use console.log(ctx.CurrentItem) and you will spot your error – Danny '365CSI' Engelman May 6 '17 at 16:52
  • Thanks Danny for guiding me in the right direction. All is working now, but, two things: 1. debugging shows me some weird things and 2. When I stop editing the list I get TypeError. I'd appreciate if you could guide me in the correct direction on this one :) I added new info to the main post. – Maciek May 6 '17 at 20:13
  • Your second moment function has a date variable; but where does that come from? The error could come from other SP code, check line numbers and filenames – Danny '365CSI' Engelman May 7 '17 at 9:56
  • The missing Date variable was deleted by mistake when editing post. (It's there now). There problem with date 31/12/2017 still exists though :( – Maciek May 7 '17 at 19:44
  • What code do you log to display those incorrect dates? Must be a formatting or dateoffset issue – Danny '365CSI' Engelman May 7 '17 at 19:55
1

Good, you found the issue with the internal name yourself, that is always the best way to make learning stick.

Some tips

  • avoid creating new List Fields with that "easy" SharePoint UI, that's how you get those stupid weird internal names.
    Instead create new Fields in the List settings, where you specify the Internal name first (without spaces!), then rename the column to give its DisplayName (the first name will stick as Internal Name)

  • Always use Chrome and the Cisar WYSIWYG CSR editor when editing CSR files

  • Don't hardcode fieldnames, the fieldname the function was called on is in the this JavaScript Scope as this.Name

  • No need for the MomentJS library
    If you only do simple date calculations, SharePoint provides a GetDaysAfterToday() function

  • Try to write as less repeating code as possible, keeps your code readable and easy maintainable
    The only string different in your long 3 SPAN lines is the color

  • SharePoints' String.format() method is very helpful to include parameters in Strings
    And can format Dates to anything you want: Changing date format using javascript

  • The <font> tag is no longer supported in HTML5, you set the style on the parent element


You code becomes something like:

"b05o": {
    View: function (ctx) {
     var value = new Date(ctx.CurrentItem[this.Name]);
     var daysDiff = GetDaysAfterToday(value);
     var color = 'yellow';            // today
     if (daysDiff > 0) color = 'red';    // future
     if (daysDiff < 0) color = 'green';  // past
     return String.format('<span style=background:{0};color:white>{1:d}</span>',color,value);
    }

notes

  • style has no double-quotes
    because DOM element attributes (without spaces) will be quoted (with ") by the browser
    so you don't have to specify them in your code (unless they have spaces)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.