| <!-- 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> |
| |