Skip to content

Commit

Permalink
Sorting helpers feature
Browse files Browse the repository at this point in the history
  • Loading branch information
tomivirkki committed Oct 23, 2016
1 parent 7101dae commit 0d8f1f8
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 53 deletions.
6 changes: 0 additions & 6 deletions test/array-data-source.html
Expand Up @@ -91,12 +91,6 @@
expect(grid.size).to.equal(0);
});

it('should handle string values', function() {
grid.items = 'FOO';
expect(grid.size).to.equal(3);
expect(getCell(0, 0).item).to.equal('F');
});

it('should set array data source', function() {
expect(grid.dataSource).to.equal(grid._arrayDataSource);
});
Expand Down
27 changes: 26 additions & 1 deletion vaadin-grid-array-data-source-behavior.html
Expand Up @@ -26,11 +26,36 @@
},

_arrayDataSource: function(opts, cb) {
var items = this.items || [];
var items = (this.items || []).slice(0);
items.sort(this._multiSort.bind(this));

var start = opts.page * opts.pageSize;
var end = start + opts.pageSize;
var slice = items.slice(start, end);
cb(slice, items.length);
},

_multiSort: function(a, b) {
return (this._sorters || []).map(function(sort) {
if (sort.direction === 'asc') {
return this._compare(Polymer.Base.get(sort.path, a), Polymer.Base.get(sort.path, b));
} else if (sort.direction === 'desc') {
return this._compare(Polymer.Base.get(sort.path, b), Polymer.Base.get(sort.path, a));
}
return 0;
}, this).reduce(function firstNonZeroValue(p, n) {
return p ? p : n;
}, 0);
},

_compare: function(a, b) {
if (a < b) {
return -1;
}
if (a > b) {
return 1;
}
return 0;
}

};
Expand Down
38 changes: 38 additions & 0 deletions vaadin-grid-cell-click-behavior.html
@@ -0,0 +1,38 @@
<script>
window.vaadin = window.vaadin || {};
vaadin.elements = vaadin.elements || {};
vaadin.elements.grid = vaadin.elements.grid || {};

vaadin.elements.grid.CellClickBehavior = {

listeners: {
'click': '_onClick'
},

// we need to listen to click instead of tap because on mobile safari, the
// document.activeElement has not been updated (focus has not been shifted)
// yet at the point when tap event is being executed.
_onClick: function(e) {
// Prevent item action if cell itself is not focused.
if (!this._isFocusable(Polymer.dom(e).localTarget)) {
if (this._cellClick) {
this._cellClick(e);
}
}
},

_isFocusable: function(target) {
if (Polymer.Settings.useNativeShadow) {
// https://nemisj.com/focusable/
// tabIndex is not reliable in IE.
return target.tabIndex >= 0;
} else {
// unreliable with Shadow, document.activeElement doesn't go inside
// the shadow root.
// Also, atleast iOS doesn't seem to focus links or buttons.
var focusableElements = ['A', 'BUTTON'];
return target.contains(Polymer.dom(document.activeElement).node) || focusableElements.indexOf(target.tagName) > -1;
}
}
};
</script>
37 changes: 21 additions & 16 deletions vaadin-grid-data-source-behavior.html
Expand Up @@ -162,23 +162,25 @@
var firstVisiblePage = this._getPageForIndex(this.$.scroller.firstVisibleIndex + this.$.scroller._vidxOffset);

return [firstVisiblePage].concat(
this.$.scroller._physicalItems
.filter(function(row) { return row.index; })
.map(function(row) {
return this._getPageForIndex(row.index);
}.bind(this)))
.reduce(function(prev, curr) {
if (prev.indexOf(curr) === -1) {
prev.push(curr);
}
this.$.scroller._physicalItems
.filter(function(row) {
return row.index;
})
.map(function(row) {
return this._getPageForIndex(row.index);
}.bind(this)))
.reduce(function(prev, curr) {
if (prev.indexOf(curr) === -1) {
prev.push(curr);
}

return prev;
}, []);
return prev;
}, []);
},

_updateItems: function(page, items) {
for(var i=0;i<this.pageSize;i++) {
var index = page*this.pageSize + i;
for (var i = 0; i < this.pageSize; i++) {
var index = page * this.pageSize + i;
var row = this.$.scroller._virtualIndexToItem[index];
if (row) {
this._updateItem(row, items[i]);
Expand All @@ -204,12 +206,15 @@
},

_loadPage: function(page) {
if (this._cache[page]) {
} else {
if (this._cache[page]) {} else {
// make sure same page isn't requested multiple times.
if (!this._pendingRequests[page] && this.dataSource) {
this._pendingRequests[page] = true;
var opts = {page: page, pageSize: this.pageSize};
var opts = {
page: page,
pageSize: this.pageSize,
sortOrder: this._mapSorters()
};
this.dataSource(opts, function(items) {
this._cache[page] = items;
delete this._pendingRequests[page];
Expand Down
161 changes: 161 additions & 0 deletions vaadin-grid-sort-behavior.html
@@ -0,0 +1,161 @@
<link rel="import" href="vaadin-grid-cell-click-behavior.html">

<dom-module id="vaadin-grid-sorter">
<template>
<style>
:host {
display: inline-flex;
justify-content: space-between;
cursor: pointer;
}

#indicators {
position: relative;
padding-right: 8px;
}

#indicators[direction=desc] #direction {
transform: rotateZ(180deg);
}

#indicators:not([direction]) {
opacity: 0.2;
}

#order {
position: absolute;
right: 0;
top: 0;
transform: translateY(-4px) scale(0.7);
}

</style>

<content></content>
<div id="indicators" direction$="[[direction]]">
<div id="direction"></div>
<div id="order">[[_getDisplayOrder(_order)]]</div>
</div>

</template>
<script>
Polymer({
is: 'vaadin-grid-sorter',

properties: {

path: String,

direction: {
type: String,
reflectToAttribute: true,
notify: true,
value: null
},

_order: Number

},

observers: [
'_parametersChanged(path, direction)'
],

behaviors: [
vaadin.elements.grid.CellClickBehavior
],

attached: function() {
this._fireChange();
},

_parametersChanged: function(grid, path, direction) {
this._fireChange();
},

_fireChange: function() {
this.fire('sorter-changed');
},

_getDisplayOrder: function(order) {
return order === null ? '' : order + 1;
},

_cellClick: function(e) {
if (this.direction === 'asc') {
this.direction = 'desc';
} else if (this.direction === 'desc') {
this.direction = null;
} else {
this.direction = 'asc';
}
}

});
</script>
</dom-module>

<script>
window.vaadin = window.vaadin || {};
vaadin.elements = vaadin.elements || {};
vaadin.elements.grid = vaadin.elements.grid || {};

vaadin.elements.grid.SortBehavior = {

properties: {

_sorters: {
type: Array,
value: function() {
return [];
}
}

},

listeners: {
'sorter-changed': '_onSorterChanged'
},

_onSorterChanged: function(e) {
var sorter = e.target;

this._removeArrayItem(this._sorters, sorter);
if (sorter.direction) {
this._sorters.unshift(sorter);
}

sorter._order = null;
this._sorters.forEach(function(sorter, index) {
sorter._order = this._sorters.length > 1 ? index : null;
}, this);

e.stopPropagation();

this.fire('sort-order-changed', {
sortOrder: this._mapSorters()
});

if (this.dataSource) {
this.clearCache();
}
},

_mapSorters: function() {
return this._sorters.map(function(sorter) {
return {
path: sorter.path,
direction: sorter.direction
};
});
},

_removeArrayItem: function(array, item) {
var index = array.indexOf(item);
if (index > -1) {
array.splice(index, 1);
}
},

};
</script>
38 changes: 9 additions & 29 deletions vaadin-grid-table-cell.html
@@ -1,3 +1,5 @@
<link rel="import" href="vaadin-grid-cell-click-behavior.html">

<dom-module id="vaadin-grid-table-cell"></dom-module>
<dom-module id="vaadin-grid-table-header-cell"></dom-module>
<dom-module id="vaadin-grid-table-footer-cell"></dom-module>
Expand Down Expand Up @@ -223,38 +225,16 @@

behaviors: [
Polymer.Templatizer,
vaadinGridTableCellBehavior
vaadinGridTableCellBehavior,
vaadin.elements.grid.CellClickBehavior
],

listeners: {
'click': '_onClick'
},

_isFocusable: function(target) {
if (Polymer.Settings.useNativeShadow) {
// https://nemisj.com/focusable/
// tabIndex is not reliable in IE.
return target.tabIndex >= 0;
} else {
// unreliable with Shadow, document.activeElement doesn't go inside
// the shadow root.
// Also, atleast iOS doesn't seem to focus links or buttons.
var focusableElements = ['A', 'BUTTON'];
return target.contains(Polymer.dom(document.activeElement).node) || focusableElements.indexOf(target.tagName) > -1;
}
},

// we need to listen to click instead of tap because on mobile safari, the
// document.activeElement has not been updated (focus has not been shifted)
// yet at the point when tap event is being executed.
_onClick: function(e) {
// Prevent item action if cell itself is not focused.
if (!this._isFocusable(Polymer.dom(e).localTarget)) {
this.fire('cell-click', {
model: this.instance
});
}
_cellClick: function() {
this.fire('cell-click', {
model: this.instance
});
}

});

Polymer({
Expand Down
4 changes: 3 additions & 1 deletion vaadin-grid.html
Expand Up @@ -5,6 +5,7 @@
<link rel="import" href="vaadin-grid-data-source-behavior.html">
<link rel="import" href="vaadin-grid-array-data-source-behavior.html">
<link rel="import" href="vaadin-grid-selection-behavior.html">
<link rel="import" href="vaadin-grid-sort-behavior.html">

<dom-module id="vaadin-grid">
<style>
Expand Down Expand Up @@ -60,7 +61,8 @@
vaadin.elements.grid.RowDetailsBehavior,
vaadin.elements.grid.DataSourceBehavior,
vaadin.elements.grid.ArrayDataSourceBehavior,
vaadin.elements.grid.SelectionBehavior
vaadin.elements.grid.SelectionBehavior,
vaadin.elements.grid.SortBehavior
],

observers: ['_columnsChanged(columns.*)'],
Expand Down

0 comments on commit 0d8f1f8

Please sign in to comment.