1
\$\begingroup\$

Firstly, here's a link to the fiddle.

Basically my situation is that there is a requirement to show tooltips on textboxes on some forms being created for a website to allow employees to update their personal information (among other things).

The customer likes the idea of the tooltip being displayed to the right of the textbox when the user clicks into it rather than jQuery UI's default of when hovering over it. To that end, I created the following code that shows and hides the tooltip when the user clicks into/out of the textbox:

$(function () {
    $('.tooltip').each(function () {
        var $this,
            id, 
            t;

        $this = $(this);
        id = this.id;      
        t = $('<span />', {
            title: $this.attr('title')
        }).appendTo($this.parent()).tooltip({
            position: {
                of: '#' + id,
                my: "left+190 center",
                at: "left center",
                collision: "fit"
            }
        });
        // remove the title from the real element.
        $this.attr('title', '');
        $('#' + id).focusin(function () {
            t.tooltip('open');
        }).focusout(function () {
            t.tooltip('close');
        });
    });
});

My question is simple, is there a better way of doing this?

Note that I can rely on the inputs always having a unique Id as this is an ASP.Net application.

\$\endgroup\$
3
\$\begingroup\$

The demo is seen here

$('.tooltip').each(function () {

    //title can be fetched directly from the element. I know no bugs for to
    //require the use of `attr()`. This removes several function calls.

    //No need to get the element by id since the current elements you are iterating
    //over each are the same DOM elements you are trying to attach events to. The
    //`this` in here is where you attach events.

    //You are appending the content to the parent, landing the span next to input.
    //Instead of doing that, you can use `insertAfter()` which inserts the object in
    //context after  the specified element, which is the current object in the
    //`each()`. It also accepts a DOM element so no need to wrap it in jQuery.

    var t = $('<span />', {
        title: this.title
    }).insertAfter(this).tooltip({
        position: {
            of: '#' + this.id,
            my: "left+190 center",
            at: "left center",
            collision: "fit"
        }
    });

    this.title = '';

    //Now the only need to wrap the current object this is here, when we attach events. 

    //Since the event methods are merely shorthands of `on(eventName,fn)`, we use 
    //`on()` instead to lessen function calls. Also, it allows a map of events, which
    //results in calling `on()` only once.

    $(this).on({
        focusin: function () {
            t.tooltip('open');
        },
        focusout: function () {
            t.tooltip('close');
        }
    });
});
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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