tags:

views:

426

answers:

1

On my pages(ASP.NET 3.5) where all input controls have tab order set whenever next input control is not enabled or hidden it goes to the address bar and then to next available control. To fix this behavior, i.e. make it land to the next available control w/o going to address bar I am trying to use jQuery:

$(':text,textarea,select').blur(function()
{
    $(this).next(':text, textarea, select').filter(':enabled:visible').focus();        

});  

But it still goes to the adress bar in some cases. What do I need to correct here?

A: 

Let me start off by saying, I wouldn't do this, but instead use the tabindex property on your controls to get the tab order you want, the address bar only being at the very end since that's what a user expects.

That being said, there is a jQuery way to force what you want, you can do something like this:

$('form :input:enabled:visible').blur(function() {
  var con = $(this).closest('form').find(':input:enabled:visible');
  var i = con.index(this);
  setTimeout(function() { con.eq(i == con.length - 1 ? 0 : i + 1).focus(); }, 0);
});

This changes a few things:

  • .next() only looks for the very next element
    • This looks up to the <form> and gets the next match (change form to body for all inputs).
  • The tab needs to wrap around to the first element when reaching the end
    • Use .index() and i == con.length - 1 ? 0 : i + 1 for this
  • Last, the focus event of the landing element will fire after this blur (by default)
    • To fire immediately after that use a setTimeout(func, 0) like above
Nick Craver
Thanks for reply. Yes, i agree that's exactly what I tried to do at first - setting TabIndex property and all my input controls have it set, but if the next control is disabled it automatically goes to address bar, which is a very problem I am trying to fix.
Victor
@Victor - In that case, try the solution above, it'll fix the tab ordering to stay in the form. To keep the address bar enabled, change the setTimeout line to: `if (i != con.length - 1) setTimeout(function() { con.eq(i + 1).focus(); }, 0);` This will make it go to the address bar after the last enabled input.
Nick Craver
@Nick - will it work with types of controls other then textboxes, i.e. checkboxes, dropdowns, etc? And, also, using this solution will it tab onto validator messages(spans) when they appear on a page?
Victor
@VictorS - Yes, the `:input` selector matches `<input>`, `<select>`, `<textarea>` and `<button>` elements, see the docs for details: http://api.jquery.com/input-selector/
Nick Craver
@Nick - thanks for clarification and link. Will it tab onto asp.net validator controls(spans) if those appear?
Victor
@VictorS - Nope, it'll only tab onto input elements...if you also have dynamically created inputs, change it to `.live('blur', function (){` instead of `.blur(function (){`. A span has no action and so cannot be focused anyway. If you wanted to add anything that **can** be focused (`<a>` for example), just add it in both selectors in the code and it'll work.
Nick Craver
Thanks, so it will look something like this: var con = $(this).closest('form').fin(':input:enabled:visible').find('a:enabled:visible').find('span.ValidatorClass')?
Victor
@VictorS - Use commas like this:`$(this).closest('form').find(':input:enabled:visible, a:enabled:visible, span.ValidatorClass')` use the same for the selector that declares the blur function, best to switch to `.live()` like I mentioned in the previous comment as well.
Nick Craver
Nick, everything works great, thanks so much except for 'live' part, i.e. doesn't tab on to validator spans when they appear.
Victor
@Victor - You can't focus a span, I mentioned this before :)...there's no action. Think of elements you can click and do something, these are the only ones you can focus...a span isn't one of these, so you can't focus it (with jQuery or normally, because what action could happen when you hit enter?)
Nick Craver
@Nick - I would have to disagree on this one, since all Validator controls in asp.net have TabIndex property and I saw you can focus on them, while of course no action happening, except that screen reader reads it:-). That is the only reason I need this, for 508 support
Victor
@Victor - That is only if the browser supports doing it and not all do, it's even in the jQuery docs: "The `focus` event is sent to an element when it gains focus. This event is implicitly applicable to a limited set of elements, such as form elements (`<input>`, `<select>`, etc.) and links (`<a href>`). In recent browser versions, the event can be extended to include all element types by explicitly setting the element's `tabindex` property. An element can gain focus via keyboard commands, such as the Tab key, or by mouse clicks on the element." http://api.jquery.com/focus/
Nick Craver
Thanks for your help
Victor