1

I'm developing an web app using C# and MVC. One of the page has multiple <tr> which will contain information but this information gets updated over time (1 month to 6 month) range. So I only want to show the <tr> which include the information. The information is stored in a database, each <tr> has it's own column. The approach I've gone with is I read the data and apply if conditions in the view.

So something like

@if (!string.IsNullOrEmpty(Model.SomePropertyOne))
{
   <tr>
     <td>@Html.DisplayNameFor(model => model.SomePropertyOne)</td>
     <td>@Html.DisplayFor(model => model.SomePropertyOne)</td>
   </tr>
}
@if (!string.IsNullOrEmpty(Model.SomePropertyTwo))
{
   <tr>
    <td>@Html.DisplayNameFor(model => model.SomePropertyTwo)</td>
    <td>@Html.DisplayFor(model => model.SomePropertyTwo)</td>
   </tr>
}
...

I have to this 8 times. So my question is, is there a better approach than this or am I stuck with using all these if statements?

Please let me know if you require any further information

Izzy
  • 6,740
  • 7
  • 40
  • 84
  • In your example, are the two rows supposed to relate to different properties? Because they both reference `model.SomeProperty` – stuartd Jun 15 '16 at 09:42
  • @stuartd Yes, they both relate to different properties – Izzy Jun 15 '16 at 09:43
  • Possible duplicate of http://stackoverflow.com/questions/16814119/how-do-i-conditionally-show-a-field-in-asp-net-mvc-razor – diiN__________ Jun 15 '16 at 09:44
  • 1
    Create a `DisplayTemplate` (for `@model string`) and put the condition in it - then in the VIew use `@Html.DisplayFor(m => m.SomeProperty, "yourTemplate")` for each property. And note that tables are for tabular data, not layout –  Jun 15 '16 at 09:48
  • @StephenMuecke I've never used `DisplayTemplates` before. Is it like partial view? – Izzy Jun 15 '16 at 09:52
  • Create a partial view in `/Views/Shared/DisplayTemplates/` –  Jun 15 '16 at 09:54
  • @StephenMuecke I've gone ahead and created a partial view like you suggest but my if statements throw an error about the property not being available. Would you mind providing an example please if you don't mind – Izzy Jun 15 '16 at 10:44
  • In the template, the model is `string`, so you replace `Model.SomePropertyOne` with just `Model` (and the helpers become `@Html.DisplayNameFor(m => m)` –  Jun 15 '16 at 10:47
  • @StephenMuecke I've got it working, if the model is `string` then it doesn't work, so I've changed the `DisplayTemplate` to include `@model MyViewModel` and then do `@Html.DisplayNameFor(m => m)` but I don't know if that's correct :/ – Izzy Jun 15 '16 at 10:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/114734/discussion-between-stephen-muecke-and-code). –  Jun 15 '16 at 10:53

2 Answers2

1

You can create a DisplayTemplate containing the condition. In /Views/Shared/DisplayTemplates/ create a partial view (say) MyTemplate.cshtml

@model string
@if (!string.IsNullOrEmpty(Model))
{
    <tr>
        <td>@Html.DisplayNameFor(m => m)</td>
        <td>@Model</td>
    </tr>
}

and then in the view

@Html.DisplayFor(m => m.SomeProperty, "MyTemplate")
@Html.DisplayFor(m => m.AnotherProperty, "MyTemplate")
.... //etc

The DisplayFor() will generate the html based on the template, so if the value of the property is null or string.Empty, then nothing will be generated for that property.

Side note: You should not be using <table> elements for layout (refer Why not use tables for layout in HTML? and Why Tables Are Bad (For Layout*) Compared to Semantic HTML + CSS). Instead, use css to style you layout. For example, change the DisplayTemplate to

<div class="field">
    <div class="field-label">@Html.DisplayNameFor(m => m)</div>
    <div class="field-value">@Model</div>
</div>

and add the following css

.field {
    position: relative;
    margin: 5px 0;
}
.field-label {
    position: absolute;
    width: 240px;
    color: #808080;
}
.field-value {
    margin-left: 250px;
}
Community
  • 1
  • 1
0

You can solve your problem via reflection, something like that:

@foreach(var prop in Model.GetType().GetProperties().Where(x => x.PropertyType == typeof(string)))
{
    var value = prop.GetValue(Model);
    if (value != null)
    {
        <tr>
            <td>@prop.Name</td>
            <td><input value="@value.ToString()" name="@prop.Name" /></td>
        </tr>
    }
}

But, at this case, you should avoid to use @Html helpers, instead - write corresponding html explicitly.

Slava Utesinov
  • 13,410
  • 2
  • 19
  • 26