jQuery dialog losing focus on scrolling - javascript

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,
Click any of the textbox (means focus. In this example it is the one we have the value "test here").
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.

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!

I think this might help you a bit.
$('#divWithTheScrollbar').scroll(function() {
$('#elementLosingFocus').focus();
});

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!

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();
})

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.

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;
}
});

Related

JqueryUI Tooltip on modal button re-appears on modal close

Hi there StackOverflowvians!
I'm learning to Javascript and JQuery and I've got a connundrum I'm not solving very well. I've used JqueryUI tooltips on some buttons. The tooltip uses the following code to display. I realize that my structure and organizational skills with regards to code suck, and there's probably a million more efficient ways to do what I'm doing, but bear with me - This is quite literally my first attempt at any kind of javascript.
$(function() {
$("#button-menu").tooltip({
position: {
my: "top",
at: "bottom+10",
using: function( position, feedback ) {
$( this ).css( position );
$( "<div>" ).addClass( "arrow" ).addClass( "top" ).appendTo( this );
}
}
});
$("#button-menu").tooltip({ hide: { effect: "fadeOut", duration: 100 }, show: { effect: "fadeIn", duration: 100 }});
});
So I'm calling a tooltip when you hover on the buttons, it's pretty and does what I want. A couple of the buttons when you click them lead to Modal Dialog windows. If one clicks a.search, one gets a modal dialog window with a search form. If one decides to simply close the modal window, it closes and whatnot. I note that when the modal is open, the tooltip closes and the state of the button returns to unfocused. When I close the Modal, the tooltip returns as if I'm hovering on the button - no matter where my mouse is positioned.
I tried to call blur on close for the button item for all buttons in the div, but to no avail. I might try setting a timeout on that function next, because somewhere the tooltip function is re-instating the aria-tooltip class after the button close event and I suppose if I can wait it out I can close it after it opens, but that feels sloppy. The code below was my interpretation of the correct way to call a dialog and close the tooltip for the button on dialog close, but it doesn't do what I think it should. The tooltip still re-appears
$(function() {
$( "#searchform" ).dialog({
modal: true,
autoOpen: false,
close: function( event, ui ) {$('a.search').blur();},
show: {
effect: "fade",
duration: 500
},
hide: {
effect: "fade",
duration: 1000
}
});
$( "a.search" ).click(function() {
$( "#searchform" ).dialog( "open" );
});
});
edit: I suppose I should ask the question - why is this behavior happening, and is there something I can do identify how that tooltip is firing, or just stop it from reappearing when I close the modal?
The Dialog widget has an open() event. I'd be inclined to us it to disable tooltips (like so), and re-enable them on close() by naming your init function and calling it.
Something like:
$('.dialogSelector').dialog({
open: function( event, ui ) {
$('.tooltipSelector').tooltip('disable');
}
});
$('.dialogSelector').dialog({
close: function( event, ui ) {
$('.tooltipSelector').tooltip();
// OR
myTooltipFunction();
}
});
I was having the same problem. What solved it for me was adding an 'Ok' buton
$("#dialog").dialog({
resizable: false,
autoOpen: false,
height: 200,
width: 440,
modal: false,
buttons: {
"Ok": function () {
$(this).dialog("close");
}
}
});

Trigger Twitter Bootstrap Popover on Keyup Event in Textarea?

I'm trying to get a Bootstrap popover to fire when I make a change/keyup event in a text area. The idea is that a user will enter some text, I'll check to see what type of text and based on that, I will fire (or not fire) a popover.
showPopover = function() {
return $(this).popover("show");
};
hidePopover = function() {
return $(this).popover("hide");
};
$("textarea").on("change keyup", function(e) {
$("[rel=next-popover]").popover({
placement: "left",
trigger: "manual"
}).hover(showPopover, hidePopover).click(showPopover);
};
Somehow, this simple thing is not working (I'm also using the data attributes of Bootstrap popover for the popover data). Here is the jsfiddle: http://jsfiddle.net/bpjavascript/CgRKS/
Try
$("textarea").on("change keyup", function (e) {
$("[rel=next-popover]").popover("show");
});
$("[rel=next-popover]").popover({
placement: "right",
trigger: "manual"
})
Demo: Fiddle

How do I set different mmenu options by screen size?

I'm using mmenu (http://mmenu.frebsite.nl) to create my mobile menu. I implement my jQuery code like this :
$('.mobile-menu .menu-block-wrapper').attr('id', 'menu-left');
$('.mobile-menu .menu-block-wrapper').mmenu({
configuration: {
selectedClass: "active",
menuNodetype: "div",
},
dragOpen : {
open: false,
threshold : 100
}
});
$(".mobile-menu-trigger").trigger("open");
I'd like, when my browser window is less than, say, 720px, to set dragOpen to true, and when I switch back to a normal resolution, to set it back to false.
Any help is greatly appreciated.
Thanks
The plugin initializes the dragging when it is fired. So you can't update the option after the plugin has been fired.
I guess you could bind a function to the dragleft, dragright, dragup and dragdown events that measures the browser width and, if larger than 720px, prevents propagation. Something like this:
$("#page").on("dragleft dragright dragup dragdown", function( event ) {
if ( $(window).width() > 720 ) {
event.stopImmediatePropagation();
event.gesture.stopImmediatePropagation();
} else {
// the plugin will fire its events bound to dragleft/dragright/dragup/dragdown
}
});
$('.mobile-menu .menu-block-wrapper').mmenu({
drag: {
open: true,
treshold: 100
}
});
Not sure if this will work though, having seen this issue with hammer.js:
https://github.com/EightMedia/hammer.js/issues/333

ui Dialog works once in IE

I hope someone can help with this problem. I am using ui Dialog that pops up on clicking a link with the same class. The problem is that the link work great once but if i click it again or another link with the same class then only the overlay loads but not the content box in IE only. It works great in firefox.
My script includes an ajax post, if i remove the ajax code then the box works fine on every click.
My code:
$().ready(function() {
$('#dialog').dialog({
autoOpen:false,
title: $(this).attr("title"),
modal: true, width: 450, height:"auto", resizable: false,
close: function(ev, ui) { $(this).remove(); },
overlay: {
opacity: 0.5,
background: "black"
}
});
$(".mybutton").click(function(){
$.post($(this).attr("href"), { },
function(data) {
$('#dialog').html(data);
}
);
$('#dialog').dialog('open');
return false;
});
});
I have multiple links with the class "mybutton" and a div with the id #dialog . I am also using the latest version of jQuery and ui.
Any help would be greatly appreciated. Thanks
I am using IE8, jQuery 1.3.2, jQuery UI 1.7.1
The post is done asynchronously by default. It looks like you expect it to be synchronous. Try moving the open of the dialog into the callback after the data is set rather than in the click function -- which may execute before the callback returns.
move the open into the callback...
$('#dialog').html(data).dialog('open');
I was having the same problem. I resolved it by managing the state of the Dialog myself...creating a new one and disposing of it each time.
function makeDialog()
{
var html = '';
html += '<div>My dialog Html...</div>';
return $(html).dialog(
{
position: 'center',
modal: true,
width: 518,
height: 630,
autoOpen: false,
close: function() { $j(this.remove(); }
});
}

jquery-ui-dialog - How to hook into dialog close event

I am using the jquery-ui-dialog plugin
I am looking for way to refresh the page when in some circumstances when the dialog is closed.
Is there a way to capture a close event from the dialog?
I know I can run code when the close button is clicked but that doesn't cover the user closing with escape or the x in the top right corner.
I have found it!
You can catch the close event using the following code:
$('div#popup_content').on('dialogclose', function(event) {
alert('closed');
});
Obviously I can replace the alert with whatever I need to do.
Edit: As of Jquery 1.7, the bind() has become on()
I believe you can also do it while creating the dialog (copied from a project I did):
dialog = $('#dialog').dialog({
modal: true,
autoOpen: false,
width: 700,
height: 500,
minWidth: 700,
minHeight: 500,
position: ["center", 200],
close: CloseFunction,
overlay: {
opacity: 0.5,
background: "black"
}
});
Note close: CloseFunction
$("#dialog").dialog({
autoOpen: false,
resizable: false,
width: 400,
height: 140,
modal: true,
buttons: {
"SUBMIT": function() {
$("form").submit();
},
"CANCEL": function() {
$(this).dialog("close");
}
},
close: function() {
alert('close');
}
});
$( "#dialogueForm" ).dialog({
autoOpen: false,
height: "auto",
width: "auto",
modal: true,
my: "center",
at: "center",
of: window,
close : function(){
// functionality goes here
}
});
"close" property of dialog gives the close event for the same.
U can also try this
$("#dialog").dialog({
autoOpen: false,
resizable: true,
height: 400,
width: 150,
position: 'center',
title: 'Term Sheet',
beforeClose: function(event, ui) {
console.log('Event Fire');
},
modal: true,
buttons: {
"Submit": function () {
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
This is what worked for me...
$('#dialog').live("dialogclose", function(){
//code to run on dialog close
});
As of jQuery 1.7, the .on() method is the preferred method for attaching event handlers to a document.
Because no one actually created an answer with using .on() instead of bind() i decided to create one.
$('div#dialog').on('dialogclose', function(event) {
//custom logic fired after dialog is closed.
});
add option 'close' like under sample and do what you want inline function
close: function(e){
//do something
}
If I'm understanding the type of window you're talking about, wouldn't $(window).unload() (for the dialog window) give you the hook you need?
(And if I misunderstood, and you're talking about a dialog box made via CSS rather than a pop-up browser window, then all the ways of closing that window are elements you could register click handers for.)
Edit: Ah, I see now you're talking about jquery-ui dialogs, which are made via CSS. You can hook the X which closes the window by registering a click handler for the element with the class ui-dialog-titlebar-close.
More useful, perhaps, is you tell you how to figure that out quickly. While displaying the dialog, just pop open FireBug and Inspect the elements that can close the window. You'll instantly see how they are defined and that gives you what you need to register the click handlers.
So to directly answer your question, I believe the answer is really "no" -- there's isn't a close event you can hook, but "yes" -- you can hook all the ways to close the dialog box fairly easily and get what you want.
You may try the following code for capturing the closing event for any item : page, dialog etc.
$("#dialog").live('pagehide', function(event, ui) {
$(this).hide();
});

Categories

Resources