Ricardo Binns
Ricardo Binns

Reputation: 3246

prevent the action happen twice

i made a small menu with <ul> <li>:

js:

$('#ulAcoesCliente li').click(function(ev) {
    $(".ulNone").each(function(){
        if($(this).css("display") == "block"){
            $(this).hide('slow');
        }
    });
    $(this).find('>ul').toggle('slow');
    ev.stopPropagation();
});

the each get any menu aready opened, close and open where the user click, like a accordeon ( one at a time ).

but if i click in the same, the event will happen twice.

  1. will close the current sub-menu

  2. will open again.

how can i prevent that to happen ?

i accept any tips to make this event more better/intelligent.

Thansks

edit:

html as required

                              <ul id="ulAcoesCliente">
                                    <li>
                                        <button style="font-size: 9px;" id="optComentario">Comentario</button>
                                        <ul class='ulNone' style="display: none;">
                                            <li>
                                                <button style="font-size: 9px; width: 150px;" id="liInserirComentario">Inserir comentario</button>
                                                <ul style="display: none;">
                                                    <li>
                                                        <div style="margin-left: 10px;padding: 5px;">
                                                            <input id="comentario" type="text" size="20"/>
                                                            <button style="font-size: 9px; width: 60px;" id="butInsereComent">Salvar</button>
                                                        </div>
                                                    </li>
                                                </ul>
                                            </li>
                                            <li style="margin-top: 3px;"><button style="font-size: 9px; width: 150px;" id="listaComent">Listar comentarios</button></li>
                                        </ul>
                                    </li>
                                    <li>
                                        <button style="font-size: 9px; margin-top: 3px;" id="OptEmail">E-mail</button>
                                        <ul class='ulNone' style="display: none;">
                                            <li style="margin-top: 5px;"><button style="font-size: 9px; width: 150px;" id="enviaEmail">Enviar E-mail</button></li>
                                            <li style="margin-top: 3px;"><button style="font-size: 9px; width: 150px;" id="listaEmails">Listar E-mails</button></li>
                                        </ul>
                                    </li>
                                    <li>
                                        <button style="font-size: 9px; margin-top: 3px;" id="">Tarefa</button>
                                        <ul class='ulNone' style="display: none;">
                                            <li style="margin-top: 5px;"><button style="font-size: 9px; width: 150px;" id="">Criar Tarefa</button></li>
                                            <li style="margin-top: 3px;"><button style="font-size: 9px; width: 150px;" id="">Listar Tarefas</button></li>
                                        </ul>
                                    </li>
                                </ul>

edit 2:

i reach this: ( @Jayendra, did the same )

but the second level, close.

     if(!($(this).children('ul').css("display") == "block")){
        $(".ulNone").each(function(){
            if($(this).css("display") == "block"){
                $(this).stop(true,true).hide('slow');
            }
        });
        $(this).find('>ul').stop(true,true).toggle('slow');
        ev.stopPropagation();
    }

Upvotes: 0

Views: 342

Answers (4)

hunter
hunter

Reputation: 63542

What is happening is that this .ulNone that you're looping through will select the same ul as your $(this).find('>ul') selector, causing it to close and then open again.

Since you want the top buttons to drive the toggling you should put the event on that, not the li.

$('#ulAcoesCliente > li > button').click(function(ev) {
    $(this).next().toggle('slow');
    $(this).parent("li").siblings().find(".ulNone:visible").toggle('slow');
});

Working Example: http://jsfiddle.net/hunter/cnWjg/

Upvotes: 1

Jayendra
Jayendra

Reputation: 52799

Try - demo

$('#ulAcoesCliente li').click(function(ev) {
    if(!$(this).find('>ul').is(':visible')){
        $(".ulNone:visible").hide('slow');
        $(this).find('>ul').toggle('slow');
        ev.stopPropagation();
    }
});

Upvotes: 1

Richard Neil Ilagan
Richard Neil Ilagan

Reputation: 14737

Maybe something like this?

// caching
var $ulNone = $('.ulNone').filter(function () {
    return $(this).css('display') === 'block';
});

// handler
$('#ulAcoesCliente > li').click(function (e) {

    e.stopPropagation();

    var $myUl = $(this).find('> ul').show('slow');
    $ulNone.not($myUl).hide('slow');

});

The key is removing the UL you're clicking on from the set that you're hiding.

Of course, if you're OC about it, you can just throw the toggle logic into one statement:

$ulNone.not(
    $(this).find('> ul').show('slow')
).hide('slow');

Hurts readability a bit though.

Upvotes: 0

Michael Walsh
Michael Walsh

Reputation: 122

I might suggest doing something like this:

$('#ulAcoesCliente li').click(function() {
  $('#ulAcoesCliente li').slideUp();
  $(this).slideDown();
});

Upvotes: 0

Related Questions