johna
johna

Reputation: 10752

Newbie MVC usual practices for hiding and showing content

I am a long time WebForms developer but am finally getting around to learning MVC by converting one of my WebForms sites, which needs updating, to MVC3.

I know the basics of MVC from reading but am struggling in the real world on day one with what are probably simple things, and I would also like to know how best to do them and best practices.

For this answer I’m not looking for code (although a little might help), just enough information to put me on the right path. I have already looked at quite a few examples and tutorials but none seem to show something relevant for my situation, so here I am asking on SO.

So, the first page I am working on is a search results page. It’s a little more complex than a simple search page. It has an area for suggestions if it finds words spelt incorrectly, an area for if no results are found, and an area for the search results themselves, if any.

Because it searches two database tables (views actually) I have a model that contains both table models and a priority field I use for ordering results by most relevant. The model is like this:

public class SearchResult
{
    public Table1 { get; set; }
    public Table2 { get; set; }
    public int Priority { get; set; }
}

In WebForms I use panels to contain each of the areas so I can turn them on and off, something like this:

<asp:Panel ID=”panSuggest” runast=”server” Visible=”false”>
    …
</asp:Panel>
<asp:Panel ID=”panNoResults” runat=”server” Visible=”false”>
    …
</asp:Panel>
<asp:Panel ID=”panResults” runat=”server”>
    <asp:Repeater ID=”repResults” runat=”server”>
        …
    </asp:Repeater>
</asp:Panel>

In my present WebForms code behind logic I look to see if there are any misspelt works and if so display panSuggest and hide all other panels. If there are no errors then I hide show panResults/panNoResults as necessary.

So how is this kind of thing usually done in MVC? Do I set a ViewBag item in my Controller for whether PanSuggest should be shown which I look for in my View and then choose to hide/show based on that, and check if my Model has any items to determine whether panResults/panNoResults should be shown. Something like my code below or is this not the proper way to do it?

@{ if (ViewBag.Suggest == true) {
    <div>
        Suggest
    </div>
} else {
    @{ if (Model.Count == 0) {
        <div>
            No Results
        </div>
 } else {
        <div>
            @foreach (var result in Model) {
                @result.Table1.Whatever etc etc
            }
        </div>
 }
}

Update.

I have been reading more and a there is a lot of advice to avoid ViewBag.

So instead should I change my model to include the extra data I need? Something like this

Public class ViewModel
{
    public string Suggest { get; set; }
    public List<SearchResult> Result { get; set; }
}

public class SearchResult 
{ 
    public Table1 { get; set; } 
    public Table2 { get; set; } 
    public int Priority { get; set; } 
} 

Then in my view I can check if ViewModel.Suggest is not empty, and check ViewModel.Result to see if any items (search results) exists.

Is this a better solution?

Upvotes: 2

Views: 5683

Answers (2)

Paul Taylor
Paul Taylor

Reputation: 5751

My approach would be essentially the same as yours. My rationale is to put all the business logic into the controller, and to pass a simple indicator to the view in the ViewBag that indicates any options for displaying the data. Typically that would be a simple boolean value such as your ViewBag.Suggest value.

Upvotes: 0

iBoonZ
iBoonZ

Reputation: 1035

If I have 2 different tables that needs to be shown, I would to the same, the only thing I would change is

@{
    if (ViewBag.Suggest == true) 
    {
        <div>
            Suggest
        </div>
    } else {
        <table>
            <thead>
                <th>Header column</th>
            </thead>
            <tbody>
            @{ if (Model != null && Model.Any()) {
                <tr>
                @foreach (var result in Model) 
                {
                    <td>
                        @result.Table1.Whatever etc etc
                    </td>
                }
                </tr>
            } else {
                <tr>
                    <td>
                        No Results
                    </td>
                </tr>
            }
            </tbody>
        </table>
    }
}

Upvotes: 5

Related Questions