Prevent jQuery UI dialog from setting focus to first textbox

Viewed 131577

I have setup a jQuery UI modal dialog to display when a user clicks a link. There are two textboxes (I only show the code for 1 for brevity) in that dialog div tag and it is changed to be a jQuery UI DatePicker textbox that reacts on focus.

The problem is that the jQuery UI dialog('open') somehow triggers the first textbox to have focus, which then triggers the datepicker calendar to open immediately.

So I am looking for a way to prevent the focus from happening automatically.

<div><a id="lnkAddReservation" href="#">Add reservation</a></div>

<div id="divNewReservation" style="display:none" title="Add reservation">
    <table>
        <tr>
            <th><asp:Label AssociatedControlID="txtStartDate" runat="server" Text="Start date" /></th>
            <td>
                <asp:TextBox ID="txtStartDate" runat="server" CssClass="datepicker" />
            </td>
        </tr>
    </table>

    <div>
        <asp:Button ID="btnAddReservation" runat="server" OnClick="btnAddReservation_Click" Text="Add reservation" />
    </div>
</div>

<script type="text/javascript">
    $(document).ready(function() {
        var dlg = $('#divNewReservation');
        $('.datepicker').datepicker({ duration: '' });
        dlg.dialog({ autoOpen:false, modal: true, width:400 });
        $('#lnkAddReservation').click(function() { dlg.dialog('open'); return false; });
        dlg.parent().appendTo(jQuery("form:first"));
    });
</script>
30 Answers

jQuery UI 1.10.0 Changelog lists ticket 4731 as being fixed.

Looks like focusSelector was not implemented, but a cascading search for various elements was used instead. From the ticket:

Extend autofocus, starting with [autofocus], then :tabbable content, then buttonpane, then close button, then dialog

So, mark an element with the autofocus attribute and that is the element that should get the focus:

<input autofocus>

In the documentation, the focus logic is explained (just under the table of contents, under the title 'Focus'):

Upon opening a dialog, focus is automatically moved to the first item that matches the following:

  1. The first element within the dialog with the autofocus attribute
  2. The first :tabbable element within the dialog's content
  3. The first :tabbable element within the dialog's buttonpane
  4. The dialog's close button
  5. The dialog itself

I found the following code the jQuery UI dialog function for open.

c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();

You can either workaround the jQuery behaviour or change the behaviour.

tabindex -1 works as a workaround.

Set the tabindex of the input to -1, and then set dialog.open to restore tabindex if you need it later:

$(function() {
    $( "#dialog-message" ).dialog({
        modal: true,
        width: 500,
        autoOpen: false,
        resizable: false,
        open: function()
        {
            $( "#datepicker1" ).attr("tabindex","1");
            $( "#datepicker2" ).attr("tabindex","2");
        }
    });
});

This can be a browser behavior not jQuery plugin issue. Have you tried removing the focus programmatically after you open the popup.

$('#lnkAddReservation').click(function () {
    dlg.dialog('open');

    // you may want to change the selector below
    $('input,textarea,select').blur();

    return false;
});

Haven't tested that but should work ok.

I had a similar problem and solved it by focusing on the dialog after open:

var $dialog = $("#pnlFiltros")
    .dialog({
        autoOpen: false,
        hide: "puff",                   
        width: dWidth,
        height: 'auto',
        draggable: true,
        resizable: true,
        closeOnScape : true,
        position: [x,y]                    
    });
$dialog.dialog('open');
$("#pnlFiltros").focus(); //focus on the div being dialogued (is that a word?)

But in my case the first element is an anchor, so I don't know if in your case that will leave the datepicker opened.

EDIT: only works on IE

I had similar problem. On my page first input is text box with jQuery UI calendar. Second element is button. As date already have value, I set focus on button, but first add trigger for blur on text box. This solve problem in all browsers and probably in all version of jQuery. Tested in version 1.8.2.

<div style="padding-bottom: 30px; height: 40px; width: 100%;">
@using (Html.BeginForm("Statistics", "Admin", FormMethod.Post, new { id = "FormStatistics" }))
{
    <label style="float: left;">@Translation.StatisticsChooseDate</label>
    @Html.TextBoxFor(m => m.SelectDate, new { @class = "js-date-time",  @tabindex=1 })
    <input class="button gray-button button-large button-left-margin text-bold" style="position:relative; top:-5px;" type="submit" id="ButtonStatisticsSearchTrips" value="@Translation.StatisticsSearchTrips"  tabindex="2"/>
}

<script type="text/javascript">
$(document).ready(function () {        
    $("#SelectDate").blur(function () {
        $("#SelectDate").datepicker("hide");
    });
    $("#ButtonStatisticsSearchTrips").focus();

});   

Related