Rank Preferences in a Survey

C

Can

I am creating an on-line survey. I want the user to have a list of
choices of say 10 items that are radio buttons. They need to rank their
preference. They click on preference 1, that option is removed from the
top list (choices) and appears below in a list called 'Your
preferences', you keep looping until all of your preferences are made.
Does this make sense?

How to I set it up with Javascript?

Any help is appreciated.

Can
 
M

McKirahan

Can said:
I am creating an on-line survey. I want the user to have a list of
choices of say 10 items that are radio buttons. They need to rank their
preference. They click on preference 1, that option is removed from the
top list (choices) and appears below in a list called 'Your
preferences', you keep looping until all of your preferences are made.
Does this make sense?

How to I set it up with Javascript?

Any help is appreciated.

Can

How about this approach instead? Watch for word-wrap.

<html>
<head>
<title>10rank.htm</title>
<script type="text/javascript">
var op;
function rank(bool) {
var form = document.forms["form1"];
if (bool) {
for (var i=0; i<10; i++) {
form.s1.options = new Option(i+1, i+1);
form.s2.options = null;
}
op = 0;
} else {
var indx = form.s1.selectedIndex;
if (indx < 0) return;
var text = form.s1.options[indx].text;
var valu = form.s1.options[indx].value;
form.s1.options[indx] = null;
form.s2.options[op++] = new Option(text, valu);
}
}
</script>
<style type="text/css">
..sel1 { width:30px }
..sel2 { width:30px; background:#EFEFEF; font-weight:bold }
</style>
</head>
<body onload="rank(true)">
<form action="" method="get" name="form1">
<select name="s1" size="10" class="sel1" onclick="rank(false)">
</select>
<select name="s2" size="10" class="sel2" disabled>
</select>
<input type="button" value="Reset" onclick="rank(true)">
</form>
</body>
</html>
 
C

Can

Thanks, do you have a sample on a website I could look at, visually I
would like to see what the result would be.

Can
 
M

McKirahan

Can said:
Thanks, do you have a sample on a website I could look at, visually I
would like to see what the result would be.

Can


Test it as-is. Save it as "10rank.htm" (or whatever) and click on it.
 
C

Can

It works but I am not keen on the visuals / flow, I believe when people
want to rank things they want to pick them in sequential order. With
your code they need to think of here's the option, how do I want to rank
it. Unfortunately your option is less intuitive.
 
M

McKirahan

Can said:
It works but I am not keen on the visuals / flow, I believe when people
want to rank things they want to pick them in sequential order. With
your code they need to think of here's the option, how do I want to rank
it. Unfortunately your option is less intuitive.

Could you provide a page that depicts the layout you want?



Here's a variation where one can rank their favorite colors.

Their first choice is placed at the top, then their next choice, etc.

<html>
<head>
<title>10rank.htm</title>
<script type="text/javascript">
var op;
function rank(bool) {
var form = document.forms["form1"];
var list =
["White","Red","Orange","Yellow","Green","Blue","Indigo","Violet","Grey","Bl
ack"]
if (bool) {
for (var i=0; i<10; i++) {
form.s1.options = new Option(list, i);
form.s2.options = null;
}
op = 0;
} else {
var indx = form.s1.selectedIndex;
if (indx < 0) return;
var text = form.s1.options[indx].text;
var valu = form.s1.options[indx].value;
form.s1.options[indx] = null;
form.s2.options[op++] = new Option(text, valu);
}
}
</script>
<style type="text/css">
..sel1 { width:60px }
..sel2 { width:60px; background:#EFEFEF; font-weight:bold }
</style>
</head>
<body onload="rank(true)">
<form action="" method="get" name="form1">
<select name="s1" size="10" class="sel1" onclick="rank(false)">
</select>
<select name="s2" size="10" class="sel2" disabled>
</select>
<input type="button" value="Reset" onclick="rank(true)">
</form>
</body>
</html>
 
N

Nigel Greenwood

McKirahan said:
Here's a variation where one can rank their favorite colors.

Their first choice is placed at the top, then their next choice, etc.

I like this script: it's fun to use, & I've learnt a couple of
techniques from studying it. But I'd suggest 1 or 2 minor changes, as
shown below:

1. An init() function reads the colours in just once, not once per
loop.

2. The nth colour is selected automatically as soon as the (n-1)th is
chosen.

3. The reset function clears s2 in reverse order, thus preventing the
pointers from being overwritten (which meant you had to click Reset
several times to clear s2 completely).

<html>

<head>
<title>10rank.htm</title>
<script type="text/javascript">
var op;

function init()
{
form = document.forms["form1"];
list =
["White","Red","Orange","Yellow","Green","Blue","Indigo","Violet","Grey","Black"]

}

function rank(bool)
{
if (bool)
{
for (var i=0; i<10; i++)
{
form.s1.options = new Option(list, i);

//clear s2 in reverse order to prevent overwriting
form.s2.options[9-i] = null;
}
op = 0;
}
else
{
var indx = form.s1.selectedIndex;
if (indx < 0) return;
var text = form.s1.options[indx].text;
var valu = form.s1.options[indx].value;
form.s1.options[indx] = null;
form.s2.options[op++] = new Option(text, valu);

//Use recursion to set final item
if ( op == 9 )
{
form.s1.selectedIndex = 0
rank(false)
}
}
}
</script>

<style type="text/css">
..sel1 { width:60px }
..sel2 { width:60px; background:#EFEFEF; font-weight:bold }
</style>

</head>

<body onload="init();rank(true)">
<form action="" method="get" name="form1">
<select name="s1" size="10" class="sel1" onclick="rank(false)">
</select>
<select name="s2" size="10" class="sel2" disabled>
</select>
<input type="button" value="Reset" onclick="rank(true)">
</form>
</body>

</html>


Nigel
 
M

McKirahan

Nigel Greenwood said:
I like this script: it's fun to use, & I've learnt a couple of
techniques from studying it. But I'd suggest 1 or 2 minor changes, as
shown below:

1. An init() function reads the colours in just once, not once per
loop.

2. The nth colour is selected automatically as soon as the (n-1)th is
chosen.

3. The reset function clears s2 in reverse order, thus preventing the
pointers from being overwritten (which meant you had to click Reset
several times to clear s2 completely).


[snip]

Excellent suggestions.

My frst version of the script did clear the options in reverse order
then I changed it to use "var list" and forgot about it.

No "init()" is needed; just put "var list" outside of the function.

Hardcoding 9 or 10 is bad practice; below I use "list.length".

Here's my version that does your suggestions 1 and 3:


<script type="text/javascript">
var form = document.forms["form1"];
var list =
["White","Red","Orange","Yellow","Green","Blue","Indigo","Violet","Grey","Bl
ack"]
var op;
function rank(bool) {
if (bool) {
for (var i=0; i<list.length; i++) {
form.s1.options = new Option(list, i+1);
form.s2.options[list.length-i-1] = null;
}
op = 0;
} else {
var indx = form.s1.selectedIndex;
if (indx < 0) return;
var text = form.s1.options[indx].text;
var valu = form.s1.options[indx].value;
form.s1.options[indx] = null;
form.s2.options[op++] = new Option(text, valu);
}
}
</script>
 
R

RobG

Here's one that just moves 'em up & down. If IE would allow proper
DOM manipulation of option elements, you could just move the option
from one select to the other...

function moveOpt(selA)
{
var sOpt = selA.options[selA.options.selectedIndex];
selB.appendChild = sOpt.parentNode.removeChild(sOpt);
}


Here's one that just moves 'em up & down:

<script type="text/javascript">


function init(sel)
{
// Array of colours
var list = ["White","Red","Orange","Yellow","Green",
"Blue","Indigo","Violet","Grey","Black"];

for (var i=0, num=list.length; i<num; ++i){
sel.options = new Option(list, list, false, false);
}
}

function moveOpt(sel, d)
{
// Set up and check selection/movement
var idxA = sel.options.selectedIndex;
var len = sel.options.length;
var idxB = idxA + d;
if (-1==idxA || 0>idxB || len==idxB) return;

// Swap element attributes
var xT = sel.options[idxA].text;
var xV = sel.options[idxA].value;
sel.options[idxA].text = sel.options[idxB].text;
sel.options[idxA].value = sel.options[idxA].value;
sel.options[idxB].text = xT;
sel.options[idxB].value = xV;

// re-select previous selected
sel.options[idxB].selected = true;
sel.options[idxA].selected = false;

}



window.onload = function() {
init(document.forms['form1'].s5);
}


<form action="" method="get" name="form1">
<table>


<tr>
<td>
<select name="s5" size="11" class="sel1"></select>
</td>
<td>
<input type="button" value="Move up" onclick="
moveOpt(this.form.s5,-1);
"><br>

<input type="button" value="Move down" onclick="
moveOpt(this.form.s5,1);
">


</td>
</tr>
 
N

Nigel Greenwood

McKirahan said:
No "init()" is needed; just put "var list" outside of the function.

That's what I thought too: but for some reason neither IE nor Mozilla
seems to like it. They refuse to recognize "form" when I run the
script. Any idea why? I suspect "form" & "list" don't get initialized
in their present position.
Hardcoding 9 or 10 is bad practice; below I use "list.length".

Good point.
Here's my version that does your suggestions 1 and 3:

form.s2.options[list.length-i-1] = null;

In fact you can even just leave it as

form.s2.options[0] = null;

which progressively clears the whole array!

BTW What's your objection to my suggestion 2? When all but one of the
colours have been chosen the remaining one must be at the bottom of the
list -- so why force the user to click on it? I'm assuming the entire
list must be ranked.

Nigel
 
M

McKirahan

Nigel Greenwood said:
That's what I thought too: but for some reason neither IE nor Mozilla
seems to like it. They refuse to recognize "form" when I run the
script. Any idea why? I suspect "form" & "list" don't get initialized
in their present position.

"form" is not available until after the page loads.
Thus, "var form =" should be within the function not outside of it.
(I moved it outside of it after I tested!)
Hardcoding 9 or 10 is bad practice; below I use "list.length".

Good point.
Here's my version that does your suggestions 1 and 3:

form.s2.options[list.length-i-1] = null;

In fact you can even just leave it as

form.s2.options[0] = null;

which progressively clears the whole array!
Excellent!


BTW What's your objection to my suggestion 2? When all but one of the
colours have been chosen the remaining one must be at the bottom of the
list -- so why force the user to click on it? I'm assuming the entire
list must be ranked.

Good point -- unless it predisposes the user to a selection :)

P.S. May I contact you later via e-mail about "typing Classical Greek"?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top