Let the platform do the work

Modifying Calendar Item Colors

Overview

Each calendar event type (Meetings, Calls, and Tasks) has its own distinct color scheme. This article will review how to modify these colors, as well as demonstrate how to set the event color based on the event status.

The color scheme for each calendar activity type is defined in the stock file ./modules/Calendar/CalendarDisplay.php in the $activity_colors array as shown below:

  public $activity_colors = array(
	'Meetings' => array(
		'border' => '#1C5FBD',
		'body' => '#D2E5FC',
	),
	'Calls' => array(
		'border' => '#DE4040',
		'body' => '#FCDCDC',
	),
	'Tasks' => array(
		'border' => '#015900',
		'body' => '#B1F5AE',
	),
);

This file can not be overridden or extended in an upgrade-safe way, but this array can still be overridden later in the rendering process allowing for an upgrade safe customization.

Modifying the Calendar Activity Colors

The CalendarDisplay class passes the $activity_colors array to javascript by way of the ./modules/Calendar/tpls/main.tpl Smarty template.

In this template file, you will see the following code where the CAL.activity_colors object is setup:

  CAL.activity_colors = [];				
{foreach name=colors from=$activity_colors key=module item=v}
	CAL.activity_colors['{$module}'] = [];
	CAL.activity_colors['{$module}']['border'] = '{$v.border}';
	CAL.activity_colors['{$module}']['body'] = '{$v.body}'
{/foreach}

This is where we can update the $activity_colors array in an upgrade safe manner. To do this, copy the template file from./modules/Calendar/tpls/main.tpl to ./custom/modules/Calendar/tpls/main.tpl.

If we wanted to change Meetings to have a purple color scheme, we might choose:

border: #580059
body : #F2AEF5

To implement this, we'll update the activity colors array in the custom template file as follows:

./custom/modules/Calendar/tpls/main.tpl

  CAL.activity_colors = [];				
{foreach name=colors from=$activity_colors key=module item=v}
	CAL.activity_colors['{$module}'] = [];
	CAL.activity_colors['{$module}']['border'] = '{$v.border}';
	CAL.activity_colors['{$module}']['body'] = '{$v.body}'
{/foreach}

{literal}

CAL.activity_colors["Meetings"] = {
	"border": "#580059",
	"body": "#F2AEF5"
};

{/literal}


In the above code, the activity_colors entry for "Meetings" has specifically been altered to set the custom colors just for Meetings, leaving the other activity types as they were. Alternatively, the entire activity_colors array could be updated, replacing the original coming from CalendarDisplay. For example:

./custom/modules/Calendar/tpls/main.tpl

  CAL.activity_colors = [];				
{foreach name=colors from=$activity_colors key=module item=v}
	CAL.activity_colors['{$module}'] = [];
	CAL.activity_colors['{$module}']['border'] = '{$v.border}';
	CAL.activity_colors['{$module}']['body'] = '{$v.body}'
{/foreach}

{literal}

CAL.activity_colors = {
		"Meetings": {
			"border": "#580059",
			"body": "#F2AEF5"
		},
		"Calls": {
			"border": "#DE4040",
			"body": "#FCDCDC"
		},
		"Tasks": {
			"border": "#015900",
			"body": "#B1F5AE"
		}
	};

{/literal}

While Calls and Tasks have not been modified from their original colors, having the entire array defined here may make it easier to make further color customizations later on, since the modified activity_colors will be completely defined in the custom template file.

After making the above changes, run a Quick Repair and Rebuild and reload the Calendar module in your browser to see the changes take effect.

Customizing colors based on event status

If you wanted to go a step further, you might want to customize the colors based on the status of the activity. For example, perhaps for Meetings, the color should reflect if the Meeting status is Scheduled, Held, or Canceled. To achieve this, we will need to customize the javascript that actually renders the activities onto the calendar view, so we will copy ./modules/Calendar/Cal.js to ./custom/modules/Calendar/Cal.js.

Additionally, in order for our custom template to load the custom Cal.js, it will need to be updated to point to the custom Cal.js by changing the line:

  {sugar_getscript file="modules/Calendar/Cal.js"}

to

  {sugar_getscript file="custom/modules/Calendar/Cal.js"}

The activity colors from the CAL.activity_colors object get applied in the Cal.js script at:

  el.style.backgroundColor = CAL.activity_colors[item.module_name]['body'];
el.style.borderColor = CAL.activity_colors[item.module_name]['border'];						

The activity type (Meetings, Calls, Tasks) comes from item.module_name, as shown above. The activity's status can be found in the item.status variable. Using these, we can modify the color-setting logic to apply a status-specific color scheme to the Meeting items in the calendar, for example:

  if (item.module_name =="Meetings") {
    el.style.backgroundColor = CAL.activity_colors[item.module_name][item.status]['body'];
    el.style.borderColor     = CAL.activity_colors[item.module_name][item.status]['border'];
} 
else {
    el.style.backgroundColor = CAL.activity_colors[item.module_name]['body'];
    el.style.borderColor     = CAL.activity_colors[item.module_name]['border'];
}

This assumes that the 'Meetings' part of CAL.activity_colors has status-specific colors set. Therefore we will need to update our custom template file so that this is the case:

./custom/modules/Calendar/tpls/main.tpl

  {literal}

CAL.activity_colors = {
    "Meetings": {
        "Planned": {
            "border": "#FF6666",
            "body": "#FF6666"
        },
        "Held": {
            "border": "#FF9999",
            "body": "#FF9999"
        },
        "Not Held": {
            "border": "#6C8CD5",
            "body": "#6C8CD5"
        }
    },
    "Calls": {
        "border": "#DE4040",
        "body": "#FCDCDC"
    },
    "Tasks": {
        "border": "#015900",
        "body": "#B1F5AE"
    },
    "Planned": {
        "border": "#ff6666",
        "body": "#ff6666"
    },
    "Held": {
        "border": "#FF9999",
        "body": "#FF9999"
    },
    "Not Held": {
        "border": "#6C8CD5",
        "body": "#6C8CD5"
    }
};

{/literal}

After making the above changes, run Rebuild JS Grouping Files followed by a Quick Repair and Rebuild, then reload the Calendar module in your browser to see the changes take effect.