Firefox & IE中,列表显示如预期,默认排序很好。并且No.列从1,2,3...升序显示

但是问题出在Chrome中,并且显示顺序不正确(请参见下面的屏幕截图)


下面是我的代码,我也尝试了名为lineNo的相关列模型的firstsortorder:'asc',但它不起作用。

实际上,总共约有100条记录。

jQuery.post(jqDataUrl, data, function(response) {
  if(response != null) {
    jQuery("#jqTable").jqGrid("GridUnload");
    jQuery("#jqTable").jqGrid({
      data: response.rowdata,
      datatype: "local",
      colNames:
      [
        "",
        "",
        "",
        "<spring:message code = "patron.transaction.number" />",
        "<spring:message code = "sales.pdtType" />",
        "<spring:message code = "sales.pdtDetails" />",
        "<spring:message code = "patron.transaction.ticketID" />",
        "<spring:message code = "sales.priceCat" />" ,
        "<spring:message code = "sales.priceClass" />",
        "<spring:message code = "sales.unitPrice" />",
        "<spring:message code = "sales.ticketType" />",
        "<spring:message code = "sales.dateFulfilled" />",
        "<spring:message code = "sales.lastStatus" />",
        "<spring:message code = "patron.transaction.lastUpdated" />",
        "<spring:message code = "generic.jqgrid.action" />"
      ],
      colModel:
      [
        { name: "txnID", index: "txnID", width: 50,hidden:true, editable: true, align: "left" ,search:false,sortable:false},
        { name: "isReturned", index: "isReturned", width: 50,hidden:true, align: "left",title:false,search:false,sortable:false},
        { name: "description", index: "description", width: 50, align: "left",title:false,search:false,sortable:false},
        { name: "lineNo", index: "lineNo", width: 50, align: "left",title:false,search:false,sortable:false},
        { name: "pdtType", index: "pdtType", width: 100, align: "left",title:false,search:false,sortable:false},
        { name: "pdtDetails", index: "pdtDetails", width: 100, align: "left",title:false,search:false,sortable:false},
        { name: "ticketID", index: "ticketID", width: 100,key:true, align: "left",title:false,search:false,sortable:false},
        { name: "priceCat", index: "priceCat", width: 100, align: "left",title:false,search:false,sortable:false},
        { name: "priceClass", index: "priceClass", width: 100, align: "left",title:false,search:false,sortable:false},
        { name: "unitPrice", index: "unitPrice", width: 100, align: "left",title:false,search:false,sortable:false,
          formatter:function (cellvalue, options, rowObject) {
             if(cellvalue == null || cellvalue == "") {
               return "";
             } else {
                 return "${userCurrency}"+parseFloat(cellvalue).toFixed(2);
             }
          }
        },
        { name: "ticketType", index: "ticketType", width: 80, align: "left",title:false,search:false,sortable:false},
        { name: "dateFulFilled", index: "dateFulFilled", width: 80, align: "left",title:false,search:false,sortable:false},
        { name: "lastStatus", index: "lastStatus", width: 80, align: "left",title:false,search:false,sortable:false},
        { name: "lastUpdated", index: "lastUpdated", width: 80, align: "left",title:false,search:false,sortable:false},
        { name: 'action', index: 'action', width: 50, align: "center", sortable: false, search:false}
      ],
      autowidth: true,
      height: 'auto',
      grouping: true,
      groupingView : {
        groupField : ['description'],
        groupColumnShow : [false, false],
        groupText : ["<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>","<b>{0} </b>"],
        groupCollapse : false,
        groupOrder: ['asc', 'asc'],
      },
      pager: jQuery("#jqTablePager"),
      //rowNum: 10,
      rowList: [10, 20, 30],
      cmTemplate: { title: false },
      emptyrecords:"<spring:message code = 'generic.jqgrid.nosearchresults'/>",
      jsonReader : {root: "rowdata", page: "page", total: "total", records: "records", repeatitems: false, id: "ticketID"},
      gridComplete: function() {
        var grid = jQuery("#jqTable");
        var ids = grid.jqGrid('getDataIDs');
        for (var i = 0; i < ids.length; i++) {
          var row = ids[i];
          var isReturned = grid.getCell(row, 'isReturned');
          if(isReturned=='true'){
              document.getElementById(row).style.backgroundColor='orange';
          }
          var button = "<img class='icons' title='View Fee Details' src='<c:url value='/resources/img/view.png' />' onclick='viewFeeDetailPopup(" + row + ")'/> <img class='icons' title='View Ticket History' src='<c:url value='/resources/img/lookup2.png' />' onclick='viewTicketHistoryPopup(" + row + ")'/>";
          grid.jqGrid('setRowData', row, {action: button});
        }
      }
    });
  } else {
    jQuery('#statusMsg').html("<fmt:message key="generic.jqgrid.noresponse"/>");
  }
});


任何帮助表示赞赏,非常感谢!!!

最佳答案

我想您需要在网格中添加sortname: "lineNo"选项来解决您的主要问题。

您当前的代码还有其他一些小问题,可以进行改进。在下面,我列出了一些小建议(或不太小建议)。

首先,您需要遵循Limitations of grouping中使用的选项,并在网格中添加gridview: true选项。如果您使用的是当前版本的jqGrid,则可以在内部解决此问题,但是我建议您明确添加该选项。

您应该删除jsonReader选项,因为在datatype: "local"的情况下它将被忽略。如果确实需要,可以使用localReader代替(请参阅the documentation)。

您可以按一列description进行分组(请参见groupField中的groupingView)。因此groupingView的所有其他数组参数也应具有一个元素。当前,您将groupColumnShowgroupOrder与两个元素一起使用,并将groupText与11(!!!)元素一起使用。

您可以从网格中删除具有hidden:true属性(txnIDisReturned)的列。本地网格的输入data仍保留所有属性。因此,您可以使用var item = $("#jqTable").jqGrid("getLocalRow", rowid),并且item包含所有属性,例如item.isReturnedgetLocalRow比您当前使用的getCell更有效。

您修改background-color中某些行的gridComplete。这是无效的(工作缓慢)。更有效的方法是在创建网格时使用rowattr设置所需的样式。请参见the answerthis one。顺便说一句,如果需要,我建议您使用loadComplete而不是gridComplete。请参见the answer

您应该使用pager: "#jqTablePager"而不是pager: jQuery("#jqTablePager")。由于常见错误,jqGrid的代码已更改了一天。现在,如果pager的值是jQuery包装器(如jQuery("#jqTablePager")),则jqGrid会将其标准化为选择器。它获取元素的id并将pager: jQuery("#jqTablePager")固定为pager: "#jqTablePager"。但是,为什么首先需要通过id搜索页面的DOM元素并使用id="jqTablePager"查找DOM,然后为DOM元素(jQuery("#jqTablePager"))创建jQuery包装器呢?这绝对是不需要的工作。您应该知道这一点,并且始终以id选择器pager的形式始终使用"#jqTablePager"

在循环中使用setRowData更改网格的每一行的action列的速度很慢。网格中一个元素的每次更改都会导致页面中所有元素的重排。有关更多详细信息,请参见the answerthe article。更有效的方法是直接使用custom formatter创建action单元格的正确内容。与您当前的实现非常接近的最简单的实现如下

{ name: 'action', width: 50, align: "center", sortable: false, search: false,
    formatter: function (cellvalue, options) {
        return "<img class='icons' title='View Fee Details' src='<c:url value='/resources/img/view.png' />' onclick='viewFeeDetailPopup(" +
            options.rowId + ")'/> <img class='icons' title='View Ticket History' src='<c:url value='/resources/img/lookup2.png' />' onclick='viewTicketHistoryPopup(" +
            options.rowId + ")'/>";
    }}


rowId参数的options属性为您提供必需的信息。如果需要,您可以使用自定义格式化程序的第三个rowObject参数来访问行项目的所有其他属性。

顺便说一下,您可以考虑从上述onclick列中添加的图像中删除action,而改用beforeSelectRow回调。请参见the answer。您可以轻松地修改代码,以区分列内的两个不同的imge.target是单击的元素。例如,如果单击第一个img,则$(e.target).attr("title")将为"View Fee Details";单击第二个img,则将为View Ticket History

最后一句话。我建议您减少使用的colModel。您应该删除所有index属性以及所有具有默认值(例如align: "left")的属性。您可以在cmTemplate中包含更多常用属性。使用cmTemplate: {title: false, search: false, sortable: false}可以减少代码并使代码更具可读性。列定义

{ name: "priceCat", index: "priceCat", width: 100, align: "left",
    title: false, search: false, sortable: false}


例如将减少为

{ name: "priceCat", width: 100 }


该代码将更小,加载更快,更易于阅读,易于维护。

09-25 19:59