Using jQuery To Hijack ASP.NET MVC Form Posts

Posted by: Malcolm Sheridan , on 12/22/2009, in Category ASP.NET MVC
Views: 99306
Abstract: The following article demonstrates how to hijack ASP.NET MVC form posts using jQuery.
Using jQuery To Hijack ASP.NET MVC Form Posts
 
I’ve been working with jQuery and ASP.NET MVC for a while now, and it always amazes me the things you can do, but you never think of doing them! Recently I had to post data from a form asynchronously so as not to move the user from the current page. Sounds hard but in reality it’s quite simple. When you use jQuery it’s possible to intercept and change behaviours through hijacking. Some refer as hijaxing since the goal is to add Ajax functionality.  

Shown below is a screencast that demonstrates how to use jQuery to Hijack MVC Forms Posts. If for some reason, you are unable to view the screencast shown below, you can view the screencast directly over here

 


To demonstrate this I’ve created a simple form in my view:
 
<% using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post))
       { %>
       <%= Html.AntiForgeryToken("Sample") %>
        <table>
            <tr>
                <td>
                    <label for="title">
                        Title</label>
                </td>
                <td>
                    <select id="title" name="title">
                        <option>Mr</option>
                        <option>Dr</option>
                        <option>Ms</option>
                        <option>Mrs</option>
                    </select>
                </td>
            </tr>
            <tr>
                <td>
                    <label for="givenName">
                        Given Name</label>
                </td>
                <td>
                    <input id="name" name="givenName" type="text" />
                </td>
            </tr>
            <tr>
                <td>
                    <label for="surname">
                        Surname</label>
                </td>
                <td>
                    <input id="surname" name="surname" type="text" />
                </td>
            </tr>
            <tr>
                <td>
                    &nbsp;
                </td>
                <td>
                    <input type="submit" value="Submit" />
                </td>
            </tr>
        </table>
    <% } %>
<div id="result"></div>
 
I think you’ll agree that’s a pretty standard form. I’ve told the form to post to the Home controllers SubmitForm action, and a post will occur. If you filled in the form and clicked submit now, the data will be posted to the controller’s action, but a full page refresh will also occur. To get around this you can use jQuery to hijack the form. Here’s the following code to be able to post data using ajax.
 
<script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script language="javascript" type="text/javascript">
        $(function() {
            $("form").submit(function(e) {
                $.post($(this).attr("action"),
                        $(this).serialize(),
                        function(data) {
                    $("#result").html(data);
                });
                e.preventDefault();
            });
        });
</script>
 
I’m catching the forms post event by this line:
 
$("form").submit(function(e) {
 
From there I’m using jQuery $.post operation to send the post request to the server. $.post in its simplest form expects a URL, data and a call-back function. I am retrieving the forms action with this line:
 
$(this).attr("action")
 
This maps back to Home/SubmitForm. I defined this when creating the form:
 
using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post))
 
The data is serialized with the following code:
 
$(this).serialize()
 
Finally I’ve created a call back function to render the result in a <div> element. All of that is good, but the real trick to hijack the form post is the following line:
 
e.preventDefault();
 

preventDefault() does what it says. It prevents the default behaviour of the object. Because the event is from the form, the default behaviour of the form is to submit data. This line stops the page refresh. This is a nice and simple way to post data using Ajax without having to do a page refresh. The entire source code of this article can be downloaded over here

Give me a +1 if you think it was a good article. Thanks!
Recommended Articles
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Jeremy K on Thursday, December 24, 2009 11:30 PM
Enjoyed reading it
Comment posted by Pete on Tuesday, January 19, 2010 9:46 AM
This is an interesting example of how to intercept a form submit.   But if you are making an ajax call ($.post), there is an easier way.    First change the type=”submit”  to type=”button”.   Then add an onclick=”RunIt()”.     Then you will need to add two two javascript functions.   One to get/build the object to send.   Second one that will call the ajax method.

// build args and call Controller/Action
function RunIt()
{
            var dataToSend = BuildDataToSend()
            var methodAction = '/YourApp/YourController/YourAction';
       
          $.ajax({
                data: dataToSend,
                dataType: 'html',
                error: function(XMLHttpRequest, textStatus, errorThrown) {
           // show error if action blows up   
                    var errorObj = JSON.parse(XMLHttpRequest.responseText);
                    alert( “error happen:” + errorObj.message);
                },
                success: function(data) {
                    // fill div with result that came back
                    $('#result').html(data);
                    },
                url: methodAction
            });
}
// Read Dom using JQuery to build data for controller action.
function BuildDataToSend()
        {
            var objToSend = new Object();

// Use JQuery to grab value from DropDown
            objToSend.Title = $('#title option:selected').val();

// Use JQuery to grab value from TextBox
            objToSend.GivenName = $("input[name='givenName']").val();
            objToSend.SurName = $("input[name='surname']").val();
                
            return objToSend;
  }
Comment posted by Malcolm Sheridan on Thursday, January 21, 2010 4:14 AM
@Pete
If you ran your code you're not hijacking a form, just running a function from an onclick event.
Comment posted by fgf on Wednesday, January 27, 2010 11:47 AM
fg
Comment posted by Al on Tuesday, March 9, 2010 2:04 AM
http://jquery.malsup.com/form/
Comment posted by Andersens on Tuesday, March 9, 2010 5:13 AM
@Pete: This is a very nice little script. I'd like to extend this a bit in my application. A user makes some changes to a form, but then attempts to navigate away from the form without submitting it.

Now, I've done this so the user instead of navigating away has the form submitted (just like how your example works). What I really want is for the user to post the form synchronously via ajax before navigating onwards.

I've looked up the .post and .ajax methods, but haven't quite been able to figure out if that at all is possible. Do you have any ideas?

What I basically what to do is the same as you're doing, but not e.preventDefault(). I just want to post the form (and wait for the reply), before continuing the event. Is that possible ?
Comment posted by pufa on Tuesday, March 9, 2010 7:06 AM
Why not just use the jquery forms plug in.

http://malsup.com/jquery/form/#ajaxForm
Comment posted by John Goode on Tuesday, March 9, 2010 8:43 AM
Why not just use the jQuery Form plugin or similar plugin to handle the ajax (aka. Al). It makes no sense to me to have to hijack it.
Comment posted by john Goode on Tuesday, March 9, 2010 8:44 AM
Will add that the explanation of the jQuery post function was very well done. Thanks!
Comment posted by Malcolm Sheridan on Tuesday, March 9, 2010 5:47 PM
@pufa, @john Goode
Yes you can use plugin for that.  I didn't know it existed! This article hopefully just explained another way to do this.  Glad you enjoyed it.
Comment posted by Kacey Jone on Tuesday, April 27, 2010 4:21 AM
Thanks for taking the time to share this, I feel strongly about it and love reading more on this topic. If possible, as you gain knowledge, would you mind updating your blog with more information? It is extremely useful for me.

Comment posted by Justin on Monday, June 21, 2010 8:57 PM
Great article. I was having problems with getting it to work till I found out that the jquery serialise method was sending the option text instead of the values.
Fixed it by adding this beforehand.

$('option').each(function(){
    $(this).text($(this).attr('value'));
});
Comment posted by Sally Omega on Friday, July 16, 2010 7:24 AM
Great article. Thanks for taking the time to share this. I to had trouble getting it to work and used the the above code posted by Justin. Thanks
Comment posted by Jasper Monars on Saturday, July 31, 2010 4:47 PM
@Pete: your code is much longer than the Malcolm Sheridan version. You describe it as an easier way, but I completely disagree. The BuildDataToSend() method is not required - it can be replaced by $(this).serialize().
Comment posted by Josh Williams on Friday, August 13, 2010 2:06 PM
@Jasper: I agree - Malcoms code is 10 lines, with 3 lines being )}; - which is much easier in my book :). Thanks for this btw!
Comment posted by Biruk on Monday, August 16, 2010 3:09 PM
This works fine but how do you blend it with jquery validation (valiation rewitten in the model)? I don't want this to run if my data is not validated.
Comment posted by Toadkiller71 on Friday, October 29, 2010 4:46 PM
Awesome video and article!  I am new to MVC and JQuery and was having trouble figuring out how to update part of the window with remote data whenever the user clicked a checkbox created with an HTML.CheckBoxFor.  It was easy to call a PartialView if I added an input button to the Form, but I didn't want to require the user to click an input button.  Following the steps you laid out, I was able to override the checkbox's click event with the form's action; calling the controller I needed with the form's data attached.  Huge THANKS for posting.
Comment posted by eurosportbet on Wednesday, January 5, 2011 4:50 AM
Nice article, thanks a lot ! Best regards.
John from http://www.ruedesjoueurs.com/eurosportbet.html
Comment posted by Sumit on Tuesday, February 22, 2011 3:04 AM
Thank You Malcom, all I wanted to know was how to 'post' using jQuery and it was this article that finally did it.
Question, how do you declare a 'form' using Razor syntax?
Comment posted by Sumit on Tuesday, February 22, 2011 3:32 AM
Nevermind the question, figured it out myself :-)

@using (Html.BeginForm())
{
...
}
Comment posted by JimFrenette on Saturday, February 26, 2011 10:47 AM
@Biruk - ever get this to work w/ jQuery validation plugin?
Comment posted by heartburn cure on Wednesday, April 20, 2011 9:56 PM
Thanks for the jquery hijack, just found what I was looking for.
Comment posted by Donger on Thursday, September 22, 2011 3:58 AM
var val = $('form').validate();
        var isValid = val.form();
        alert(isValid);
Comment posted by Jake on Tuesday, October 4, 2011 7:47 AM
Great post, my site is about <a href="http://www.curepilesdisease.com">piles disease</a>
Comment posted by fasfsdf on Thursday, August 9, 2012 5:08 AM
jkfjasl
Comment posted by Aitor on Thursday, September 5, 2013 2:55 AM
I have a problem with the post method. Im sending an image, with encType = "multipart/form-data". The first time  I submit the form the webImage is null. However, if I load again the page and I post the form again it wont be null.

If I post the form without hijacking it the result is fine the first time, but I need to hijack it in order to load a partialView. Any ideas about what is happening?
Comment posted by dd on Wednesday, October 2, 2013 11:59 AM
dddfdd
Comment posted by dd on Wednesday, October 2, 2013 12:00 PM
dfdfdfdfdf

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel