blob: aff71bf00a883e7fdf48b18152b0f106baf2b3ca [file] [log] [blame]
<!-- The <range-sel-sk> custom element declaration.
Allows selecting a sub-range. The full range is from [0, 100].
[......(=====)........]
Attributes:
begin - Number - The start of the selected range.
end - Number - The end of the selected range.
Events:
range-change - Fired as the sliders move. The detail
of the event contains the begin and end values:
{
begin: 15.0,
end: 50.0,
}
Note that the element properties 'begin' and 'end' don't change
until the sliders stop moving.
range-change-end - Fired when the slider is done moving.
{
begin: 15.0,
end: 50.0,
}
Methods:
None.
-->
<dom-module id="range-sel-sk">
<style>
:host {
display: block;
width: 640px;
height: 40px;
}
#wrapper {
display: block;
position: relative;
width: 600px;
height: 40px;
}
:host,
div {
user-select: none;
-webkit-user-select: none;
}
#begin,
#end {
width: 15px;
height: 38px;
background: #1F78B4;
border: solid 1px #eee;
display: inline-block;
position: absolute;
border-radius: 5px;
}
#begin:hover,
#end:hover {
border: solid 1px black;
}
#fullrange,
#range {
width: 100%;
height: 2px;
background: #ccc;
top: 20px;
display: inline-block;
position: absolute;
left: 10px;
}
#range {
background: #1F78B4;
top: 20px;
left: 15%;
width: 36%;
}
</style>
<template>
<div id=wrapper>
<div id=fullrange></div>
<div id=range></div>
<div id=begin on-track="_handleTrack"></div>
<div id=end on-track="_handleTrack"></div>
</div>
</template>
</dom-module>
<script>
Polymer({
is: "range-sel-sk",
properties: {
begin: {
type: Number,
value: 0,
reflectToAttribute: true,
observer: "_beginChange",
},
end: {
type: Number,
value: 100,
reflectToAttribute: true,
observer: "_endChange",
},
},
ready: function() {
this._setSliderPos(this.$.begin, 0);
this._setSliderPos(this.$.end, 0);
},
_beginChange: function() {
this._setSliderPos(this.$.begin, 0);
this._fireMsg(this.$.begin, 0, "range-change");
},
_endChange: function() {
this._setSliderPos(this.$.end, 0);
this._fireMsg(this.$.end, 0, "range-change");
},
// Clamps the dx so that the sliders don't move beyond
// the ends of the range bar.
_clamp: function(ele, dx) {
if (ele.offsetLeft+dx > this.$.wrapper.clientWidth) {
dx = this.$.wrapper.clientWidth - ele.offsetLeft;
}
if (ele.offsetLeft+dx < 0) {
dx = -ele.offsetLeft;
}
return dx;
},
// Sets the position of slider 'ele' with a position delta of 'dx'.
_setSliderPos: function(ele, dx) {
dx = this._clamp(ele, dx);
ele.style.left = this[ele.id] + "%";
ele.style.transform = "translateX(" + dx + "px)";
this.$.range.style.left = this.begin + "%";
this.$.range.style.width = (this.end - this.begin) + "%";
},
// Fires the 'range-change' custom event with a detail section that
// contains the new begin and end range.
//
// Returns the message detail that was sent.
_fireMsg: function(ele, dx, eventName) {
var msg = {
begin: this.begin,
end: this.end,
};
dx = this._clamp(ele, dx);
msg[ele.id] = 100*(ele.offsetLeft+dx)/this.$.wrapper.clientWidth;
if (msg.begin > msg.end) {
var tmp = msg.begin;
msg.begin = msg.end;
msg.end = tmp;
}
this.fire(eventName, msg);
return msg;
},
_handleTrack: function(e) {
switch(e.detail.state) {
case 'track':
this._setSliderPos(e.target, e.detail.dx);
this._fireMsg(e.target, e.detail.dx, "range-change");
break;
case 'end':
var msg = this._fireMsg(e.target, e.detail.dx, "range-change");
this._fireMsg(e.target, e.detail.dx, "range-change-end");
this.begin = msg.begin;
this.end = msg.end;
this._setSliderPos(this.$.begin, 0);
this._setSliderPos(this.$.end, 0);
break;
}
},
});
</script>