blob: 6a24ebabf6ec10479a35a20413b276a94c81b801 [file] [log] [blame]
<!-- The <sort-sk> custom element declaration.
Allows sorting the members of the indicated element by the values of the
data attributes.
Add children to <sort-sk> that generate click events and that have child
content, such as button or paper-button elements. Add a data-key
attribute to each child element that indicates which data-* attribute the
children should be sorted on.
Note that all sorting is done numerically, unless a data-alpha attribute is
present, in which case the sorting is done alphabetically.
Additionally a single child element can have a data-default attribute with a
value of "up" or "down" to indicate the default sorting that already exists
in the data.
An example usage, that will present two buttons to sort the contents of
div#stuffToBeSorted.
<sort-sk target=stuffToBeSorted>
<paper-button data-key="clustersize"
data-default=down>Cluster Size </paper-button>
<paper-button data-key="stepsize">Step Size </paper-button>
</sort-sk>
<div id=stuffToBeSorted>
<div data-clustersize=10 data-stepsize=0.5></div>
<div data-clustersize=50 data-stepsize=1.2></div>
...
</div>
Attributes:
target - The id of the container element whose children are to be sorted.
node_name - The type of elements that are being sorted. All other elements
will remain unchanged. If the empty string then all child elments are
sorted.
Methods:
None.
Events:
None.
-->
<link rel=import href="/res/imp/bower_components/iron-icon/iron-icon.html">
<link rel=import href="/res/imp/bower_components/iron-icons/iron-icons.html">
<dom-module id="sort-sk">
<template>
<content></content>
</template>
</dom-module>
<script>
(function () {
// The states to move each button through on a click.
var toggle = {
'': 'icons:arrow-drop-down',
'icons:arrow-drop-down': 'icons:arrow-drop-up',
'icons:arrow-drop-up': 'icons:arrow-drop-down'
};
Polymer({
is: 'sort-sk',
properties: {
target: {
type: String,
value: "",
},
node_name: {
type: String,
value: "",
}
},
ready: function () {
// Start by appending a iron-icon to each clickable child and
// registering for the click event.
$$('[data-key]', this).forEach(function (ele) {
var ico = document.createElement('iron-icon');
ico.icon = 'icons:arrow-drop-down';
ico.style.visibility = 'hidden';
Polymer.dom(ele).appendChild(ico);
ele.addEventListener('click', this.clickHandler.bind(this));
}.bind(this));
// Handle a default value if one has been set.
var def = $$$('[data-default]', this);
if (def) {
var defIcon = $$$('iron-icon', def);
defIcon.style.visibility = 'initial';
defIcon.icon = 'icons:arrow-drop-' + def.dataset.default;
}
},
clickHandler: function (e) {
var ele = e.target;
if (ele.nodeName === 'IRON-ICON') {
ele = ele.parentElement;
}
var ico = $$$('iron-icon', ele);
// Set the children elements icons to reflect the new sorting order.
ico.icon = toggle[ico.icon || ''];
ico.style.visibility = 'initial';
$$('[data-key]', this).forEach(function (innerEle) {
if (innerEle.dataset.key !== ele.dataset.key) {
$$$('iron-icon', innerEle).style.visibility = 'hidden';
}
});
// Remember the direction we are sorting in.
var up = ico.icon.indexOf('-up') > -1;
// Are we sorting alphabetically or numerically.
var alpha = ele.dataset.alpha != undefined;
// Sort the children of the element at #target.
var sortBy = ele.dataset.key;
var container = $$$('#' + this.target, this.parentElement);
var elements = [];
var children = container.children;
for (var i = 0; i < children.length; i++) {
var ele = children[i];
if (this.node_name != "" && ele.nodeName != this.node_name) {
continue;
}
var value = ele.dataset[sortBy];
if (!alpha) {
value = +value;
}
elements.push({
value: value,
node: ele
});
}
if (alpha) {
elements.sort(function (x, y) {
if (!up) {
var tmp = x;
x = y;
y = tmp;
}
return x.value == y.value ? 0 : x.value > y.value ? 1 : -1;
});
} else {
elements.sort(function (x, y) {
if (up) {
return x.value - y.value;
} else {
return y.value - x.value;
}
});
}
elements.forEach(function (i) {
container.appendChild(i.node);
});
}
});
}());
</script>