ePezhman
ePezhman

Reputation: 4010

Number of Ajax Requests increases with live jQuery

I have the code below which I use clone() and live(). The code is being load in a jQuery UI dialog with a link. Whenever I click the link it goes to server and fill the dialog with the code below. The first time page is being loaded it works fine, but if I close the dialog and click the link again to get the dialog the number of Ajax requests which is being send increases.

The first time I send trigger the change I send only one request, I close the dialog and load it again and then trigger the change, it send two Ajax request at same time, the third time three request at same time and so on.

Where do you think my problem is?

<input id="TaskId" name="TaskId" type="hidden" value="18" />
<div id="MainDiv">
    <div id="toClone">
        <div style="display: inline;">
            <select id="Tasksess">
                <option value="">لطفاً کار را انتخاب کنيد</option>
                <optgroup label="کار های جديد">
                        <option value="16"style="">q3fe</option>
                        <option value="18"style="">fjhv j</option>
                        <option value="19"style="">wref</option>
                        <option value="25"style="">ff</option>
                </optgroup>
                <optgroup label="کار های در دست اقدام">
                        <option value="13"style="">rr</option>
                        <option value="15"style="">yy</option>
                </optgroup>
                <optgroup label="کار های تمام شده">
                        <option value="14"style="">tt</option>
                        <option value="18"style="">fjhv j</option>
                </optgroup>
            </select>
        </div>
        <div style="display: inline;">
            <select id="Statusess" name="Statusess"><option value="">لطفاً وابستگی را انتخاب کنيد</option>
<option value="1">پيشنياز</option>
<option value="2">همنياز</option>
</select>
        </div>
        <div style="display: none;" id="Ok">
            ok
        </div>
        <div style="display: none;" id="noOk">
            تکراری
        </div>
        <div id="loadingGif" style="display: none;">
            <img src="/Content/Images/ajax-loader/253L.gif" alt=""/>
        </div>
    </div>
</div>
<script type="text/javascript">
    $(document).ready(function () {

        var Maindiv = $("#MainDiv");
        var toClone = $("#toClone");

        //$("#Statusess").each(function () {
            $("#Statusess").live('change', function () {
                if ($(this).find(":selected").val() != "") {                    
                    if ($(this).parent().prev().find(":selected").val() != "") {
                        $(this).parent().parent().find("#loadingGif").attr("style", "display: inline;");
                        $.ajax({
                            url: '/ProjectAdmin/Project/AddTaskDependency?MainTaskId=' + $("#TaskId").val() + '&DependentTaskId=' + $(this).parent().prev().find(":selected").val() + '&Status=' + $(this).find(":selected").val(),
                            type: 'GET',
                            success: function (data, status) {
                                if (data != "0") {
                                    $(this).parent().parent().find("#Ok").attr("style", "display: inline;");
                                    $(this).parent().parent().find("#noOk").attr("style", "display: none;");
                                }
                                else if (data == "0") {
                                    $(this).parent().parent().find("#Ok").attr("style", "display: none;");
                                    $(this).parent().parent().find("#noOk").attr("style", "display: inline;");
                                }
                                var div = $('div:eq(0)', Maindiv).clone();
                                Maindiv.append(div);
                            }
                        });
                        $(this).parent().parent().find("#loadingGif").attr("style", "display: none;");

                    }
                }
            });
        //});

    });
</script>

Upvotes: 6

Views: 819

Answers (6)

user999305
user999305

Reputation: 1013

Does your server code respond with the javascript at the bottom as well?

If so, your problem is that the javascript is executed once for each time the ui dialog is loaded, resulting in an extra binding, thus each time you execute your code, you will add an additional request.

The fix in this case would be easy, move the javascript code to the page that is loading the ui dialog instead.

Upvotes: 1

KoU_warch
KoU_warch

Reputation: 2150

as stated above you should use .delegate() instead of .live().

In order to use delegate all you need to do is specify a parent in which you will be listening to and a selector on which it's going to act.

Try this:

<script>
$(function(){
var Maindiv = $("#MainDiv");
var toClone = $("#toClone");

$("#MainDiv").delegate('#Statusess','change', function () {
    if ($(this).find(":selected").val() != "") {                    
      if ($(this).parent().prev().find(":selected").val() != "") {
        $(this).parent().parent().find("#loadingGif").attr("style", "display: inline;");
        $.ajax({
            url: '/echo/html/',
            type: 'POST',
            success: function (data, status) {
                data = "1";
                if (data != "0") {
                    $(this).parent().parent().find("#Ok").attr("style", "display: inline;");
                    $(this).parent().parent().find("#noOk").attr("style", "display: none;");
                }
                else if (data == "0") {
                    $(this).parent().parent().find("#Ok").attr("style", "display: none;");
                    $(this).parent().parent().find("#noOk").attr("style", "display: inline;");
                }
                var div = $('div:eq(0)', Maindiv).clone();
                Maindiv.append(div);
            }
        });
        $(this).parent().parent().find("#loadingGif").attr("style", "display: none;");

    }
  }
});
});
</script>

Here you a have a working jsfiddle, also here is a link for reference to .delegate() function.

Upvotes: 0

Jean G.T
Jean G.T

Reputation: 1

Perhaps you can try:

        jQuery(function ($) {

            var Maindiv = $("#MainDiv");
            var toClone = $("#toClone");

                $("#Statusess").on('change', function () {
                    if ($(this).find(":selected").val() != "") {                    
                        if ($(this).parent().prev().find(":selected").val() != "") {
                            $(this).parent().parent().find("#loadingGif").css("display", "inline");
                            $.ajax({
                                url: '/ProjectAdmin/Project/AddTaskDependency?MainTaskId=' + $("#TaskId").val() + '&DependentTaskId=' + $(this).parent().prev().find(":selected").val() + '&Status=' + $(this).find(":selected").val(),
                                type: 'GET',
                                success: function (data, status) {
                                    if (data != 0) {
                                        $(this).parent().parent().find("#Ok").css("display", "inline");
                                        $(this).parent().parent().find("#noOk").css("display", "none");
                                    }
                                    else if (data == 0) {
                                        $(this).parent().parent().find("#Ok").css("display", "none");
                                        $(this).parent().parent().find("#noOk").css("display", "inline");
                                    }
                                    var div = $('div:eq(0)', Maindiv).clone();
                                    Maindiv.append(div);
                                    div.empty();
                                }
                            });
                            $(this).parent().parent().find("#loadingGif").css("display", "none");

                        }
                    }
                });


        });

Upvotes: 0

charlietfl
charlietfl

Reputation: 171690

Either bind the event handler directly, without live() or any other delegation method , or move the code to external script file so you aren't loading the same code on each ajax call. Using die() is simply a band aid to a problem that doesn't need to exist and can be fixed simply.

If leaving the code in place can simply use:

  $("#Statusess").change(function () {...

Upvotes: 0

sp00m
sp00m

Reputation: 48837

You should try:

$("#Statusess").off('change').on('change', function() {

});

PS: only with jQuery 1.7+. If you can't upgrade:

$("#Statusess").die('change').live('change', function() {

});

Upvotes: 2

NickGreen
NickGreen

Reputation: 1752

In this case you shouldn't use live because the bindings are 'remembered' each time the dialog gets opened. If I understand your problem correctly, you should use 'click' instead of 'live' binding.

Upvotes: 1

Related Questions