Home > Software engineering >  Replace text field with a dropdown menu in ASP.NET Core MVC Application
Replace text field with a dropdown menu in ASP.NET Core MVC Application

Time:07-18

I am working through the "Get Started with ASP.NET Core MVC" tutorial at the link below:

Create New page

...the "Rating" field is a text field where the user can enter a string of length five. I'd like to change that to a dropdown menu with the following options to choose from: G, PG, PG-13, R.

How would I go about doing this?

I believe the C# code for the dropdown would look something like this:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
     
public IActionResult Index()
{
     List<SelectRating> rating = new()
     {
                new SelectRating { Value = "1", Text = "G" },
                new SelectRating { Value = "2", Text = "PG" },
                new SelectRating { Value = "3", Text = "PG-13" },
                new SelectRating { Value = "4", Text = "R" }
            };

            ViewRating.ratings = ratings;
            return View();
}

But I'm not sure where this code would go, and I'm not sure what View file I should edit. Would it be Index.cshtml in the directory /Views/Movies?

/Views/Movies/Index.cshtml

@model MovieDBApp.Models.MovieGenreViewModel

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>

<form asp-controller="Movies" asp-action="Index" method = "get">
    <p>
        <select asp-for="MovieGenre" asp-items="Model.Genres"> 
            <option value="">All</option> 
        </select> 

        Title: <input type="text" name="SearchString">
        <input type="submit" value="Filter" />
    </p>
</form>

<table >
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Title)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].ReleaseDate)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Genre)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Rating)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Movies[0].Runtime)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.Movies) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ReleaseDate)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Genre)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Rating)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Runtime)
            </td>
            <td>
                <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
            </td>
        </tr>
}
    </tbody>
</table>

CodePudding user response:

You should not put it on the Index page, because the Index is to display the data. You should change the Rating field to dropdown menu on the Creat page and Edit page.

Below is my test code,you can refer to it:

Controller:

public class MoviesController : Controller
{
     List<SelectListItem> rating = new()
     {
          new SelectListItem { Value = "G", Text = "G" },
          new SelectListItem { Value = "PG", Text = "PG" },
          new SelectListItem { Value = "PG-13", Text = "PG-13" },
          new SelectListItem { Value = "R", Text = "R" }
     };
     public IActionResult Create()
     {
          ViewBag.ratings = rating;
          return View();
     }
     [HttpPost]
     [ValidateAntiForgeryToken]
     public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
     {
          if (ModelState.IsValid)
          {
                _context.Add(movie);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
          }
          return View(movie);
     }
     public async Task<IActionResult> Edit(int? id)
     {
          ViewBag.ratings = rating;
          if (id == null || _context.Movie == null)
          {
              return NotFound();
          }

          var movie = await _context.Movie.FindAsync(id);
          if (movie == null)
          {
              return NotFound();
          }
          return View(movie);
     }
     [HttpPost]
     [ValidateAntiForgeryToken]
     public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
     {
          if (id != movie.Id)
          {
              return NotFound();
          }
          if (ModelState.IsValid)
          {
              try
              {
                  _context.Update(movie);
                  await _context.SaveChangesAsync();
              }
              catch (DbUpdateConcurrencyException)
              {
                  if (!MovieExists(movie.Id))
                  {
                      return NotFound();
                  }
                  else
                  {
                      throw;
                  }
              }
              return RedirectToAction(nameof(Index));
          }
          return View(movie);
     }
}

Creat.cshtml:

@model _2022071801.Models.Movie

@{
    ViewData["Title"] = "Create";
}

<h1>Create</h1>

<h4>Movie</h4>
<hr />
<div >
    <div >
        <form asp-action="Create">
            <div asp-validation-summary="ModelOnly" ></div>
            <div >
                <label asp-for="Title" ></label>
                <input asp-for="Title"  />
                <span asp-validation-for="Title" ></span>
            </div>
            <div >
                <label asp-for="ReleaseDate" ></label>
                <input asp-for="ReleaseDate"  />
                <span asp-validation-for="ReleaseDate" ></span>
            </div>
            <div >
                <label asp-for="Genre" ></label>
                <input asp-for="Genre"  />
                <span asp-validation-for="Genre" ></span>
            </div>
            <div >
                <label asp-for="Price" ></label>
                <input asp-for="Price"  />
                <span asp-validation-for="Price" ></span>
            </div>
            <div >
                <label asp-for="Rating" ></label>
                <select asp-for="Rating" asp-items="@(new SelectList(ViewBag.ratings,"Value","Text"))" >
                    <option>Please select one</option>
                </select>
                <span asp-validation-for="Rating" ></span>
            </div>
            <div >
                <input type="submit" value="Create"  />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Edit.cshtml:

@model _2022071801.Models.Movie

@{
    ViewData["Title"] = "Edit";
}

<h1>Edit</h1>

<h4>Movie</h4>
<hr />
<div >
    <div >
        <form asp-action="Edit">
            <div asp-validation-summary="ModelOnly" ></div>
            <input type="hidden" asp-for="Id" />
            <div >
                <label asp-for="Title" ></label>
                <input asp-for="Title"  />
                <span asp-validation-for="Title" ></span>
            </div>
            <div >
                <label asp-for="ReleaseDate" ></label>
                <input asp-for="ReleaseDate"  />
                <span asp-validation-for="ReleaseDate" ></span>
            </div>
            <div >
                <label asp-for="Genre" ></label>
                <input asp-for="Genre"  />
                <span asp-validation-for="Genre" ></span>
            </div>
            <div >
                <label asp-for="Price" ></label>
                <input asp-for="Price"  />
                <span asp-validation-for="Price" ></span>
            </div>
            <div >
                <label asp-for="Rating" ></label>
                <select asp-for="Rating" asp-items="@(new SelectList(ViewBag.ratings,"Value","Text"))" >
                    <option>Please select one</option>
                </select>
                <span asp-validation-for="Rating" ></span>
            </div>
            <div >
                <input type="submit" value="Save"  />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

Model:

public class Movie
{
     public int Id { get; set; }
     public string? Title { get; set; }

     [Display(Name = "Release Date")]
     [DataType(DataType.Date)]
     public DateTime ReleaseDate { get; set; }
     public string? Genre { get; set; }
     [Column(TypeName = "decimal(18, 2)")]
     public decimal Price { get; set; }
     public string? Rating { get; set; }      
}

Test Result: enter image description here enter image description here

  • Related