-1

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);
}
Mackan
  • 6,200
  • 2
  • 25
  • 45
Isley
  • 197
  • 15

1 Answers1

1

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.
Mackan
  • 6,200
  • 2
  • 25
  • 45
  • Hi, thank you so much to point out these issues. I am inexperienced therefore the mistakes. Could you please enlighten me why in your code the ActionLink will not call the action? And why the last line needed to be commented out? I thought if customer doesn't have an order (customer.Orders.ToList().Count() == 0), it would return the view and go to the "Delete" view page? Thanks. – Isley Jun 02 '15 at 13:39
  • @KEIOKRYSHA The ActionLink won't be called because I put `return false;` in the `click` event (the same as using `event.preventDefault()`). In your code, you were calling the Action with the same parameters, so if it returned json to Ajax it would also return json to the View. If it returned a View, it would do the same to the Ajax (not accepted!). An Action can return different kind of strings, and you can stringify a view to be returned like a json response, but not as you have currently designed it. Instead, I would load the View in another Action, called from the Ajax success (`load()`). – Mackan Jun 02 '15 at 13:45