4

In a table row (<tr>) there are several input elements.

I need to execute some JavaScript code when the tr loses focus (but not when the user just switches to a different input element in the same tr).

I use jQuery.

How to do it cross-browser?

porton
  • 5,214
  • 11
  • 47
  • 95

1 Answers1

14

I suppose you're looking for this approach (demo, checked in Chr/Ff/IE10):

var delayedFn, blurredFrom;
$('tr').on('blur', 'input', function(event) {
    blurredFrom = event.delegateTarget;
    delayedFn = setTimeout(function() {
        console.log('Blurred');
    }, 0);
});
$('tr').on('focus', 'input', function(event) {
    if (blurredFrom === event.delegateTarget) {
        clearTimeout(delayedFn);
    }
});

As you see we delay the call to our "true blur handler" (which is the function with console.log in this example) with setTimeout - and clear this timeout if we see the focus stayed in the same row.

I use delegation here so I won't need to call closest(tr) each time. But it has another side-effect here, as the handler will deal correctly with the inputs added to the table dynamically.

raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • You code produces false alerts when I click inside `` (or inside a ` – porton Jun 03 '13 at 15:24
  • Yes, as the only thing that clears the timeout is the function handling `focus` on `input`. It's trivial to update for `select` and all the other inputs (just replace `input` with `:input` selector); as for clicking on `tr`, it should be processed by another event handler - click (but that may fail if user holds a mouse button long enough; focus is lost but click is yet to fire) or mousedown (but that event will be fired before `blur`). – raina77ow Jun 03 '13 at 16:29
  • BTW, what should happen when a user first clicks inside ``, then click in another `` (or whatever he seems useful)? – raina77ow Jun 03 '13 at 16:36
  • But what to do if I have several tables for which different event handlers should be executed? Could you provide a code for this more general case? – porton Jun 29 '13 at 16:06
  • 1
    It's only a handler function (send in `setTimeout`) that should be replaced in this case. One approach to generalise this to move the whole code into a jQuery plugin taking a callback function as a param, like in this [demo](http://jsfiddle.net/DRmdd/). – raina77ow Jun 29 '13 at 17:20