This Dial
widget example shows the following:
- A demonstration of a large value range combined with fine increment control.
- Setting UI strings before rendering
- Setting configuration attributes
- Construction-time event subscription allowing Dial to control an interactive UI
- Calling one of Dial's value change methods from the click of a link.
<a>Hubble</a>
Notice the Dial can traverse the entire 6,000+ pixels of the scene height, but by pulling the handle farther away from the Dial's center while rotating, the user can get 1 pixel movements, without strain. After the dial has focus, the following keys also opperate the Dial, arrow up/down/left/right, page up/down, home, end. The action of these keys can be controlled via Dial's configuration attributes.
Making a Dial Drive an Interactive UI
The valueChange
event of a Dial
can be the means of controlling other UI displayed on a page.
The Markup
Note: be sure to add the yui3-skin-sam
classname to the
page's <body>
element or to a parent element of the widget in order to apply
the default CSS skin. See Understanding Skinning.
<body class="yui3-skin-sam"> <!-- You need this skin class -->
The only markup requirement for the Dial
itself is an element to contain the Dial.
The rest of the markup and CSS in this example is just for the Hubble telescope visualization.
<div id="demo"></div>
The JavaScript
This example builds on previous examples by showing how to modify the visible UI strings before the dial renders.
During instatiation of a Dial, several configuration attributes can be set (see the code-block below); note the construction-time event subscription:
YUI().use('dial', function(Y) { var sceneH = Y.one('#scene').get('region').height, subSea = 450, viewFrameH = Y.one('#view_frame').get('region').height -2, zeroPt = 100, originY = -sceneH + subSea + viewFrameH - zeroPt; Y.one('#scene').setStyle('top', originY + 'px'); /** * The Dial's valueChange event is passed to this. * sets the CSS top value of the pictoral scene of the earth to the hubble. * This scene is an absolute positioned div inside another div with * overflow set to hidden. */ setSceneY = function(e) { Y.one('#scene').setStyle('top', (originY + (e.newVal * 10)) + 'px'); } var dial = new Y.Dial({ min:-35, max:559, stepsPerRevolution:30, value: 0, diameter: 100, minorStep: 1, majorStep: 10, decimalPlaces: 2, strings:{label:'Altitude in Kilometers:', resetStr: 'Reset', tooltipHandle: 'Drag to set'}, // construction-time event subscription after : { valueChange: Y.bind( setSceneY, dial ) } }); dial.render('#demo'); // Function that calls a method in Dial that sets its value to the value of the max config attribute // Other methods available include, // _setToMin(), _resetDial(), _incrMinor(), _decrMinor(), _incrMajor(), _decrMajor(), var setDialToMax = function(e){ e.preventDefault(); this._setToMax(); } // Subscribe to the click of the "Hubble" anchor, passing the dial as the 'this' Y.on('click', setDialToMax, '#a-hubble', dial); });
The Event Handler
Preceding the code that instantiates the Dial
widget, declare the event handler.
We can use the value of the Dial
to do whatever we want, but
in this example the event handler updates the CSS top
property of the pictorial scene <div id="scene">
of Hubble's relationship to Earth.
This scene is moved up or down inside a framing element <div class="viewframe">
that has CSS overflow:hidden;
.
The reason e.newVal
is multiplied by 10
is so that the scene moves 10px for every 1 kilometer of the Dial
's value.
/** * The Dial's valueChange event is passed to this. * sets the CSS top value of the pictoral scene of the earth to the hubble. * This scene is an absolute positioned div inside another div with * overflow set to hidden. */ setSceneY = function(e) { Y.one('#scene').setStyle('top', (originY + (e.newVal * 10)) + 'px'); }
Complete Example Source
<!DOCTYPE HTML> <html> <script src="http://yui.yahooapis.com/3.8.0/build/yui/yui-min.js"></script> <style> #example_container { position:relative; } #demo{ margin:0; position:absolute; top:321px; left:0; } .controls { position:absolute; top:0; left:328px; margin:0 0 0 0; color:#808080; width:300px; } .controls a { color:#4B78D9 !important; cursor:pointer; } .intro-sentence{ font-size: 183%; left: 0; line-height: 0.9em; position: absolute; top: 273px; width: 6em; } #view_frame{ position:relative; height:500px; width:300px; border:solid 1px #cccccc; overflow:hidden; } #scene{position:absolute; left:0; top:-6440px; height:6440px; width:100%; background:url(../assets/dial/images/earth_to_hubble_bkg.png) repeat; } #altitude_mark { border-top:solid 1px #CCCCCC; left:-33px; position:absolute; top:403px; width:30px; } #earth{ position:absolute; left:0; top:5834px; height:214px; width:300px; } #hubble{ position:absolute; left:5px; top:7px; height:393px; width:300px; } #stars{ position:absolute; left:0; top:0; background:url(../assets/dial/images/stars.png) repeat; height:5000px; width:300px; } .label{ text-transform:uppercase; width:100%; letter-spacing:5px; font-family:Verdana; font-size:85%; position:absolute; left:0; text-align:center; } .hubble{ bottom:6023px; color:#612C88; } .thermosphere{ bottom:1290px; color:#5A009D; } .mesosphere{ bottom:840px; color:#570BFF; } .stratosphere{ bottom:540px; color:#006999; } .troposphere{ bottom:477px; color:#036585; } .ozone{ bottom:692px; color:#005AAE; } .crust{ bottom:270px; color:#4F2D00; } .mantle{ bottom:42px; color:#897701; } </style> <body class="yui3-skin-sam"> <!-- You need this skin class --> <div id="example_container"> <div id="view_frame"> <div id="scene"> <div id="stars"></div> <img id="hubble" src="http://yuilibrary.com/yui/docs/assets/dial/images/hubble.png"/> <img id="earth" src="http://yuilibrary.com/yui/docs/assets/dial/images/mountain_earth.png"/> <div class="label hubble">hubble</div> <div class="label thermosphere">thermosphere</div> <div class="label mesosphere">mesosphere</div> <div class="label stratosphere">stratosphere</div> <div class="label troposphere">troposphere</div> <div class="label ozone">ozone</div> <div class="label crust">crust</div> <div class="label mantle">mantle</div> </div> </div> <div class="controls"> <div class="intro-sentence">From Earth to <a id="a-hubble">Hubble</a></div> <div id="altitude_mark"></div> <div id="demo"></div> </div> </div> </body> <script> YUI().use('dial', function(Y) { var sceneH = Y.one('#scene').get('region').height, subSea = 450, viewFrameH = Y.one('#view_frame').get('region').height -2, zeroPt = 100, originY = -sceneH + subSea + viewFrameH - zeroPt; Y.one('#scene').setStyle('top', originY + 'px'); /** * The Dial's valueChange event is passed to this. * sets the CSS top value of the pictoral scene of the earth to the hubble. * This scene is an absolute positioned div inside another div with * overflow set to hidden. */ setSceneY = function(e) { Y.one('#scene').setStyle('top', (originY + (e.newVal * 10)) + 'px'); } var dial = new Y.Dial({ min:-35, max:559, stepsPerRevolution:30, value: 0, diameter: 100, minorStep: 1, majorStep: 10, decimalPlaces: 2, strings:{label:'Altitude in Kilometers:', resetStr: 'Reset', tooltipHandle: 'Drag to set'}, // construction-time event subscription after : { valueChange: Y.bind( setSceneY, dial ) } }); dial.render('#demo'); // Function that calls a method in Dial that sets its value to the value of the max config attribute // Other methods available include, // _setToMin(), _resetDial(), _incrMinor(), _decrMinor(), _incrMajor(), _decrMajor(), var setDialToMax = function(e){ e.preventDefault(); this._setToMax(); } // Subscribe to the click of the "Hubble" anchor, passing the dial as the 'this' Y.on('click', setDialToMax, '#a-hubble', dial); }); </script> </html>