0

Note: I am pretty new to SharePoint, so be gentle.

We are using SharePoint online, and I have complete control of the site. One of my users would like to have the row change color when a column (calculated as a reminder date) is equal or more than the current date. Basically to let her know when an item needs attention.

I have found java script that alters the color, but no way for the list to see today's date.

I have thought of using a workflow, but can't figure out how to make it change a row's back-ground color.

Moving it to an Excel spreadsheet won't work, because it is a list of folders going elsewhere. (URL's are too big for Excel.)

Thanks, Robin

  • You should be able to do this using Conditional Formatting in SharePoint Designer. – Ramana Viswanadha Apr 21 '16 at 18:52
  • Conditional Formatting doesn't exist in SharePoint Designer 2013. – Robin Huighe Apr 21 '16 at 20:55
  • Robin, I did not know that. In that case you can use Javascript with a Script editor. sharepoint247.com/office-365/… – Ramana Viswanadha Apr 21 '16 at 21:00
10

You definitely don't want to use a workflow for this. Workflows are good for certain things, but the background color for a list item is not actually stored on the list item, so there is no way a workflow will be able to access or modify it.

To me, it sounds like a job for Client Side Rendering (CSR), which would use JavaScript to check the value of the field, check it against today's date, and set the color of the row accordingly.

You said you have JavaScript to change the color. The way you get the script to see today's date is by doing this:

var rightNow = new Date(); // rightNow has the date and time value of the moment it was created

Here is a good resource for learning about CSR:

http://www.codeproject.com/Articles/620110/SharePoint-Client-Side-Rendering-List-Views

This was adapted from another answer on this site:

function colorCodeRows() {

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
        OnPostRender: function (ctx) {

            // get today's date
            var today = new Date();
            // zero out the time portion so we will only compare days
            today.setHours(0,0,0,0);

            var rows = ctx.ListData.Row;
            for (var i = 0; i < rows.length; i++) {

                // get the date set in your date YourDateField
                var itemDate = new Date(rows[i]['YourDateField']);
                // zero out the time portion so we only compare days
                itemDate.setHours(0,0,0,0);

                var rowId = GenerateIIDForListItem(ctx, rows[i]);
                var row = document.getElementById(rowId);

                if (itemDate >= today) {
                    row.style.backgroundColor = '#ED9898';
                }
            }
        }
    });
}
RegisterModuleInit(SPClientTemplates.Utility.ReplaceUrlTokens('~site/SiteAssets/Scripts/example.js'), colorCodeRows);
colorCodeRows();

How to set it up:

Copy all that code into a .js file and put it somewhere on your site. Before uploading it, change the URL in the second to last line to reflect the URL of where you plan to put the file. (I tend to put scripts in a folder called "Scripts" in my Site Assets library, but wherever you put it is fine as long as everyone has read access to it, so their browsers can download the file.)

Then go to the list in question, and from the gear menu in the upper right, choose "Edit Page". Once the page is in edit mode, edit the List View Web Part. In the Editor Pane, expand the "Miscellaneous" section at the bottom. At the bottom of the "Miscellaneous" section should be the JSLink box. Put the same URL to the file in the JSLink box. (Keep in mind you need to use URL tokens in JSLink, so it will be something like ~site/LibraryName/Folder/filename.js, not a server relative URL like /sites/MySite/LibraryName/filename.js.)

Hit OK, and stop editing the page. You should now see color coded rows.

A few other things to keep in mind:

When you add the script via the list view web part's JSLink property, you are really adding the script to the currently selected view. That means that if you want the script to be active on other views, you need to select the other views and repeat the process of setting the JSLink property with the URL of your script.

In your question, you say you want to color code the row when "a column...is equal or more than the current date", so that's what I put in the script example. But keep in mind that

if (itemDate >= today)

will color code items with today's date or dates in the future. In order to color code things with today's date or dates in the past, use

if (itemDate <= today)

In the line

var itemDate = new Date(rows[i]['YourDateField']);

'YourDateField' is the internal name of the field. This is important, it won't work if you use the display name.

  • Take a look at iCSR and especially the (new) LinkManager Bookmarklet I wrote.. saves you heaps of time applying JSLinks on webparts. BTW.. SharePoint has a GetDaysAfterToday global function which does all the date calc work for you. – Danny '365CSI' Engelman Apr 21 '16 at 20:10
  • why do you do this on post-render? you could as well do this with a field overwrite in viewform ? – Gwny Apr 22 '16 at 7:55
  • @Gwny well, you are probably right, and actually my first inclination was to do it with an Item override, since the OP is asking to color the entire row, and I usually think of Field overrides to only change that particular cell. But then I did a quick search and found the other answer I linked to. It's short and simple, and I could see how it would work in this case, so I just made a couple minor modifications to it. But you are right, there are other ways to get it done. – Dylan Cristy Apr 22 '16 at 12:55
  • Thanks Dylan. This worked on my test site. I only added one line in addition to the instructed changes. I created a variable that pulled the internal name from the field name after reading about that odd SharePoint quirk. – Robin Huighe Apr 22 '16 at 16:25
2

Just finished v2.1 of a CSR support library last week.

http://iCSR.github.io

It now has a whole slidedeck with Why,What, How

With the icsr.js library loaded (no jQuery or any dependencies) all you need to write in a CSR file is:

iCSR.Me({
  file:'~sitecollection/style library/csr_remindercolor.js',
  Fields: {
    ReminderDate:{// internal fieldname!
      View:iCSR.DueDate({
         colors:['inherit','lightcoral'],
         ranges:[0]
      })
    }
  }
});

The colors and ranges arrays are developed to handle more ranges (negative numbers are days past) But this makes your before and after Today work.

Update 1

Mark Dylans answer as the correct one, this is just a shorter version:

SP.SOD.executeFunc("clienttemplates.js", "SPClientTemplates", function () {
    function init() {
        SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
            OnPostRender: function (ctx) {
                ctx.ListData.Row.forEach(function (row) {
                    var rowId = GenerateIIDForListItem(ctx, row);
                    // native SP function for day calcs: (negative is past days)
                    if (GetDaysAfterToday(new Date(row.DueDate)) >= 0) { 
                        document.getElementById(rowId).style.backgroundColor = '#ED9898';
                    }
                });
            }
        });
    }
    RegisterModuleInit(SPClientRenderer.ReplaceUrlTokens("~siteCollection/Style Library/colordays.js"), init);
    init();
});
  • Thank you Danny. I can't wait to play with this. Unfortunately I need to go with Dylan's solution, because I am new with JavaScript (> 1 month) and I work with with some very sensitive information. So far it looks like a really useful tool. – Robin Huighe Apr 22 '16 at 16:27
0

Great answer by Dylan Cristy.

One thing to note. Please check your date format as the JavaScript Date function has following format.

Date(year, month, day, hours, minutes, seconds, milliseconds);

I had to use a function to format the date as my SharePoint list date value was in dd/mm/yyyy format.

function toDate(dateStr) {
  var parts = dateStr.split("/")
  return new Date(parts[2], parts[1]-1, parts[0])
}

and colorcode function changed as follows:

var itemVal = rows[i]['End_Date'];
var itemDate = toDate(itemVal);

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.