Search code examples
javascriptcssipadjquery-uitooltip

Simple jQuery Tooltip (position distorted on iPad)


I've used simple jQuery UI tooltip on form-fields of my webpage(viz responsive), its working perfectly on desktop on every browser, but on iPad its get distorted when I tap on form-fields as keypad swipe-up. Also header section of my webpage gets fixed on scroll. I've used below code for the custom jQuery Tooltip.

$(function () {
    $('.form-control').tooltip({
      disabled: true,
      position: {
      my: "left top",
      at: "left top-50",
      using: function( position, feedback ) {
        $( this ).css( position );
        $( "<div>" )
        .addClass( "arrow" )
        .addClass( feedback.vertical )
        .addClass( feedback.horizontal )
        .appendTo( this );
      }
      }
    }).on("focusin", function () {

        $(this)
            .tooltip("enable")
            .tooltip("open");

    }).on("focusout", function () {
        $(this)
            .tooltip("close")
            .tooltip("disable");
    });

});

I've written this code to re-initialize the tooltip for the focused field by calling its focusin trigger manually when document size changed. It is working as expected on Desktop browsers but on iPad tooltip is being re-initialized at same place again viz incorrect.

var toolTipEl;
$('#inputSuccess, #inputWarning').tooltip({
  open: function (event, ui) {
   toolTipEl = event.target;
}
});
function checkDocumentHeight(callback){
var lastHeight = document.body.clientHeight, newHeight, timer;
(function run(){
  newHeight = document.body.clientHeight;

  if( lastHeight != newHeight )
    callback();
  lastHeight = newHeight;
  timer = setTimeout(run, 100);
})();
}
function doSomthing(){
  console.log('document resized');


setTimeout(function() {
if ($(toolTipEl).is(':focus')) {
  $(toolTipEl).trigger('focusout').trigger('focusin');
    }
 }, 500);
}
checkDocumentHeight(doSomthing);

Please help me to find out the solution for this.


Solution

  • You will need to reinitialize active Tooltip after completion of any event which cause change in the content (actually height) of your document affecting your Tooltip position.

    First keep reference of the element for which the tooltip is active by listening to its events by adding following codes in your tooltip initialization (Keep your existing code as it is. Just add these additional statements).

    var toolTipEl = undefined;
    
    $(function () {
    
        $('.form-control').tooltip({
    
          open: function (event, ui) {
            toolTipEl = event.target;
          }
    
        }).on("focusin", function () {
    
             toolTipEl = undefined;
    
        }).on("focusout", function () {
    
            toolTipEl = undefined;
    
        }).on("mouseleave", function () {
    
            toolTipEl = undefined;
    
        });
    
    });
    

    Please note, as you are displaying tooltip on focusin event as well. So, you will also need to release the variable if you do not want tooltip pop-upped if focus has changed/left.

    And then create a function for resetting tooltip like below.

    function resetTooltip() {
      if (toolTipEl) {
        $(toolTipEl).trigger('focusout').trigger('focusin');
      };
    }
    

    Call this function in any events which is causing change in the document height. For example if content is coming from an ajax request. You can call restTooltip function by listing to the gloab ajax events. See example below.

    $( document ).ajaxComplete(function() {
      resetTooltip();
    });
    

    I hope it will help you. Ask me if you need any further clarification.