Steve Wylie said:
I am constructing an HTML questionnaire and one of the questions
requires people to rate some choices from 1 to 5, where 1 is their
favourite and 5 is their least favourite:
Car
Bus
Taxi cab
Train
Airplane
Each choice has an INPUT TYPE=TEXT tag to contain the response. I
also have a function that is called ONCHANGE in order to check that a
number is entered between 1 and 5:
function CheckNos(obj) {
if(obj.value.match(/[^\d]/) || obj.value<1 || obj.value>5)
{alert("Please enter a number between 1 and 5");obj.value="";return
false}
}
This works fine, but ideally I would like a function that could check
ONCHANGE that someone has not filled in the same number twice, for
example answered "1" for all of them. They are only allowed to use
each rating number once, so rating their choice 1 to 5.
Can anyone suggest a short function that could accomplish this easily?
Could I use some kind of array with 5 elements and allocate a flag
value once that number had been chosen, then check that the value had
been set?
I'll assume that this is not a class assignment.
Since the elements of the form are accessible as an array, you don't
need to create a new one. If each entry is checked as it is changed,
the only possible source of duplication is for this new value to be
a duplicate of one existing value. All you need to do is to check
each other member of this ranking group against this new value.
Here's a simple (not completely idiot-proof or the most efficient)
solution that's flexible enough to use more than once in the same
form with a different number of members in each ranking group:
<html>
<head>
<script type="text/javascript">
function checkRank(box,firstName,count){
// *box* is the text field whose onChange handler called us.
// *firstName* is the name of the first field in this rank group.
// *count* is the number of items being ranked.
// Note that *count* must be less than 10.
//
// Check that text field *box* has a value from 1 to *count*,
// then check *count* text fields beginning at *firstName*,
// ensuring that no other field has the same value as *box*.
var errMsg="Please enter a digit 1-"+count+"\n"
+"that has not been used previously."
box.value=box.value.replace(/\s*/g,""); // remove spaces
if(!box.value.search(/^$/)) return; // this change is a deletion
if(box.value.search(new RegExp("^[1-"+count+"]$"))){
alert(errMsg);
box.value="";
return;
}
var group=box.form.elements;
for(var i=0;i<group.length;i++){
if(group[i].name==firstName){
firstIndex=i;
break;
}
}
var firstIndex=i; // will be group.length if no match
if(firstIndex+count-1>group.length){
alert("Bad arguments! Fire the web designer!");
return;
}
for(var i=0;i<count;i++){
if(group[firstIndex+i]!=box &&
group[firstIndex+i].value==box.value){
alert(errMsg);
box.value="";
return;
}
}
}
</script>
</head>
<body>
<form>
<table>
<tr>
<td align="right">Car</td>
<td><input name="car" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Bus</td>
<td><input name="bus" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Taxi cab</td>
<td><input name="taxi" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Train</td>
<td><input name="train" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Airplane</td>
<td><input name="plane" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
</table>
<input type="reset" value="clear">
</form>
</body>
</html>
<html>
<head>
<script type="text/javascript">
function checkRank(box,firstName,count){
// *box* is the text field whose onChange handler called us.
// *firstName* is the name of the first field in this rank group.
// *count* is the number of items being ranked.
// Note that *count* must be less than 10.
//
// Check that text field *box* has a value from 1 to *count*,
// then check *count* text fields beginning at *firstName*,
// ensuring that none has the same value as *box*.
var errMsg="Please enter a digit 1-"+count+"\n"
+"that has not been used previously."
box.value=box.value.replace(/\s*/g,""); // remove spaces
if(!box.value.search(/^$/)) return; // change is a deletion
if(box.value.search(new RegExp("^[1-"+count+"]$"))){
alert(errMsg);
box.value="";
return;
}
group=box.form.elements;
for(var i=0;i<group.length;i++){
if(group[i].name==firstName){
firstIndex=i;
break;
}
}
var firstIndex=i; // will be group.length if no match
if(firstIndex+count-1>group.length){
alert("Bad arguments! Fire the web designer!");
return;
}
for(var i=0;i<count;i++){
if(group[firstIndex+i]!=box &&
group[firstIndex+i].value==box.value){
alert(errMsg);
box.value="";
return;
}
}
}
</script>
</head>
<body>
<form>
<table>
<tr>
<td align="right">Car</td>
<td><input name="car" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Bus</td>
<td><input name="bus" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Taxi cab</td>
<td><input name="taxi" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Train</td>
<td><input name="train" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
<tr>
<td align="right">Airplane</td>
<td><input name="plane" size="3" onchange="checkRank(this,'car',5)"></td>
</tr>
</table>
<input type="reset" value="clear">
</form>
</body>
</html>