Sirber
Sirber

Reputation: 3428

.focus() doesn't work on an input while orher attributes works

I have a classic table / thead / tbody structure, which I add a line at the end of the tbody. The line contains only an input element. The code works in Firefox 3.6 but not in Chrome v5 or IE8. I'm using jQuery 1.4.2.

Does not work: $("#" + AJAX_ID).parent().find('tr:last > td:nth-child(2) > input').focus();

Does work: $("#" + AJAX_ID).parent().find('tr:last > td:nth-child(2) > input').css('background-color', 'red');

even setting an ID on the input, and using document.getElementBuId('id').focus() doesn't work.

*** edit ***

The site is pretty complex (mix of template / static html and dynamic html), but the table looks like this (rendered html in chrome, layout via tidy) : http://pastebin.com/PHqxAEVm

*** edit 2 ***

Even $("#lectures").find("input:last").focus(); called from the ajax callback doesn't do anything.. $("#lectures").find("input:last").css('background-color', 'red'); turns one red though, but the focus goes to the address bar.

Here's a dump of the returned object from the selector: http://pastebin.com/Jdw1TZXf

*** edit 3 ***

Here's the JavaScript code that builds the table: http://pastebin.com/cbCfi0UY on page load, oContainer is $("#lectures") while after the ajax call it's $("#" + AJAX_ID).parent(), which is supposed to point to the table's tbody

*** edit 4 ***

Hard problem... here's the full lectures.js file: http://pastebin.com/Jkg0DZqa batisses and compteurs are json objects loaded via the template. the user select a batisse then a compteur then press a button that calls buildAjout(), which calls in this example buildElectric($("#lectures"), compteur);. Once the line is filled bu the user, onBlurLecture(tr_parent) is called, the data is sent to the server via AJAX and function callback_compteurs_lecture_add(AJAX_ID) is called after the ajax call is complete. The function SendCommand is a custom function which use jQuery ajax.

The creation of the first input line (and the focus) works, but not the one created in the callback of the ajax.

*** edit 5 ***

The full rendered page looks like: http://pastebin.com/UfBYcjX3 I shortened the batisses variable. The (full) page has no JavaScript errors. In Chrome's JavaScript console, I cannot focus the inputs.

*** edit 6 ***

Wrong function name in this question for SendCommand. fixed.

Solution found: .focus() doesn't work on an input while orher attributes works

Upvotes: 0

Views: 3279

Answers (4)

Sirber
Sirber

Reputation: 3428

got it!

I use "tab" (tabulation) to switch to the next input while writing in them. At the last one, the focus goes out of the window so I cannot set it. I converted the last column "status" into a input so it gets the focus while onBlur is executed. When the ajax load callback is called, the new line is added and the input is focused as it should.

Chrome: works
Firefox: works
IE8: works (with fix)

spent 1½ day on that lol

thanks everyone!

Upvotes: 1

Mottie
Mottie

Reputation: 86413

What ID are you targeting? Because if I replace $("#" + AJAX_ID) with $('table') it works -> demo (at least in Chrome)

and if I wrap the function inside a $(document).ready(function(){...}) it works in IE -> demo


I'm still looking to see what the problem might be, but I have a few comments about your code so far.

  1. I haven't tested this, but I creating a jQuery object then appending another object inside ends up taking a lot of time because of the number of function calls. I've found it easier to just build up a string and only use one append. This example makes it easy to read:

    var table = '\
     <table style="width: 100%">\
      <thead>\
       <tr>\
        <th>Numéro</th>\
        <th>litre</th>\
        <th style='width: 100px;'>Status</th>\
       </tr>';
    
    // append more to the string
    table += '<tbody>.....</tbody></table>';
    $('body').append(table);
    
  2. I found this bit of code and I just wanted to show you that you can shorten it:

    $("#no_batisse").css('display', 'none');
    $("#lectures").html("");
    $("#lectures").css('display', '');
    

    shortens to:

    $("#no_batisse").hide();
    $("#lectures").empty().hide();
    
  3. Instead of calling this function after each row addition, you could try adding a live function once that works with dynamically added content:

    $(oLigne).find("input").blur(function() { onBlurLecture(oLigne); });
    

    try running this when you initialize the script (just once)

    $('#lecture').find('input').live('blur', function(){
     onBlurLecture( $(this).closest('tr') );
    })
    

I'll keep looking!

Upvotes: 3

user113716
user113716

Reputation: 322462

EDIT:

If your code is being triggered via some element that has a default behavior (like an <a> element), try adding return false; to the end of its callback.

Alternatively, if you give a parameter to the event handler's function, like function(e) {...}, you can call e.preventDefault() from within the callback instead of return false;.


First, I don't know if this is the issue, but IDs can not start with a number.

Second, which element has the AJAX ID that are you using? You'll get different results depending on that.

To avoid any ID issues, you could do:

$("#lectures").find('tr:last > td:nth-child(2) > input').focus();

or if you want it to be relative, do:

$("#" + AJAX_ID).closest('tbody').find('tr:last > td:nth-child(2) > input').focus();

Upvotes: 2

adardesign
adardesign

Reputation: 35691

Try to trigger .focusin() (this was added in jQuery's 1.4) See documentation.

Upvotes: -1

Related Questions