Ricardo Andres
Ricardo Andres

Reputation: 335

How can I make a hidden panel toggle on focus or click?

I'm trying to make a panel that appears when focused or clicked. Originally it was on click only and it is easy to set it up that way, but for accessibility I needed to make it so it also expanded when someone tabbed to it (on focus). I tried making it so it opens on focus only since a click will focus as well, but then it wouldn't close when clicked on after open because the focus was still enabled. Anyone got an idea to how to make this work?

$('.online-banking a.button.toggleClosed').one("click focusin", function() {
    $(this).removeClass('toggleClosed');
    $(this).addClass('toggleOpen');
    $('.online-banking-slidedown').slideDown(function() {
        $('.online-banking-slidedown input[type="text"]').focus();
    });
});
$('.online-banking a.button.toggleOpen').one("click focusout", function() {
    $(this).removeClass('toggleOpen');
    $(this).addClass('toggleClosed');
    $('.online-banking-slidedown').slideUp(function() {
        $('.online-banking-slidedown input[type="text"]').blur();
    });

and here's the HTML

<div class="online-banking">
    <a href="#" class="button toggleClosed">Online <span>Banking</span> Login</a>
    <div class="online-banking-slidedown">
        <form id="login" name="login" method="post" action="login.aspx">
            <input type="radio" name="radio" value="radio" id="banking_personal" checked="checked">
            <label class="personal" for="banking_personal">Personal</label>
            <input type="radio" name="radio" value="radio" id="banking_business">
            <label class="business" for="banking_business">Business</label>
            <input name="LoginName" type="text" maxlength="25" autocomplete="off" placeholder="User ID">
            <input type="submit" value="Sign In" data-category="Login" data-action="Click" data-label="Button" data-value="">
        </form>
    </div>
</div>

Upvotes: 0

Views: 179

Answers (2)

zer00ne
zer00ne

Reputation: 43910

  • Toggling implies more than one use. When you use .one() method that's all you get to do...once. Fix: Use .on()
  • If there's an opposite effect method, then there's probably a combination of both methods. Fix: toggleClass() and slideToggle() replaces the corresponding add/removeClass() and slideDown/Up() methods.
  • The .on() method can handle multiple events there's no need to make another event handler for focus and blur when the function is the same for all of them (i.e. toggling). Fix: Add click focus blur to the .on() method.
  • Added style=display:none to $('.online-banking-slidedown') which can be removed as long as .toggleClosed class has display:none in CSS.
  • Since the button is an <a>nchor, it's a good precaution to add e.preventDefault() to keep the link from jumping to another location.

$('.online-banking a.button.toggleClosed').on("click focus blur", function(e) {
  e.preventDefault();
  e.stopImmediatePropagation();
  $(this).toggleClass('toggleClosed toggleOpen');
  $('.online-banking-slidedown').slideToggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="online-banking">
  <a href="#" class="button toggleClosed">Online <span>Banking</span> Login</a>
  <div class="online-banking-slidedown" style='display:none'>
    <form id="login" name="login" method="post" action="login.aspx">
      <input type="radio" name="radio" value="radio" id="banking_personal" checked="checked">
      <label class="personal" for="banking_personal">Personal</label>
      <input type="radio" name="radio" value="radio" id="banking_business">
      <label class="business" for="banking_business">Business</label>
      <input name="LoginName" type="text" maxlength="25" autocomplete="off" placeholder="User ID">
      <input type="submit" value="Sign In" data-category="Login" data-action="Click" data-label="Button" data-value="">
    </form>
  </div>
</div>

Upvotes: 1

Huangism
Huangism

Reputation: 16438

I think you may have the wrong idea when it comes to accessibility(AODA). Your button which is an anchor is NOT hidden, only some contents are hidden. So there is no need to bind focus on the anchor, the only real to do here for AODA is to set focus on the content that shows after you clicked on the button. So the user knows that something happened.

Or you could announce that some content was just shown to the user. When user clicks on the button again (close) the focus should just remain on the anchor, so there should not be any to dos there.

To set focus on the content, say a div, you just need to give it a tabindex="-1" and then you can programmatically focus it with js.

It looks like you are already setting focus to the input after the slide down is done, which is great.

You can remove

$('.online-banking-slidedown').slideUp(function() {
    $('.online-banking-slidedown input[type="text"]').blur();
});

Because when you clicked on the button to close it, the focus is already on the button and there is no need to blur.

Revert your code back to when you only bound click and you should be good to go

Upvotes: 1

Related Questions