S
Steve Wylie
Last year a kind soul by the name of Lasse Reichstein Nielsen answered
a question for me on this newsgroup, including a script that solved my
problem. I now need to script to be slightly amended to take account
of something, and I am posting this message in the hope that Lasse, or
another equally talented reader, can help with this latest tweak to
the script.
On this newsgroup I asked for help with a questionnaire I was
doing in HTML & Javascript. I wanted a script that allowed me to use
the keys 1-9 to fill in the form rather than using the mouse (so where
there was a selection of radio controls, I would hit 1 to select the
first one, two for the second etc), and use Enter to move down the
form.
Lasse provided the script below, however sometimes there is a question
with an option "Other" which people can tick then write their "other"
response in the textarea below the question. Normally, the textarea is
disabled and greyed out (using box.disabled=true;
box.style.backgroundColor='#EEEEEE') until someone ticks the "Other"
box whereupon the box is enabled and they can type into it.
Lasse's script comes up with an error when it jumps to one of these
disabled boxes. Is there a way the script can be amended so that it
would skip past any disabled boxes, or at least not come up with an
error when it jumped to them?
Hope you can help.
Steve Wylie
Canterbury
United Kingdom
<script type="text/javascript">
var snapForm;
var currentControl;
var currentGroup;
var nextControl
function setTDBackground(elem,bg) {
// find surrounding td elements
var cnt;
var tds = [];
while(elem) {
if (elem.tagName == "TD") {
tds[tds.length] = elem;
}
elem = elem.parentNode;
}
// if successful, set the background color of the td around
// this answer.
if (tds && tds.length>=2) {
tds[tds.length-2].style.backgroundColor = bg;
}
}
function active(thisElem,nextElem) {
setTDBackground(currentControl,""); // clear previous highlight
currentControl = thisElem;
setTDBackground(currentControl,"yellow"); // set new highlight
nextControl = nextElem;
if (thisElem.name) {
currentGroup = thisElem.form.elements[thisElem.name];
if (! currentGroup.length) {
currentGroup = undefined;
}
}
}
function snapkey(event) {
event = event || window.event;
var key = event.keyCode || event.charCode || event.which;
if(key == 0x30 && currentGroup) { // 0
for (var i=0;i<currentGroup.length;i++) {
currentGroup.checked = false;
}
return false;
}
if (0x31 <= key && key <= 0x39 && currentGroup) { // 1-9
var idx = key - 0x31;
if (idx < currentGroup.length) {
currentGroup[idx].checked = true;
}
return false;
}
if (key == 13) {
if(nextControl){
var next = nextControl;
next.focus();
next.onfocus();
return false;
}
}
return true;
}
function init(formName) {
var makeActiveCall = function(next) {
return function(){active(this,next);};
};
var elems = document.forms[formName].elements;
var firstElem; // first named element. Is focused at start.
var currentName = "";
var currentIdx = 0;
for (var i=1;i<elems.length;i++) {
if (elems.type.toLowerCase() != "hidden" &&
elems.name && currentName != elems.name) {
if (!firstElem) {firstElem = elems;}
for (var j = currentIdx; j < i; j++) {
if (elems[j].name) {
elems[j].onfocus = makeActiveCall(elems);
}
}
currentIdx = i;
currentName = elems.name;
}
}
for (j=currentIdx;j<elems.length;j++) {
elems[j].onfocus = makeActiveCall();
}
firstElem.focus();
firstElem.onfocus();
document.onkeypress = snapkey;
}
</script>
And at the top of the HTML, it needs:
<BODY onload="init('theForm')">
<FORM id="theForm" name="theForm">
a question for me on this newsgroup, including a script that solved my
problem. I now need to script to be slightly amended to take account
of something, and I am posting this message in the hope that Lasse, or
another equally talented reader, can help with this latest tweak to
the script.
On this newsgroup I asked for help with a questionnaire I was
doing in HTML & Javascript. I wanted a script that allowed me to use
the keys 1-9 to fill in the form rather than using the mouse (so where
there was a selection of radio controls, I would hit 1 to select the
first one, two for the second etc), and use Enter to move down the
form.
Lasse provided the script below, however sometimes there is a question
with an option "Other" which people can tick then write their "other"
response in the textarea below the question. Normally, the textarea is
disabled and greyed out (using box.disabled=true;
box.style.backgroundColor='#EEEEEE') until someone ticks the "Other"
box whereupon the box is enabled and they can type into it.
Lasse's script comes up with an error when it jumps to one of these
disabled boxes. Is there a way the script can be amended so that it
would skip past any disabled boxes, or at least not come up with an
error when it jumped to them?
Hope you can help.
Steve Wylie
Canterbury
United Kingdom
<script type="text/javascript">
var snapForm;
var currentControl;
var currentGroup;
var nextControl
function setTDBackground(elem,bg) {
// find surrounding td elements
var cnt;
var tds = [];
while(elem) {
if (elem.tagName == "TD") {
tds[tds.length] = elem;
}
elem = elem.parentNode;
}
// if successful, set the background color of the td around
// this answer.
if (tds && tds.length>=2) {
tds[tds.length-2].style.backgroundColor = bg;
}
}
function active(thisElem,nextElem) {
setTDBackground(currentControl,""); // clear previous highlight
currentControl = thisElem;
setTDBackground(currentControl,"yellow"); // set new highlight
nextControl = nextElem;
if (thisElem.name) {
currentGroup = thisElem.form.elements[thisElem.name];
if (! currentGroup.length) {
currentGroup = undefined;
}
}
}
function snapkey(event) {
event = event || window.event;
var key = event.keyCode || event.charCode || event.which;
if(key == 0x30 && currentGroup) { // 0
for (var i=0;i<currentGroup.length;i++) {
currentGroup.checked = false;
}
return false;
}
if (0x31 <= key && key <= 0x39 && currentGroup) { // 1-9
var idx = key - 0x31;
if (idx < currentGroup.length) {
currentGroup[idx].checked = true;
}
return false;
}
if (key == 13) {
if(nextControl){
var next = nextControl;
next.focus();
next.onfocus();
return false;
}
}
return true;
}
function init(formName) {
var makeActiveCall = function(next) {
return function(){active(this,next);};
};
var elems = document.forms[formName].elements;
var firstElem; // first named element. Is focused at start.
var currentName = "";
var currentIdx = 0;
for (var i=1;i<elems.length;i++) {
if (elems.type.toLowerCase() != "hidden" &&
elems.name && currentName != elems.name) {
if (!firstElem) {firstElem = elems;}
for (var j = currentIdx; j < i; j++) {
if (elems[j].name) {
elems[j].onfocus = makeActiveCall(elems);
}
}
currentIdx = i;
currentName = elems.name;
}
}
for (j=currentIdx;j<elems.length;j++) {
elems[j].onfocus = makeActiveCall();
}
firstElem.focus();
firstElem.onfocus();
document.onkeypress = snapkey;
}
</script>
And at the top of the HTML, it needs:
<BODY onload="init('theForm')">
<FORM id="theForm" name="theForm">