Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Partial Views issue

Tags:

I'm very new to MVC and I'm trying to figure out if there is a better way to do this. I have a textbox for the user to put in their search, then based on that search I am displaying some results below said search box. I am trying to avoid having so much code logic in my view and would like to know if there is a better way of handling this. Here is my existing code, where based on what the value of "Model.Results" is it will return one of 3 partial views or a button if the rest of my logic passes:

@section CustomerPrefixInfo
{
    @if (Model.Results == PrefixSearch.SearchResults.CustomerFound)
    {
        @Html.Partial("_CustomerPrefixInfo")
    }
    @if (Model.Results == PrefixSearch.SearchResults.PrefixResultsFound)
    {
        @Html.Partial("_PrefixResults")
    }
    @if (Model.Results == PrefixSearch.SearchResults.AnimalsFound)
    {
        @Html.Partial("_AnimalSearchResults")
    }
    @if (Model.Results == PrefixSearch.SearchResults.ValidNewPrefix)
    {
        using (Html.BeginForm("Index", "PrefixManagement", new { prefix = Model.AnimalPrefix.Prefix, dbPrefix = Model.AnimalPrefix.DbPrefix }))
        {
            <fieldset>
                <input id="btnReservePrefix" type="submit" value="Reserve Prefix" />
            </fieldset>
        }
    }
}

I would like to put this inside a controller so that it just returns the view that is to be displayed, then just display that view on the page. Aftering doing some rearch I thought using Ajax.BeginForm with the InsertionMode set to InsertAfter would do the trick:

@using (Ajax.BeginForm("GenericSearch", "Home", FormMethod.Post, new AjaxOptions { InsertionMode = InsertionMode.InsertAfter, UpdateTargetId = "searchResults" }))
{
    <fieldset>
        <input id="btnPrefixSearch" type="submit" value="Prefix Search/Validate"/>
        @Html.EditorFor(model => model.Input)
    </fieldset>
    <div id="searchResults">

    </div>
}

My GenericSearch Action then uses a switch to decide which partial view to return:

public ActionResult GenericSearch(PrefixSearch prefixSearch)
{
    //some database logic here to get the results
    switch (prefixSearch.Results)
    {
        case PrefixSearch.SearchResults.CustomerFound:
            return PartialView("_CustomerPrefixInfo", prefixSearch);
        case PrefixSearch.SearchResults.PrefixResultsFound:
            return PartialView("_PrefixResults", prefixSearch);
        case PrefixSearch.SearchResults.AnimalsFound:
            return PartialView("_AnimalSearchResults", prefixSearch);
        default:
            return null;
     }
}

But when I tried this it puts the partial view on a new page.

here is one of my partial views (they are all 3 mostly identical to this)

@model MVC_Test_Project.Models.PrefixSearch

@{
    ViewBag.Title = "PrefixResults";
 }

@{
    Layout = null;
 }
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.PrefixResults[0].Prefix)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.PrefixResults[0].CustomerCount)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.PrefixResults[0].Link)
        </th>
    </tr>

@foreach (var item in Model.PrefixResults)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Prefix)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.CustomerCount)
        </td>
        <td>
            <a href="@item.Link">edit</a>               
        </td>
    </tr>
}
 </table>

Any help would be appreciated!

Edit Just a helpful hint in case anybody makes the same stupid mistake I did, make sure your bundles are called before your scripts.

@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/bootstrap")
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.min.js"></script>

I had added in those last 2 lines when it was mentioned to use those, but they were above my bundles....and thus the ajax didn't work because of it. Thanks for everybodies help, all is well now! --Joseph

like image 597
jpaugh78 Avatar asked May 11 '16 19:05

jpaugh78


People also ask

Can we use multiple partial view in MVC?

You can only return one value from a function so you can't return multiple partials from one action method. If you are trying to return two models to one view, create a view model that contains both of the models that you want to send, and make your view's model the new ViewModel. E.g.

What is advantage of partial view in MVC?

The major advantage of partial view is that we can reuse the partial view logic.

How do you call a partial view in another view in MVC?

To create a partial view, right click on the Shared folder -> click Add -> click View.. to open the Add View popup, as shown below. You can create a partial view in any View folder. However, it is recommended to create all your partial views in the Shared folder so that they can be used in multiple views.

How do you know if a view is a partial view in MVC?

Partials often have an underscore prefix in their name. Other than that, nothing really separates them from other views.


1 Answers

I would like to put this inside a controller so that it just returns the view

Seems pretty straight forward:

ViewModel:

public class MyModel
{
  public string PageToRender { get; set; }
}

Controller Action

public ActionResult DoLogic()
{
  //var Results = ?? as The ENum

  switch(Results)
  {
    PrefixSearch.SearchResults.CustomerFound:
      model.PageToRender = "_CustomerPrefixInfo";
    // etc etc
  }    

  return View(model);
}

View:

 @{if (!string.IsNullOrEmpty(model.PageToRender))
   Html.RenderPartial(model.PageToRender);}

Although I would probably decorate the Enum:

public enum SearchResults
{
  [Display(Name="_CustomerPrefixInfo")]
  CustomerFound
}

And then there is no switch statement, you just grab the enum value display attribute's name value.

like image 145
Erik Philips Avatar answered Sep 28 '22 02:09

Erik Philips