Izzy
Izzy

Reputation: 6866

Display table rows based on condition

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

Upvotes: 1

Views: 3540

Answers (2)

user3559349
user3559349

Reputation:

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;
}

Upvotes: 1

Slava Utesinov
Slava Utesinov

Reputation: 13488

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.

Upvotes: 0

Related Questions