Number of Ajax Requests increases with live jQuery
Asked Answered
M

6

6

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>
Minivet answered 13/6, 2012 at 12:36 Comment(2)
sidenote, not a fix: don't use live() but on() insteadLeporide
I tried your code in Firefox and Chrome (see jsfiddle.net/PXhdj) but it only makes one Ajax request for each change event. Perhaps you have some other code that is making Ajax calls / causing change events? BTW To set styles on elements, use .css('display', 'inline') instead of .attr('style', ...)Swaney
F
0

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.

Falange answered 23/6, 2012 at 12:1 Comment(0)
M
2

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() {

});
Multiply answered 13/6, 2012 at 12:41 Comment(2)
If they can't upgrade and use .on(), they should use .delegate() instead.Marnie
I used live because I wanted to clone my code and the new code also respond to change() but with off the new code which just injected doesn't trigger change. what should I do? thanksMinivet
C
1

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.

Comfortable answered 13/6, 2012 at 12:39 Comment(0)
C
1

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.

Chlorella answered 23/6, 2012 at 13:32 Comment(0)
M
0

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 () {...
Messere answered 17/6, 2012 at 5:56 Comment(0)
J
0

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");

                        }
                    }
                });


        });
Jetsam answered 17/6, 2012 at 19:1 Comment(0)
F
0

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.

Falange answered 23/6, 2012 at 12:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.