You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jqGrid在keyup事件下无法正确重载刷新问题排查

jqGrid实时搜索参数不更新问题排查与解决

问题描述

我需要创建一个包含各类文本框、下拉框、日期字段的搜索页面,为每个文本框添加了keyup事件,期望输入内容时显示带子网格的jqGrid。目前遇到的问题是:首次输入时网格能加载正确数据,清空字段后网格也能重载,但再次输入该字段或其他文本框时,JS不会携带更新后的参数向后端Action方法发送请求。

视图代码

<section class="content">
    <div class="container-fluid">
        <!-- SELECT2 EXAMPLE -->
        <!-- SELECT2 EXAMPLE -->
        <div class="card card-info">
            <div class="card-header">
                <h3 class="card-title">Search Criteria</h3>

                <div class="card-tools">
                    <button type="button" class="btn btn-tool" data-card-widget="collapse">
                        <i class="fas fa-minus"></i>
                    </button>
                </div>
            </div>
            <!-- /.card-header -->
            @using (Html.BeginForm("SearchReport", "LRLiveSearch", FormMethod.Post))
            {
                <div class="card-body">
                    <div class="row">
                        <div class="col-md-12" style="line-height:1.50px;">

                            <div class="row">
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>Deed No</label>
                                        @Html.TextBoxFor(model => model.DeedNo, new { @class = "form-control", onkeyup = "LiveSearch('DN', this.value)" })
                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>Deed Identity</label>
                                        @Html.TextBoxFor(model => model.DeedId, new { @class = "form-control", onkeyup = "LiveSearch('DI', this.value)" })

                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>Client Name</label>
                                        @Html.TextBoxFor(model => model.ClientName, new { @class = "form-control", onkeyup = "LiveSearch('CN', this.value)" })
                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>Client Contact Number</label>
                                        @Html.TextBoxFor(model => model.ClientPhoneNumber, new { @class = "form-control", onkeyup = "LiveSearch('CP', this.value)" })
                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>MR No</label>
                                        @Html.TextBoxFor(model => model.MRNo, new { @class = "form-control", onkeyup = "LiveSearch('MR', this.value)" })
                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>Cheque No</label>
                                        @Html.TextBoxFor(model => model.ChequeNo, new { @class = "form-control", onkeyup = "LiveSearch('CQN', this.value)" })
                                    </div>
                                </div>
                            </div>
                            <div class="row">
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>Collection Type</label>
                                        @Html.DropDownListFor(model => model.CollectionType, Model.CollectionTypeList, new { @class = "form-control" })
                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>From Date</label>
                                        <div class="input-group date" id="FirstDate" data-target-input="nearest">
                                            @Html.TextBoxFor(model => model.FromDate, new { @class = "form-control datetimepicker-input", @data_target = "#FirstDate" })
                                            <div class="input-group-append" data-target="#FirstDate" data-toggle="datetimepicker">
                                                <div class="input-group-text"><i class="fa fa-calendar"></i></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-2">
                                    <div class="form-group">
                                        <label>To Date</label>
                                        <div class="input-group date" id="SecondDate" data-target-input="nearest">
                                            @Html.TextBoxFor(model => model.ToDate, new { @class = "form-control datetimepicker-input", @data_target = "#SecondDate" })
                                            <div class="input-group-append" data-target="#SecondDate" data-toggle="datetimepicker">
                                                <div class="input-group-text"><i class="fa fa-calendar"></i></div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                @*<div class="col-md-1">
                                        <div class="form-group">
                                            <center>
                                                <button id="btnLRSearch" formaction="SearchList" class="btn btn-md btn-primary" style="margin-top:.80rem" type="button">Search</button>
                                            </center>
                                        </div>
                                    </div>
                                    <div class="col-md-1">
                                        <div class="form-group">
                                            <center>
                                                <button id="btnPrint" formaction="SearchReport" class="btn btn-md btn-warning" style="margin-top:.80rem" type="submit">Report</button>
                                            </center>
                                        </div>
                                    </div>*@
                            </div>
                        </div>
                    </div>
                </div>
            }
        </div>
    </div>
    <!-- /.container-fluid -->
    <table class="table table-bordered table-striped table-hover text-nowrap text-sm" id="Demogrid"></table>
    <div class="container-fluid" id="pager"></div>
</section>

JS代码(原代码)

function LiveSearch(type, value) {
            var searchType = type;
            var searchValue = value;
            if (value == "" || value == null) {
                $("#Demogrid").jqGrid('setGridParam', { postData: { Type: searchType, SearchValue: searchValue } }).trigger('reloadGrid');
                return true;
            }
            else {
                $("#Demogrid").jqGrid({
                    url: '/HRM/LRLiveSearch/LiveSearch',
                    datatype: "json",
                    mtype: 'Get',
                    //table header name
                    colNames: ['ProjectName', 'PlotName', 'TotalLandArea', 'DeedId', 'DeedDate', 'RentFeeType', 'RentFee', 'ClientName', 'ClientAddress', 'ClientContactNo', 'EffectiveDate'],
                    //colModel takes the data from controller and binds to grid
                    colModel: [
                        { name: "ProjectName" },
                        { name: "PlotName" },
                        { name: "TotalLandArea" },
                        { name: "DeedId" },
                        { name: "DeedDate" },
                        { name: "RentFeeType" },
                        { name: "RentFee" },
                        { name: "ClientName" },
                        { name: "ClientAddress" },
                        { name: "ClientContactNo" },
                        { name: "EffectiveDate" }
                    ],
                    height: '100%',
                    viewrecords: true,
                    caption: 'Deed Info',
                    emptyrecords: 'No records',
                    rowNum: 10,
                    pager: jQuery('#pager'),
                    rowList: [10, 20, 30, 40],
                    jsonReader:
                    {
                        root: "rows",
                        page: "page",
                        total: "total",
                        records: "records",
                        repeatitems: false,
                        Id: "0"
                    },
                    postData: {
                        Type: searchType,
                        SearchValue: searchValue
                    },
                    autowidth: true,
                    subGrid: true,
                    subGridRowExpanded: function (subgridId, rowId) {
                        // create the subgrid HTML here
                        var subgridTableId = subgridId + "_t";
                        $("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
                        // get the data for the parent row
                        var parentRowData = $("#Demogrid").jqGrid("getRowData", rowId);
                        // retrieve the primary key value of the parent row
                        var parentId = parentRowData.DeedId;
                        $("#" + subgridTableId).jqGrid({
                            // configure the subgrid
                            url: '/HRM/LRLiveSearch/LiveSearch',
                            datatype: "json",
                            mtype: 'Get',
                            //table header name
                            colNames: ['CollectionId', 'CollectionDate', 'MRIdentity', 'MRNo', 'MRDate', 'MRType', 'CollectionType', 'ChequeNo', 'BankName'],
                            //colModel takes the data from controller and binds to grid
                            colModel: [
                                { name: "CollectionId", hidden: true },
                                { name: "CollectionDate" },
                                { name: "MRIdentity" },
                                { name: "MRNo" },
                                { name: "MRDate" },
                                { name: "MRType" },
                                { name: "CollectionType" },
                                { name: "ChequeNo" },
                                { name: "BankName" }
                            ],
                            height: '100%',

                            viewrecords: true,
                            caption: 'Collection Details',
                            emptyrecords: 'No records',
                            rowNum: 10,
                            jsonReader: {
                                repeatitems: false
                            },
                            postData: {
                                Type: searchType,
                                SearchValue: searchValue,
                                DeedId: parentId
                            },
                            autowidth: true
                        });
                    },

                }).navGrid('#pager',
                    {
                        edit: true,
                        add: true,
                        del: true,
                        search: true,
                        refresh: true,
                        closeAfterSearch: true
                    });
            }

        }

后端Action方法

public JsonResult LiveSearch(string sord, int page, int rows, string searchString, string Type, string SearchValue, string DeedId)
        {
            if(SearchValue == "")
            {
                SearchValue = "$";
            }
            var query = iLRSearchRepository.LiveSearchFilter(Type, SearchValue);
            if (DeedId == null)
            {
                //#2 Setting Paging  
                int pageIndex = Convert.ToInt32(page) - 1;
                int pageSize = rows;
                //#3 Linq Query to Get Data
                
                var Results = query.Select(
                    x => new
                    {
                        ProjectName = x.ProjectName,
                        PlotName = x.PlotName,
                        TotalLandArea = x.TotalLandArea,
                        DeedId = x.DeedId,
                        DeedDate = x.DeedDate.ToString("dd/MM/yyyy"),
                        RentFeeType = x.RentFeeType,
                        RentFee = x.RentFee,
                        ClientName = x.ClientName,
                        ClientAddress = x.ClientsAddress,
                        ClientContactNo = x.ClientsContactNo,
                        EffectiveDate = x.ActivateDate.ToString("dd/MM/yyyy")
                    }).Distinct();
                //#4 Get Total Row Count  
                int totalRecords = Results.Count();
                var totalPages = (int)Math.Ceiling((float)totalRecords / (float)rows);

                //#5 Setting Sorting  
                if (sord.ToUpper() == "DESC")
                {
                    Results = Results.OrderByDescending(s => s.DeedId);
                    Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
                }
                else
                {
                    Results = Results.OrderBy(s => s.DeedId);
                    Results = Results.Skip(pageIndex * pageSize).Take(pageSize);
                }
                //#6 Setting Search  
                if (!string.IsNullOrEmpty(searchString))
                {
                    Results = Results.Where(m => m.DeedId == searchString);
                }
                //#7 Sending Json Object to View.  
                var jsonData = new
                {
                    total = totalPages,
                    page,
                    records = totalRecords,
                    rows = Results
                };
                return Json(jsonData, JsonRequestBehavior.AllowGet);
            }
            else
            {
                var Results = query.Where(x => x.DeedId == DeedId).Select(
                    x => new
                    {
                        CollectionId = x.CollectionId,
                        CollectionDate = x.CollectionDate?.ToString("dd/MM/yyyy"),
                        MRIdentity = x.MRIdentity,
                        MRNo = x.MRNo,
                        MRDate = x.MRDate?.ToString("dd/MM/yyyy"),
                        MRType = x.MRType,
                        CollectionType = x.CollectionType,
                        ChequeNo = x.ChequeNo,
                        BankName = x.BankName,
                    });
                var jsonData = new
                {
                    rows = Results
                };
                return Json(jsonData, JsonRequestBehavior.AllowGet);
            }
            
            //model.landRent_View_SearchInfos = query;
            //return View("_LandRentInfoList", model);
        }

问题原因

当前JS逻辑存在缺陷:只有首次输入非空值时才初始化jqGrid,后续输入非空值时,再次调用$("#Demogrid").jqGrid({...})不会重新创建网格(jqGrid已初始化的情况下会忽略该调用),导致新的搜索参数无法传递到后端。而清空字段时的逻辑是正确的,因为用了setGridParam更新参数并重载。

解决方案

修改LiveSearch函数,先判断jqGrid是否已初始化,初始化过的话直接更新参数并重载,未初始化才执行网格创建逻辑。同时,子网格的参数需要动态获取当前最新的搜索条件,避免使用函数闭包中保存的旧参数。

修改后的JS代码

function LiveSearch(type, value) {
    var searchType = type;
    var searchValue = value;
    // 检查网格是否已初始化
    var grid = $("#Demogrid");
    if (grid.length > 0 && grid[0].grid) {
        // 已初始化,更新参数并重载
        grid.jqGrid('setGridParam', {
            postData: {
                Type: searchType,
                SearchValue: searchValue
            }
        }).trigger('reloadGrid');
    } else {
        // 未初始化,创建网格
        grid.jqGrid({
            url: '/HRM/LRLiveSearch/LiveSearch',
            datatype: "json",
            mtype: 'Get',
            colNames: ['ProjectName', 'PlotName', 'TotalLandArea', 'DeedId', 'DeedDate', 'RentFeeType', 'RentFee', 'ClientName', 'ClientAddress', 'ClientContactNo', 'EffectiveDate'],
            colModel: [
                { name: "ProjectName" },
                { name: "PlotName" },
                { name: "TotalLandArea" },
                { name: "DeedId" },
                { name: "DeedDate" },
                { name: "RentFeeType" },
                { name: "RentFee" },
                { name: "ClientName" },
                { name: "ClientAddress" },
                { name: "ClientContactNo" },
                { name: "EffectiveDate" }
            ],
            height: '100%',
            viewrecords: true,
            caption: 'Deed Info',
            emptyrecords: 'No records',
            rowNum: 10,
            pager: jQuery('#pager'),
            rowList: [10, 20, 30, 40],
            jsonReader:
            {
                root: "rows",
                page: "page",
                total: "total",
                records: "records",
                repeatitems: false,
                Id: "0"
            },
            postData: {
                Type: searchType,
                SearchValue: searchValue
            },
            autowidth: true,
            subGrid: true,
            subGridRowExpanded: function (subgridId, rowId) {
                var subgridTableId = subgridId + "_t";
                $("#" + subgridId).html("<table id='" + subgridTableId + "'></table>");
                var parentRowData = $("#Demogrid").jqGrid("getRowData", rowId);
                var parentId = parentRowData.DeedId;
                // 动态获取当前最新的搜索参数
                var currentPostData = $("#Demogrid").jqGrid('getGridParam', 'postData');
                $("#" + subgridTableId).jqGrid({
                    url: '/HRM/LRLiveSearch/LiveSearch',
                    datatype: "json",
                    mtype: 'Get',
                    colNames: ['CollectionId', 'CollectionDate', 'MRIdentity', 'MRNo', 'MRDate', 'MRType', 'CollectionType', 'ChequeNo', 'BankName'],
                    colModel: [
                        { name: "CollectionId", hidden: true },
                        { name: "CollectionDate" },
                        {
相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 08:22:49