#

Jump to Table of Contents

# Example: Dial With Interactive UI

This `Dial` widget example shows the following:

1. A demonstration of a large value range combined with fine increment control.
2. Setting UI strings before rendering
3. Setting configuration attributes
4. Construction-time event subscription allowing Dial to control an interactive UI
5. 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.

hubble
thermosphere
mesosphere
stratosphere
troposphere
ozone
crust
mantle
From Earth to Hubble

### 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.10.3/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>