Linga
Linga

Reputation: 10573

jQuery dialog losing focus on scrolling

I have a jQuery dialog below. I'm using jQuery UI 1.11.

$("#contactContainer").dialog({
  closeOnEscape: false,
  modal: true,
  dialogClass: 'contactsFooter', 
  open: function(event, ui) {
    $(".ui-dialog-titlebar-close").show();
    $('#dialog_footer').remove();
    $(".contactsFooter").append('<div class="" id="dialog_footer"><div class="dialog-footer-buttons"><button type="button" id ="close" class="button-style-2" onclick="$(\'#hasChangedForm\').val(\'\');" style="margin-left: 5px;">Cancel</button></div></div>');
  },
  autoOpen: false,          
  width: 300,
  minHeight: 'auto',
  maxHeight: 400,
  position: { my: 'top', at: 'top+50' },
  close:function() {
    $('#contactContainer').dialog("option", "position", { my:"top", at:"top+50", of: window });
    $('#contactContainer').html('');
  }
}); 

$("#contactContainer").dialog('open');

Here is the Fiddle. In that fiddle,

  1. Click any of the textbox (means focus. In this example it is the one we have the value "test here").

  2. Now scroll the dialog by clicking the scrollbar of the dialog and drag it down / up and see what is happening. It is loosing the focus on the textbox we clicked. If I press tab, it is setting the focus to the first field again. This is weird.

If I use mouse scroll, the focus is still there on the same field. This is normal.

Frankly, I don't know why this is happening. Can someone help me for how do I prevent the dialog loosing focus when scrolling? I want the focus to be retained on the same field.

Upvotes: 13

Views: 2957

Answers (6)

Fixed. The problem is the tabindex.

I let you a fiddle working. The trick is removing the tabindex just after the initialization of the dialog, it can be done like this:

$(".ui-dialog.ui-widget").removeAttr("tabindex")

If you want this behaviour to be permanent you can edit the jQuery source code. If you reach the dialog section you are going to see a function called _createWrapper. Inside, you can see something like this:

.attr( {

            // Setting tabIndex makes the div focusable
            tabIndex: -1,
            role: "dialog"
        } )

Remove the tabindex from there, and that's all!

Upvotes: 6

Mitul
Mitul

Reputation: 3437

Please try with following JavaScript update.

https://jsfiddle.net/3q22xLhk/5/ You can check on fiddle

$("#contactContainer").dialog({
  closeOnEscape: false,
  modal: true,
  dialogClass: 'contactsFooter',
  open: function(event, ui) {
    $(".ui-dialog-titlebar-close").show();
    $('#dialog_footer').remove();
    $(".contactsFooter").append('<div class="" id="dialog_footer"><div class="dialog-footer-buttons"><button type="button" id ="close" class="button-style-2" onclick="$(\'#hasChangedForm\').val(\'\');" style="margin-left: 5px;">Cancel</button></div></div>');
  },
  autoOpen: false,
  width: 300,
  minHeight: 'auto',
  maxHeight: 400,
  position: {
    my: 'top',
    at: 'top+50'
  },
  close: function() {
    $('#contactContainer').dialog("option", "position", {
      my: "top",
      at: "top+50",
      of: window
    });
    $('#contactContainer').html('');
  }
});
var scrolling = false;
$("#contactContainer").dialog('open');
var lastFocusTextbox = null;
$("#contactContainer input").focus(function() {
  lastFocusTextbox = this;
});

$("#contactContainer").scroll(function(e) {
  scrolling = true;
});


$("#contactContainer").mouseup(function() {
  if (scrolling) {
    if (lastFocusTextbox != null) {
      $(lastFocusTextbox).focus();
    }
    scrolling = false;
  }
});

Upvotes: 0

Christoph
Christoph

Reputation: 1630

This might be a general solution but it needs to be tested:

var lastFocus;

$(document)
  .on("focus", function(e) { lastFocus = e.target; })

$("#divWithTheScrollbar").scroll(function () {
  if (lastFocus) lastFocus.focus();
})

It generally saves which element had focus last and sets it again when you scroll the div. You need to extend it so an intentional blur event will still work without the element being focused again after scroll.

Upvotes: 0

KOUSIK MANDAL
KOUSIK MANDAL

Reputation: 2052

Try this; its working(Not necessary to add id or other selectors with the inpus)

var focused;
setInterval(function(){
        focused = $(':focus');
},500)

$("#contactContainer").scroll(function(){
       //console.log(focused[0]);
       $(focused).focus();
})

Upvotes: 0

geostocker
geostocker

Reputation: 1200

From having looked around on the web it seems like the most viable option you have is the one @pritishvaidya added.

You have to realize that the focus event is triggered when anything gets clicked on your page. Meaning that if you click the scrollbar whilst having your textbox in focus you will put that the scrollbar in focus and lose the focus of the textbox.

I'd suggest you implement the solution by @pritishvaidya, but add some sort of validation around it where you know which one of the controls was in focus last and then force focus on that when the scrollbar's focus has been lost. That would put minimal strain on the client as well as allow you to progress with your use-case.

Happy coding!

Upvotes: 0

Pritish Vaidya
Pritish Vaidya

Reputation: 22209

I think this might help you a bit.

$('#divWithTheScrollbar').scroll(function() {
    $('#elementLosingFocus').focus();
});

Upvotes: 2

Related Questions