Reputation: 183
I'm new to ASP.NET Core and learning. I've been trying for few days now trying to implement a simple form in ASP.NET Core 8 with multi-select drop-down list.
I'm not sure why implementing multi-select drop-down list is so difficult in asp.net core. I want to use X.PagedList
on the Index
page. This form will have nothing but two fields - Firstname a text field and a multi select drop-down list that contains three options - A, B and C. I need to be able to do CRUD options including Index page that will list all the forms entries stored in a database.
Can someone provide a simple but complete example or point me to an existing solution that I can download?
Upvotes: 0
Views: 430
Reputation: 378
I provide you with a list with multi-select and string searches, as well as pagination functionality, I hope it will help you
Here's an example:
1). Create a class to support paging.
using Microsoft.EntityFrameworkCore;
namespace Case1
{
public class PaginatedList<T> : List<T>
{
public int PageIndex { get; private set; }
public int TotalPages { get; private set; }
public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
{
PageIndex = pageIndex;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);
this.AddRange(items);
}
public bool HasPreviousPage => PageIndex > 1;
public bool HasNextPage => PageIndex < TotalPages;
public static async Task<PaginatedList<T>> CreateAsync(
IQueryable<T> source, int pageIndex, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip(
(pageIndex - 1) * pageSize)
.Take(pageSize).ToListAsync();
return new PaginatedList<T>(items, count, pageIndex, pageSize);
}
}
}
2).Add PageSize to the appsettings.json Configuration file
3). Add a data model then use the scaffolding tool produces pages for Create, Read, Update, and Delete (CRUD) operations for the movie model.
if your project is razor Pages,you can do it like this : https://learn.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/?view=aspnetcore-8.0
if your project is MVC,you can do it like this : https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc?view=aspnetcore-8.0&tabs=visual-studio
4).Modify Index.cshtml
@page
@model Case1.Pages.Movies.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<form method="post">
<div class="form-actions no-color">
<p>
Municipality:
<select name="Municipality" multiple style="width:200px;" >
<option>4</option>
<option>3</option>
<option>2</option>
</select>
<span style="margin-left:30px;">ActiveVote:</span> <input name="ActiveVote" />
<input type="submit" value="Search" class="btn btn-primary" />
</p>
</div>
</form>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Movies[0].VoteId)
</th>
<th>
@Html.DisplayNameFor(model => model.Movies[0].Municipality)
</th>
<th>
@Html.DisplayNameFor(model => model.Movies[0].ActiveVote)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Movies) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.VoteId)
</td>
<td>
@Html.DisplayFor(modelItem => item.Municipality)
</td>
<td>
@Html.DisplayFor(modelItem => item.ActiveVote)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Id">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
@{
var prevDisabled = !Model.Movies.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.Movies.HasNextPage ? "disabled" : "";
}
<a asp-page="./Index"
asp-route-pageIndex="@(Model.Movies.PageIndex - 1)"
class="btn btn-primary @prevDisabled">
Previous
</a>
<a asp-page="./Index"
asp-route-pageIndex="@(Model.Movies.PageIndex + 1)"
class="btn btn-primary @nextDisabled">
Next
</a>
5). Modify Index.cshtml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Case1.Data;
using Case1.Models;
using Microsoft.Extensions.Configuration;
using System.ComponentModel;
namespace Case1.Pages.Movies
{
public class IndexModel : PageModel
{
private readonly Case1.Data.Case1Context _context;
private readonly IConfiguration Configuration;
public IndexModel(Case1.Data.Case1Context context, IConfiguration configuration)
{
_context = context;
Configuration = configuration;
}
public PaginatedList<Models.Movies> Movies { get;set; } = default!;
public async Task OnPostAsync(List<string> Municipality, string ActiveVote ,int? pageIndex)
{
var pageSize = Configuration.GetValue("PageSize", 4);
IQueryable<Models.Movies> MoviesIQ = from s in _context.Votes
select s ;
if (Municipality.Count != 0 ) {
var _Municipality = Municipality.ToArray();
MoviesIQ = MoviesIQ.Where(s => _Municipality.Contains(s.Municipality));
}
if (!string.IsNullOrEmpty(ActiveVote))
{
MoviesIQ = MoviesIQ.Where(s => s.ActiveVote.Contains(ActiveVote));
}
Movies = await PaginatedList<Models.Movies>.CreateAsync(
MoviesIQ.AsNoTracking(), pageIndex ?? 1, pageSize);
}
}
}
The result is as follows:
Upvotes: 0
Reputation: 1326
Dunno what X.PagedList
is, but here’s a working <select multiple>
:
@*MultiSelect.cshtml*@
@page
@model MultiSelectModel
<main>
<form action="" method="post">
<select name="ingredients" multiple>
<option>Gin</option>
<option>Campari</option>
<option>Sweet Vermouth</option>
</select>
<button type="submit">Submit</button>
</form>
</main>
//MultiSelect.cshtml.cs
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
[IgnoreAntiforgeryToken]
public class MultiSelectModel : PageModel
{
public void OnPost(List<string> ingredients)
{
foreach (var ingredient in ingredients)
Console.WriteLine(ingredient);
}
}
Obviously this is the simplest form without dynamic options or model binding, but the important bit is clear: ASP.Net puts the chosen values into a List
. Although you may also use an array or HashSet
(will automatically deduplicate) or probably any ICollection
, I guess.
Upvotes: 0