5
<title>Example: Creating a Slider from Existing Markup</title>
6
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Maven+Pro:400,700">
7
<link rel="stylesheet" href="../../build/cssgrids/grids-min.css">
8
<link rel="stylesheet" href="../assets/css/main.css">
9
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
10
<script src="../../build/yui/yui-min.js"></script>
15
<h1>Example: Creating a Slider from Existing Markup</h1>
20
<div class="yui3-u-3-4">
22
<div class="content"><style scoped>
25
border: 1px solid #999;
36
background: url(../assets/slider/images/sprite.png) repeat-x 0 0;
40
#volume_control label {
47
border: 1px inset #999;
55
/* Support open/close action for the slider */
56
#demo .volume-hide #volume_slider {
61
background: url(../assets/slider/images/sprite.png) no-repeat 0 -25px;
68
/* move the button text offscreen left */
74
* adjust the speaker icon sprite in accordance with volume level and
77
#demo .volume-hide .level_0 { background-position: 0 -25px; }
78
#demo .volume-hide .level_1 { background-position: 0 -50px; }
79
#demo .volume-hide .level_2 { background-position: 0 -75px; }
80
#demo .volume-hide .level_3 { background-position: 0 -100px; }
83
#demo .level_0:hover {
84
background-position: 0 -125px;
87
#demo .level_1:hover {
88
background-position: 0 -150px;
91
#demo .level_2:hover {
92
background-position: 0 -175px;
95
#demo .level_3:hover {
96
background-position: 0 -200px;
104
/* rail image on the containing box rather than the rail element */
106
background: url(../assets/slider/images/sprite.png) no-repeat 0 -259px;
113
#volume_slider .yui3-slider-rail {
114
background-image: none;
118
#volume_slider .yui3-slider-thumb {
124
#volume_slider .yui3-slider-thumb img {
129
#volume_slider .yui3-slider-disabled .yui3-slider-thumb img {
141
<p>This example illustrates a few points:</p>
143
<li>How to create a Slider using existing markup</li>
144
<li>How to disable a Slider</li>
145
<li>How to use an image sprite to create a custom Slider skin</li>
148
<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>
151
<div class="example">
152
<div id="demo" class="yui3-skin-sam">
154
<div id="volume_control" class="volume-hide">
155
<label for="volume">volume</label><input type="text" size="3" maxlength="3" name="volume" id="volume" value="50">
156
<button type="button" id="volume_icon" class="level_2" title="Open volume slider"><p>Open</p></button>
157
<span id="volume_slider">
158
<span class="yui3-slider-rail">
159
<span class="yui3-slider-thumb"><img src="../assets/slider/images/sprite.png" height="384" width="31"></span>
162
<label for="mute"><input type="checkbox" id="mute"> mute</label>
165
<div class="demo-content">
166
<p>Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</p>
167
<p>Phasellus wisi purus, interdum vitae, rutrum accumsan, viverra in, velit. Sed enim risus, congue non, tristique in, commodo eu, metus. Aenean tortor mi, imperdiet id, gravida eu, posuere eu, felis.</p>
173
YUI().use("slider", function (Y) {
175
var control = Y.one('#volume_control'),
176
volInput = Y.one('#volume'),
177
icon = Y.one('#volume_icon'),
178
mute = Y.one('#mute'),
185
Y.one("#volume_slider").setStyle('left',icon.get('offsetLeft')+'px');
187
volume = new Y.Slider({
195
volume.renderRail = function () {
196
return Y.one( "#volume_slider span.yui3-slider-rail" );
198
volume.renderThumb = function () {
199
return this.rail.one( "span.yui3-slider-thumb" );
202
volume.render( "#volume_slider" );
204
// Initialize event listeners
205
volume.after('valueChange', updateInput);
206
volume.after('valueChange', updateIcon);
208
mute.on('click', muteVolume);
211
keydown : handleInput,
215
icon.on('click', showHideSlider);
217
Y.one( 'doc' ).on('click', handleDocumentClick );
220
function updateInput(e) {
221
if (e.src !== 'KEY') {
222
volInput.set('value',e.newVal);
226
function updateIcon(e) {
227
var newLevel = e.newVal && Math.ceil(e.newVal / 34);
229
if (level !== newLevel) {
230
icon.replaceClass('level_'+level, 'level_'+newLevel);
235
function muteVolume(e) {
236
var disabled = !volume.get('disabled');
237
volume.set('disabled', disabled);
240
beforeMute = volume.getValue();
242
volInput.set('disabled','disabled');
244
volume.setValue(beforeMute);
245
volInput.set('disabled','');
249
function handleInput(e) {
250
// Allow only numbers and various other control keys
251
if (e.keyCode > 57) {
256
function updateVolume(e) {
257
// delay input processing to give the user time to type
262
wait = Y.later(400, null, function () {
263
var value = parseInt(volInput.get('value'),10) || 0;
266
volInput.set('value', 100);
270
volume.setValue( value );
274
function showHideSlider(e) {
275
control.toggleClass('volume-hide');
283
function handleDocumentClick(e) {
284
if (open && !icon.contains(e.target) &&
285
!volume.get('boundingBox').contains(e.target)) {
294
<h3 id="prog_enh">Progressive Enhancement</h3>
295
<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 <code>HTML_PARSER</code> to reuse existing markup. However, it is possible to override a couple methods to accomplish the task.</p>
297
<p>The starting markup for the volume control area is as follows:</p>
299
<pre class="code prettyprint"><div id="volume_control" class="volume-hide">
300
<label for="volume">volume</label><input type="text" size="3" maxlength="3" name="volume" id="volume" value="50">
301
<button type="button" id="volume_icon" class="level_2" title="Open volume slider"><p>Open</p></button>
303
<span id="volume_slider">
304
<span class="yui3-slider-rail">
305
<span class="yui3-slider-thumb"><img src="../assets/slider/images/sprite.png" height="384" width="31"></span>
309
<label for="mute"><input type="checkbox" id="mute"> mute</label>
310
</div></pre>
313
<p>To tell the Slider to use the existing rail and thumb elements, override the <code>renderRail</code> and <code>renderThumb</code> methods.</p>
315
<pre class="code prettyprint">var volume = new Y.Slider({
316
axis : 'y',
317
min : 100, // reverse min and max to make the top
318
max : 0, // equal 100 and the bottom 0
320
length: '105px'
323
// Override renderRail to just return the existing rail node
324
volume.renderRail = function () {
325
return Y.one( "#volume_slider span.yui3-slider-rail" );
327
// Override renderThumb to just return the existing thumb node
328
volume.renderThumb = function () {
329
return this.rail.one( "span.yui3-slider-thumb" );
332
volume.render( "#volume_slider" );</pre>
335
<h3 id="syncui">Hide and show the Slider</h3>
336
<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>
338
<pre class="code prettyprint">var control = Y.one('#volume_control'),
339
icon = Y.one('#volume_icon'),
342
function showHideSlider(e) {
343
control.toggleClass('volume-hide');
351
icon.on('click', showHideSlider);
353
// Also support hiding the Slider when the user clicks outside the
354
// Slider element.
355
function handleDocumentClick(e) {
356
if (open && !icon.contains(e.target) &&
357
!volume.get('boundingBox').contains(e.target)) {
362
Y.one( 'doc' ).on('click', handleDocumentClick );</pre>
365
<h3 id="demo_mute">Mute and unmute</h3>
366
<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 <code>disabled</code> attribute to <code>true</code>.</p>
368
<pre class="code prettyprint">var volInput = Y.one('#volume'),
369
mute = Y.one('#mute'),
372
function muteVolume(e) {
373
// Set disabled to false if currently true; true if currently false
374
var disabled = !volume.get('disabled');
375
volume.set('disabled', disabled);
378
beforeMute = volume.getValue();
380
volInput.set('disabled','disabled');
382
volume.setValue(beforeMute);
383
volInput.set('disabled','');
387
mute.on('click', muteVolume);</pre>
390
<h3>Skinning and CSS</h3>
391
<img id="demo_sprite" src="../assets/slider/images/sprite.png" height="384" width="31" alt="Sprite of all custom image resources for this example">
392
<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>
394
<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—the thumb would slide off the ends. Instead, the rail image is assigned as the background to the Slider's containing element <code>#volume_slider</code>. Then the default skin background image is removed on the rail.</p>
396
<pre class="code prettyprint">/* rail image on the containing box rather than the rail element */
398
background: url("assets/images/sprite.png") no-repeat 0 -259px;
404
#volume_slider .yui3-slider-rail {
405
background-image: none;
409
#volume_slider .yui3-slider-thumb {
415
#volume_slider .yui3-slider-thumb img {
420
#volume_slider .yui3-slider-disabled .yui3-slider-thumb img {
425
<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>
428
<h3 id="full_code_listing">Full Code Listing</h3>
429
<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>
432
<pre class="code prettyprint"><div id="demo" class="yui3-skin-sam">
434
<div id="volume_control" class="volume-hide">
435
<label for="volume">volume</label><input type="text" size="3" maxlength="3" name="volume" id="volume" value="50">
436
<button type="button" id="volume_icon" class="level_2" title="Open volume slider"><p>Open</p></button>
437
<span id="volume_slider">
438
<span class="yui3-slider-rail">
439
<span class="yui3-slider-thumb"><img src="../assets/slider/images/sprite.png" height="384" width="31"></span>
442
<label for="mute"><input type="checkbox" id="mute"> mute</label>
445
<div class="demo-content">
446
<p>Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</p>
447
<p>Phasellus wisi purus, interdum vitae, rutrum accumsan, viverra in, velit. Sed enim risus, congue non, tristique in, commodo eu, metus. Aenean tortor mi, imperdiet id, gravida eu, posuere eu, felis.</p>
449
</div></pre>
452
<h4 id="full_js">JavaScript</h4>
453
<pre class="code prettyprint">YUI().use("slider", function (Y) {
455
var control = Y.one('#volume_control'),
456
volInput = Y.one('#volume'),
457
icon = Y.one('#volume_icon'),
458
mute = Y.one('#mute'),
465
Y.one("#volume_slider").setStyle('left',icon.get('offsetLeft')+'px');
467
volume = new Y.Slider({
468
axis : 'y',
472
length: '105px'
475
volume.renderRail = function () {
476
return Y.one( "#volume_slider span.yui3-slider-rail" );
478
volume.renderThumb = function () {
479
return this.rail.one( "span.yui3-slider-thumb" );
482
volume.render( "#volume_slider" );
484
// Initialize event listeners
485
volume.after('valueChange', updateInput);
486
volume.after('valueChange', updateIcon);
488
mute.on('click', muteVolume);
491
keydown : handleInput,
495
icon.on('click', showHideSlider);
497
Y.one( 'doc' ).on('click', handleDocumentClick );
499
// Support functions
500
function updateInput(e) {
501
if (e.src !== 'KEY') {
502
volInput.set('value',e.newVal);
506
function updateIcon(e) {
507
var newLevel = e.newVal && Math.ceil(e.newVal / 34);
509
if (level !== newLevel) {
510
icon.replaceClass('level_'+level, 'level_'+newLevel);
515
function muteVolume(e) {
516
var disabled = !volume.get('disabled');
517
volume.set('disabled', disabled);
520
beforeMute = volume.getValue();
522
volInput.set('disabled','disabled');
524
volume.setValue(beforeMute);
525
volInput.set('disabled','');
529
function handleInput(e) {
530
// Allow only numbers and various other control keys
531
if (e.keyCode > 57) {
536
function updateVolume(e) {
537
// delay input processing to give the user time to type
542
wait = Y.later(400, null, function () {
543
var value = parseInt(volInput.get('value'),10) || 0;
545
if (value > 100) {
546
volInput.set('value', 100);
550
volume.setValue( value );
554
function showHideSlider(e) {
555
control.toggleClass('volume-hide');
563
function handleDocumentClick(e) {
564
if (open && !icon.contains(e.target) &&
565
!volume.get('boundingBox').contains(e.target)) {
573
<h4 id="full_css">CSS</h4>
574
<pre class="code prettyprint"><style scoped>
577
border: 1px solid #999;
581
#demo .demo-content {
588
background: url(../assets/slider/images/sprite.png) repeat-x 0 0;
592
#volume_control label {
599
border: 1px inset #999;
607
/* Support open/close action for the slider */
608
#demo .volume-hide #volume_slider {
613
background: url(../assets/slider/images/sprite.png) no-repeat 0 -25px;
620
/* move the button text offscreen left */
622
text-indent: -9999px;
626
* adjust the speaker icon sprite in accordance with volume level and
629
#demo .volume-hide .level_0 { background-position: 0 -25px; }
630
#demo .volume-hide .level_1 { background-position: 0 -50px; }
631
#demo .volume-hide .level_2 { background-position: 0 -75px; }
632
#demo .volume-hide .level_3 { background-position: 0 -100px; }
635
#demo .level_0:hover {
636
background-position: 0 -125px;
639
#demo .level_1:hover {
640
background-position: 0 -150px;
643
#demo .level_2:hover {
644
background-position: 0 -175px;
647
#demo .level_3:hover {
648
background-position: 0 -200px;
656
/* rail image on the containing box rather than the rail element */
658
background: url(../assets/slider/images/sprite.png) no-repeat 0 -259px;
665
#volume_slider .yui3-slider-rail {
666
background-image: none;
670
#volume_slider .yui3-slider-thumb {
676
#volume_slider .yui3-slider-thumb img {
681
#volume_slider .yui3-slider-disabled .yui3-slider-thumb img {
690
</style></pre>
696
<div class="yui3-u-1-4">
697
<div class="sidebar">
701
<div class="sidebox">
703
<h2 class="no-toc">Examples</h2>
707
<ul class="examples">
710
<li data-description="The basics of setting up a horizontal and vertical Slider">
711
<a href="slider-basic.html">Basic Sliders</a>
716
<li data-description="Creating a vertical Slider from existing markup">
717
<a href="slider-from-markup.html">Creating a Slider from Existing Markup</a>
722
<li data-description="Specifying an alternate skin for a Slider instance">
723
<a href="slider-skin.html">Alternate Skins</a>
739
<div class="sidebox">
741
<h2 class="no-toc">Examples That Use This Component</h2>
745
<ul class="examples">
754
<li data-description="Shows how to use Overlay's constrainment support, to limit the XY value which can be set for an Overlay.">
755
<a href="../overlay/overlay-constrain.html">Constrain Support</a>
760
<li data-description="Use StyleSheet to adjust the CSS rules applying a page theme from user input">
761
<a href="../stylesheet/stylesheet-theme.html">Adjusting a Page Theme on the Fly</a>
766
<li data-description="Example Photo Browser application.">
767
<a href="../dd/photo-browser.html">Photo Browser</a>
780
<script src="../assets/vendor/prettify/prettify-min.js"></script>
781
<script>prettyPrint();</script>