Sorting dgrid column does not work as expected

时间:2016-10-20 13:15:24

标签: javascript sorting dojo dgrid dijit.layout

I have a dgrid table comprising 13 columns.

The sort in decreasing order works as expected: Highest values, followed by lowest values, followed by entries that have no values.

However, when I sort in ascending order, there are fields with no values, then fields with 0, then fields with no values again and finally fields with values in ascending order.

I have looked into source code, but I am unable to figure out what is causing this.

Is this a bug with dgrid sorting?

What could be the workaround for this?

2 个答案:

答案 0 :(得分:0)

如果您的列是只读的,您可以在数据源中添加一个字段(请参阅下面代码中的displayValue),反映您的值,但字符串替换为负数< /强>

然后,将该字段仅放入网格中,而不是真实字段。并在列的get函数中显示实际值。

我使用相同的解决方法在填充了专有名称的列中应用不区分大小写的排序。

require(["dgrid/Grid", "dojo/domReady!"], function (Grid) {

	var data = [];

	for(var i = 0; i < 3; i++) for(j = 1; j <= 2; j++) data.push({value: i});
	for(i = 1; i < 3; i++) data.push({value: ""});

	data.forEach(function(item) {
		item.displayValue = typeof item.value == "string" ? -1 : item.value;
	});

	var grid = new Grid({
		columns: {
			displayValue: {
				label: "Value",
				get: function(item) { return item.value; }
			}
		}
	}, 'grid');

	grid.renderArray(data);
	grid.set("sort", "displayValue");
  
});
<script>
  dojoConfig = {
    async: true,
    packages: [
      {
        name: 'dgrid',
        location: 'https://cdn.rawgit.com/SitePen/dgrid/v1.1.0'
      }
    ]
  }
</script>
<script src="https://ajax.googleapis.com/ajax/libs/dojo/1.11.2/dojo/dojo.js"></script>

<link rel="stylesheet" href="https://cdn.rawgit.com/SitePen/dgrid/v1.1.0/css/dgrid.css"/>
  
<style>
  .dgrid-row-table {
      height: 24px;
  }
</style>

<body>
  <div id="grid" style="width:200px;height:210px">
  </div>
</body>

答案 1 :(得分:0)

=在您的评论=

之后,作为我的上一篇文章提供更好的答案

AFAIK,dgrid(以及dstore)不允许使用自定义排序功能。

下面的模式克服了这个限制。它使用填充了OnDemandGrid的{​​{1}}。

例如,此网格的dstore列包含从“g1”到“g20”的值。它们不是按照数字(默认排序)进行排序,而是按数字排序(自定义排序基于“g”之后的数字)=&gt; “g1”&lt; “g2”&lt; “g3”&lt; ......&lt; “g10”&lt; “G11” ...

此自定义排序由field1回调函数执行:

comparegXX

... var comparegXX = function(a, b) { // 'compare' is a generic comparison function for values of the same type try { return compare(parseInt(a.value.substr(1), 10), parseInt(b.value.substr(1), 10)); } catch(ex) { return compareMixedTypes(a, b); } } 已在其列定义(comparegXX属性)中分配给field1

sort

field1: { sort: comparegXX }, (混合类型排序 - 字符串和数字 - 由field2执行)相同。

如果要为字段指定其他自定义排序,请编写自定义比较回调函数并将其添加到字段的列定义中:compareMixedTypes

请注意,商店不应包含任何名为fieldX: {sort: myCompareFunction}的字段。该字段由_newPos函数创建和使用。它包含应用自定义排序后数据行的新相对位置 - 网格的新排序基于此字段。

doSort
var compare = function(a, b) { return a > b ? 1 : a < b ? -1 : 0; }

// comparison functions for custom sorts
// use a.value and b.value in these functions, not directly a and b

var comparegXX = function(a, b) {
  try {
    return compare(parseInt(a.value.substr(1), 10), parseInt(b.value.substr(1), 10));
  }
  catch(ex) { return compareMixedTypes(a, b); }
}

var compareMixedTypes = function(a, b) {
  var aType = typeof a.value;
  return aType == typeof b.value ? compare(a.value, b.value) :
    aType == "string" ? -1 : 1;
}

require(["dstore/Memory", "dgrid/OnDemandGrid", "dojo/domReady!"], function (Memory, OnDemandGrid) {

  // populate the store (random values in field2)

  var tbl = [];
  for(var i = 1; i < 21; i++) {
    var item = {id: i};
    item.field1 = "g" + i;
    item.field2 = (i == 1 || Math.random() < 0.2) ? "" : Math.floor(Math.random() * 10);
    tbl.push(item);
  }
	
  var store = new Memory( {data: tbl });

  var grid = new OnDemandGrid({
    collection: store,
    columns:
    {
      id: {},
      field1: {
        sort: comparegXX
      },
      field2: {
        sort: compareMixedTypes
      }
    },
  }, 'grid');
	
  var lastField = null;
  var descending = null;

  grid.doSort = function(e) {
  
    // custom sort of the grid, replaces the default sort
    
    var field = e.sort[0].property;

    if(lastField == field) descending = !descending;
    else {
      lastField = field;
      if(descending == null) descending = e.sort[0].descending;
    }

    var sortFunc = grid.column(field).sort;
		
    if(sortFunc) {
      // calculate the positions of the rows based on the custom compare function,
      // they are stored in the _newPos field, and then the grid is sorted on it
      var tmp = [], tmp2 = {};
      store.forEach(function(item, i) { tmp.push({value: item[field], pos: i}); });
      tmp.sort(sortFunc);
      tmp.forEach(function(item, i) { tmp2[item.pos] = i; });
      store.forEach(function(item, i) { item._newPos = tmp2[i]; });
      grid.set("sort", "_newPos", descending);
    }
    else grid.set("sort", field, descending);
		
    grid.updateSortArrow([{property: field, descending: descending}]);
		
  }

  grid.on("dgrid-sort", function(e) {
    grid.doSort(e);
    e.preventDefault();
  });

  // initial sort of the grid, use this instead of grid.set("sort"...)
  grid.doSort({sort: [{property: "field1", descending: false}]});

  grid.startup();
  
});