【问题标题】:How to implement pagination in MVC with bootstrap datepicker?如何使用引导日期选择器在 MVC 中实现分页?
【发布时间】:2020-03-07 13:15:47
【问题描述】:

朋友们,我已经用一个项目 MVC 实现了一个解决方案类型 ASP.NetCore。我有一个视图,我使用https://github.com/cloudscribe/cloudscribe.Web.Pagination 进行分页。 **老实说,我举了这个例子并使用了它。但我不了解此代码示例的详细信息。

我现在遇到的问题是,我必须包含过滤器,例如 datepicker 范围。所以我正在使用引导日期选择器。但分页停止工作。

分页使查询字符串中的以下参数起作用:pageNumber、pageSize 和 query。当我发送过滤日期的请求时,我可以得到控制器中选择的日期,但是分页的参数为空。

这是一个分页工作正常的 url 示例:http://localhost/pager?query=1&pagesize=10&pageNumber=2

这是一个 url,当我在“应用”按钮中发送带有日期范围的请求时,分页在没有“查询”等参数的情况下死亡:http://localhost/pager?startDate=11/04/2019&endDate=11/11/2019

我想我也必须在请求中发送当前的查询字符串,但我不确定,我对这项技术有点陌生。感谢您的帮助。

我的看法→

@using (Html.BeginForm("Details", "Movements", routeValues: new { pageNumber = @Model.UserMovementsResults.PageNumber, pageSize = @Model.UserMovementsResults.PageSize, query = @Model.Query }, FormMethod.Get))
{
    <br />
    <div style="border: 2px solid #dee2e6;padding: 5px;width: 50%;">
        <br />
        <div class="input-daterange input-group" id="datepicker">
            <span style="font-weight:bold">Date</span>&nbsp;From&nbsp;

            @Html.TextBoxFor(model => model.StartDateFilter, "{0:d MMM yyyy}", new
            {
            id = "StartDateFilter",
            @class = "input-sm form-control",
            @readonly = "readonly"
            })

            <span class="input-group-addon">&nbsp;To&nbsp;</span>

            @Html.TextBoxFor(model => model.EndDateFilter, "{0:d MMM yyyy}", new
            {
            id = "EndDateFilter",
            @class = "input-sm form-control",
            @readonly = "readonly"
            })
        </div>
        <br />
        <input type="submit" value="Apply" class="btn btn-primary" name="Apply" />
    </div>

    <br />
    <br />
    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.UserMovementsResults.Data.FirstOrDefault().Date)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.UserMovementsResults.Data.FirstOrDefault().Description)
                </th>
            </tr>
        </thead>

        <tbody>
            @foreach (var item in Model.UserMovementsResults.Data)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Date)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Description)
                    </td>                        
                </tr>
            }
        </tbody>

    </table>
    <div>
        <cs-pager cs-paging-pagesize="@Model.UserMovementsResults.PageSize"
                  cs-paging-pagenumber="@Model.UserMovementsResults.PageNumber"
                  cs-paging-totalitems="@Model.UserMovementsResults.TotalItems"
                  cs-pagenumber-param="pageNumber"
                  cs-show-first-last="true"
                  cs-suppress-empty-nextprev="true"
                  cs-remove-nextprev-links="false"
                  cs-suppress-inactive-firstlast="true"
                  cs-first-page-text="First"
                  cs-last-page-text="Last"
                  cs-pager-li-current-class="active"
                  cs-pager-li-non-active-class="disabled"
                  asp-controller="Movements"
                  asp-route-query="@Model.Query"
                  asp-route-pagesize="@Model.UserMovementsResults.PageSize"
                  asp-route-startDateFilter="@Model.StartDateFilter.GetValueOrDefault()"
                  asp-route-endDateFilter="@Model.EndDateFilter.GetValueOrDefault()"
                  asp-action="Details" cs-preserve-ambient-querystring="true"></cs-pager>
    </div>
}

我的控制器(我已经尝试设置方法 HttpGet 和 HttpPost)→

   [HttpGet]        
   public async Task<IActionResult> Details(int? pageNumber, int? pageSize, int? query, string startDate, string endDate)
    {
        if (query == null)
        {
            return NotFound();
        }

        DateTime startDateFilter = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
        DateTime endDateFilter = DateTime.Now.EndOfWeek(DayOfWeek.Monday);

        var userMovements = await GetUserMovements(user.Id, pageNumber, pageSize, query, startDateFilter, endDateFilter);

        return View(userMovements);
        }
    }

我的视图模型 →

public class UserMovementsViewModel
{
    private DateTime? endDateFilter;

    public UserMovementsViewModel()
    {
        UserMovementsResults = new PagedResult<UserMovementsResult>();
    }

    public string Query { get; set; } = string.Empty;

    [Key]
    public int Id { get; set; }

    public int UserId { get; set; }

    public PagedResult<UserMovementsResult> UserMovementsResults { get; set; } = null;

    public DateTime? StartDateFilter { get; set; }

    public DateTime? EndDateFilter
    {
        get => endDateFilter;
        set
        {
            if (value != null)
            {
                endDateFilter = value;
                endDateFilter = endDateFilter.Value.AddHours(23).AddMinutes(59).AddSeconds(59);
            }                
        }
    }
}
public class UserMovementsResult
{
    public DateTime Date { get; set; }

    public string Description { get; set; }
}

【问题讨论】:

    标签: c# asp.net-mvc asp.net-core pagination asp.net-core-2.2


    【解决方案1】:

    这是一个简单的解决方法,如下所示:

    1.在_ViewImports.cshtml中添加如下组件:

    @using cloudscribe.Web.Pagination
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @addTagHelper "*, cloudscribe.Web.Pagination"
    

    2.型号:

    public class UserMovements
    {
        public string Name { get; set; } = string.Empty;
        public DateTime Date { get; set; } = DateTime.UtcNow;
        public string Description { get; set; } = string.Empty;
    }
    public class ViewByDateViewModel
    {
        public ViewByDateViewModel()
        {
            UserMovements = new PagedResult<UserMovements>();
    
        }
        public PagedResult<UserMovements> UserMovements { get; set; }
        public string[] Date { get; set; }
    }
    

    3.View(ViewByDate.cshtml):

    @using System.Linq
    @model ViewByDateViewModel
    
    <form class="form-inline" role="form" asp-controller="Home" asp-action="ViewByDate" method="get" asp-antiforgery="false">
        <div class="input-daterange input-group" id="datepicker">
            <span style="font-weight:bold">Date</span>&nbsp;From&nbsp;
    
            @Html.TextBox("startDate", null, new
       {
           id = "startDate",
           @class = "input-sm form-control",
       })
    
            <span class="input-group-addon">&nbsp;To&nbsp;</span>
    
            @Html.TextBox("endDate", null, new
       {
           id = "endDate",
           @class = "input-sm form-control",
       })
        </div>
        <input type="submit" value="Browse" class="btn btn-default" />
    
    </form>
    
    @if (Model.UserMovements.Data.Any())
    {
        <table class="table table-striped table-bordered">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Date</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var product in Model.UserMovements.Data)
                {
                    <tr>
                        <td>@product.Name</td>
                        <td>@product.Date</td>
                    </tr>
                }
            </tbody>
        </table>
        <cs-pager cs-paging-pagesize="@Model.UserMovements.PageSize"
                  cs-paging-pagenumber="@Model.UserMovements.PageNumber"
                  cs-paging-totalitems="@Model.UserMovements.TotalItems"
                  cs-pagenumber-param="page"
                  asp-controller="Home"
                  asp-action="ViewByDate"
                  asp-route-categories="@Model.Date.ToCsv()"
                  asp-route-pagesize="@Model.UserMovements.PageSize"
                  cs-first-page-text="First"
                  cs-last-page-text="Last"
                  cs-previous-page-text="Prev"
                  cs-next-page-text="Next"></cs-pager>
    
    
    }
    @section Scripts
    {
        <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script>
            $(document).ready(function () {
                $("#startDate").datepicker({ format: 'dd/mm/yyyy', autoclose: true, todayBtn: 'linked' });
                $("#endDate").datepicker({ format: 'dd/mm/yyyy', autoclose: true, todayBtn: 'linked' })
            });
        </script>
    }
    

    4.控制器:

    public class HomeController : Controller
    {
        private const int DefaultPageSize = 10;
        private List<UserMovements> allMovements = new List<UserMovements>();
    
        public HomeController()
        {
            InitializeMovements();
        }
    
        private void InitializeMovements()
        {
            // Create a list of Movements. 
            for (var i = 0; i < 527; i++)
            {
                var userMovements = new UserMovements();
                userMovements.Name = "UserMovements " + (i + 1);
                var categoryIndex = i % 4;
                if (categoryIndex > 2)
                {
                    categoryIndex = categoryIndex - 3;
                }
                userMovements.Date = DateTime.Now.AddDays(i);
                allMovements.Add(userMovements);
            }
        }    
    
        public IActionResult ViewByDate(string startDate, string endDate, int? page)
        {
    
            string[] dates = { startDate, endDate };
            List<UserMovements> filtered;
            var currentPageNum = page.HasValue ? page.Value : 1;
            var offset = (DefaultPageSize * currentPageNum) - DefaultPageSize;
            var model = new ViewByDateViewModel();
    
            model.Date = dates ?? new string[0];
            int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
            if (startDate == null && endDate == null)
            {
                filtered = this.allMovements.ToList();
            }
            else
            {
                filtered = this.allMovements
                    .Where(p => p.Date.Date >= DateTime.Parse(startDate) && p.Date.Date <= DateTime.Parse(endDate))
                    .ToList();
            }
    
            model.UserMovements.Data = filtered
                .Skip(offset)
                .Take(DefaultPageSize)
                .ToList();
    
            model.UserMovements.PageNumber = currentPageNum;
            model.UserMovements.PageSize = DefaultPageSize;
            model.UserMovements.TotalItems = filtered.Count;
    
            return View(model);
        }
    }
    

    5.结果:

    更新:

    1.型号:

    public class ViewByDateViewModel
    {
        private DateTime? endDateFilter;
        public ViewByDateViewModel()
        {
            UserMovements = new PagedResult<UserMovements>();
    
        }
        public PagedResult<UserMovements> UserMovements { get; set; }
        //public string[] Date { get; set; }
        public DateTime? StartDateFilter { get; set; }
    
        public DateTime? EndDateFilter
        {
            get => endDateFilter;
            set
            {
                if (value != null)
                {
                    endDateFilter = value;
                    endDateFilter = endDateFilter.Value.AddHours(23).AddMinutes(59).AddSeconds(59);
                }
            }
        }
    }
    

    2.查看:

    @using System.Linq
    @model ViewByDateViewModel
    <form class="form-inline" role="form" asp-controller="Home" asp-action="ViewByDate" method="get" asp-antiforgery="false">
            <div class="input-daterange input-group" id="datepicker">
                <span style="font-weight:bold">Date</span>&nbsp;From&nbsp;
    
                @Html.TextBox("startDate", null, new
           {
               id = "startDate",
               @class = "input-sm form-control",
           })
    
                <span class="input-group-addon">&nbsp;To&nbsp;</span>
    
                @Html.TextBox("endDate", null, new
           {
               id = "endDate",
               @class = "input-sm form-control",
           })
            </div>
            <input type="submit" value="Browse" class="btn btn-default" />
    
        </form>
    
        @if (Model.UserMovements.Data.Any())
        {
            <table class="table table-striped table-bordered">
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Date</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var product in Model.UserMovements.Data)
                    {
                        <tr>
                            <td>@product.Name</td>
                            <td>@product.Date</td>
                        </tr>
                    }
                </tbody>
            </table>
            <cs-pager cs-paging-pagesize="@Model.UserMovements.PageSize"
                      cs-paging-pagenumber="@Model.UserMovements.PageNumber"
                      cs-paging-totalitems="@Model.UserMovements.TotalItems"
                      cs-pagenumber-param="page"
                      asp-controller="Home"
                      asp-action="ViewByDate"
    
                      asp-route-pagesize="@Model.UserMovements.PageSize"
                      asp-route-startDateFilter="@Model.StartDateFilter"
                      asp-route-endDateFilter="@Model.EndDateFilter"
                      cs-first-page-text="First"
                      cs-last-page-text="Last"
                      cs-previous-page-text="Prev"
                      cs-next-page-text="Next"></cs-pager>
        }
    
    @section Scripts
        {
        <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        <script>
            $(document).ready(function () {
                $("#startDate").datepicker({ format: 'dd/mm/yyyy', autoclose: true, todayBtn: 'linked' });
                $("#endDate").datepicker({ format: 'dd/mm/yyyy', autoclose: true, todayBtn: 'linked' })
            });
        </script>
    }
    

    3.控制器:

    public IActionResult ViewByDate(string startDate, string endDate, int? page)
    {
    
        string[] dates = { startDate, endDate };
        List<UserMovements> filtered;
        var currentPageNum = page.HasValue ? page.Value : 1;
        var offset = (DefaultPageSize * currentPageNum) - DefaultPageSize;
        var model = new ViewByDateViewModel();
    
        model.StartDateFilter = startDate==null? DateTime.Now:DateTime.Parse(startDate);
        model.EndDateFilter = endDate == null ? DateTime.Now : DateTime.Parse(endDate);
    
        int currentPageIndex = page.HasValue ? page.Value - 1 : 0;
        if (startDate == null && endDate == null)
        {
            filtered = this.allMovements.ToList();
        }
        else
        {
            filtered = this.allMovements
                .Where(p => p.Date.Date >= DateTime.Parse(startDate) && p.Date.Date <= DateTime.Parse(endDate))
                .ToList();
        }
    
        model.UserMovements.Data = filtered
            .Skip(offset)
            .Take(DefaultPageSize)
            .ToList();
    
        model.UserMovements.PageNumber = currentPageNum;
        model.UserMovements.PageSize = DefaultPageSize;
        model.UserMovements.TotalItems = filtered.Count;
    
        return View(model);
    }
    

    如果你想通过 url 发送,url 就像:https://localhost:44367/Home/ViewByDate?startdate=11-14-2019&amp;enddate=11-27-2019

    【讨论】:

    • 您好,非常感谢您的回答。我要试一试,然后告诉你。 =)
    • 嗨,我尝试执行您的示例,但它对我不起作用。我发现我必须在标签 cs-pager 中发送其他查询字符串。像这样 → asp-route-startDateFilter="@Model.StartDateFilter.GetValueOrDefault()"。但现在我得到了一个日期的最小值,而不是文本框上选择的日期。
    • 请查看我的回答。建议您提供详细代码。
    • 嗨,感谢您的回答和时间。请给我一个尝试的机会,我会告诉你的。谢谢
    • 嗨。最后我发现我错过了控制器中的参数设置。像这样 → ViewBag.StartDateFilter = starDate;否则,当我尝试在其他页面更改时,它总是变为 null。我不知道为什么,但它终于奏效了。感谢您的帮助,您的示例也帮助了我。
    【解决方案2】:

    如果有人也需要这个,这就是我得到它的方法 → 我错过了 ViewBag 控制器中的参数设置。像这样 → ViewBag.StartDateFilter = starDate;否则,当我试图在另一个页面上更改时,它总是变为 null。我不知道为什么。 我也使用了一个隐藏字段来保存“查询”(在我的情况下这是用户 ID),因为当我在按钮中发送请求提交时,这也失去了它的价值。真是一团糟!!

    这是一个缩小版

    查看:

    <script src="~/lib/bootstrap/bootstrap-datepicker/js/bootstrap-datepicker.js"></script>
    
    <form class="form-inline" role="form" asp-controller="Movements" asp-action="Details" method="get" asp-antiforgery="false" asp-route-query="@ViewBag.Query">
        <div>            
            <div class="input-daterange input-group" id="datepicker">
                <span style="font-weight:bold">Date</span>&nbsp;From&nbsp;
    
                @Html.TextBox("startDate", null, new
           {
               id = "startDate",
               @class = "input-sm form-control",
               @readonly = "readonly"
           })
    
                <span class="input-group-addon">&nbsp;To&nbsp;</span>
    
                @Html.TextBox("endDate", null, new
           {
               id = "endDate",
               @class = "input-sm form-control",
               @readonly = "readonly"
           })
            </div>            
            <button asp-route-query="@ViewBag.Query" type="submit" value="Filter" name="Filter">Apply</button>
            @Html.Hidden("Query", (object)ViewBag.Query)
        </div>
    </form>
    <br />
    <table>
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.UserMovementsResults.Data.FirstOrDefault().Date)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.UserMovementsResults.Data.FirstOrDefault().Description)
                </th>                
            </tr>
        </thead>
    
        <tbody>
            @foreach (var item in Model.UserMovementsResults.Data)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Date)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Description)
                    </td>                    
                </tr>
            }
        </tbody>
    </table>
    <div>
        <cs-pager cs-paging-pagesize="@Model.UserMovementsResults.PageSize"
                  cs-paging-pagenumber="@Model.UserMovementsResults.PageNumber"
                  cs-paging-totalitems="@Model.UserMovementsResults.TotalItems"
                  cs-pagenumber-param="pageNumber"                  
                  asp-controller="Movements"
                  asp-action="Details"
                  asp-route-query="@ViewBag.Query"
                  asp-route-pagesize="@Model.UserMovementsResults.PageSize"
                  cs-preserve-ambient-querystring="true"
                  asp-route-startDate="@ViewBag.StartDateFilter"
                  asp-route-endDate="@ViewBag.EndDateFilter">
        </cs-pager>
    </div>    
    

    控制器:

    [HttpGet]
        public async Task<IActionResult> Details(int? pageNumber, UserMovementsViewModel userMovementsViewModel)
        {
            userMovementsViewModel.StartDateFilter = DateTime.ParseExact(userMovementsViewModel.StartDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
            userMovementsViewModel.EndDateFilter = DateTime.ParseExact(userMovementsViewModel.EndDate, "dd/MM/yyyy", CultureInfo.InvariantCulture).SetEndOfDay();
    
            var userMovements = await GetUserMovements(pageNumber, userMovementsViewModel).ConfigureAwait(true);
    
            ViewBag.StartDateFilter = userMovementsViewModel.StartDateFilter.Value.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
            ViewBag.EndDateFilter = userMovementsViewModel.EndDateFilter.Value.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
            ViewBag.Query = userMovementsViewModel.Query;
    
            return View(userMovements);
        }
    

    我的班级:

    public class UserMovementsViewModel
    {
        public UserMovementsViewModel()
        {
            UserMovementsResults = new PagedResult<UserMovementsResult>();
        }
        public string Query { get; set; } = string.Empty;
        public PagedResult<UserMovementsResult> UserMovementsResults { get; set; } = null;
        public DateTime? StartDateFilter { get; set; }
        public DateTime? EndDateFilter { get; set; }
        public string StartDate { get; set; }
        public string EndDate { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-09-22
      • 1970-01-01
      • 2023-03-10
      • 2013-09-02
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多