score:3

Accepted answer

Toggle saves it's state on the object you call it on. Each time you call Toggle, it alternates between function 1 and function 2. It knows nothing else about your app. It just alternates between the two functions you pass it each time you call it.

When you reset the state of the popup without using Toggle, it gets out of sync as it now has no idea that you want to go back to the first state. So, when you click again, it executes the second function when you want it to execute the first function.

The best way to solve this problem is to use something smarter than Toggle. You need to either detect whether the popup is open and act accordingly or store some state on whether it's open or not. You can't use Toggle because it isn't smart enough for your application.

In working with your actual code, I also found that handling the mouseup event in the document is not very compatible with handling the click event in the object. The issue is that mouseup comes before click so you would get both events in sequence and you wouldn't get the effect you want. When I changed to a click in the document, it worked a lot easier like this:

$("#general_show").click(function () {
    var $this = $(this);
    if ($this.hasClass('selected')) {
        $this.removeClass('selected').parent().next().hide();
    } else {
        $this.addClass('selected').parent().next().show();
    }
    return(false);
});

$(document).click(function (e) {
    if ($('#general_info').is(':visible') &&
          $(e.target).parents('#general_info').length === 0) {
      $('#general_show').removeClass('selected').parent().next().hide();
      return(false);
    }
});

Working example: http://jsfiddle.net/jfriend00/KTNAq/

score:0

  $("#general_show").click(function () {
      if( $(this).is('.selected') ){
          $(this).removeClass().parent().next().hide()
      }else{
          $(this).addClass('selected').parent().next().show()
      }
  });

  $(document).mouseup(function (e) {
    if (
        $('#general_show').is('.selected')
        && $(e.target).parents('#general_info').length === 0 
        && $(e.target).attr('id')!== "general_show"
    ) {
      $('#general_show').click()
    }
  });

score:0

$("#general_show").click(function () {
    if ( $('#general_info').is(':visible') ){
        // Hiding informations 

        $(this).removeClass('selected').parent().next().hide(); // try to always pass argument to removeClass, which class you want to remove
     } else {
        // Showin informations     
        $(this).addClass('selected').parent().next().show();

  }});

$(document).mouseup(function (e) {
    // We don't want to use this function when clicked on button
    if (e.target.id == 'general_show') return;

    if ( $('#general_info').is(':visible') ){

          $('#general_show').removeClass().parent().next().hide();
       }
});

JSFiddle link: http://jsfiddle.net/MEweN/5/


Related Query

More Query from same tag