Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery custom events attached to .show and .hide

I'm exploring the potential of jquery to satisfy some of our UI requirements, and am experiencing some curious behaviour. I'm very new to jQuery, and I'm trying to implement a basic pub-sub type of pattern that's hooked into the show & hide functions.

Despite the custom event mechanism looking perfectly simple on the surface, it isn't behaving as I expect. I can't see my syntactical mistake, so I must be misunderstanding the way these custom events are intended to work.

When I execute this code, Here's what I think should happen.

Initially (after doc.Ready) the question2 element should be hidden.

When I click on the 'Vermont' radio button, question 2 should be made visible followed by one alert box indicating that 'question2 has been made visible'.

When I click on another radio button, question 2 should be hidden followed by one alert box indicating that question 2 has been made hidden.

What is actually happening is that I get numerous alert boxes when making question 2 visible, and none when I hide it? Please help me understand why it's doing this.

Here is the script:

    <script type="text/javascript">

    function processRadioButtonASD() {
        var isChecked = ($("input[name=question1]:checked").val() == "question1.Vermont");
        if (isChecked == true) {
            $("[data-uniquename=question2]").show(250);
        } else {
            $("[data-uniquename=question2]").hide(250);
        }
    }

    function detectVisibilityChange(uniqueName) {
        $("[data-uniquename=" + uniqueName + "]").bind("madeVisible", function () {
            alert($(this).attr("data-uniquename") + " was made visible");
        });
        $("[data-uniquename=" + uniqueName + "]").bind("madeHidden", function () {
            alert($(this).attr("data-uniquename") + " was made hidden");
        });
    }

    $(function () {
        $.each(["show", "hide"], function () {
            var _oldFn = $.fn[this];
            $.fn[this] = function () {
                var wasVisible = $(this).is(':visible');
                var result = _oldFn.apply(this, arguments);
                var isVisible = $(this).is(':visible');

                if ((isVisible == true) && (wasVisible == false)) {
                    $(this).triggerHandler("madeVisible");
                } else if ((isVisible == false) && (wasVisible == true)) {
                    $(this).triggerHandler("madeHidden");
                }
                return result;
            }
        });
    });

    $(document).ready(function () {
        processRadioButtonASD();
        detectVisibilityChange("question2");
        $("input[name='question1']").change(function () { processRadioButtonASD(); });
    });
</script>

Here is the html:

    <div id="content">
    <div id="radioButtonASD" class="example">
        <h2>radio button visibility trigger</h2>
        <div data-uniquename="question1" class="question">
            <label for="question1">
                Question 1) (select Vermont to show Question2)
            </label>
            <br />
            <label data-uniquename="question1.Maine">
                <input name="question1" data-uniquename="question1.Maine" type="radio" value="me" />Maine</label><br />
            <label data-uniquename="question1.Vermont">
                <input name="question1" data-uniquename="question1.Vermont" type="radio" value="question1.Vermont" />Vermont</label><br />
            <label data-uniquename="question1.NewHampshire">
                <input name="question1" data-uniquename="question1.NewHampshire" type="radio" value="question1.NewHampshire" />New
                Hampshire</label><br />
            <label data-uniquename="question1.Conneticut">
                <input name="question1" data-uniquename="question1.Conneticut" type="radio" value="question1.Conneticut" />Conneticut</label><br />
            <label data-uniquename="question1.Massachusetts">
                <input name="question1" data-uniquename="question1.Massachusetts" type="radio" value="question1.Massachusetts" />Massachusetts
            </label>
        </div>
    <br />
        <div data-uniquename="question2" class="question">
            <label>
                Question 2)
            </label>
            <br />
            <select>
                <option data-uniquename="question2.honda" value="honda">Honda</option>
                <option data-uniquename="question2.volvo" value="volvo">Volvo</option>
                <option data-uniquename="question2.saab" value="saab">Saab</option>
                <option data-uniquename="question2.mercedes" value="mercedes">Mercedes</option>
                <option data-uniquename="question2.audi" value="audi">Audi</option>
            </select>
        </div>
    </div>
</div>

Thanks for looking.

like image 668
Todd Avatar asked Jan 23 '26 13:01

Todd


1 Answers

I came up with an alternative way.

$.each(["show", "hide"], function() {
    var effect = $.fn[this];
    $.fn[this] = function(duration, move, callback) {
        // Match the arguments
        var speed = duration;
        var easing = callback && move || move && !jQuery.isFunction( move ) && move;
        var fn = callback || !callback && move || jQuery.isFunction( duration ) && duration;
        // Wrap the callback function   
        var wrapped = fn;
        var wasVisible = $(this).is(':visible');
        fn = function(){
            var isVisible = $(this).is(':visible');
            $.proxy(wrapped, this);
            if ((isVisible == true) && (wasVisible == false)) {
                $(this).triggerHandler("madeVisible");
            } else if ((isVisible == false) && (wasVisible == true)) {
                $(this).triggerHandler("madeHidden");
            }
        };   
        // Run the effect with the wrapped callback             
        return effect.call(this, speed, easing, fn);
    };
});

The idea is make use of the callback function. From there you can refactor and clean the code.

Take a look at a working example.

like image 112
Alexander Avatar answered Jan 25 '26 06:01

Alexander



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!