Hallo all,
I’ve bungled my way through some more JS, and it even (somehow) works on all browsers tested (haven’t tested IE8)! But I see repetition, which tells me I’m writing too much. Also, it’s still a little brittle, but dunno if I can really do anything about that? So, how can I write this better (guess this is mostly a learning question, nothing’s broken… yet)?
This JS basically looks for certain HTML form controls, checks their values on load, and uses that to determine whether a following (usually but not always sibling) stays onscreen or not.
In addition, this is checked again onchange of the form control.
The HTML being affected can be seen here and [url=http://stommepoes.nl/Motorverzekeren/motorbereken1.html]here.
The elements in question have a class of “toggle” (in order to be found), and there are only 3 of these in the first link, only one in the second link.
I have a lib: funclib.js
The main file is here but here also is the current code in this one:
/*motor.js*/
var Motor = {
init: function () {
function checkStatus(field){
var Jong = document.getElementById("Jong"),
Dekking = document.getElementById("Dekking"),
Meerkost = document.getElementById('Meerkost');
function check(control) {
var val = control.value;
if (val === 'ja' || val === 'WA-Extra' || val === 'WA-Casco') {
Basis.removeClass(field, 'hidden');
}
else if (val === 'nee' || val === 'WA') {
Basis.addClass(field, 'hidden');
}
}
if (field.id === 'JongField') {
check(Jong);
Jong.onchange = function() {
check(this);
};
}
if (field.id === 'Cascodekking') {
check(Dekking);
Dekking.onchange = function() {
check(this);
};
}
if (field.id === 'Meerkostja') {
check(Meerkost);
Meerkost.onchange = function() {
check(this);
};
}
}
var hiddenFields = Basis.getElementsByClass('toggle');
for (i = 0, l = hiddenFields.length; i < l; i++) {
var field = hiddenFields[i];
checkStatus(field);
}
}//init
};
Basis.begin(Motor);
CSS:
form .hidden {
position: absolute;
left: -999em;
}
Yeah, you can see I modeled this after the Core namespacing trick but named mine differently because I don’t have nearly the amount of memory management etc that Core has.
I ran this through Lint, fine, but I’m wondering where I can make this better and possibly more flexible. I’m not sure if I’m stuck always listing all the possible values that would equal “true” and all those who may equal “false” (function(check)), or the id’s of the particular elements (since not everyone is always in the same relationship to each other, I can’t just use things like next or prev sibling).
I’m using values rather than selectIndex because the order may be changed arbitrarily. However I also work with a colleague who seems to switch between caps and lowercase in his sleep, so I’ve considered for safety adding some bloataceous toLowerCase() stuff in there, but not sure…
So mostly wondering how I can reduce the repetition here:
if (field.id === 'JongField') {
check(Jong);
Jong.onchange = function() {
check(this);
};
}
if (field.id === 'Cascodekking') {
check(Dekking);
Dekking.onchange = function() {
check(this);
};
}
if (field.id === 'Meerkostja') {
check(Meerkost);
Meerkost.onchange = function() {
check(this);
};
}
And maybe make this value checker better:
function check(control) {
var val = control.value;
if (val === 'ja' || val === 'WA-Extra' || val === 'WA-Casco') {
Basis.removeClass(field, 'hidden');
}
else if (val === 'nee' || val === 'WA') {
Basis.addClass(field, 'hidden');
}
}
I keep thinking I should be able to have some list of things that always just mean “true” and another list of things that can just be “false” and have the check function just do one thing if val is true and another if val is false. This may fail in the future if for some reason we needed opposite functionality for true and false values, though.
I went through closure hell trying to get this as far as it is. Often I got errors saying “cannot access optimised closure”. Everything seems to “work” now and passes Lint. Any suggestions? Thanks in advance.