I currently have a scheduling grid with alot of cells that have this CSS update binding depending on a property value of the object. When a subscription of one of these elements changes, then it updates the CSS. Is there a better way to do this in terms of performance or strategy?
HTML
<div class="item" data-bind="draggableCss: { linkedEventId: $data.LinkedEventId, disabled: $data.Disabled(), matchup: $data.Matchup(), invalid: $data.Invalid() && !$root.members.eventSchedule.disableValidation(), caution: $data.Caution() && !$root.members.eventSchedule.disableValidation(), available: $data.Available(), conflict: $data.Conflict() && !$root.members.eventSchedule.disableValidation(), current: $data.Current() }></div>
Binding
ko.bindingHandlers.draggableCss = {
update: function (element, valueAccessor) {
var values = valueAccessor();
var addedClasses = '';
var removedClasses = '';
if (values.linkedEventId) {
addedClasses += " linked-event";
}
if (values.editable) {
addedClasses += " editable-game";
}
if (values.matchup) {
if (values.matchup.Selected()) {
removedClasses += " occupied";
}
if (values.current) {
updateElementColors(element, values.matchup.Color, 'current');
}
else if (values.invalid && !values.linkedEventId) {
updateElementColors(element, values.matchup.Color, 'invalid');
}
else if (values.conflict && !values.linkedEventId) {
updateElementColor(element, values.matchup.Color, false).parent().addClass('conflict');
}
else if (values.caution && !values.linkedEventId) {
updateElementColor(element, values.matchup.Color, false).parent().addClass('caution');
}
else {
updateElementColor(element, values.matchup.Color, false);
}
if (values.matchup.CrossGame) {
addedClasses += " cross-game";
}
if (values.matchup.Status === 0) {
addedClasses += " top-left-triangle";
}
}
else if (values.available && !values.disabled && !values.linkedEventId) {
updateElementColors(element, null, 'available');
}
else if (values.invalid && !values.disabled && !values.linkedEventId) {
updateElementColors(element, null, 'invalid');
}
else if (values.caution && !values.disabled && !values.linkedEventId) {
updateElementColors(element, null, 'caution');
}
else {
removedClasses += " invalid";
removedClasses += " current";
removedClasses += " caution";
removedClasses += " available";
}
$(element).toggleClass('ui-droppable-disabled', values.disabled);
$(element).attr('title', values.disabled ? 'Double click to enable' : '');
$(element).toggleClass('hide-game', (!values.matchup || !values.matchup.Selected()));
$(element).toggleClass('show-game', (values.matchup && values.matchup.Selected()) ? true : false);
$(element).toggleClass('empty', !values.matchup);
if (removedClasses) {
$(element).removeClass(removedClasses);
}
if (addedClasses) {
$(element).addClass(addedClasses);
}
}
};
function updateElementColors(element, borderColor, cssClass) {
$(element)
.removeClass('invalid')
.removeClass('conflict')
.removeClass('current')
.removeClass('available')
.addClass(cssClass);
if (borderColor) {
$(element).css('border-color', 'rgba(' + borderColor.Red + ',' + borderColor.Green + ',' + borderColor.Blue + ',' + borderColor.Alpha + ")");
}
}
function updateElementColor(element, color, updateBorder) {
var $element = $(element);
$element
.removeClass('invalid')
.removeClass('available')
.removeClass('current')
.parent().removeClass('conflict');
if (color) {
$element
.css('border-color', '')
.css('background-color', 'rgba(' + color.Red + ',' + color.Green + ',' + color.Blue + ',' + color.Alpha + ')');
if (updateBorder) {
$element.css('border-color', 'rgba(' + color.Red + ',' + color.Green + ',' + color.Blue + ',' + color.Alpha + ')');
}
}
return $element;
}