views:

90

answers:

4

Can somebody tell me what I am doing wrong?

window.onload = initForm;
function initForm() {
    var allTags = document.getElementsByTagName("*");
    for(i=0; i<allTags.length; i++) {
        if (allTags[i].className.indexOf("textbox") > -1) {
            allTags[i].onFocus = fieldSelect;
            allTags[i].onBlur = fieldDeSelect;          
        }
    }
}
function fieldSelect() {
    this.style.backgroundImage = "url('inputBackSelected.png')";
}

function fieldDeSelect() {
    this.style.backgroundImage = "url('inputBack.png')";
}

I am a beginner at JavaScript so I am not used to debugging code yet.

Thanks

Luke

A: 

Instead of window.onload=initform try window.onload=function(){/the init function/} Also when refering to a function you should use () even if there are no arguments.

Ruffian
Not true at all. `window.onload=initform` is perfectly legal. You are assigning the value of `window.onload` to be the `function initform`, if you were to add `()` it would immediately call that function and assign `window.onload` to the return value of `initform`.
gnarf
+1  A: 

The problem is that when fieldSelect and fieldDeselect are getting called, this refers to the window object, not to the element that fired the event. You might want to consider using jQuery:

$(document).ready(function() {
    $('.textbox').focus(fieldSelect).blur(fieldDeselect);
});

function fieldSelect() {
    $(this).css('background-image', 'url("inputBackSelected.png")');
}

function fieldDeselect() {
    $(this).css('background-image', 'url("inputBack.png")');
}

jQuery takes care of making sure that when your event handlers are getting called, this refers to the element that fired the event.

Aistina
This is the issue.
David
(In internet explorer...)
gnarf
+2  A: 

Your problem lies in attaching your event handlers. You should bind to onfocus and onblur (note the lowercase event name).

As a suggestion, you may want to look at a very simple cross browser addEvent() with a quick line of code added to ensure the proper this pointer:

function addEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.attachEvent){
    // fix added by me to handle the `this` issue
    var r = obj.attachEvent("on"+evType, function(){ 
      retrun fn.apply(obj, arguments); 
    });
    return r;
  } else {
    alert("Handler could not be attached");
  }
} 

And then use the addEvent function instead of allTags[i].onfocus = you will probably have better mileage in the future binding events.

addEvent(allTags[i], 'focus', fieldSelect);
addEvent(allTags[i], 'blur', fieldDeSelect);

jsfiddle demonstration

gnarf
A: 

Two things, the events should be all lower case (onfocus, onblur) and this doesn't point to the object that triggered the event in IE. Try this:

function fieldSelect(e) {
    var event;
    if(!e) {
        event = window.event;
    } else {
        event = e;
    }
    event.target.style.backgroundImage = "url('inputBackSelected.png')"; 
} 

function fieldDeSelect(e) {
    var event;
    if(!e) {
        event = window.event;
    } else {
        event = e;
    }
    event.target.style.backgroundImage = "url('inputBack.png')"; 
} 

Standards complient browsers will pass an event object to the event handler. IE uses a global window.event object instead. Either way you can use that object to get the target of the event that triggered the handler.

Another, probably preferable option would be to have your functions set and remove a className instead of directly changing the style. Then put a style called maybe selected in your stylesheet that overrides the background image. That way you keep style info and behavior separate.

jasongetsdown
`e = e || window.event;` is a quick way to ensure the proper event object in `e`. If `e` is falsy (undefined/0/''/etc) the JavaScript or operator `||` will result in `window.event` being assigned to `e`;
gnarf
Thanks for the responses, It seems that the fact that I had onBlur instead of onblur meant that it didn't work. But neither firefox's firebig, nor chrome's inspector pointed this out. Anyway it works now, and also seems to work in IE 8. Not sure about other versions of IE though.
Lukes123
I meant firebug!
Lukes123
@Lukes123: Note that you can edit your comments. Also, don't forgot to mark an answer as accepted when it solved your problem (click the checkmark next to the answer).
Aistina
JavaScript can't catch those kinds of errors because of the way it's objects work. You were actually assigning a new method called onBlur to each element, which is perfectly legal. The browser won't find it when an event fires, so it doesn't behave as you expect, but it's legal. It may seem frustrating at first, especially if you're coming from a "classicaly" OO language, but it's actually one of the best features of js.
jasongetsdown