Fixed Suvery Number js validation

Attaching the number validation code to onkeydown was very problematic.
Changing to onblur is much cleaner, and probably nicer for the user.
This commit also fixes the problem that Number questions without a 'step'
set would not be checked for 'required'-ness.
This commit is contained in:
Patrick Donelan 2009-08-24 08:31:02 +00:00
parent 6e0fcee52e
commit 491e06bf7d

View file

@ -77,11 +77,11 @@ if (typeof Survey === "undefined") {
answered = 1; answered = 1;
for (var z1 in toValidate[i].answers) { for (var z1 in toValidate[i].answers) {
if (YAHOO.lang.hasOwnProperty(toValidate[i].answers, z1)) { if (YAHOO.lang.hasOwnProperty(toValidate[i].answers, z1)) {
var m = parseFloat(document.getElementById(z1).value); // We rely on server-side validation for actual value checking,
var ansValues = toValidate[i].answers[z1]; // and onblur js for user-friendly validation, so here we only
if((ansValues.max != '' && m > ansValues.max) || // need to check that required values look like numbers
(ansValues.min != '' && m < ansValues.min) || var m = parseFloat(document.getElementById(z1).value, 10);
(ansValues.step != '' && ( (m % ansValues.step) != 0) )){ if (!YAHOO.lang.isNumber(m)) {
answered = 0; answered = 0;
break; break;
} }
@ -189,56 +189,28 @@ if (typeof Survey === "undefined") {
function numberHandler(event, objs){ function numberHandler(event, objs){
var keycode = event.keyCode;
var value = parseFloat(this.value, 10); var value = parseFloat(this.value, 10);
// Keep a record of the original value entered
var originalValue = value;
// Get the constraints // Get the constraints
var min = parseFloat(objs.min, 10); var min = parseFloat(objs.min, 10);
var max = parseFloat(objs.max, 10); var max = parseFloat(objs.max, 10);
var step = parseFloat(objs.step, 10); var step = parseFloat(objs.step, 10);
// Response to up/down arrow keys if (YAHOO.lang.isNumber(value)) {
if (keycode == 38 || keycode == 40) { // Enforce step
// start at zero if we don't have a valid number if (YAHOO.lang.isNumber(step) && value % step != 0){
if (!YAHOO.lang.isNumber(value)) { this.value = value - value % step;
value = 0;
} }
// Enforce max/min constraints
// Default to 1 for increment steps if (YAHOO.lang.isNumber(min) && value < min){
step = step ? step : 1; this.value = min;
}
if (keycode == 38){ // up if (YAHOO.lang.isNumber(max) && value > max){
value += step; this.value = max;
}
if (keycode == 40){ // down
value -= step;
} }
} else { } else {
// Apart from when we respond to up/down requests, if the input // Clear value if it is not a valid number
// isn't a valid number it's best if we do nothing - the user this.value = '';
// might be half-way through entering something, and
// besides, validation will take care of it for us later
if (!YAHOO.lang.isNumber(value)) {
return;
}
}
// Enforce max/min constraints
if (YAHOO.lang.isNumber(min) && value < min){
value = min;
}
if (YAHOO.lang.isNumber(max) && value > max){
value = max;
}
// Only modify the value if the new numeric value
// is different from the original parsed value
// (so that "0.000" doesn't get turned into "0" etc..)
if (value != originalValue) {
this.value = value;
} }
} }
@ -752,7 +724,8 @@ if (typeof Survey === "undefined") {
if (toValidate[q.id]) { if (toValidate[q.id]) {
toValidate[q.id].answers[q.answers[x1].id] = {'min':q.answers[x1].min,'max':q.answers[x1].max,'step':q.answers[x1].step}; toValidate[q.id].answers[q.answers[x1].id] = {'min':q.answers[x1].min,'max':q.answers[x1].max,'step':q.answers[x1].step};
} }
YAHOO.util.Event.addListener(q.answers[x1].id, "keydown", numberHandler, q.answers[x1]); // Attach to the onblur event rather than keydown otherwise things get very cludgy for the end-user
YAHOO.util.Event.addListener(q.answers[x1].id, "blur", numberHandler, q.answers[x1]);
} }
} }
continue; continue;