tags:

views:

150

answers:

4

I have a model being populated by my data layer and then I have a partial view which is rendering an instance of that model.

<li class="<%= td.Active ? "youarehere" : string.Empty %> <%= i == ViewData.Model.Count() - 1 ? "last" : string.Empty %>">

The problem is that class="" is invalid XHTML and I will need more complex logic to output the class attribute. What would be the proper way to go about this using ASP.NET MVC. Should the logic live in the view or the model?

I'm just starting out with MVC and I guess I'm still struggling on where exactly to draw the lines as far as where I put logic and what is an acceptable amount of logic for each layer to contain.

+4  A: 

I'd probably implement the code to render that class attribute in a helper method. Either one specific to this view, or one slightly more generic. That way you have less code in your view and it could handle whether or not to even render the class attribute in the case there's nothing to render.

Haacked
A: 

Alright, so based on Phil's input this is what I have done. It works. Please add a comment if there is any useful feedback that anyone has.

  1. I created a HtmlHelper extension method called GenerateAttribute.

    public static string GenerateAttribute(this HtmlHelper hh,
                                           string name,
                                           Func<string> valueFunc)
    { 
        string value = valueFunc().Trim();
        if (!string.IsNullOrEmpty(value))
            return string.Format("{0}=\"{1}\"", name, value);
        return string.Empty;
    }
    
  2. From my View I call Html.GenerateAttribute, passing it a lambda expression that generates the value. The GenerateAttribute method will then return the full attribute (name="val") if the value is not string.Empty.

    <li <%= Html.GenerateAttribute("class", () => string.Format("{0} {1}", td.Active ? "youarehere" : string.Empty, i == ViewData.Model.Count() - 1 ? "last" : string.Empty)) %>>
    
spoon16
+1  A: 

An additional thing for this code would be to move the calculation work to a either the controller or the code-behind.

i.e. replace

<li <%= Html.GenerateAttribute("class", 
   () => string.Format("{0} {1}", td.Active 
     ? "youarehere" : string.Empty, 
   i == ViewData.Model.Count() - 1 
     ? "last" : string.Empty)) %>>

with something like

<%= Html.ListItem( ViewData.Model.Value, 
       GetItemCssClass(i, ViewData.Model.Count()) ) %>

and GetItemCssClass could be in code-behind.

Greg Ogle
Good answer Oglester, thanks for your time.
spoon16
Oglester, I can't find an Html.ListItem() method. Is that something that is part of MVC or an extension method that you made up?
spoon16
You can make a custom Html helper (extension method) public static string HelperName(this System.Web.Mvc.HtmlHelper helper, params{return string.format("", param)}
Greg Ogle
http://weblogs.asp.net/andrewrea/archive/2008/06/05/a-simple-mvc-preview-3-contact-form-custom-htmlhelper-and-model-example.aspx explains better
Greg Ogle
A: 

Spoon16, excuse me, can you help me? I'm trying to use your solution, but my highlighted-tab is not in a td of a table. How can I to catch the property Active, if the cursor is in over simple anchor?

PS:i'm new with asp.net-mvc

Marco Mangia