【问题标题】:How to stop auto sorting of Jqpivot?如何停止 Jqpivot 的自动排序?
【发布时间】:2017-01-04 15:42:02
【问题描述】:

下面的 jqpivot 网格显示汽车租赁的销售信息。完整的代码在jsfiddle

var data = [{
    "id": 1,
    "make": "toyota",
    "model": "corolla",
    "fuelusagecity": "17",
    "fuelusagehwy": "12",
    "fuelmeasure":'Litre',
    "salesaboveavg": false,
    "totalnumberofsales": 120000.0000,
    "highsalestext": null,
    "salesdate": "2010-12-01"
}, {
    "id": 2,
    "make": "toyota",
    "model": "corolla",
    "fuelusagecity": "10",
    "fuelusagehwy": "14",
    "salesaboveavg": false,
    "fuelmeasure":'Litre',
    "totalnumberofsales": 100000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2010-12-15"
}, {
    "id": 3,
    "make": "toyota",
    "model": "belta",
    "fuelusagecity": "15",
    "fuelusagehwy": "10",
    "salesaboveavg": true,
    "fuelmeasure":'Litre',
    "totalnumberofsales": 200000.0000,
    "highsalestext": null,
    "salesdate": "2011-01-10"
}, {
    "id": 4,
    "make": "toyota",
    "model": "camry",
    "fuelusagecity": "13",
    "fuelusagehwy": "10",
    "fuelmeasure":'Litre',
    "salesaboveavg": false,
    "totalnumberofsales": 300000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2011-04-23"
}, {
    "id": 5,
    "make": "nissan",
    "model": "skyline",
    "fuelusagecity": "14",
    "fuelusagehwy": "9",
    "fuelmeasure":'Litre',
    "salesaboveavg": true,
    "totalnumberofsales": 500000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2010-09-10"
}, {
    "id": 6,
    "make": "nissan",
    "model": "zx300",
    "fuelusagecity": "10",
    "fuelusagehwy": "8",
    "fuelmeasure":'Litre',
    "salesaboveavg": false,
    "totalnumberofsales": 400000.0000,
    "highsalestext": null,
    "salesdate": "2012-01-06"
}];

/* convert the salesdate in  */
var i, item, dateParts;
for (i = 0; i < data.length; i++) {
    item = data[i];
    if (typeof item.salesdate === "string") {
        dateParts = item.salesdate.split("-");
        item.salesYear = dateParts[0];
        item.salesMonth = dateParts[1];
        item.salesDay = dateParts[2];
        item.salesDateFormatted = dateParts[0];
    }
}

var myIntTemplate = {
    formatter: "currency",
    align: "right", sorttype: "number",
    searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] },
    formatoptions: { defaultValue: ""}
},
    $grid = $("#list483");

$grid.jqGrid("jqPivot",
             data,
             {
    frozenStaticCols: true,
    skipSortByX: true,
    useColSpanStyle: true,
    //defaultFormatting: false,
    xDimension: [
        { dataName: "make", width: 100, label: "Make", compareVectorsEx(x1,x2){
        // how do i use x1, x2 parameters to stop auto sort
        }  },
        { dataName: "model", width: 100, label: "Model", align: "center", skipGrouping:true, compareVectorsEx(x1,x2){

        } },
        { dataName: "fuelmeasure", width: 103, label: "Units", compareVectorsEx(x1,x2){

        } },
    ],
    yDimension: [
        { dataName: "salesdate", sortorder: "desc"}//,
        //{ dataName: "salesYear", sorttype: "integer" },
        //{ dataName: "salesMonth", sorttype: "integer" }
    ],
    aggregates: [{
        member: "totalnumberofsales",
        template: myIntTemplate,
        formatter:function(cellvalue, options, rowObject){
            if(cellvalue=== undefined){
                return '';
            }
            else{

                var x = options.rowData.pivotInfos[options.colModel.name].rows[0].highsalestext;

                if(x==="HIGH")
                {
                    return x;
                }
                else
                {
                    return cellvalue;
                }
            }
        },
        cellattr: function (rowId, cellValue, rawObject, cm, rdata) {
            if (rawObject != null) {
                var items = rawObject.pivotInfos[cm.name];
                if (items != null && items.rows != null && items.rows.length > 0) {
                    var isHigh = true, i;
                    for (i = 0; i < items.rows.length; i++) {
                        if (items.rows[i].highsalestext !== "HIGH") {
                            isHigh = false;
                            break;
                        }
                    }
                    if (isHigh) {
                        return "class='high-marker'";
                    }
                }
            }
        },
        aggregator: "max"
    }/*,
                 {
                 member: "totalnumberofsales",
                 aggregator: "count",
                 //template: "integer",
                 label: "{0}"
                 }*/]
},
             // grid options
             {
    iconSet: "fontAwesome",
    cmTemplate: { autoResizable: true, width: 75 },
    shrinkToFit: false,
    useUnformattedDataForCellAttr: false,
    autoResizing: { compact: true },
    groupingView: {
        groupField: ["x0"],
        groupColumnShow: [false],
        groupText: ["<span class='group-text'>{0}</span>"]
    },
    //width: 450,
    pager: true,
    rowNum: 20,
    caption: "<b>Car sales statistics</b>",
    rowList: [5, 10, 20, 100, "10000:All"]
}
            );    

根据维基底部的 jqpivot 官方 wiki 上的这个 wiki suppress auto sort 声明:

按整个 x 或 y 向量自定义排序

compareVectorsByX 和 compareVectorsByY 选项允许指定 回调函数将用于整个 x 的自定义排序 或 y 向量。

按向量排序的默认实现可以在这里找到。 它是 ArrayOfFieldsets 的 compareVectorsEx 方法。重要的是 了解该功能将用于两个目的:1)比较 向量 2) 找到向量的索引 比较向量的差异。所以方法 compareVectorsEx 返回具有两个属性的对象:索引和结果。该物业 结果是众所周知的值-1,这意味着第一个向量是 小于第二个 0 表示向量等于 1,即 表示第一个向量大于第二个向量。这 属性 index 返回比较元素的从 0 开始的索引 向量不同的向量。

我已经添加了函数compareVectorsEx,但如何使用该函数来停止自动排序?

我必须停止所有 x 字段的自动排序。我需要停止排序的原因是让网格以与原始 json 相同的顺序显示字段制作和模型。

更新:

我已修改原始 json 数据源,使其在每个对象 groupheaderorderchildorder 上有两个属性。属性groupheaderorderjson 中对象的属性make 的顺序,childorder 属性是all make namesmodel 属性的顺序。

这是json数据

var data = [{
    "id": 1,
    "make": "toyota",
    "model": "corolla",
    "fuelusagecity": "17",
    "fuelusagehwy": "12",
    "fuelmeasure":'Litre',
    "salesaboveavg": false,
    "totalnumberofsales": 120000.0000,
    "highsalestext": null,
    "salesdate": "2010-12-01", 
    "groupheaderorder":"1",
    "childorder":"1"
}, {
    "id": 2,
    "make": "toyota",
    "model": "corolla",
    "fuelusagecity": "10",
    "fuelusagehwy": "14",
    "salesaboveavg": false,
    "fuelmeasure":'Litre',
    "totalnumberofsales": 100000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2010-12-15",
    "groupheaderorder":"1",
    "childorder":"1"
}, {
    "id": 3,
    "make": "toyota",
    "model": "belta",
    "fuelusagecity": "15",
    "fuelusagehwy": "10",
    "salesaboveavg": true,
    "fuelmeasure":'Litre',
    "totalnumberofsales": 200000.0000,
    "highsalestext": null,
    "salesdate": "2011-01-10",
    "groupheaderorder":"1",
    "childorder":"2"
}, {
    "id": 4,
    "make": "toyota",
    "model": "camry",
    "fuelusagecity": "13",
    "fuelusagehwy": "10",
    "fuelmeasure":'Litre',
    "salesaboveavg": false,
    "totalnumberofsales": 300000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2011-04-23",
    "groupheaderorder":"1",
    "childorder":"3"
}, {
    "id": 5,
    "make": "nissan",
    "model": "skyline",
    "fuelusagecity": "14",
    "fuelusagehwy": "9",
    "fuelmeasure":'Litre',
    "salesaboveavg": true,
    "totalnumberofsales": 500000.0000,
    "highsalestext": "HIGH",
    "salesdate": "2010-09-10",
    "groupheaderorder":"2",
    "childorder":"1"
}, {
    "id": 6,
    "make": "nissan",
    "model": "zx300",
    "fuelusagecity": "10",
    "fuelusagehwy": "8",
    "fuelmeasure":'Litre',
    "salesaboveavg": false,
    "totalnumberofsales": 400000.0000,
    "highsalestext": null,
    "salesdate": "2012-01-06",
    "groupheaderorder":"2",
    "childorder":"2"
}];

Here is link to the jsfiddle code(除了添加了两个新属性之外,这与我的原始帖子的代码相同)

让我通过一个例子来解释一下

在 josn 中有三辆丰田和两辆日产。如果您查看 相同品牌和型号groupheaderorder 号码和childorder 号码,它们具有相同的值,但对于不同的品牌和型号 > 它们具有不同的值。因此,groupheaderorderchildheaderorder 的组合对于品牌和型号的不同组合而言始终是唯一的。我认为这可能是为 grouptext他们的孩子 提供自定义排序顺序的好选择,因为他们保留并显示了他们的 原始排序顺序

原始数据来自我无法在存储过程代码中修改的存储过程,而且令人生畏的返回结果集甚至没有用于排序的列。因此,在我从 ASP MVC 构建的 Web 应用程序中,在其控制器逻辑中,我唯一的选择是添加这两个排序属性,以便将它们包含在 json.

可能还有其他更好的方法,如果是这样,我真的很想知道:)
但是,由于我添加了这两个属性以保留原始排序顺序,是否可以在生成的枢轴网格中保留并显示此顺序?

【问题讨论】:

  • 您已经使用了skipSortByX: true 选项。这意味着 jqPivot 已经不对输入数据进行排序。不过,您还有另一个问题。 jqPivot 聚合源数据并生成新数据,供第二步使用:在网格中显示新数据。您使用groupField: ["x0"],因此 jqGrid 按x0(按make排序先前生成的数据。您没有为该列指定任何 sorttype,因此数据将按 asc 文本顺序排序(“nissan”在“toyota”之前)。在按 x0 排序期间,第二列 x1(模型)也将被混合。

标签: jquery jqgrid free-jqgrid jqpivot


【解决方案1】:

应该对您的代码进行一些小的更改。首先应该删除skipSortByX: true 选项,不需要更多。几秒钟后,我们应该使用groupheaderorderchildorder 属性扩展xVector,我们需要这些属性进行排序。我们不会显示列,因此我们可以为列使用additionalProperty: true 属性。结果我们可以使用下面的xDimension

xDimension: [
    { /*x0*/ dataName: "make", width: 100, label: "Make" },
    { /*x1*/ dataName: "model", width: 100, label: "Model", align: "center", skipGrouping:true },
    { /*x2*/ dataName: "fuelmeasure", width: 103, label: "Units", skipGrouping:true },
    { /*x3*/ dataName: "groupheaderorder", additionalProperty: true },
    { /*x4*/ dataName: "childorder", additionalProperty: true }
]

我包含了 cmets,它描述了属性的名称(索引):make 属性在 x 向量中的索引为 0,model 属性的索引为 1,... childorder 属性的索引为 4。

最终的 jqGrid 将具有输入 data 和属性 x0x1、...、x4,它们对应于列。要使列“make”和“model”(x0x1)可基于groupheaderorderchildorder 进行排序,我们可以将sorttype 回调添加到前两列。结果我们得到

xDimension: [
    { /*x0*/ dataName: "make", width: 100, label: "Make",
        sorttype: function (cellValue, item) {
            return parseInt(item.x3, 10);
        } },
    { /*x1*/ dataName: "model", width: 100, label: "Model", align: "center", skipGrouping:true,
        sorttype: function (cellValue, item) {
            return parseInt(item.x4, 10);
        }},
    { /*x2*/ dataName: "fuelmeasure", width: 103, label: "Units", skipGrouping:true },
    { /*x3*/ dataName: "groupheaderorder", additionalProperty: true },
    { /*x4*/ dataName: "childorder", additionalProperty: true }
]

最后我们需要实现compareVectorsByX回调,可以用来对数据进行X-vector排序。回调compareVectorsByX 有两个参数,它们将是来自源数据的 x 项,例如 x1 = ["toyota", "corolla", "Litre", "1", "1"]2 = ["toyota", "belta", "Litre", "1", "2"]。回调应返回具有两个属性的对象:indexresult。结果是 -1、0 或 1,每个人在比较数字时都知道。 index 是 x 数组中的索引,人们在其中发现了 x1x2 之间的差异,然后进行比较。在上述示例的情况下,找到 x 数组的第二个元素的差异(第二个元素的索引为 1)。我们根据最后一个 ("childorder") 值比较 "corolla""belta":通过比较 "1""2"。因此,compareVectorsByX 回调应该在上述选项上返回 { index: 1, result: -1 }。通用代码如下:

compareVectorsByX: function (x1, x2) {
    // x1 = ["toyota", "corolla", "Litre", "1", "1"],
    // x2 = ["toyota", "belta", "Litre", "1", "2"]
    var groupheaderorder1 = parseInt(x1[3], 10), childorder1 = parseInt(x1[4], 10),
        groupheaderorder2 = parseInt(x2[3], 10), childorder2 = parseInt(x2[4], 10);
    if (groupheaderorder1 !== groupheaderorder2) {
        return { index: 0, result: groupheaderorder1 - groupheaderorder2 };
    }
    if (childorder1 !== childorder2) {
        return { index: 1, result: childorder1 - childorder2 };
    }
    return {
        index: -1,
        result: 0
    };
}

就是这样。修改后的带代码的demo是https://jsfiddle.net/OlegKi/cukLs23n/2/

【讨论】:

  • 感谢您的全面回复:)。当我比较我发布的原始 jsfiddle jsfiddle.net/9xxzsuu4/3 并排序小提琴与排序顺序 jsfiddle.net/cukLs23n/1 显示相同的记录顺序。但是通过添加明确的排序顺序,新生成的网格应该以与它们在 json 中出现的顺序相同的顺序显示数据。 eg: TOYOTA group 必须出现在 NISSAN 之前,并且 TOYOTA group 中的汽车顺序必须是以下顺序 corolla、belta、camry。在 NISSAN 组中,汽车必须按以下顺序显示天际线,zx300,订单编号是否错误?
  • @Dore.Ad:对不起,我在答案末尾发布了错误的 URL。如果您愿意按照我的回答,评论skipSortByX: true,替换xDimension 并添加compareVectorsByX,那么您将获得正确的排序结果,如jsfiddle.net/OlegKi/cukLs23n/2
  • 我想知道问题出在哪里。现在自定义排序顺序开始生效。多谢! :)
  • @Dore.Ad:我刚刚发布了带有错误演示 (jsfiddle.net/cukLs23n/1) 的 URL,它没有使用我在回答中描述的全部内容。演示 jsfiddle.net/OlegKi/cukLs23n/2 使用 compareVectorsByX 等等,它可以工作。
猜你喜欢
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
  • 1970-01-01
  • 2020-01-12
  • 2019-02-04
  • 2014-12-09
相关资源
最近更新 更多