1

I have two ajax functions that one is recursively working at loop and other is working when click event invoked. I tested both of the functions that are able to work properly. But when i start recursive function button event is not invoked.

Function that works on click event GET Content from ActionResult (MVC)

function UpdateRequests(url, state, id, cell)
{
    $.ajax({
        type: "GET",
        url: url + id,
        success: function (result) {

            if (result == "OK")
            {
                cell.fadeOut("normal", function () {
                    $(this).html(state);
                }).fadeIn();  
            }
            else if(result == "DELETE" || result == "CANCEL")
            {
                cell.parent().fadeOut("normal", function () {
                    $(this).remove();
                });  
            }
            else
            {
                $(".modal-body").html(result);
                $("#myModal").modal();
            }
        },
        error: function () {
            alert("Something went wrong");
        }
    });
}

Recursive function GET partial view from ActionResult (MVC)

function RefreshRequests()
        {
            if (isListPage())
            {
                var id = PageId();
                var url = "/Home/List/" + id;
            }
            else
            {
                var url = "/Home/Index";
            }

            $.ajax({
                type: "GET",
                url: url,
                success: function (data) {
                    $(".ajaxRefresh").html(data);
                    EditPageHeader();
                },
                complete: function () {
                    setTimeout(RefreshRequests, 2000);
                }
            });
        }

Click event

    $(".tblRequests").on("click", button, function (e) {

        e.preventDefault();

        var id = $(this).data("id");
        var currentRow = $(this).closest("tr");
        var cell = currentRow.children('td.requestState');

        UpdateRequests(url, state, id, cell);
    });

Main

    $(document).ready(function () {

        EditPageHeader();

        RefreshRequests();
        ButtonEvent(".btnPrepare", "/Home/Prepare/", "PREPARING");
        ButtonEvent(".btnApprove", "/Home/Approve/", "APPROVED");
        ButtonEvent(".btnCancel", "/Home/Cancel/", "CANCELED");

        RefreshRequests();
    }); 
Jongware
  • 22,200
  • 8
  • 54
  • 100
  • When you replace the content of `.ajaxRefresh` with `.html()` any event handlers bound to elements in the previous content will be lost. – Pointy Jul 11 '18 at 12:36
  • In order to prevent this issue i used `$("item").on("click", button, function)` in order to use `$("item").click()` –  Jul 11 '18 at 12:43
  • `$("item")` matches `` elements in the document. Do you mean `$(".item")`? – Pointy Jul 11 '18 at 12:47
  • I use `$("item")` referring to any possible item. I try to give example. –  Jul 11 '18 at 13:11
  • Answers go into "Your Answer", not in your question. – Jongware Jul 11 '18 at 14:31

2 Answers2

0

Assumptions:

  1. The Ajax Calls bring you data that end up as HTML elements in the modal body.
  2. These new elements added above need to respond to the click event (the one that doesn't work correctly right now)

If the above 2 are true, than what is happening is you are binding events to existing elements (if any) and new elements (coming from API response) are not bound to the click event.

The statement

$(".tblRequests").on("click", button, function (e) {
... 
})

needs to be executed every time new elements are added to the body. A better approach for this would be to define the event handler as an individual method and then bind it to each new element.

var clickHandler = function (e) {

  e.preventDefault();

  var id = $(this).data("id");
  var currentRow = $(this).closest("tr");
  var cell = currentRow.children('td.requestState');

  UpdateRequests(url, state, id, cell);
}
// Then for each new record that you add
$(".tblRequests").on("click", button, clickHandler);    

It would be helpful if you can try to explain what exactly you are trying to achieve.

  • Thanks for your answer. I tried it but it did not worked. There are some incoming request and i update table at loop in order to show these requests. In button event status of these requests are updated. Requests are come with the status as "WAITING", buttons changes these requests like "PREPARING", "APPROVED" and "CANCELED". –  Jul 11 '18 at 13:09
0

Problem is that the $(this) will hold all elements of the selector. And will also now with one as it will be triggered one time and then never again. Also as can be seen from here, delegate events should be at the closest static element that will contain the dynamic elements.

    function ButtonEvent(button, url, state)
    {
        $("body").on("click", button, function (e) {

            e.preventDefault();
            var button = e.target;

            var id = $(button).data("id");
            var currentRow = $(button).closest("tr");
            var cell = currentRow.children('td.requestState');

            UpdateRequests(url, state, id, cell);
        });
    }