0

I am trying to enable Event Handling in JavaScript. This is what I have so far:

function Field(args) {
    this.id = args.id;

    this.name = args.name ? args.name : null;
    this.reqType = args.reqType ? args.reqType : null;
    this.reqUrl = args.reqUrl ? args.reqUrl : null;
    this.required = args.required ? true : false;
    this.error = args.error ? args.error : null;

    this.elem = document.getElementById(this.id);
    this.value = this.elem.value;

    this.elem.addEventListener('onblur', this, false);
    this.elem.addEventListener('click', this, false);
    this.elem.addEventListener('change', this, false);
    console.log(JSON.stringify(this.elem.value));

}

function FormTitle(args) {
    Field.call(this, args);
}

Field.prototype.getValue = function() { return Helpers.trim( this.value ) };

Field.prototype.sendRequest = function () {

};

Field.prototype.click = function (value) {
    alert("click");  
};

Field.prototype.onblur = function (value) {
    alert("onblur");  
};

Field.prototype.change = function (value) {
    alert("change");  
};

Field.prototype.dblclick = function (value) {
    alert("dblclick");  
};

Field.prototype.handleEvent = function(event) {
    switch (event.type) {
    case "click": this.click(this.value);
    case "onblur": this.onblur(this.value);
    case "change": this.change(this.value);
    case "dblclick": this.dblclick(this.value);
    }
};

// inheritProtootype uses parasitic inheritance to inherit from the Field's prototype
// and then assign the results to FormTitle's prototype.
inheritPrototype(FormTitle, Field);

var title = new FormTitle({name: "sa", id: "title"});

For some reason however, all events are triggered at the same time. For example, when I click on the Title field in the Form, instead of only Click event triggering, all four events are triggered.

What am I doing wrong?

1
  • this.elem.addEventListener('…', this, false); does attach the Field instance, an object, as event listener - which needs to be a function? Commented May 17, 2013 at 13:50

3 Answers 3

3

Simple. At the end of each of your case blocks, separate it from every succeeding block with a break; statement.

Sign up to request clarification or add additional context in comments.

4 Comments

Your answer is correct. I am not sure what I was thinking! But Bergi's seems more elegant than the switch statement. So I chose that as the answer. By the way, would you know why 'onblur' event might not be triggering?
@user Perhaps because, when registering using listeners, you omit the 'on'. So try addEventListener('blur', ...); only.
Ok so that blur worked. But last question. It (blur) seems to be triggered multiple times, including when I first focus on the field also. It is then also triggered when I switch windows. Would you know a solution to that?
@user Sorry, don't know an answer to that. The switching windows part seems legit though since the field actually is blurred when quitting focus on the browser. However, it is unusual to have the event triggered when focusing the field...
2

Your switch statements misses some break statements, so in case click all four methods would be executed.

However, there's a better option than a switch-statement:

Field.prototype.handleEvent = function(event) {
    var prop = event.type;
    if (prop in this) // && typeof this[prop] == "function"
        this[prop](this.value);
};

which will work for all events without explicitly mentioning them.

14 Comments

Yep, that worked like a charm. By the way, would you know why the 'onblur' event isn't triggering?
@user: Because the event is named blur :-) The on prefix is only for M$ .attachEvent and event-properties.
@user This approach of event handling is definitely better than a switch. To explain what this piece of code does: the in keyword checks if the property denoted to the left exists in the specified object to the right. JavaScript allows accessing of properties in 'dot notation' and index notation. Using index notation, it is possible to dynamically access properties of an object by means of a variable. This effective approach allows for simple expansion of events without having to modify a list or so.
@user By the way, index notation is somewhat different from dot notation. Also index isn't quite the right word as the notation rather works like a map. Basically anything, including objects, can serve as key. This also means that you can have properties named foo bar which is impossible for dot notation. So quite a nice feature...
@Derija93: That type of member operator is named bracket notation (only with numbers I'd call it index). And no, it works only for string; everything you pass in is implicitly stringified
|
1

In your switch statement, you need to have a break after each case.

switch (event.type) {
  case "click": this.click(this.value); break;
  case "onblur": this.onblur(this.value); break;
  case "change": this.change(this.value); break;
  case "dblclick": this.dblclick(this.value); break;
}

The last break isn't needed but it's good practice to include it because you might add additional cases.

1 Comment

You have the right answer but Bergi's solution is so elegant. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.