{{>slider-from-markup-css}}
<div class="intro">
<p>This example illustrates a few points:</p>
<ol>
<li>How to create a Slider using existing markup</li>
<li>How to disable a Slider</li>
<li>How to use an image sprite to create a custom Slider skin</li>
</ol>
<p>The visualization of the Slider is based on the volume control in Mac OS X 10.5, with additional controls included for illustration. <strong>Click on the speaker icon to show the Slider</strong>.</p>
</div>
<div class="example">
{{>slider-from-markup-html}}
</div>
<script>
{{>slider-from-markup-js}}
</script>
<h3 id="prog_enh">Progressive Enhancement</h3>
<p>The <a href="http://en.wikipedia.org/wiki/Progressive_enhancement">Progressive Enhancement</a> strategy recommends that your page not contain markup that will only be useful in cases where JavaScript is available. For this reason, Slider does not include an `HTML_PARSER` to reuse existing markup. However, it is possible to override a couple methods to accomplish the task.</p>
<p>The starting markup for the volume control area is as follows:</p>
```
<div id="volume_control" class="volume-hide">
<label for="volume">volume</label><input type="text" size="3" maxlength="3" name="volume" id="volume" value="50">
<button type="button" id="volume_icon" class="level_2" title="Open volume slider"><p>Open</p></button>
<span id="volume_slider">
<span class="yui3-slider-rail">
<span class="yui3-slider-thumb"><img src="{{componentAssets}}/images/sprite.png" height="384" width="31"></span>
</span>
</span>
<label for="mute"><input type="checkbox" id="mute"> mute</label>
</div>
```
<p>To tell the Slider to use the existing rail and thumb elements, override the `renderRail` and `renderThumb` methods.</p>
```
var volume = new Y.Slider({
axis : 'y',
min : 100, // reverse min and max to make the top
max : 0, // equal 100 and the bottom 0
value : 50,
length: '105px'
});
// Override renderRail to just return the existing rail node
volume.renderRail = function () {
return Y.one( "#volume_slider span.yui3-slider-rail" );
};
// Override renderThumb to just return the existing thumb node
volume.renderThumb = function () {
return this.rail.one( "span.yui3-slider-thumb" );
};
volume.render( "#volume_slider" );
```
<h3 id="syncui">Hide and show the Slider</h3>
<p>By default, we want the Slider to be hidden until the user clicks on the speaker icon. However, we want to support muting or changing the value of the Slider while it is hidden.</p>
```
var control = Y.one('#volume_control'),
icon = Y.one('#volume_icon'),
open = false;
function showHideSlider(e) {
control.toggleClass('volume-hide');
open = !open;
if (e) {
e.preventDefault();
}
}
icon.on('click', showHideSlider);
// Also support hiding the Slider when the user clicks outside the
// Slider element.
function handleDocumentClick(e) {
if (open && !icon.contains(e.target) &&
!volume.get('boundingBox').contains(e.target)) {
showHideSlider();
}
}
Y.one( 'doc' ).on('click', handleDocumentClick );
```
<h3 id="demo_mute">Mute and unmute</h3>
<p>We want to disable the Slider and input and set the value to 0 if a user checks the mute checkbox. The value should be returned to the last assigned value when unmuted. To disable the Slider, set its `disabled` attribute to `true`.</p>
```
var volInput = Y.one('#volume'),
mute = Y.one('#mute'),
beforeMute = 0;
function muteVolume(e) {
// Set disabled to false if currently true; true if currently false
var disabled = !volume.get('disabled');
volume.set('disabled', disabled);
if (disabled) {
beforeMute = volume.getValue();
volume.setValue(0);
volInput.set('disabled','disabled');
} else {
volume.setValue(beforeMute);
volInput.set('disabled','');
}
}
mute.on('click', muteVolume);
```
<h3>Skinning and CSS</h3>
<img id="demo_sprite" src="{{componentAssets}}/images/sprite.png" height="384" width="31" alt="Sprite of all custom image resources for this example">
<p>We'll be using the image sprite to the left to create a custom skin. In this design, to keep things simple, the Slider's container and end caps are all rendered together at the bottom of the sprite.</p>
<p>Slider's thumb range is constrained by the rail element, so it wouldn't be appropriate to use this image as the rail's background&#8212;the thumb would slide off the ends. Instead, the rail image is assigned as the background to the Slider's containing element `#volume_slider`. Then the default skin background image is removed on the rail.</p>
```
/* rail image on the containing box rather than the rail element */
#volume_slider {
background: url("assets/images/sprite.png") no-repeat 0 -259px;
height: 116px;
width: 31px;
padding-top: 9px;
}
#volume_slider .yui3-slider-rail {
background-image: none;
width: 31px;
}
#volume_slider .yui3-slider-thumb {
height: 17px;
width: 31px;
overflow: hidden;
}
#volume_slider .yui3-slider-thumb img {
position: absolute;
top: -225px;
}
#volume_slider .yui3-slider-disabled .yui3-slider-thumb img {
top: -242px;
}
```
<p>You can see the full CSS and JavaScript for the other controls in the <a href="#full_code_listing">Full Code Listing</a> below.</p>
<h3 id="full_code_listing">Full Code Listing</h3>
<p>Here is the full markup, CSS, and JavaScript for the entire example, including the volume input and mute controls, and CSS for placing the Slider and setting up the volume icon sprite positioning.</p>
<h4>Markup</h4>
```
{{>slider-from-markup-html}}
```
<h4 id="full_js">JavaScript</h4>
```
{{>slider-from-markup-js}}
```
<h4 id="full_css">CSS</h4>
```
{{>slider-from-markup-css}}
```