Question

I am using JQuery ui with datepicker and when a user tabs on to a field, they appropriately get the calendar pop up.

  1. User tabs (via key onto field
  2. User selects date with mouse click
  3. User tabs
  4. Tabindex starts over at one (at the beginning of form)

Here is code. (May also have the tab index set)

<input type="text" name="demo" />
<input type="text" class="date" />

The jquery code is:

$(".date").datepicker();

Any suggestions on how I might go about solving this issue (bonus to shortest solution)?

Was it helpful?

Solution

Subscribe to the onClose or the onSelect event:

$("#someinput").datepicker(
{
    // other options goes here
    onSelect: function ()
    {
        // The "this" keyword refers to the input (in this case: #someinput)
        this.focus();
    }
});

Or in the case of onClose:

$("#someinput").datepicker(
{
    onClose: function ()
    {
        this.focus();
    }
});

OTHER TIPS

Thanks for the suggestion Jeff, I modified your onSelect function to use the attribute filter to retrieve only elements with the tabindex specified by "nexttab".

$(function(){
  $(".date").datepicker({
      onSelect: function(){
          currenttab = $(el).attr("tabindex");
          nexttab = currenttab * 1 + 1;
          $("[tabindex='" + nexttab + "']").focus();
      }
  });
});

PS: If you don't have tabindexes specified in your code, like I neglected to do earlier, simply add the following code:

$('input, select').each(function(i, val){
    $(this).attr('tabindex', i + 1);
});

See discussion about this problem at http://bugs.jqueryui.com/ticket/7266 with a solution at http://jsfiddle.net/lankarden/9FtnW/

Similar to Jimmy's approach, but this sets the focus to the calendar icon (assuming your calender uses an icon), I found this way more appropriate when I had multiple date pickers next to each other.

Set the date default options so that they set focus to the icon when the calendar popup closes:

    $(".date").datepicker({
        onClose: function() {
            $(this).next('a').focus(); 
        }
    });

Add a tag to the calendar icon so that it's focusable:

    $(".date").each(function() {
        $($(this).next('img')).wrap($("<A/>").attr("href","#"));
    });

If you really don't care about the tab order, that is, not having it assigned so it follows the flow of the page, you could do something like this.

jQuery('.date').datepicker({
    'onSelect': function(){
        $(this).nextAll('input, button, textarea, a').filter(':first').focus();
    }
});

It works on the assumption that when the user selects the date, he is finished with that field and moves on to the next one, so it simply selects the next field.

You can probably use the onClose event to return focus to your input when the datepicker closes, as this refers to the associated input field in that callback. For example:

$('.date').datepicker({
   onClose: function() { this.focus(); }
});

Having it focus on the same box ultimately causes the date picker to pop back up and what we really want is for it to go to the next field. Here is teh devised solution:

  1. Requires the tabindex attribute to be set on your fields.
  2. This is casting from a string to int in javascript (the * 1).
  3. This actually moves the selected field to the next element, instead of the current focus

    $(function(){
      $(".date").datepicker({
          onSelect: function(){
              currenttab = $(this).attr("tabindex");
              nexttab = currenttab * 1 + 1;
              $(":input").each(function(){
                  if ($(this).attr("tabindex") == nexttab)
                     $(this).focus();
              });
      }
      });
    });
    

Any suggestions to improve on this technique are appreciated.

I had to solve this problem as well and found that the given answers weren't exactly what I was looking for. Here is what I did.

A blog mentioned a jQuery function that would allow you to select the next form element on the screen. I imported that into my project and called it onClose of the datepicker dialog.

In case the link goes dead, here is the function

$.fn.focusNextInputField = function() {
    return this.each(function() {
        var fields = $(this).parents('form:eq(0),body').find('button,input,textarea,select');
        var index = fields.index( this );
        if ( index > -1 && ( index + 1 ) < fields.length ) {
            fields.eq( index + 1 ).focus();
        }
        return false;
    });
};

Then simply called it onClose of the datepicker

$(this).datepicker({
    onClose: function () {
       $(this).focusNextInputField();
    }
});

Hope this helps future visitors.

I was able to get the focus to the next input field after pressing enter (which selects todays date by default) or when clicking a date from the calendar by using this

$(".jqDateField").datepicker('option', {
    dateFormat: 'mm/dd/y', onClose: function () {
        $(':input:eq(' + ($(':input').index(this) + 1) + ')').focus();
    }
});

This may be required to set focus on the next text input incase you have a select or an input button in the "way"

$(':input[type="text"]:eq(' + ($(':input[type="text"]').index(this) + 1) + ')')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top