1
\$\begingroup\$

I'm making a calendar and this is one part of the larger project. This adds a tooltip with more information when a calendar event is clicked. It then disappears after 10 seconds, or earlier if a click is detected. The exception being if the click in on the tooltip itself. This code works but feels kind of "cheaty" to me. I wanted a fresh pair of eyes to let me know if there's a better way of doing this all or a specific part I could do differently.

setUpCalendar: function() {
    var self = this; //Refers to the main Calendar Object
    //Render Calendar
    this.elem.fullCalendar({
        height:     this.options.elemHeight,
        events:     this.entries,
        eventClick: function(event, jsEvent, view) {
            var left = parseInt($(this).css("left")) - 4;
            var top =  parseInt($(this).css("top")) - 80;
            self.placeTooltip(left, top, event);
            return false;
        }
    });
},

placeTooltip: function(left, top, event) {
    var toolTip = $(".tooltip"),
        date = $.fullCalendar.formatDate(event.start, "MM dd yyyy hh TT");

    //Format date
    date = date.replace(" ", "/");
    date = date.replace(" ", "/");

    toolTip
        .css({
            "display": "block",
            "position": "absolute",
            "z-index": 10,
            "left": left,
            "top": top
        })
        .html(event.title + "<br />" + date)
        .on("click", function(e) {
            e.stopPropagation(); //Stop click from closing tooltip
        });

    //Remove it later
    $(document).on("click", function() {
        toolTip.hide(); //Hide if clicked anywhere
    });

    if(this.closeTool)
        clearTimeout(this.closeTool);

    this.closeTool = setTimeout(function() {
        toolTip.fadeOut(); //Run this timeout to hide tooltip if not clicked
    }, 10000);
}
\$\endgroup\$
2
  • \$\begingroup\$ are there any particular lines that look weird to you? all I can think of is, if you're using underscore.js you can use the delay function instead of setTimeout: underscorejs.org/#delay \$\endgroup\$
    – user26977
    Commented Jul 16, 2013 at 15:58
  • \$\begingroup\$ How does underscore's delay handle multiple calls? Does it cancel the previous ones, or add them all to a queue of sorts? \$\endgroup\$ Commented Jul 16, 2013 at 16:00

1 Answer 1

2
\$\begingroup\$

You could change the close tooltip fade out to use the jquery delay method (assuming you're using jQuery 1.4+).

Instead of this:

if(this.closeTool)
    clearTimeout(this.closeTool);

this.closeTool = setTimeout(function() {
    toolTip.fadeOut(); //Run this timeout to hide tooltip if not clicked
}, 10000);

You can do this:

if (toolTip.queue().length > 0) {
    toolTip.finish();
} else {
    toolTip.delay(10000).fadeOut();
}

When the user clicks the first time, the effects queue will be empty (length will be 0), so we queue up the delay and the fade out.

When the user clicks the second time, the effects queue length will be more than one, so we use finish to stop the current animation (either the delay or the fade out) and to remove all effects in the effects queue (which will be the delay or both the delay and fade out).

\$\endgroup\$
3
  • \$\begingroup\$ I can't have more than one function call at a time or else the tooltip will disappear at a random time. So if the click event happens again, there needs to be a way to cancel the previously set delay/fadeOut call. \$\endgroup\$ Commented Jul 16, 2013 at 16:47
  • \$\begingroup\$ I like your edit! But I'm trying to understand the advantages of doing it like this over the setTimeout \$\endgroup\$ Commented Jul 16, 2013 at 18:01
  • \$\begingroup\$ @JonnySooter if you're working within jquery you should use whatever it provides and it gives you a nice language to indicate what you actually want to do. You aren't just canceling a function timeout, what you really want to do is stop the animations. \$\endgroup\$
    – user26977
    Commented Jul 16, 2013 at 18:27

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.