第19章 查询表单与JQuery DataTables级联渲染显示

1 重构Web.Areas.Admin.Models.Customers.CustomerSearchModel

using Framework.Models;

using Microsoft.AspNetCore.Mvc.Rendering;

using System.ComponentModel.DataAnnotations;

namespace Web.Areas.Admin.Models.Customers

{

    /// <summary>

    /// 【用户过滤筛选模型--纪录】

    /// <remarks>

    /// 摘要:

    ///     为用户表的过滤筛选操作提供数据支撑后,把这些数据对JQuery DataTables插件表格进行渲染显示。

    /// </remarks>

    /// </summary>

    public record CustomerSearchModel : BaseSearchModel

    {

        #region 拷贝构造方法

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     实例化该纪录时,为列表接口类型的属性成员实例分配内存空间。

        /// </remarks>

        /// </summary

        public CustomerSearchModel()

        {

            DeletedSelectList = new List<SelectListItem> {

                new SelectListItem { Value = null, Text = "全部" },

                new SelectListItem { Value = "False", Text = "可用" },

                new SelectListItem { Value = "True", Text = "已被删除" },

            };

        }

        #endregion

        #region 属性

        /// <summary>

        /// 【用户名】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定的用户名(账户、昵称)

        /// </remarks>

        /// </summary>

        [Display(Name = "用户名")]

        public string Username { get; set; }

        /// <summary>

        /// 【电子邮箱】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定用户所对应的电子邮箱。

        /// </remarks>

        /// </summary>

        [Display(Name = "邮箱")]

        [EmailAddress(ErrorMessage = "输入的电子邮件格式错误。")]

        public string Email { get; set; }

        /// <summary>

        /// 【手机号】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定用户所对应的手机号。

        /// </remarks>

        /// </summary>

        [Display(Name = "手机号")]

        [RegularExpression(@"^(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}$", ErrorMessage = "输入的手机号格式错误。")]

        public string Phone { get; set; }

        /// <summary>

        /// 【逻辑删除?】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个值false(可用)/true(已经被逻辑删除),该值指示用户实体的1个指定实例是否已经处于逻辑删除状态。

        /// </remarks>

        /// </summary>

        [Display(Name = "删除")]

        public bool? Deleted { get; set; }

        /// <summary>

        /// 【班级选择列表实例】

        /// <remarks>

        /// 摘要:

        ///     获取/设置把班级实体的所有下拉列表实例,存储到列表接口实例中。

        /// </remarks>

        /// </summary>

        public IList<SelectListItem> DeletedSelectList { get; set; }

        /// <summary>

        /// 【注册时间从】

        /// <remarks>

        /// 摘要:

        ///     获取/设置用户实体1个指定实例第1次被持久化到用户表中的时间。

        /// </remarks>

        /// </summary>

        [Display(Name = "注册日期从")]

        public DateTime? CreatedDateFrom { get; set; }

        /// <summary>

        /// 【注册时间到】

        /// <remarks>

        /// 摘要:

        ///     获取/设置用户实体1个指定实例第1次被持久化到用户表中的时间。

        /// </remarks>

        /// </summary>

        [Display(Name = "注册日期到")]

        public DateTime? CreatedDateTo { get; set; }

        #endregion

    }

}

2 Web.Areas.Admin.Factories.CustomerModelFactory.GetAbsoluteAvatarUrl

/// <param name="virtualAvatarUrl">1个指定头像图片网络格式的相对路径。</param>

        /// <summary>

        /// 【获取头像图片网络格式的绝对路径】

        /// <remarks>

        /// 摘要:

        ///     获取1个指定头像图片网络格式的绝对路径。

        /// </remarks>

        /// <returns>

        ///   1个指定头像图片网络格式的绝对路径。

        /// </returns>

        /// </summary>

        private string GetAbsoluteAvatarUrl(string virtualAvatarUrl)

        {

            string absoluteAvatarUrl = string.Empty;

            if (string.IsNullOrEmpty(virtualAvatarUrl))

            {

                string _path = _nopFileProvider.Combine(_nopFileProvider.WebRootPath, @"\images\Avatar\Default.jpg");

                if (_nopFileProvider.FileExists(_path))

                {

                    string _absoluteAvatarUrl = _nopFileProvider.GetVirtualPath(@"\images\Avatar\Default.jpg");

                    //URL格式路径字符中的第一个字符:“~/”

                    _absoluteAvatarUrl = _absoluteAvatarUrl.Replace("~/", string.Empty);

                    absoluteAvatarUrl = _webHelper.GetStoreHost() + _absoluteAvatarUrl;

                }

            }

            else

            {

                absoluteAvatarUrl = _webHelper.GetStoreHost().TrimEnd('/') + virtualAvatarUrl;

            }

            return absoluteAvatarUrl;

        }

3 重构Web.Areas.Admin.Factories.CustomerModelFactory.PrepareCustomerListModelAsync

 /// <param name="searchModel">用户过滤筛选模型纪录的1个指定实例。</param>

        /// <summary>

        /// 【异步预处理用户分页列表模型纪录】

        /// <remarks>

        /// 摘要:

        ///     获取用户分页列表模型纪录的1个指定实例,为Jquery DataTable插件当前页渲染显示提供基本且必须的数据支撑。

        /// </remarks>

        /// <returns>

        ///      用户分页列表模型纪录的1个指定实例。

        /// </returns>

        /// </summary>

        public virtual async Task<CustomerListModel> PrepareCustomerListModelAsync(CustomerSearchModel searchModel)

        {

            var createdTo = !searchModel.CreatedDateTo.HasValue ? null

               : searchModel.CreatedDateTo?.AddDays(1);

            //根据前端传递的用户过滤筛选模型纪录的1个指定实例,从用户表中获取(1逻辑页中的)相应行数的数据,并把这些数据存储到列表实例中。

            var customers = await _customerService.GetAllCustomersAsync(

                deleted: searchModel.Deleted,

                email: searchModel.Email,

                username: searchModel.Username,

                phone: searchModel.Phone,

                createdDateFrom: searchModel.CreatedDateFrom,

                createdDateTo: createdTo,

                orderByFiled: searchModel.OrderBy,

                orderByType: searchModel.OrderDir.ToString(),

                pageIndex: searchModel.Page - 1,

                pageSize: searchModel.PageSize);

            //实例化当前用户分页列表模型纪录(“物理页”),为Jquery DataTable插件当前页渲染显示提供基本且必须的数据支撑。

            var model = new CustomerListModel().PrepareToGrid(searchModel, customers, () =>

            {

                return customers.Select(customer =>

                {

                    var customerModel = customer.ToModel<CustomerModel>();

                    customerModel.Avatar = GetAbsoluteAvatarUrl(customerModel.Avatar);

                    return customerModel;

                });

            });

            return model;

        }

4 重构Web\Areas\Admin\Views\Customer\Index.cshtml

@model CustomerSearchModel

<div class="content-header">

    <div class="container-fluid">

        <div class="row mb-2">

            <div class="col-sm-6">

                <div class="fs-3">用户列表</div>

            </div>

            <div class="col-sm-6">

                <ol class="breadcrumb float-sm-end">

                    <li class="breadcrumb-item">

                        @*resetRoleList:用于控制对弹出框的关闭和角色列表的刷新渲染*@

                        <button type="button" id="resetRoleList" class="btn btn-secondary me-3 d-none">

                            <i class="fa-solid fa-rotate-right"></i>

                            重置

                        </button>

                        <button type="button" onclick="OpenWindow('@(Url.Action("Create", "Role",  new {btnId = "resetRoleList"}))', 500, 500, true); return false;" class="btn btn-success float-end">

                            <i class="fas fa-plus"></i>

                            添加

                        </button>

                    </li>

                </ol>

            </div>

        </div>

    </div>

</div>

<!-- Main content -->

<div class="content">

    <div class="container-fluid">

        <div class="row">

            <div class="col-12">

                <div class="card card-primary card-outline">

                    <form id="customerSearchModelForm" asp-action="Index" class="form-horizontal" method="post">

                        <div class="card-body">

                            <div class="row mb-3">

                                <div class=" col-sm-6">

                                    <div class="form-group row mb-3">

                                        <label asp-for="Username" class="col-sm-2 col-form-label"></label>

                                        <div class="col-sm-10">

                                            <input asp-for="Username" class="form-control" />

                                            <span asp-validation-for="Username" class="text-danger"></span>

                                        </div>

                                    </div>

                                </div>

                                <div class="col-sm-6">

                                    <div class="form-group row mb-3">

                                        <label asp-for="Email" class="col-sm-2 col-form-label"></label>

                                        <div class="col-sm-10">

                                            <input asp-for="Email" class="form-control" />

                                            <span asp-validation-for="Email" class="text-danger"></span>

                                        </div>

                                    </div>

                                </div>

                            </div>

                            <div class="row mb-3">

                                <div class=" col-sm-6">

                                    <div class="form-group row mb-3">

                                        <label asp-for="Phone" class="col-sm-2 col-form-label"></label>

                                        <div class="col-sm-10">

                                            <input asp-for="Phone" class="form-control" />

                                            <span asp-validation-for="Phone" class="text-danger"></span>

                                        </div>

                                    </div>

                                </div>

                                <div class="col-sm-6">

                                    <div class="form-group row mb-3">

                                        <label asp-for="Deleted" class="col-sm-2 col-form-label"></label>

                                        <div class="col-sm-10">

                                            <select asp-for="Deleted" class="form-select" asp-items="Model.DeletedSelectList"></select>

                                        </div>

                                    </div>

                                </div>

                            </div>

                            <div class="row mb-3">

                                <div class=" col-sm-6">

                                    <div class="form-group row mb-3">

                                        <label asp-for="CreatedDateFrom" class="col-sm-2 col-form-label"></label>

                                        <div class="col-sm-10">

                                            <input asp-for="CreatedDateFrom" class="form-control" />

                                            <span asp-validation-for="CreatedDateFrom" class="text-danger"></span>

                                        </div>

                                    </div>

                                </div>

                                <div class="col-sm-6">

                                    <div class="form-group row mb-3">

                                        <label asp-for="CreatedDateTo" class="col-sm-2 col-form-label"></label>

                                        <div class="col-sm-10">

                                            <input asp-for="CreatedDateTo" class="form-control" />

                                            <span asp-validation-for="CreatedDateTo" class="text-danger"></span>

                                        </div>

                                    </div>

                                </div>

                             </div>

                        </div>

                        <div class="card-footer text-center">

                            <button type="submit" class="btn btn-primary btn-search">

                                <i class="fas fa-search"></i>

                                查询

                            </button>

                            <button type="submit" class="btn btn-default float-right">Cancel</button>

                        </div>

                    </form>

                </div>

                <div class="card">

                    <div class="card-body">

                        <table id="example" class="table table-striped table-bordered nowrap projects" width="100%" cellspacing="0">

                        </table>

                    </div>

                    <!-- /.card-body -->

                </div>

                <!-- /.card -->

            </div>

        </div>

        <!-- /.row -->

    </div><!-- /.container-fluid -->

</div>

@section Scripts {

    @{

        await Html.RenderPartialAsync("_ValidationScriptsPartial");

    }

    <script type="text/javascript">

        var tableModel;

        $(document).ready(function () {

            kendo.culture("zh-CN");//对所有的“kendo”控件时进行全局性汉化。

            $("#CreatedDateFrom").kendoDatePicker({

                format: "yyyy-MM-dd", //设定显示在input标签的日期格式

                max: new Date(Date.now()),设定最大日期为当前日期。

            });

            $("#CreatedDateTo").kendoDatePicker({

                format: "yyyy-MM-dd", //设定显示在input标签的日期格式

                max: new Date(Date.now()),设定最大日期为当前日期。

            });

            tableModel = $("#example").DataTable({

                language: {

                    url: '../../lib/DataTables/DataTables-1.13.4/language/zh.json' //DataTables语言配置选项

                },

                processing: true,    //是否显示处理中...”(排序的时候,数据很多耗费时间长的话,也会显示这个)

                serverSide: true,  //是否开启服务器模式

                paging: true, //是否允许翻页

                lengthMenu: [10, 20, 50, 100], //Jquery DataTable插件下拉框控件中的数量选择内容。

                pageLength: 10, // 每页的行数的默认值:10

                searching: false, //是否在Jquery DataTable插件中显示搜索框控件。

                //autoWidth: true,   //自适应宽度

                bSort: true, //显示排序按钮

                pagingType: "numbers",//使用该类型,为在表中数据为空时,禁止在Jquery DataTable插件中,显示上页下页按钮。

                //当处理大数据时,延迟渲染数据,有效提高Datatables处理能力

                deferRender: true,

                order: [[8, "desc"]],//默认设置第8列以倒序方式对Jquery DataTable插件进行排序显示。

                ajax: {

                    url: "/Admin/Customer/CustomerList",

                    type: "POST",

                    datatype: "JSON",

                    cache: false,  //禁用缓存

                    data: function (customerSearchModel) { //传递参数

                        customerSearchModel.Username = $("#Username").val();

                        customerSearchModel.Email = $("#Email").val();

                        customerSearchModel.Phone = $("#Phone").val();

                        customerSearchModel.Deleted = $("#Deleted").val();

                        customerSearchModel.CreatedDateFrom = $("#CreatedDateFrom").val();

                        customerSearchModel.CreatedDateTo = $("#CreatedDateTo").val();

                    },

                },

                columnDefs: [{  //设置列定义初始化属性

                    defaultContent: "", //为列设置默认的静态内容

                    targets: "_all"  //指定所有列

                }],

                //注意:"data"对应的字段(实体属性)的第1个字母必是小写,否则实体实例的值将不会被浏览器渲染出来。

                columns: [

                    {

                        data: "id", "title": "<input type='checkbox' id='checkAll' class='form-check-input checkBox20' />",

                        width: "25px",

                        orderable: false,//禁止当前列渲染显示排序按钮。

                        render: function (data, type, row, meta) {

                            return "<input type='checkbox' name='checkItem' value=" + data + " class='form-check-input checkBox20' />";

                        },

                    },

                    { data: "id", title: "编号", width: "100px" },

                    { data: "username", title: "用户名", autoWidth: true },

                    {

                        data: null,

                        title: "头像",

                        width: "65px",

                        orderable: false,//禁止当前列渲染显示排序按钮。

                        render: function (data, type, full, meta) {

                            return "<img  src='" + data.avatar + "'class='img-size-64'/>";

                        },

                    },

                    { data: "email", title: "邮箱", autoWidth: true },

                    { data: "phone", title: "手机", width: "100px", orderable: false },

                    {

                        data: "active",

                        title: "可用",

                        width: "50px",

                        orderable: false,

                        //禁止当前列渲染显示排序按钮。

                        render: function (data, type, row, full, meta) {

                            //console.log(data);

                            if (data) {

                                return "<span class='badge bg-success'>激活</span>";

                            }

                            else {

                                return "<span class='badge bg-danger'>禁用</span>";

                            }

                        },

                    },

                    {

                        data: "deleted",

                        title: "删除",

                        width: "50px",

                        orderable: false,//禁止当前列渲染显示排序按钮。

                        render: function (data, type, row, full, meta) {

                            //console.log(data);

                            if (data) {

                                return "<span class='badge bg-danger'>已经删除</span>";

                            }

                            else {

                                return "<span class='badge bg-success' style='letter-spacing: 8px; text-indent: 8px; '>可用</span>";

                            }

                        },

                    },

                    {

                        data: "createdDate",

                        title: "创建日期",

                        width: "100px",

                        render: function (data, type, full, meta) {

                            //console.log(data);

                            //console.log(type);

                            //console.log(full);

                            //console.log(meta);

                            //时间格式化

                            return moment(data).format("YYYY-MM-DD HH:mm:ss");

                        }

                    },

                    {

                        data: null,

                        width: "100px",

                        orderable: false,//禁止当前列渲染显示排序按钮。

                        render: function (data, type, row, full, meta) {

                            return "<a href='#' class='btn btn-sm btn-info me-3' >编辑</a>"

                                + "<a href='#' class='btn btn-sm btn-danger' οnclick=deleteData('" + data.id + "'); >删除</a>";

                        },

                    },

                ],

            });

        });

        //查询表单必须使用该事件来执行筛选操作,否则查询表单中的输入控件将被清空。

        $("#customerSearchModelForm").on("submit", function (e) {

            //该方法将通知Web浏览器不要执行与事件关联的默认动作(如果存在这样的动作),

            // 例如:例如,当你点击一个超链接时,浏览器会自动跳转到超链接指向的页面,这就是浏览器的默认行为。

            // 如果你希望在点击超链接时不跳转,可以在超链接的事件处理函数中使用e.preventDefault()来阻止浏览器的默认行为。

            e.preventDefault();

            tableModel.ajax.reload();

        });

    </script>

}

对以上功能更为具体实现和注释见230601_019ShopRazor(查询表单与JQuery DataTables级联渲染显示)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值