Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: How do other people apply conditional CSS classes?

Say I have two CSS styles called january and tuesday. I want to apply them to some text fields in my view depending on whether or not it's January, and Tuesday.

Option A: Do the logic in the controller, and put the styles in the ViewData.

In the controller:

if( month == Month.January) 
  ViewBag.UserNameCssStyles = "january";
if( today == Day.Tuesday )
  ViewBag.UserNameCssStyles += " tuesday";

And in the view:

@Html.TextBoxFor(model => model.UserName, new { @class = ViewBag.UserNameCssStyles }

Option B: Do the logic in the controller and assign the styles in the view?

In the controller:

ViewBag.IsJanuary = (month == Month.January);
ViewBag.IsTuesday = (today == Day.Tuesday);

And in the view:

@if (ViewBag.IsJanuary && !ViewBag.IsTuesday) 
{
  @Html.TextBoxFor(model => model.UserName, new { @class = "january" })
}
else if (!ViewBag.IsJanuary && ViewBag.IsTuesday)
{
  @Html.TextBoxFor(model => model.UserName, new { @class = "tuesday" })
}
else if(ViewBag.IsJanuary && ViewBag.IsTuesday)
{
  @Html.TextBoxFor(model => model.UserName, new { @class = "january tuesday" })
}
else
{
  @Html.TextBoxFor(model => model.UserName)
}

Neither way seems right to me. The first option has the controller concerning itself with display, and also kind of locks up the styles so someone working on the view can't change them and, say, add a third class. But the second option seems pretty logic-heavy for being just the "dumb" view.

How do other people normally do this?

like image 388
Sean Avatar asked Sep 13 '11 18:09

Sean


3 Answers

Option C: Do the logic in the controller and assign the styles in the view but in a simpler way:

In the controller:

ViewBag.IsJanuary = (month == Month.January);
ViewBag.IsTuesday = (today == Day.Tuesday);

In the view:

@string userNameClass = string.Empty;
@userNameClass += ViewBag.IsJanuary ? "january " : "";
@userNameClass += ViewBag.IsTuesday ? "tuesday " : "";

@Html.TextBoxFor(model => model.UserName, new { @class = userNameClass })

otherwise your controller is getting polluted with view concerns. An empty class is mostly harmless unless you're google and every byte counts.

like image 70
Todd Smith Avatar answered Nov 08 '22 05:11

Todd Smith


Option A - definitely.

All the logic should be placed in the controller. It is controller's responsibility to pass all the necessary data to the view through the model.

Instead of multiple if statements (which is a bit of a smell) use switch or create a static dictionaries of <Month, string> and <Day, string> to store the mappings.

like image 2
Jakub Konecki Avatar answered Nov 08 '22 04:11

Jakub Konecki


Have you considered using jQuery to attach the css classes? The controller should imo have no knowledge of the css class names as it breaks the separation of concerns design principle.

What you are trying to do is vary your styling based on a date, easily accomplished with jQuery so long as your are interested in the date on the client browser and not on the server where you are hosting your web site...

e.g. in your sites main .js file enter the following

$(document).ready(function () {
    var today = new Date();
    if (today.getMonth() == 0) $(".dateStyle").addClass("january");
    if (today.getDay() == 2) $(".dateStyle").addClass("tuesday");
});

Then in your view use

@Html.TextBoxFor(model => model.UserName, new { @class = "dateStyle" }

If you really need it to vary based on the date on the server, then if you want to follow this approach you will need to pass the values you have stored in your ViewBag to the javascript via a JSON object.

like image 2
magritte Avatar answered Nov 08 '22 04:11

magritte