0
votes

I'm new on ASP.NET MVC. I just created a classic MVCMovie application. Now, I'd like to add more features, just for study. I done a "SearchByGen" View for searching movies by genre: in the View there are a dropdown list of genres and a DIV placeholder. The content of the placeholder is loaded by jQuery by a PartialView "SearchByGenGetResult" and all works fine.

The questions are:

  1. It's the architecture correct?

  2. How can I map the values of the PartialView in the URL by calling the View (ex. if I search for "horror" by DropDown selection I'd like to see in the URL something like "SearchByGen/horror", and I'd like to see correctly the result and the DropDown option selected accessing the page by "SearchByGen/horror")

Thank you to all, now the code:

Controller Code:

public ActionResult SearchByGen()
    {
        //get the genres list
        var totalGens = _repository.GetGenrs(); 

        //put into List<SelectListItem> for @Dropdown it
        List<SelectListItem> items = totalGens.Select(genere => new SelectListItem { Text = genere, Value = genere }).ToList();

        //passing to the View
        ViewBag.TotalGen = items;

        return View();
    }

    public ActionResult SearchByGenGetResult(string gen)
    {
        //select movies by gen
        var moviesByGen = _repository.GetByGen(gen);

        //render partial view
        return PartialView(moviesByGen);
    }

View SearchByGen

@model IEnumerable<MvcMovies.Models.Movie>
@{
   ViewBag.Title = "Search By Gen";
 }

<script src="@Url.Content("~/Scripts/jquery-1.7.1.js")" type="text/javascript"></script>

<script src="@Url.Content("~/Scripts/jquery-ui-1.8.20.js")" type="text/javascript"></script>

<link href="@Url.Content( "~/content/themes/base/jquery-ui.css")" rel="Stylesheet" type="text/css" />

<script type="text/javascript">

$(document).ready(
    function () {

        var dropDownSelectedDefault = $("#TotalGen option:selected").text();
        $("#viewPlaceHolder").load("/Movie/SearchByGenGetResult", { gen: dropDownSelectedDefault });

        //$("input#search").click(
        $("#TotalGen").change(
            function () {
                var dropDownSelected = $("#TotalGen option:selected").text();
                $("#viewPlaceHolder").load("/Movie/SearchByGenGetResult", { gen: dropDownSelected });
            }
        );
    }
);    
</script>
<h2>Search By Gen</h2>
<div>
@Html.DisplayName("Genere ")
@Html.DropDownList("TotalGen")
</div>
<div id="viewPlaceHolder"></div>

Partial View SearchByGenGetResult (not shown, classic scaffold-list View)

2

2 Answers

0
votes

You can do this by using a form with FormMethod.Get so that the correct url is generated (and added to the browser history). You only need one method, and you should be using a view model to represent what you want to display in the view

public class MovieVM
{
  public string Genre { get; set; }
  public SelectList GenreList { get; set; }
  public IEnumerable<Movie> Movies { get; set; }
}

public ActionResult Index(string genre)
{
  var genreList = _repository.GetGenrs(); // assume this returns IEnumerable<string>
  genre = genre ?? genreList.First();
  MovieVM model = new MovieVM
  {
    Genre = genre,
    GenreList = new SelectList(genreList),
    Movies = _repository.GetByGen(genre)
  };
  return View(model)
}

@model MovieVM
....
@using (Html.BeginForm("Index", "Movie", FormMethod.Get))
{
  @Html.LabelFor(m => m.Genre)
  @Html.DropDownListFor(m => m.Genre, Model.GenreList)
  <input type="submit" value="Search" />
}
<div id="movies">
  @foreach (var movie in Model.Movies)
  {
     ....
  }
</div>

Alternatively if you want to use ajax (there is probably not a lot of performance benefit because the bulk of the html is in the list of movies) you will need to use History.js or a similar plugin as described in this answer and its associated links

0
votes

Firstly,

Architecture can be change to your project But you can look these title;
  1. What is Antiforgerytoken ? (example here: include antiforgerytoken in ajax post ASP.NET MVC )
  2. What is Bundling ?
  3. You can also look this example (include antiforgerytoken in ajax post ASP.NET MVC)

Second Question Answer ;

public PartialViewResult SearchByGenGetResult(string gen)
{
    //select movies by gen
    var moviesByGen = _repository.GetByGen(gen);

    //render partial view
    return PartialView(moviesByGen);
}

View Script;

var dropDownSelected = $("#TotalGen option:selected").text();
   var url = '@Url.Action("SearchByGenGetResult", "Home")/' + dropDownSelected ;
   $('#viewPlaceHolder').load(url);

Example here : (Render Partial View Using jQuery in ASP.NET MVC)