views:

123

answers:

1

Here's the thing.

I have multiple icons, which each show a message in a div.

when i hover over the icon, the box shows, when i mouse out, it closes. when i click, i want that the box will not close automatic, but only after i click the X in the corner of this box.

this all worked good, until I added animation.

the problem is that the ":animated" selector doesnt seem to work EVER, and ":visible" seems to work faulty.

when i hover over the icon, the animation starts, when i click on the icon, during the animation, i want that it will not close when i hover out. in stead, when i click it now, it starts the closing animation immediately.

The code:

$(document).ready(function () {

    $(".flyoutdialog").hide();

    $('.flyouticon').click(function () {
        //alert("click");
    //when i click and this function gets called DURING animation i get:
        alert($(this).next(".flyoutdialog").is(":visible")); //false
        alert($(this).next(".flyoutdialog").is(":animated")); //false
        $(this).next(".flyoutdialog").data("clicked", true);
        showDialog($(this));
        return false;
    });

    $('.flyouticon').hoverIntent({
        over: function () {
            showDialog($(this));
        },
        timeout: 500,
        out: function () {
            hideDialog($(this));
        }
    });

    $(".closedialog").click(function () {
        var dialog = $(this).parent().parent();
        dialog.removeData("clicked");
        hideDialog(dialog.prev(".flyouticon"));
    });

});

function showDialog(button) {
    var dialog = button.next(".flyoutdialog");
    alert(dialog.is(":visible")); //false
    alert(dialog.is(":animated")); //false 
    if (!dialog.is(":visible") && !dialog.is(":animated")) { //tried to not run this code when the dialog is not open nor is it in an animation.
        //close all the other dialogs
        $(".flyoutdialog").each(function () {
//$(".flyoutdialog:visible") DID return RESULTS (1), the one under animation
            if ($(this).is(":visible")) {
                alert($(this).is(":visible")); //true??????? why is this true now?
                alert($(this).is(":animated")); //STILL false! and that during animation....
                if ($(this)[0] === dialog[0]) { //this equal thing is false so the hidedialog gets called
                    //alert("hide");
                } else {
                    dialog.removeData("clicked");
                    hideDialog($(this).prev(".flyouticon"));
                }
            }
        });
        var offset = button.offset();
        dialog.offset({ top: offset.top - 5, left: offset.left + 25 });
        dialog.show("blind", { direction: "horizontal" }, 1500);
    }

}

function hideDialog(button) {
    var dialog = button.next(".flyoutdialog");
    //alert(dialog.data("clicked"));
    if (!dialog.data("clicked")) {
        dialog.hide("blind", { direction: "horizontal" }, 1500);
    }
}

is this me or is this a bug in jQuery, or should i do this differently?

html:

 <div class="editor-field">
        <input id="postcode" name="postcode" value="" type="text">
<a href="#" class="flyouticon">
    <img src="/img/help.png" alt="Flyout" width="16"></a>
<div style="display: none; top: 370px; left: 315.55px;" class="flyoutdialog grayicon" title="Postcode">
    <div class="title">

        <h4>
            Postcode</h4>
        <span class="closedialog ui-icon ui-icon-closethick">&nbsp;</span>
    </div>
    <p>
        De postcode kan je met een asterix (*) invullen om zo een reeks van postcodes op te zoeken.<br> Bijvoorbeeld: 92** geeft alle postcodes terug tussen 9200 en 9299</p>
</div>

    </div>
    <div class="editor-label">
        <label for="Gebruikerscode">Gebruikerscode</label>
    </div>
    <div class="editor-field">
        <input id="gebruikerscode" name="gebruikerscode" value="" type="text">
<a href="#" class="flyouticon">
    <img src="/img/help.png" alt="Flyout" width="16"></a>

<div style="display: none;" class="flyoutdialog grayicon" title="Gebruikerscode">
    <div class="title">
        <h4>
            Gebruikerscode</h4>
        <span class="closedialog ui-icon ui-icon-closethick">&nbsp;</span>
    </div>
    <p>
        Dit is de code of 'gebruikersnaam' waarmee de school inlogt. Deze is uniek.</p>

</div>

    </div>

Edit 2:

if I run this code in function showDialog

alert(dialog.html());

when I click on the button to fire this event, When this dialog is ANIMATING, it alerts null

so this is where my problem is. but how do i fix this, and why is this.

+1  A: 

This is how i fixed it. (if anyone can optimize it feel free to do so)

$(document).ready(function () {

    $('.flyouticon').each(function () {
        var dlg = $(this).next(".flyoutdialog");
        var close = dlg.find(".closedialog");
        dlg.hide();

        close.click(function () {
            //alert("clicked  " + dlg.data("clicked"));
            dlg.removeData("clicked");
            hideDialog(dlg);
        });

        $(this).click(function () {
            dlg.data("clicked", true);
            showDialog(dlg, $(this));
            return false;
        });
        $(this).hoverIntent({
            over: function () {
                showDialog(dlg, $(this));
            },
            timeout: 500,
            out: function () {
                hideDialog(dlg);
            }
        });

    });

});


function showDialog(dialog, button) {
    //close all the other dialogs
    $(".flyoutdialog:visible").each(function () {

        if ($(this)[0] === dialog[0]) {
            // alert("dont hide");
        } else {
            $(this).removeData("clicked");
            hideDialog($(this));
        }
    });
    if (!dialog.is(":visible")) {
        //position the dialog next to the button
        var offset = button.offset();
        dialog.offset({ top: offset.top - 5, left: offset.left + 25 });
        dialog.show("blind", { direction: "horizontal" }, 1500);
    }
}

function hideDialog(dialog) {
    if (!dialog.data("clicked") && dialog.data("status") != "closing" && dialog.is(":visible")) {
        dialog.data("status", "closing"); //set the status to closing, so it doesnt close again, when it's already closing (but still visible) 
        dialog.hide("blind", { direction: "horizontal" }, 1500);
        dialog.queue(function () {
            //alert(dialog.data("status"));
            dialog.removeData("status");
            $(this).dequeue();
        });
    }
}

an extra word:

By binding functions seperately per item, I made a 'link' between the icon and the dialog. this link was needed, because using sibling() doesnt always work, like when the dialog was in an animation, the sibling returned null. by 'linking' these 2, I no longer have this problem. It works rather nicely now.

Stefanvds