views:

279

answers:

4

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.

Thank you!

* 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 exemple 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: http://bit.ly/bHd6nH

A: 

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

adardesign
same thing, it doesn't focus on the input :(
Sirber
I am sorry about that, I will now `focusin` on the other part of your code that might be the problem :)
adardesign
`focusin()` doesn't give focus to an element, but rather detects whether or not focus was received. From docs: *The focusin event is sent to an element when it, or any element inside of it, gains focus.* The issue here is getting focus in the first place.
patrick dw
+3  A: 

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!

fudgey
Updated my answer
fudgey
on page load, javascript creates the table then add a line (id=AJAX_ID) with empty inputs, and focus the second field (working). Once all the input are filled, they are sent to the server with the line ID (AJAX_ID), the server save the request, and send AJAX_ID back so I can update the last field (status) and add a new line above it. Then, focus the second field (failing). I'm pretty sure that just playing with the html dump will work, but in the real code it doesn't.
Sirber
If you are loading the row dynamically with ajax, then you should set the focus in the load callback function.
fudgey
+1 for fudgey..
patrick dw
I'm in the load callback function. whatever I do I can only cahnge the CSS of the input, I cannot focus it, even with patrick's answer.
Sirber
thank you for the coding hints!
Sirber
The only thing I can think of is that you may be setting focus on another element unintentionally. I set up a third demo (http://jsfiddle.net/QPJhq/3/) that works on FF, IE and Chrome... so I don't know why it's not working.
fudgey
+1  A: 

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();
patrick dw
Down-voted why? I **really, really hope** it is because there is an error in my answer, and not because I pointed out why two of the other answers are wrong.
patrick dw
To clarify my comment, one of the two wrong answers is now removed. fudgey seems to be on the right track.
patrick dw
I added "ID" in front of the number. Both doesn't work. maybe I have something wrong in the creation of the second line.. but the DOM seems fine.
Sirber
the code is triggered via `blur()` on each `input`, blur call jquery/ajax and ajax calls my callback function. `return false;` didn't help :(
Sirber
@Sirber: But you say that the user presses a button. What is that button? And do I understand correctly that the ajax is working and you are receiving the response you expect?
patrick dw
They select one building then a "power meter", then they press a button to build the rest of the interface which is different for each kind of "power meter". On every input field of the input line, there's an onblur function to validate the line and send the ajax if the line is full. I addes the javascript in **edit4** and the html in **edit5**
Sirber
+1  A: 

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!

Sirber
on a side note, IE8 adds two lines since `.blur()` is triggered when the input lose it's focus (via code). I had to add an array of "already sent" IDs so it doesn't execute twice.
Sirber
+1 Glad you found it.
patrick dw
thank you patrick! ^^
Sirber