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" }, {
相关产品推荐
相关产品推荐

