39

In an ASP.NET MVC app I use jQuery for posting data on button-click:

<button onclick="addProducts()">Add products</button>
....
$.post('<%= Url.Action("AddToCart", "Cart") %>',
            {
                ...
                returnUrl: window.location.href
            });

In the "AddToCart" action of "Cart" controller I use redirection to another View after posting:

    public RedirectToRouteResult AddToCart(..., string returnUrl)
    {
        ...
        return RedirectToAction("Index", new { returnUrl });            
    }

All is okay, except this redirection. I stay on the same page after posting. I suspect it's due to AJAX type of "POST" request.

How to solve the problem with jQuery POST request blocking the redirection?

1
  • Are you trying to redirect to the same page that initiates the Ajax request? Commented Jan 26, 2012 at 15:47

5 Answers 5

102

I created a $.form(url[, data[, method = 'POST']]) function which creates a hidden form, populates it with the specified data and attaches it to the <body>. Here are some examples:

$.form('/index')

<form action="/index" method="POST"></form>
$.form('/new', { title: 'Hello World', body: 'Foo Bar' })

<form action="/index" method="POST">
    <input type="hidden" name="title" value="Hello World" />
    <input type="hidden" name="body" value="Foo Bar" />
</form>
$.form('/info', { userIds: [1, 2, 3, 4] }, 'GET')

<form action="/info" method="GET">
    <input type="hidden" name="userIds[]" value="1" />
    <input type="hidden" name="userIds[]" value="2" />
    <input type="hidden" name="userIds[]" value="3" />
    <input type="hidden" name="userIds[]" value="4" />
</form>
$.form('/profile', { sender: { first: 'John', last: 'Smith', postIds: null },
                     receiver: { first: 'Foo', last: 'Bar', postIds: [1, 2] } })

<form action="/profile" method="POST">
    <input type="hidden" name="sender[first]" value="John">
    <input type="hidden" name="sender[last]" value="Smith">
    <input type="hidden" name="receiver[first]" value="John">
    <input type="hidden" name="receiver[last]" value="Smith">
    <input type="hidden" name="receiver[postIds][]" value="1">
    <input type="hidden" name="receiver[postIds][]" value="2">
</form>

With jQuery's .submit() method you can create and submit a form with a simple expression:

$.form('http://stackoverflow.com/search', { q: '[ajax]' }, 'GET').submit();

Here's the function definition:

jQuery(function($) { $.extend({
    form: function(url, data, method) {
        if (method == null) method = 'POST';
        if (data == null) data = {};

        var form = $('<form>').attr({
            method: method,
            action: url
         }).css({
            display: 'none'
         });

        var addData = function(name, data) {
            if ($.isArray(data)) {
                for (var i = 0; i < data.length; i++) {
                    var value = data[i];
                    addData(name + '[]', value);
                }
            } else if (typeof data === 'object') {
                for (var key in data) {
                    if (data.hasOwnProperty(key)) {
                        addData(name + '[' + key + ']', data[key]);
                    }
                }
            } else if (data != null) {
                form.append($('<input>').attr({
                  type: 'hidden',
                  name: String(name),
                  value: String(data)
                }));
            }
        };

        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                addData(key, data[key]);
            }
        }

        return form.appendTo('body');
    }
}); });
Sign up to request clarification or add additional context in comments.

7 Comments

Why not calling a .remove() after the .submit() to prevent having multiple hidden forms when you call the function a couple of times?
@Samuel Hmm, I haven't used this in a situation where they could happen. Typically, after submitting the user would load the target page, making it irrelevant that I left a <form> in the DOM. I can see that there are some cases where this might come up, but it's probably not worth worrying about in general.
Nice solution, thanks! If you want to post it in a new window you can simply do $.form('/url', { data: data}).attr('target', '_blank').submit().remove();
Something like this should really be part of jQuery already. (+1)
This was helpful for me, but I had to make a change because null was considered an object and was making an extra request recursive request (and never hitting the test for null near the end). Changed to ... } else if (data && typeof data === 'object') { for (var key in data) { if (data.hasOwnProperty(key)) { addData(name + '[' + key + ']', data[key]); } } } else { return ("<input type='hidden' name='"+name+"' value='"+data+"' />"); }
|
9

$.post is an AJAX call.

Your best bet is to make the button a trigger for a form and just submit that using the post method.

An alternative would be to echo your new url from the server, but that defeats the point of AJAX.

Comments

7

Use jQuery.submit() to submit form: http://api.jquery.com/submit/

1 Comment

jQuery.submit() is not a valid method
3
+50

It looks like you are trying to Add Products to the cart and then redirect to your current page. My guess is is that is how you are updating the visual effect of your shopping cart. I would suggest adding the success handler on your $.post and then redirecting to the current page. If an error occurs on the server, you can send back the serialized error and handle it client side.

function addProducts() {
    $.post('<%= Url.Action("AddToCart", "Cart") %>',{
        returnUrl: window.location.href
    }, function(data){
        window.location.href = window.location.href
    });
}

This will refresh your current page after your products are posted.

Here is a fiddle for reference: http://jsfiddle.net/brentmn/B4P6W/3/

Comments

1

If you're doing a full redirect after a post, then why do it with Ajax? You should be able to perform a tradtional POST here and have it successfully redirect.

If you really want an ajax request to go through and still redirect, a very easy and non-intrusive way to do that would be to return a JavascriptResult from your action instead of a RedirectResult:

return JavaScript("window.location = " + returnUrl);

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.