0

This should be simple but I can't get it to work so would appreciate any pointers.

I have a function in my webpage that adds a new line into a table with inputs etc. This is a pretty basic POST that looks something like this...

$.post(url, {
    newRow : newRow
}, function(data) {
    $('#' + tableName + ' > tbody > tr').eq(rowLoc).before(data);
}).done(function() {
    reNumberTableIDName($tb)
});

The reNumberTableIDName function is pretty straightforward, it runs through all the objects in the table and changes their id/name so that they are in order relevant to the row they are in the table for other reasons.

Now, one of the elements added in to this table is an auto complete input which looks like so...

<input id="autoLook[9]" class="required yui-ac-input" type="text" title="" value="" name="autoLook[9].id" style="width:500px" autocomplete="off" required="required">

Note that the name and ID are not altered as part of the reNumberTableIDName function.

I tried adding in a line to the "done"portion of the post to then put the focus/carat into that new input but it doesn't work (focus stays on the button previously clicked to add the row).

$("#autoLook[" + (newRow -1) + "]").focus();

I've checked with an alert that "#autoLook[" + (newRow -1) + "]" does indeed come up with the right string so I'm at a loss as to why this doesn't work. What obvious litle gotcha am I missing?

Its also worth noting that I tried to add in a autofocus property to the input being added, but I'm working in grails and this type of auto complete doesn't allow me to do this.

Thanks!

Worth noting that the solution should be to use setTimeout as mentioned below else it will continually put focus back to the object!

MorkPork
  • 844
  • 3
  • 20
  • 41

1 Answers1

2

The selector #autoLook[9] matches an element with the id autoLook and the attribute 9; which is obviously wrong. Add backslashes around the square brackets to escape them:

$("#autoLook\\[" + (newRow - 1) + "\\]").focus();

Quote from jQuery Documentation: Selectors:

To use any of the meta-characters (such as !"#$%&'()*+,./:;<=>?@[\]^``{|}~) as a literal part of a name, it must be escaped with with two backslashes: \\. For example, an element with id="foo.bar", can use the selector $("#foo\\.bar"). The W3C CSS specification contains the complete set of rules regarding valid CSS selectors. Also useful is the blog entry by Mathias Bynens on CSS character escape sequences for identifiers.

Salman A
  • 262,204
  • 82
  • 430
  • 521
  • 1
    This solves it, but it may be worth pointing out why - without escaping the square brackets, the jQuery selector engine is looking for an element with id `autoLook` and an attribute called `9`. See http://api.jquery.com/has-attribute-selector/ – Josh Harrison May 08 '14 at 08:29
  • Ah yes, I missed the obvious. – Salman A May 08 '14 at 08:31
  • This doesn't seem to work for me :( I've tried putting in the done, both before and after `reNumberTableIDName($tb)`, also putting it outside and after the POST and that doesn't work either :( – MorkPork May 08 '14 at 08:45
  • What does `alert($("#autoLook\\[" + (newRow - 1) + "\\]").length)` give you? – Salman A May 08 '14 at 08:48
  • Interestingly if I put that length alert before and after my rename function it returns 1, if I put it outside of the POST completely then it returns 0! – MorkPork May 08 '14 at 08:56
  • `1` is good; try changing the matched element's css color or value to make sure it is the right element. If these work but focus does not working try wrapping your code inside `setInterval(function() { $(...).focus(); }, 1 )`. – Salman A May 08 '14 at 08:58
  • This did the trick, nice one cheers! :) Why it needs this wait in there though I don't know (but I'm not gonna question it! :D – MorkPork May 08 '14 at 09:08
  • 2
    [Here's why that works](http://stackoverflow.com/a/779785/940252). Essentially you are allowing the JS to wait until the browser's DOM changes have completed, as these do not necessarily happen synchronously. Also, perhaps use setTimeout instead of setInterval, otherwise it will execute every millisecond until you leave the page! Yikes! – Josh Harrison May 08 '14 at 10:39
  • @ZougenMoriver - thanks for that explanation, its quite obvious once looked at a bit more logically :) also I discovered that setTimeout worked a litle better as a little later on I realised I couldnt click on anything else! :D – MorkPork May 08 '14 at 12:33