oobie11
oobie11

Reputation: 925

How do I show a div when a textarea is focused and hide it when the textarea is blurred in jQuery?

So my question is a bit more complicated then I could fit in the title. I am trying to recreate something like how trello does comments on cards. On trello, when you click inside of the new comment textarea, the textarea expands and a div containing the "Submit Comment" link as well as a few other links for different actions shows (lets call this div the "links-div".

They simply do this by adding a "is-focused" class to the parent div of the "links-div" and handle the un-hiding via CSS.

Where I'm stuck is that if you click outside of the textarea (blurring it), the textarea shrinks back down and the "links-div" hides again UNLESS you click on one of the links inside of the "links-div".

I want to recreate this and be able to click a link or submit button inside of my "links-div" without it hiding, but if I click anything outside of that "links-div", it should hide as normal. How would I go about recreating this? Thanks.

Upvotes: 1

Views: 1076

Answers (2)

oobie11
oobie11

Reputation: 925

So I got this working after going over the answer by @Alex McMillan. It is actually more simple than I was going about it. Instead of using the .on 'focus' and .on 'blur' events on the textarea, I used the .on 'mousedown' event on the document.

Here is a jsfiddle https://jsfiddle.net/h9ohkzdf/8/.

I may try and and use a containing div instead of the whole document and see if that works.

Upvotes: 0

Alex McMillan
Alex McMillan

Reputation: 17962

Here's a potential solution jsbin

This works by monitoring the focus and blur events on elements inside a .comment and toggling a class on the .comment itself.

When a blur event takes place on an element inside a .comment, we can use e.relatedTarget to find out which element has the new focus. Then we can check if the newly-focused element exists inside a .comment or not. If it does, we "cancel" the blur. If it doesn't, we continue as normal.

HTML

<div class="comment">
    <textarea id="ta"></textarea>
    <div class="controls">
        <button>One</button>
        <a href="#">Two</a>
    </div>
</div>

<div>
    <a href="#">This is outside the comment</a>
</div>

CSS

.comment .controls {
    display: none;
}

.comment.is-focused .controls {
    display: block;
}

Javascript / jQuery

// The selector ".comment *" will grab any element INSIDE a .comment
$('.comment *').on('focus', function () {
    // Whenever an element inside a comment gets the focus, give
    // its parent element a class
    $(this).parents('.comment').addClass('is-focused');
});

$('.comment *').on('blur', function (e) {
    var $newFocus = $(e.relatedTarget);

    if ($newFocus.parents('.comment').length > 0) {
        // The newly focused element is inside a comment (potentially
        // not the SAME comment - you'll want to fix this) so cancel
        // the blur
        e.preventDefault();
        return;
    }

    // The newly focused element is outside a comment, so continue
    // to blur this element and also remove our class
    $(this).parents('.comment').removeClass('is-focused');
});

Upvotes: 1

Related Questions