1

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

16
  • 1
    Anyone care to comment on why this was worthy of a down arrow? Commented Oct 16, 2013 at 18:28
  • 2
    I didn't downvote, but most likely because it's off topic on Programmers.SE. Why didn't you post it on Stack Overflow where it belongs? Commented Oct 16, 2013 at 19:26
  • 1
    Rough rule of thumb: If you would solve the problem by writing code it's SO, if you would discuss it with other people at the whiteboard it's Programmers (more the architectural view). Lines can be blurred sometimes but this one seems rather clear a SO topic. Commented Oct 16, 2013 at 20:45
  • 1
    Yes, it is. Added a bootstrap tag. Commented Oct 18, 2013 at 18:25
  • 1
    @EranMedan I don't like that's a good idea. I don't want to go home to your wife and kids :) Commented Oct 18, 2013 at 18:41

3 Answers 3

2
+50

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

10
  • Yes I tried to explain it. Wait a sec im about to edit for easier solution
    – Kierchon
    Commented Oct 18, 2013 at 18:52
  • @gloomy.penguin See my edit. It should make sense. You jsut have to call tooltipManager.title(); so the tooltip is created for when you try and click the div
    – Kierchon
    Commented Oct 18, 2013 at 18:54
  • @Kierchon when the data source is coming from an AJAX request this still doesn't load the data on the first click. Commented Oct 18, 2013 at 18:55
  • @wootscootinboogie It should load the data on the $(document).ready() function. Thats where the tooltipManager.title(); is called and in that function is what calls the ajax so you shouldnt even need a click
    – Kierchon
    Commented Oct 18, 2013 at 18:58
  • @wootscootinboogie Whats happening when you try this code? Does it just take two clicks? I think it might be AJAX takign too long and you just have to wait. Try loading the page and waiting like 20-30 secodnds then making a click. Let me know what happens please
    – Kierchon
    Commented Oct 18, 2013 at 19:01
0

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/

2
  • what is the browser you have tested with i can see it showing tooltip in single click in chrome Commented Oct 18, 2013 at 19:04
  • I am using chrome too. Click it once to open. Then click again to close and again to open and it starts blinking
    – Kierchon
    Commented Oct 18, 2013 at 19:05
0

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/.

1
  • I dont know if this will work. He mentioned that he wanted to pull the XY coordinates from the div. Look in the console on his/my fiddles. They will log the coordinates but yours does not. I think it gets lost when you destroy it
    – Kierchon
    Commented Oct 18, 2013 at 19:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.