Search code examples
ajaxjsoncontrollerasp.net-mvc-5actionlink

Click actionlink on view, controller checks condition, returns JSON, jQuery Ajax doesn't work


Click ActionLink on view, controller checks condition, returns JSON, JQuery Ajax doesn't work.

Click the "Delete" ActionLink, "Delete" controller if customer's "Orders" property is null, if not null, a message will be popped up. If null, process to "Delete" view.

Here are the codes:

1, on the view, the @Html and <script> are together in a loop which goes through all the customers.

@Html.ActionLink("Delete", "Delete", new { id = item.CustomerId }, htmlAttributes: new { @class = "mergo-actionlink", id = "customer-delete-ajax" })

<script type="text/javascript">
$('#customer-delete-ajax').click(
    function doSomething() {
        $.ajax({
            dataType: "json",
            url: '@Url.Action("Delete", "Controllers", new { id = item.CustomerId })',
            success: function (data) {
                alert(data.message);
            },
            async: false
        });
    }
);
</script>

2, the "Delete" controller

public ActionResult Delete(Guid? id)
{
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        Customer customer = db.Customers.Find(id);
        if (customer == null)
        {
            return HttpNotFound();
        }

        if (customer.Orders.ToList().Count() != 0)
        {
            return Json(new { message = "This customer has order(s) attached." }, "text/plain", JsonRequestBehavior.AllowGet);
        }
        return View(customer);
}

Solution

  • Your question is anything but easy to interpret, but as for "Ajax doesn't work":

    1. You state that "the @Html and <script> are together in a loop which goes through all the customers". This will be the first error, since this would create a lot of elements using the same Id, and Id's must be unique. Try with class name as trigger instead (example below).

    2. The JavaScript should not be a part of that loop. There is no need to loop this script - if anything it will be damaging. Move it outside of the loop, and try with class as trigger instead like mentioned above (example below).

    3. Both your ActionLink and click event will call the same Action, at the same time, with the same parameter. I'm not sure I understand what your expectation of this is, but I'll assume that the ActionLink is not supposed to call the Action at all.

    To solve the above issues, follow those steps and try with this code instead:

    // loop begins
    @Html.ActionLink("Delete", "Delete", new { id = item.CustomerId }, htmlAttributes: new { @class = "mergo-actionlink", data_value = item.CustomerId })
    // loop ends
    
    <script type="text/javascript">
    $('.mergo-actionlink').click(function() {
        var clickedId = $(this).attr('data-value');
        $.ajax({
            dataType: "json",
            url: '@Url.Action("Delete", "Controllers")',
            data: { id: clickedId },
            success: function (data) {
                alert(data.message);
            },
            async: false
        });
        return false;
    }); 
    </script>
    
    1. And in your controller, comment out the return View(customer);. Actually the only thing that Action should return is json, since that's the only thing your Ajax will accept. You can change your return type to JsonResult to be explicit.