wootscootinboogie
wootscootinboogie

Reputation: 8695

Dynamic div loaded only after second click

I've got an element in the DOM that's draggable and when it's clicked, I want to grab the x/y coordinates (not shown in this example, but for the future) and the height of tooltip that fades in. The source text for the tooltip is an AJAX call and can be of variable length. My problem currently is that the shown.bs.tooltip event is only fired on the second click on the triggering element. code:

        $('#click').draggable();
        $(document.body).on('click', function () {

            tooltipManager.title();
        });
        $('#click').on('shown.bs.tooltip', function () {
            console.log('from getHeight: ' + getHeight($('.tooltip')));
        });
        var tooltipManager = {
            title: function () {
                //ajax code to get title from database
                $.ajax({
                    type: "POST",
                    contentType: "application/json",
                    url: "Service.asmx/GetDrugs",
                    dataType: "json",
                    success: function (data) {
                        //bootstrap uses the title attribute to set the html inside the tooltip
                        //here it's set to the results of the AJAX
                        var $tooltipData = prettyTooltip(data.d);
                        var offset = $('#click').offset();
                        var windowSize = [
                            width = $(window).width(),
                            height = $(window).height()
                        ]
                        //this fires on the first click
                        console.log(window.width);
                        console.log(offset.top);
                        $('#click').tooltip({
                            trigger: 'click',
                            html: true,
                            placement: tooltipManager.placement.setPlacement(data.d),
                            title: $tooltipData.html()
                            //it seems to me that it would be better design to call the tooltipManager
                            //setPlacement function, but since it's an async request, it fails
                        });
                        //if I add click() at the above line I get an infinite loop of AJAX calls

                    },
                    error: function (xhr) {
                        console.log('failed: ' + xhr.status);
                    }
                });
            },
            placement: {
                left: 'left',
                top: 'top',
                right: 'right',
                bottom: 'bottom',
                //if the value of getHeight is over a certain amount
                //I want to change the position of the tooltip
                setPlacement: function () {
                    var height = getHeight($('.tooltip'));
                    var place = '';
                    if (height < 150) {
                        place = 'right';
                    }
                    else {
                        place = 'left'
                    }
                    return place;
                }
            }
        }
        //not sure if this is good design to have this not a property of the tooltipManager object
        //this works currently for placing the tooltip in the correct position
        function prettyTooltip(data) {
            var $div = $('<div>');
            for (var i = 0; i < data.length; i++) {
                var $p = $('<p>').text(data[i]).appendTo($div);
            }
            return $div;
        }
        function getHeight(el) {
            return $(el).height();
        }

If I use the one method instead of on and I add a click() where the code indicates, the tooltip fires on the first click, but I can't get the offset after the one-time click. How can I make sure I retain all my current functionality and not require two clicks to show the tooltip?

EDITED: fiddle

Upvotes: 1

Views: 423

Answers (3)

mnoble01
mnoble01

Reputation: 579

I think the problem is all of the tooltip events are colliding in some way. If you need to fetch the tooltip content fresh every time, one way is to destroy and reinitialize.

Note that the following code also listens for the additional click to hide the tooltip. (If that's not what you wanted, let me know).

if ($('.tooltip:visible').length) { // destroy
  $('#click')
    .tooltip('destroy');
} else { // reinitialize
  $('#click')
    .tooltip('destroy')
    .tooltip({
      trigger: 'click',
      html: true,
      title: $tooltipData.html()})
    .tooltip('show');
}

Updated fiddle: http://jsfiddle.net/RxtBq/4/.

Upvotes: 0

Anto Subash
Anto Subash

Reputation: 3215

you can place a .tooltip('show') after the tooltip is created

$('#click').tooltip({
                    trigger: 'click',
                    html: true,
                    title: $tooltipData.html()

                }).tooltip('show');

here is the fiddle http://jsfiddle.net/g5mbn/

Upvotes: 0

Kierchon
Kierchon

Reputation: 2289

Youre document.body needs to be clicked once to initiate the tooltip. So at the bottom of your document.ready just add a click event. Before the first click was initiating the tooltip and then the second click on the actual #click was showing it.

See here: http://jsfiddle.net/RxtBq/2/

I just added

$(document.body).click();

right before the end of $(document).ready(function () {

EDIT:

Alternatively. You can get rid of the:

$(document.body).on('click', function () {
            tooltipManager.title();
        });

And just call the tooltipManager.title(); at the end of the document.ready function.

http://jsfiddle.net/RxtBq/3/

The most important part is that tooltipManager.title(); is called before you try and click the #click div

Upvotes: 2

Related Questions