Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Twitter Bootstrap 3 - popover not hiding when leaving the textbox in Opera 12

• ♠️​ ♦️ ♣️ ​♥️ •
Joined
Mar 25, 2012
Messages
909
Reaction score
464
Hey guys,
I've prolly never asked for any help in the coding section of RaGEZONE, until now, I want to give it a try:


I'm using the following script to display popovers on focus with HTML support in Bootstrap 3:

Code:
    $(document).ready(function () {
    	$(".focus-popover").each(function (index) {
    		var showPopover = function () {
    			$(this).popover('show');
    		};
    		var hidePopover = function () {
    			$(this).popover('hide');
    		};
    		$(this).popover({
    			html: true,
    			placement: $(this).attr('data-placement'),
    			trigger: 'manual'
    		})
    		.focus(showPopover)
    		.blur(hidePopover);
    	})
    });

However this input ...
Code:
    <input type="date" ID="test2" class="form-control focus-popover" data-original-title="This is my title" data-placement="top" data-container="body" data-content="Click away and see how this will be dismissed.<br />However, on Opera 12 it will remain."></input>
... is somehow bugged in Opera 12. Due the fact the input type is "date" and not "text" it will not hide the popover when leaving the textbox. I know supporting Opera 12 is kinda odd, but 40% of all Opera users are still using the 12th version due feature reasons.

Please look at in Opera 12 as well as any other browser. The example shows the blur event is not getting called when leaving the "date" type textbox on Opera 12.

What can I do to make it work properly?
(I need solutions to this problem, do not suggest me using any JS calendar control, even when FF is not supporting input type "date" right now, the website will be online in 2 years, assuming the "date" type of inputs will be supported by all common browsers.)
 
Joined
Dec 5, 2004
Messages
2,781
Reaction score
85
Hey, I was curious about this so I decided to make a workaround.

The blur event doesn't fire when the date picker is there for some reason, probably because the date picker is poorly implemented.

A workaround is simple emulating a blur event by using click/focus on another element, so we use html. You can use a parent element if you want
PHP:
$(document).ready(function () {
        $(".focus-popover").each(function (index) {
            var showPopover = function () {
                $(this).popover('show');
            };
            var hidePopover = function () {
                $(this).popover('hide');
            };
            $(this).popover({
                html: true,
                placement: $(this).attr('data-placement'),
                trigger: 'manual'
            })
            .focus(showPopover)
            .blur(hidePopover);

        })
        // The nasty Opera < 12 "workaround"
        if ( window.opera && +window.opera.version() <= 13 ) {
           var $buggyInput = $("#test2"), // Caching is important!
               buggyInputFocus = false,
               buggyFocus = function(event) {
                   event.stopPropagation();
                   if(!buggyInputFocus) {
                       $(this).popover('show');
                       buggyInputFocus = true;
                   }
               },
               buggyBlur = function(event) {
                   $(this).popover('hide');
                   buggyInputFocus = false;
               }
             // The focus also stop triggering if it was blurred then clicked back, so we added a click. It doesn't run buggyFocus twice since it only execute itself if it hasn't been focused first
            $buggyInput.on({
                "focus": buggyFocus,
                "click": buggyFocus,
                "blur":buggyBlur,
                "change":buggyBlur // On change is also important, you don't want to leave it open when it changes
            })
            // Since it doesn't the blur event, we fake it by capturing focus or click on the html tag
            $("html").on({
                click: function() {
                    if ( buggyInputFocus ) $buggyInput.trigger("blur");
                },
                focus: function() {
                    if ( buggyInputFocus ) $buggyInput.trigger("blur");
                }
            })
        }        
});

Working Fiddle:
 
• ♠️​ ♦️ ♣️ ​♥️ •
Joined
Mar 25, 2012
Messages
909
Reaction score
464
Hey, I was curious about this so I decided to make a workaround.

The blur event doesn't fire when the date picker is there for some reason, probably because the date picker is poorly implemented.

A workaround is simple emulating a blur event by using click/focus on another element, so we use html. You can use a parent element if you want
PHP:
$(document).ready(function () {
        $(".focus-popover").each(function (index) {
            var showPopover = function () {
                $(this).popover('show');
            };
            var hidePopover = function () {
                $(this).popover('hide');
            };
            $(this).popover({
                html: true,
                placement: $(this).attr('data-placement'),
                trigger: 'manual'
            })
            .focus(showPopover)
            .blur(hidePopover);

        })
        // The nasty Opera < 12 "workaround"
        if ( window.opera && +window.opera.version() <= 13 ) {
           var $buggyInput = $("#test2"), // Caching is important!
               buggyInputFocus = false,
               buggyFocus = function(event) {
                   event.stopPropagation();
                   if(!buggyInputFocus) {
                       $(this).popover('show');
                       buggyInputFocus = true;
                   }
               },
               buggyBlur = function(event) {
                   $(this).popover('hide');
                   buggyInputFocus = false;
               }
             // The focus also stop triggering if it was blurred then clicked back, so we added a click. It doesn't run buggyFocus twice since it only execute itself if it hasn't been focused first
            $buggyInput.on({
                "focus": buggyFocus,
                "click": buggyFocus,
                "blur":buggyBlur,
                "change":buggyBlur // On change is also important, you don't want to leave it open when it changes
            })
            // Since it doesn't the blur event, we fake it by capturing focus or click on the html tag
            $("html").on({
                click: function() {
                    if ( buggyInputFocus ) $buggyInput.trigger("blur");
                },
                focus: function() {
                    if ( buggyInputFocus ) $buggyInput.trigger("blur");
                }
            })
        }        
});

Thank you.

Are you jsachs from StackOverflow? Anyway, it works for one date field, but not for multiple:

Navigate between them with your mouse.
 
Last edited:
Joined
Dec 5, 2004
Messages
2,781
Reaction score
85
Yes, I am jsachs. I posted there so other people can use this workaround.

It didn't worked for more than an element because I didn't thought of it :p:

Here's the edited code:

PHP:
$(document).ready(function () {
	$(".focus-popover").each(function (index) {
		var showPopover = function () {
			$(this).popover('show');
		};
		var hidePopover = function () {
			$(this).popover('hide');
		};
		$(this).popover({
			html: true,
			placement: $(this).attr('data-placement'),
			trigger: 'manual'
		})
		.focus(showPopover)
		.blur(hidePopover);
	})
    // The nasty Opera < 12 "workaround"
    if (window.opera && +window.opera.version() < 13) {
        var $buggyInputs = $(".operaFix"), // Caching is important!
            buggyInputFocus = false,
            buggyInput = {}, // We store an instance of the focused element
            buggyFocus = function(event) {
                event.stopPropagation();
                if(!buggyInputFocus) {
                    $(buggyInput).popover('hide');
                    $(this).popover('show');
                    buggyInputFocus = true;
                    buggyInput = $(this);
                }
                else if ($(buggyInput).attr("id") !== $(this).attr("id")){
                   $(buggyInput).trigger("blur")
                }
            },
            buggyBlur = function(event) {
                $(this).popover('hide');
                buggyInputFocus = false;
                buggyInput = {}
            }
        ;
             // The focus also stop triggering if it was blurred then clicked back, so we added a click. It doesn't run buggyFocus twice since it only execute itself if it hasn't been focused first
        $buggyInputs.on({
            "focus": buggyFocus,
            "click": buggyFocus,
            "blur": buggyBlur,
            "change": buggyBlur // On change is also important, you don't want to leave it open when it changes
        })
        // Since it doesn't the blur event, we fake it by capturing focus or click on the html tag
        $("html").on({
            click: function() {
                if (buggyInputFocus) $(buggyInput).trigger("blur");
            },
            focus: function() {
                if (buggyInputFocus) $(buggyInput).trigger("blur");
            }
        })
    }
});

I added the class "operaFix" for those inputs that needs the workaround, and remember to always have a different ID on each element since we are comparing them for preventing the input for closing itself!
 
Last edited:
• ♠️​ ♦️ ♣️ ​♥️ •
Joined
Mar 25, 2012
Messages
909
Reaction score
464
Yes, I am jsachs. I posted there so other people can use this workaround.

It didn't worked for more than an element because I didn't thought of it :p:

Here's the edited code:

PHP:
$(document).ready(function () {
	$(".focus-popover").each(function (index) {
		var showPopover = function () {
			$(this).popover('show');
		};
		var hidePopover = function () {
			$(this).popover('hide');
		};
		$(this).popover({
			html: true,
			placement: $(this).attr('data-placement'),
			trigger: 'manual'
		})
		.focus(showPopover)
		.blur(hidePopover);
	})
    // The nasty Opera < 12 "workaround"
    if (window.opera && +window.opera.version() < 13) {
        var $buggyInputs = $(".operaFix"), // Caching is important!
            buggyInputFocus = false,
            buggyInput = {}, // We store an instance of the focused element
            buggyFocus = function(event) {
                event.stopPropagation();
                if(!buggyInputFocus) {
                    $(buggyInput).popover('hide');
                    $(this).popover('show');
                    buggyInputFocus = true;
                    buggyInput = $(this);
                }
                else if ($(buggyInput).attr("id") !== $(this).attr("id")){
                   $(buggyInput).trigger("blur")
                }
            },
            buggyBlur = function(event) {
                $(this).popover('hide');
                buggyInputFocus = false;
                buggyInput = {}
            }
        ;
             // The focus also stop triggering if it was blurred then clicked back, so we added a click. It doesn't run buggyFocus twice since it only execute itself if it hasn't been focused first
        $buggyInputs.on({
            "focus": buggyFocus,
            "click": buggyFocus,
            "blur": buggyBlur,
            "change": buggyBlur // On change is also important, you don't want to leave it open when it changes
        })
        // Since it doesn't the blur event, we fake it by capturing focus or click on the html tag
        $("html").on({
            click: function() {
                if (buggyInputFocus) $(buggyInput).trigger("blur");
            },
            focus: function() {
                if (buggyInputFocus) $(buggyInput).trigger("blur");
            }
        })
    }
});

I added the class "operaFix" for those inputs that needs the workaround, and remember to always have a different ID on each element since we are comparing them for preventing the input for closing itself!

Thank you and great you are at StackOverflow, too. Ofc every ID is unique (this is a gold rule). Your solution is not bad, but I can see it will blink a bit when navigating between those date inputs. But it's fine, Opera 12 users doesn't deserve something more elegant as long as it works. :p
 
Back
Top