Anybody know a good snippet for interactive slider?

I’m looking for 5-radio button replacement. The user should be able to slide a slider between values from 0 to a 100. Text will appear under it that will say “I strongly agree” “I agree somewhat” “I am indifferent” “I disagree” “I strongly disagree” depending on the values of the slider (they should change in real-time).

Unfortunately I do not have the skill to make one, especially one that has a good browser-compatibility.

Does anyone know any good snippets? I’ll keep searching on google and post back if I find one.

Thanks all

jQuery’s Slider would help to complete this project.

I disagree though about the text values only appearing based on the slider position, as that’s strongly leaning in the mystery meat direction. What would work better is for the other unchosen text values to be partly visible, but only as a light-grey colour.

This is really easy to do with jQuery UI, as most of your requirements are covered by its slider. I made a [URL=“http://ratherodd.com/tests/jquerylikert.html”]quick example.

Sorry Raffles but I don’t see your quick example working in Chrome.

Here’s one that I ran up a few minutes ago.

Here’s the html code for the slider, and below it the list of choices


<div class="slider">
    <ul>
        <li>I strongly agree</li>
        <li>I agree somewhat</li>
        <li>I am indifferent</li>
        <li>I disagree</li>
        <li>I strongly disagree</li>
    </ul>
</div>

The CSS to spread the choices out along one line is:


.slider ul { margin-left: 0; padding-left: 0; }
.slider li { float: left; margin-left: 0; padding-left: 0; list-style-type: none; width: 20&#37;; }
.slider li { color: #ccc; }
.slider li.selected { color: black; }

The scripting code mostly relates to changing the color of the choice that’s within range:


$(function () {
    $('.slider').slider({
        change: function () {
            $('#slider li').each(function (i) {
                $(this).removeClass('selected');
                var pos = parseInt($('#slider').slider('option', 'value') / 20, 10);
                if (pos === i) {
                    $(this).addClass('selected');
                }
            });
        }
    });
    $('.slider li:first').addClass('selected');
});

You can add also into the change section, code to update a hidden field in a form.

Here’s the working example:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
.slider ul { color: #ccc; margin-left: 0; padding-left: 0; }
.slider li { float: left; margin-left: 0; padding-left: 0; list-style-type: none; width: 20%; }
.slider li.selected { color: black; }
</style>
<link type="text/css" rel="stylesheet" href="http://jqueryui.com/latest/themes/base/ui.all.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"> </script>
<script type="text/javascript" src="http://jqueryui.com/latest/ui/ui.core.js"> </script>
<script type="text/javascript" src="http://jqueryui.com/latest/ui/ui.slider.js"> </script>

</head>
<body>
<div class="slider">
    <ul>
        <li>I strongly agree</li>
        <li>I agree somewhat</li>
        <li>I am indifferent</li>
        <li>I disagree</li>
        <li>I strongly disagree</li>
    </ul>
</div>
<script type="text/javascript">
$(function () {
    $('.slider').slider({
        change: function () {
            $('#slider li').each(function (i) {
                $(this).removeClass('selected');
                var pos = parseInt($('#slider').slider('option', 'value') / 20, 10);
                if (pos === i) {
                    $(this).addClass('selected');
                }
            });
        }
    });
    $('.slider li:first').addClass('selected');
});
</script>
</body>
</html>

I agree with pmw57, so I changed my example to reflect this.

$(document).ready(function() {
  var slider = $('#slider'), scale = $('#scale');
  slider.slider({
   slide: function(event, ui) {
     var spans = $('span', scale);
     spans.removeClass('chosen');
     spans.eq(Math.floor((ui.value / 20.01))).attr('class', 'chosen');
     a.text(ui.value);
   }
  });
  var a = slider.find('a');
  a.text('0');
});
#slider, #scale {
  width:240px;
  margin:50px auto;
  text-align:center
}
#scale {
  width:auto;
}
#scale span {
  color:#AAA; margin:20px;
}
#scale .chosen {
  color:#000
}
#slider a {
  text-decoration:none;
  font:normal 10px sans-serif;
  height:1.6em;
  width:2em;
  padding-top:0.4em
}
<div id="slider"></div>
<p id="scale"><span>Strongly disagree</span><span>Disagree</span><span>Neutral</span><span>Agree</span><span>Strongly agree</span></p>

Paul’s HTML is more semantic though.

Edit:

Yeah, it stopped working because I played with it directly on the server… schoolboy error. :slight_smile:

Paul, I gave your example a go. BTW, there are a couple of typos where it should be .slider, not #slider. Also I think the “slide” event is better than “change”, as the colours only change when the mouse button is released when you use “change”.

Thank you both Raffles & pmw57! Much appreciated :slight_smile:

Okay I have two new questions

  1. I’m trying to make multiple sliders. I thought I would be able to do this but I’m having trouble separating the “this is unique for every slider” from the “all sliders have this”. For instance, the CSS refers to id’s. If I change those #ids to .classes to apply to every slider, then the javascript messes up. I don’t know how to fix the javascript because there’s plenty inside that script I do not understand. This part especially:
var slider = $('.slider'), scale = $('.scale');
  slider.slider({
   slide: function(event, ui) {
     var spans = $('span', scale)

Is it possible to do without having to copy paste the javascript AND css for every new slider?

  1. How do I style the little slider (the actual thing that you slide. the button.). I’m assuming the javascript automatically creates it. I don’t know the id/class for it. For some reason it’s really skinny when I put it in my site. The text overflows.

Thanks again!

There. I managed to make a code with multiple sliders :slight_smile:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Likert Scale JavaScript Slider</title>
<link type="text/css" href="http://jqueryui.com/latest/themes/base/ui.all.css" rel="stylesheet">
<style type="text/css">
#slider, #scale {
  width:240px;
  margin:50px auto;
  text-align:center;
}
#scale {
  width:auto;
}
#scale span {
  color:#AAA; margin:20px;
}
#scale .chosen {
  color:#000
}
#slider a {
  text-decoration:none;
  font:normal 10px sans-serif;
  height:1.6em;
  width:2em;
  padding-top:0.4em
}


#slider2, #scale2 {
  width:240px;
  margin:50px auto;
  text-align:center;
}
#scale2 {
  width:auto;
}
#scale2 span {
  color:#AAA; margin:20px;
}
#scale2 .chosen {
  color:#000
}
#slider2 a {
  text-decoration:none;
  font:normal 10px sans-serif;
  height:1.6em;
  width:2em;
  padding-top:0.4em
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
						   
						   
						   
 
  var slider = $('#slider'), scale = $('#scale');
  slider.slider({
   slide: function(event, ui) {
     var spans = $('span', scale);
     spans.removeClass('chosen');
     spans.eq(Math.floor((ui.value / 20.01))).attr('class', 'chosen');
     a.text(ui.value);
   }
  });
  var a = slider.find('a');
  a.text('0');
  
  
  var slider2 = $('#slider2'), scale2 = $('#scale2');
  slider2.slider({
   slide: function(event, ui) {
     var spans = $('span', scale2);
     spans.removeClass('chosen');
     spans.eq(Math.floor((ui.value / 20.01))).attr('class', 'chosen');
     a2.text(ui.value);
   }
  });
  var a2 = slider2.find('a');
  a2.text('0');
  
  
  
  
});
</script>
<head>
<body>
<h1>Likert Scale JavaScript Slider</h1>

<div id="slider" class="slider"></div>
<p id="scale" class="scale"><span>Strongly disagree</span><span>Disagree</span><span>Neutral</span><span>Agree</span><span>Strongly agree</span></p>

<div id="slider2" class="slider2"></div>
<p id="scale2" class="scale2"><span>Strongly disagree</span><span>Disagree</span><span>Neutral</span><span>Agree</span><span>Strongly agree</span></p>
</body>

</html>

It may not be pretty but it works… Now to try to get CSS to work well

Looks good in my editor, but I can’t help but notice that you have a slight typo. There are two head tags, neither of which are closed. :slight_smile:

Ok, done nitpicking. :smiley:

Haha. Oops.

If anyone is interested, I made a little PHP code for automatic rendering

The questions are listed in an array [0] = question, [1] = question 2, so on


$thequestions[0] = array('pie/*this is what will be returned in the form on submit*/', 'What do you think about pie?', 'It's great', 'It's pretty good', 'It's alright', 'I don't like it', 'I hate it');
$thequestions[1] = array('cake', 'What do you like about eating cake?', 'One of the best decisions of my life', 'I made the right decision', 'Indifferent', 'I regret it', 'I strongly regret it');

The javascript. The “foreach” automatically makes a new javascript entry for every question


<script type="text/javascript">
$(document).ready(function() {
   
 <?php foreach($thequestions as $info)
 	{ ?>
  var <?php echo $info[0] ?>slider = $('#<?php echo $info[0] ?>slider'), <?php echo $info[0] ?>scale = $('#<?php echo $info[0] ?>scale');
  <?php echo $info[0] ?>slider.slider({
   slide: function(event, ui) {
     var spans = $('span', <?php echo $info[0] ?>scale);
     spans.removeClass('chosen');
     spans.eq(Math.floor((ui.value / 20.01))).attr('class', 'chosen');
     <?php echo $info[0] ?>a.text(100-ui.value);
	 document.getElementById('<?php echo $info[0] ?>_box').value = 100-ui.value;
   }
  });
  var <?php echo $info[0] ?>a = <?php echo $info[0] ?>slider.find('a');
  <?php echo $info[0] ?>a.text('100');
  
  <?php } ?>
  
});

</script>

The css:


<style type="text/css">

 <?php foreach($thequestions as $info)
 	{ ?>
#<?php echo $info[0] ?>slider a {
  text-decoration:none;
  font:normal 10px sans-serif;
  height:1.6em;
  width:2em;
  padding-top:0.4em
}
#<?php echo $info[0] ?>slider, #<?php echo $info[0] ?>scale {
  width:240px;
  margin:20px auto;
  text-align:center
}
#<?php echo $info[0] ?>scale {
  width:auto;
  margin-bottom:50px;
}
#<?php echo $info[0] ?>scale span {
  color:#999; margin:15px;
}
#<?php echo $info[0] ?>scale .chosen {
  color:#fff
}
  <?php } ?>
</style>

The following function will post the argumented question when called:


function postQuestion($question)
	{
	?>
    
        <p class="question"><?php echo $question[1]; ?></p>
        <div id="<?php echo $question[0]; ?>slider"></div>
		<p id="<?php echo $question[0]; ?>scale"><span><?php echo $question[2]; ?></span>
        <span><?php echo $question[3]; ?></span><span><?php echo $question[4]; ?></span><span><?php echo $question[5]; ?></span>
        <span><?php echo $question[6]; ?></span><input id="<?php echo $question[0]; ?>_box" type="hidden" name="<?php echo $question[0]; ?>" value="100" /></p>
        
    <?php
	}

And then in the body:

 <form ... >
        <?php postQuestion($thequestions[0]); ?>

        <?php postQuestion($thequestions[1]); ?> ...

Hope this somehow becomes useful to somebody :slight_smile:

Just one more thing…

how can I make it start at 50%? I know I can make the a.text 50%, but that won’t actually move the slider halfway through. Does anyone know how to do this? Thanks again

What do you see in the slider options that may help with that?

I did, actually, I’m not completely inadequate :stuck_out_tongue:

$(‘.selector’).slider({ value: 37 });

I got here, and then I said to myself “hey, I’ll just initialize it with value: x”, except i had no clue how to actually write that into the script, since it was already intialized with the action option. so i tried:

$(‘.selector’).slider({slide: function stuff; }, { value: 37 });

that didn’t work, so then i tried:

$(‘.selector’).slider({slide: function stuff; }; { value: 37 });

that didn’t work either - so then i googled “how to initialize with multiple options javascript” but that didn’t turn up any results. then I gave up and posted here…

and that’s my story. so do you know how to do this?

This “options” stuff is exclusive to jQuery. The { } notation means it is an object. It is just a container for things. THe things are placed in it like this:

$('.selector').slider({
  slide: function() {
    // function stuff
  },
  value: 37
});

The indentations just make it easier to read

If anyone’s interested I’ve expanded on this slider solution in a 6-part series of posts http://jstricks.wordpress.com/2010/01/11/introduction-to-sliders/

It’s a scripting blog that I’ve just started (like we need another one) so feedback would be welcomed.