Wesley
Wesley

Reputation: 307

MVC3 AJAX passing data to controller. It's being submitted twice

So I have a table that gets transformed to an array using:

var result = $("#enrolledStudents").sortable('toArray');

But when I go a head an pass that into my controller like so:

$("#update-enroll").click(function () {
            var result = $("#enrolledStudents").sortable('toArray');
            $.ajax({
                url: '@Url.Action("Enrollment", "Classroom")',
                data: { students: result },
                type: 'POST',
                traditional: true
            });
        });

My debugging breakpoint gets set off twice, causing issues to arise. What is the proper way to submit data to my controller on POST?

Upvotes: 0

Views: 3394

Answers (3)

anAgent
anAgent

Reputation: 2780

Per my comments, there are a couple things that could be causing this.

  1. You have have the unobtrusive file(s) loaded multiple times
  2. Your form has an action method defined, and your button is inside the form tag as a submit button. This will submit the form, and then the click will also submit the form - see example

Example

<form action="/somerowout/someaction">
  <input type="text" id="text1"/>
  <input type="text" id="text1"/>
  <input type="submit" />
</form>

If you need to validate a value on your form before posting, don't hook up an additional Ajax call. Your javascript will look something like:

$(document).ready(function () {
    $("form").submit(function(){
        var result = $("#enrolledStudents").sortable('toArray');
        if(result == null){
            //do something to show validation failed
            return false;
        }
        return true;        
    });
});

And your form code would then look something like:

@using (@Ajax.BeginForm(new AjaxOptions { })) { 
    <input type="text" id="text1"/>
    <input type="text" id="text1"/>
    <input type="submit" />
}

If you want to use Ajax rather than the Html Helpers, use a div instead of a form, and you won't get a duplicate post. Here's how you could achieve this:

<div id="enrolledStudents">
  <--! your elements -->
  <button id="saveStudents">Save</button>
</div>

JavaScript

$(document).ready(function () {
    $("saveStudents").click(function(){
        var result = $("#enrolledStudents").sortable('toArray');
        if(result !== null){ /* do some kind of check here. */
            $.ajax({
                url: '@Url.Action("Enrollment", "Classroom")',
                data: { students: result },
                type: 'POST',
                traditional: true,
                success : function(data) {
                    if (data.status) {
                        window.location = data.route;
                    }               
                }
            })
        } else {
            /* notify ui that save didn't happpen */
        }           
    });
});

Example Controller Action When posting your data using Ajax, here's an example of how to pass the route

[HttpPost]
public ActionResult SomethingPost(SomeModel model) {
    if (Request.IsAjaxRequest()) {
        var json = new {
                   status = true,
                   route = @Url.RouteUrl("MyRouteName", new { /* route values */ })
        };
        return Json(json, JsonRequestBehavior.AllowGet);
    }
}

Upvotes: 3

GRGodoi
GRGodoi

Reputation: 1996

Check if you don't have the jquery files loaded twice. I had this behavior and the problem was files loaded twice.

Upvotes: 1

Shyju
Shyju

Reputation: 218722

Are you sure you are preventing the default behaviour (form POSTING) of the submit button ? use preventDefault to do so.

$("#update-enroll").click(function (e) {
  e.preventDefault();
 //rest of the code

});

EDIT : As per the comment

To do the redirect in the ajax handler, you need to return the URL to be redirected in a JSON Response back to the calle.

[HttpPost]
public ActionResult Classroom(string students)
{
  //do some operaton
  if(Request.IsAjax())
  {
     //This is an Ajax call
     return Json(new
                   {
                     Status="Success",
                     NewUrl = Url.Action("Index","Home")
                   });
  }
  else
  {
     //Normal request. Use RedirectToActiom
      return RedirectToAction("Index","Home");
  }

}

Now in your ajax call check the JSON result and do the redirect.

 $.ajax({
         url: '@Url.Action("Enrollment", "Classroom")',
         data: { students: result },
         type: 'POST',           
         dataType: "json",
         contentType: "application/json; charset=utf-8",
         success: function (data) {
               if(data.Status=="Success")
               {
                  window.location.href = data.Newrl;
               }
               else
               {
                   alert("some error");
               }
         }

});

Upvotes: 1

Related Questions