1

I have a form submit with an AJAX post. It works fine.

But when I delete the item by clicking the delete link, I have an issue, a get request not post.

But from my javascript function, you can see I use jQuery css selctor to detect the link clicked or not, so I am confused.

Here is my code

My controller:

public class SessionsController : Controller
{
    private SessionRepository _repository;

    public SessionsController() : this(new SessionRepository()) { }

    public SessionsController(SessionRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index()
    {
        var sessions = _repository.FindAll();

        //for ajax requests, we simply need to render the partial
        if (Request.IsAjaxRequest())
            return PartialView("_sessionList2", sessions);
            //return View("_sessionList", sessions);

        return View(sessions);
    }

    [HttpPost]
    public ActionResult Add(Session session)
    {
        _repository.SaveSession(session);

        if (Request.IsAjaxRequest())
            return Index();

        return RedirectToAction("index");
    }

    [HttpPost]
    public ActionResult Remove(Guid session_id)
    {
        _repository.RemoveSession(session_id);

        return RedirectToAction("index");
    }

}

The session view:

@model IEnumerable<MyMVCDemo.Models.Session>


<h2>Hijax Technique</h2>    

<div id="session-list">        
    @{Html.RenderPartial("_sessionList2");}
</div>

<p>
</p>

@using (Html.BeginForm("add", "sessions", FormMethod.Post, new { @class = "hijax" }))
{
<fieldset>
    <legend>Propose new session</legend>
    <label for="title">Title</label>
    <input type="text" name="title" />

    <label for="description">Description</label>    
    <textarea name="description" rows="3" cols="30"></textarea>

    <label for="level">Level</label>
    <select name="level">
        <option selected="selected" value="100">100</option>
        <option value="200">200</option>
        <option value="300">300</option>
        <option value="400">400</option>        
    </select>

    <br />
    <input type="submit" value="Add" />
    <span id="indicator" style="display:none"><img src="../../content/load.gif"   alt="loading..." /></span>
</fieldset>

}

<label>
   <input type="checkbox" id="use_ajax" />
   Use Ajax?
</label>

<script src="../../Scripts/Common.js" type="text/javascript"></script>

My Partial View:

@model IEnumerable<MyMVCDemo.Models.Session>

<table id="sessions">
<tr>
    <th>Title</th>
    <th>Description</th>
    <th>Level</th>
    <th></th>
</tr>

@if(Model.Count() == 0) {
<tr>
    <td colspan="4" align="center">There are no sessions.  Add one below!</td>
</tr>
}

@foreach (var session in Model)
{ 

    <tr>
        <td>@session.Title</td>
        <td>@session.Description</td>
        <td>session.Level</td>
        <td>   
            @Html.ActionLink("remove", "remove", new { session_id = session.Id }, new { @class = "delete" })
        </td>
    </tr>

}

This is my javascript which call the ajax post:

            $('.delete').click(function () {
    if (confirm('Are you sure you want to delete this item?')) {
        $.ajax({
            url: this.href,
            type: 'POST',
            success: function (result) {
                $("#session-list").html(result);
            }
        });

        return false;
    }
    return false;
});
    $("form.hijax").submit(function (event) {
    if ($("#use_ajax")[0].checked == false)
        return;

    event.preventDefault();  //prevent the actual form post
    hijack(this, update_sessions, "html");
});

function hijack(form, callback, format) {
    $("#indicator").show();
    $.ajax({
        url: form.action,
        type: form.method,
        dataType: format,
        data: $(form).serialize(),
        completed: $("#indicator").hide(),
        success: callback
    });
}
function update_sessions(result) {
    //clear the form
    $("form.hijax")[0].reset();

    //update the table with the resulting HTML from the server
    $("#session-list").html(result);
    $("#message").hide().html("session added")
            .fadeIn('slow', function () {
                var e = this;
                setTimeout(function () { $(e).fadeOut('slow'); }, 2000);
            });
}
4
  • why someone devote my post? what's happening? Commented May 29, 2011 at 6:27
  • maybe its just me.. but from your paragraph its difficult to tell exactly what you are looking for. What worked the first time? the form submit or the delete link? Commented May 29, 2011 at 6:27
  • The downvote is not mine, but there's a lot of code in your question. Can you try keeping only the code necessary to understand your problem? Commented May 29, 2011 at 6:28
  • I just try to edit it to simplified my question and how to reproduce my issue, you then devote it. Commented May 29, 2011 at 6:30

1 Answer 1

2

It looks to me like you do not rebind the click event after you update the partial.

What happends is that you replace the DOM(which the events are bound to) when you make the ajax call. So after you update post the form all your events are gone.

In jquery there is a live event that would help you here.

The code below is not tested some there might be some problems with it but it should give you an idea.

var sessionList = $('#session-list'); 
$('.delete', sessionList).live('click', function () {
    if (confirm('Are you sure you want to delete this item?')) {
        $.ajax({
            url: this.href,
            type: 'POST',
            success: function (result) {
                sessionList.html(result);
            }
        });

        return false;
    }
    return false;
});

The selector $('.delete', sessionList) is to give the live function a context so it doesn't bubble events all the way to the top.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi Mikael, thanks for your fast response. I'd like to know why do I need to declare sessionList variable and attach with jquery selector?
The reason i declare the variable is because you will use it twice. A good rule of thumb is to never do the same thing against the DOM twice as that is expensive. The reason I use it as context in the other selector is so the live function can stop bubbling click events on the sessionsList to save some performance. Not sure where I read that though.
thanks mikael, the live event does solve the problem, I don't know there is such event before. So what's the point to have live and other concreate event like click, keydown etc

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.