Ajax submit redirect MVC 3 - ajax

Although I read dozens of answers I could not find a solution.
I'm using MVC 3 with Razor. I have a simple Form with client validation via ajax. This part works fine. My problem is: In the update Action of my Controller I want to redirect to another Action. If the user disables Javacript, this works fine. But with javascript/ajax enabled, the redirectaction doesn't seem to work. Instead it looks like if some kind of partialview or something like that is executed.
My Controller/Action-code:
Function UpdateItem(Item As CItem) As ActionResult
' some validation code, save etc.
if everythingok then
Return RedirectToAction("Updatesuccess")
else
Return RedirectToAction("EditItem")
endif
End Function
My html page looks like (shortened/pseudo):
Logo image
H1
some text
<form>....</form>
When the form is submitted via ajax the new html code is added beyond "some text", so the form is replaced but everything above the replaced form stays on the page.
When ajax/javascript is disabled then after submit a whole new page is loaded. I checked the http headers and noticed, that with ajax there is no redirect (which is logical in some way because it is ajax).
What can I do? I want to redirect to a new page.
Is it possible to disable the ajax-submit and only use the "normal" form-submit?
I like the client validation via ajax while the user enters data and I want to use this, but for me it would be good enough, if the submit would be a "normal" submit.
I hope someone understands what I want and can help me.
Thanks.

I'm not a 100% sure I understand your question, but what the heck, don't downvote me :)
The problem is, redirect works via sending a HttpResponse with the redirect indicated in the headers, which the browser understands. If you submit via AJAX, it's not the browser that handles the request, it's your OWN JS code.
Here is the trick: instead of returning a redirect, return the Url (preferably as json), and then redirect manually using window.location.
I'm not fluent in VB, here is how I'd do it in C#:
var url = new UrlHelper(this.ControllerContext.RequestContext);
var link = url.Action("UpdateSuccess");
return Json(new {link});
and then in jQuery:
$.ajax({ method: 'POST',
url: 'your post url',
success: function(result) {window.location = result.link; },
// ... (passing form etc)
});

Related

php redirect to another page in laravel

I have a modal view (the one from bootstrap) in the front end.
Upon clicking the submit button the user will be going to a function in controller:
Route::post('post_question', array('uses' => 'QuestionController#postQuestion'));
And at the end of the postQuestion i want to redirect to another page.
I tried:
return Redirect::to('mywebsite/question/1');
return Response::make( '', 302 )->header( 'Location', 'mywebsite/question/1' );
return Redirect::route('question/'.$question_id)->with("question",Question::find($question_id));
header("Location: mywebsite/question/$question_id");
none seem to work though.
The thing is, i can see the request in XHR but just that the page is not redirected.
Is the modal somehow blocking the behavior?
You can redirect with an AJAX request. However, you will find that the results will not be quite what you expected.
On a redirect, Laravel will should set your response code header as a redirect response and then the content of the redirected page would be sent.
You could do one of two things depending on how you wanted to handle things.
Send a JSON response back to the submitted form with a meta data parameter and then use this meta data in your success function to set window.location.
Your Laravel controller responding to the post would look a bit like this:
public function postQuestion()
{
// DO stuff to set your $question
return [
'question' => $question,
'meta' => [
'redirect_url' => url('mywebsite/question/'.$question->id),
'status' => '400',
// Any other meta data you may want to send
],
];
}
Then assuming you are doing some jQuery AJAX call, change your success callback (I'm calling it questionSubmitSuccess here):
questionSubmitSuccess = function (data) {
// Anything you may want to do before redirecting the user
if (data.meta.redirect_url) {
// This redirects the page
window.location = data.meta.redirect_url;
}
}
Continue redirecting from your controller and then do something a bit more similar to rails turbo links and replace the entire page with Javascript:
You can do this a few ways: using [Modify the URL without reloading the page browser History API), or using jQuery.load to submit your form.
The browser history API might work a bit easier as it would still allow you to handle response errors, but it only works in more modern browsers.
jQuery.load would likely require rewriting a bit of your AJAX submitting code and is harder to handle things like errors (it will replace your page content no matter the status code from what I can tell), but it has better browser support.
IMO, the first approach is a bit more maningful as the API endpoint is usable by something other than this single implementation.
Also, there are fewer points of failure and error states to manage compared to trying to replace your entire DOM without a page reload.
U can put button inside form and when u submit that button pass data from page to controller and from controller call the another page with that data
like return View::make('users.index,compact('data'));

Chrome displays ajax response when pressing back button

I've come across a problem that if I use jQuery's Get method to get some content, if I click back, instead of it actually going back one page in the history, it instead shows the content returned by the Ajax query.
Any idea's?
http://www.dameallans.co.uk/preview/allanian-society/news/56/Allanian-test
On the above page, if you use the pagination below the list of comments you will notice when clicking back after changing a page, that it shows the HTML content used to generate the list of comments.
I've noticed it doesn't always do it, but if you click on a different page a few times and click the back button, it simply displays json text within the window instead of the website.
For some reason, this is only affecting Chrome as IE and Firefox work ok.
Make sure your AJAX requests use a different URL from the full HTML documents. Chrome caches the most recent request even if it is just a partial.
https://code.google.com/p/chromium/issues/detail?id=108425
Just in case you are using jQuery with History API (or some library like history.js), you should change $.getJSON to $.ajax with cache set to false:
$.ajax({
dataType: "json",
url: url,
cache: false,
success: function (json) {...}
});
Actually this is the expected behavior of caching system according to specs and not a chrome issue. The cache only differentiate requests base on URL and request method (get, post, ...), not any of the request headers.
But there is a Vary header to tell browser to consider some headers when checking the cache. For example by adding Vary:X-Requested-With to the server response the browser knows that this response vary if request X-Requested-With header is changed. Or by adding Vary:Content-Type to the server response the browser knows that this response vary if request Content-Type header is changed.
You can add this line to your router for PHP:
header('Vary:X-Requested-With');
And use a middleware in node.js:
app.use(function(req, res) {
res.header('Vary', 'X-Requested-With');
});
You can also add a random value to the end of the ajax url. This will ignore the previous chrome cache and will request a new version
url = '/?'+Math.random()
Just add the following header to the Response headers :
Vary: Accept
I couldn't give different urls for each ajax request as it was an ajax pagination, declaring no cache on headers did nothing, so i included a little javascript in the view only when headers were for the ajax request:
<script>
if (typeof jQuery == 'undefined') {
window.location = "<?php echo $this->here; ?>";
}
</script>
It is a dirty trick, but it works, if the ajax content is normally loaded, the container has Jquery loaded so it does nothing. But if you load the ajax supposed content without the surrounding content, Jquery is missing (at least in my case), so i redirect to the current page requesting a normal GET page with all the headers and scripts.
If you put it in the top of the page, the user won't notice because it won't wait till the page loads, it will redirect as soon as the browser gets this 4 lines...
Replace here; ?> by the current url in your APP, this was a CakePhp 2.X
Still had this problem in 2021 in Chrome.
Problem is doing underlying ajax request to the same url as the one the user is currently on.
I was working in Symfony and the complete fix that did the work for me was
$response->headers->addCacheControlDirective('no-cache', true);
$response->headers->addCacheControlDirective('max-age', 0);
$response->headers->addCacheControlDirective('s-maxage', 0);
$response->headers->addCacheControlDirective('must-revalidate', true);
$response->headers->addCacheControlDirective('no-store', true);
/**
* from https://stackoverflow.com/a/1975677/5418514
*
* The HTTP request header 'Accept' defines the Content-Types a client can process.
* If you have two copies of the same content at the same URL, differing only in Content-Type,
* then using Vary: Accept could be appropriate.
*/
$response->headers->set('Vary', 'Accept');
The #abraham's answer is right.
I just wanted to post a solution for Rails: all you need is just add different path to routes.rb.
In example, I have resource :people and I want to compose index page from ajax parts one of those is list of people. The straightforward way is to create index.js.erb and to load partial via ajax using url: people_path. But here occurs the issue.
So, for Rails, it needs just add a different route, like
get 'people_list', to: 'people#index', as: :people_list, format: :js
If I want to use index method of a laravel controller returns both html and json response, I add a get parameter at the end of the endpoint to pass browser caching:
axios.get(url, {params: {ajax: 1}})

RedirectToAction MVC 3 after $.ajax call

From my view I am sending via $.ajax a JSON object to my controller to save it in the database.
If all succeeded i want to redirect to another action which will show a diferent view.
If i use this code:
return RedirectToAction("CreatePage", "Survey", new {id = question.PageId});
The execution goes to the Survey controller which returns a view but it is not shown.
I have read some post which said that it is not posible to redirect via ajax.
The solution I use so far is to redirect via javascript like this:
success: function (ret) {
window.location.href = "/Survey/CreatePage/" + $("#PageId").val();
}
Although this always works, sometimes i need to refresh the CreatePage view to show the last changes made.
Any idea of how to solve this problem better?
Thanks in advance
As mccow002 suggested, I wasn't really needing to make the call via AJAX for that part. After studying the solutions suggested, i realized that i could simple submit it in a form. My confusion came because I have a save and continue editing and a save. For the save and continue I use the AJAX call, but for the save option with the form being submitted is ok.
Thanks very much for your help.
Instead of redirecting to a new page, you can send a rendered html from .net code back to client and load that html in page, like this $("#main").load(renderedHtml).
But for refreshing the page you can write a simple script that run at specified intervals and refresh the page contens.
You could use [OutputCache] on the CreatePage action so that it doesn't cache the page or only caches for so long.
output caching

how to get information from php without refreshing the page

hi
sorry for the bad title but I'm not 100% sure what I need for this problem
I created a welcome page and then when you click on links you get more information, for example:
Click Me
And then the php would get the information based on the id.
so the information received is reloaded on the page after the pages refreshes
what I would like to be able to do is when user clicks on the link, use jquery to not allow the link to run but still run the url in the background (without refreshing the page)
I have no idea where to start from so I really hope you could help
thanks
In a nutshell, it's called Ajax: sending an HTTP request to your server through javaScript, and receiving a response which can contain results, data, or other information.
You mention jQuery, here are the docs about that:
http://api.jquery.com/jQuery.get/
http://api.jquery.com/jQuery.post/
are convenience methods, which encapsulate $.ajax with preset options.
http://api.jquery.com/category/ajax/ is an overview of the whole system in jQuery.
The basics go like
//include jquery, etc.
$(document).ready(function(){
$('#some_element').click(function(){
$.get('some_url_on_your_server.php',{'data':'whatever params'},function(data){
do_something();//
},'json');
});
This will bind an element to make an Ajax call on click, and then you use the function ('success' function, in $.ajax) to handle the json data.
Have your server send back the data in JSON by using json_encode in php. Be sure to send the right header back, like
<?php
header('Content-Type: application/json');
echo json_encode($some_array);
exit;
There's a lot of resources on the web and SO for learning about Ajax, it's a big topic. Best of luck.
Make a JavaScript function, like sendData(linkId) and then each tag would have an onclick event called sendData(this). SendData(linkId) can then do an HTTPRequest (also known as an asynchronous or AJAX request) to a php file, let's call it handler.php, which receives GET or POST methods. I prefer using the prototype framework to do this kind of thing (you can get it at prototypejs.org).
Okay, now that I have said all that, let's look into the nitty-gritty of how to do this (way simplified for illustrative purposes).
Download the prototype script, save it on your server (like prototype/prototype.js, for example) and then put somewhere in your html <script type='text/javascript' language='Javascript' src='prototype/prototype.js'></script>
Your tags would look like this:<a id='exampleLink' onclick = 'sendData(this)'>Click me!</a>
You need JavaScript to do this: function sendData(tagId){
var url = 'handler.php?' + 'id=' + tagId;
var request = new AJAX.Request(url, {method = 'get'});
}
Finally, you need a php file (let's call it handler.php) that has the following: <?php
$tag_to_get = $_GET['tagId'];
do_a_php_function($tag_to_get);
?>
That's it in a nutshell, but it's worth mentioning that you should give your user some sort of feedback that clicking link did something. Otherwise he will click the link furiously waiting for something to happen, when it is actually doing just what its supposed to but in secret. You do that by making your php script echo something at the end, like 'Success!', and then add an onSuccess parameter to your JavaScript's new Ajax.Request. I'll let you read how to do that on your own because the prototype website explains how to receive a response from the handler and put the feedback somewhere in your HTML without making the user refresh.
you can achieve that behavior with a jquery function called $.get ... you can get more information on how to use here http://api.jquery.com/jQuery.get/
If you really want to (and I don't think you really do), you can use XMLHTTPRequest (wrapped in jQuery.get) to facilitate loading content into the page without page refreshing. You want an id or class on that tag, i.e. Click Me, and then:
<script>
$(".fetch").bind("click", function(evt)
{
$.get(this.attr("href"), function(data)
{
$("#whereIWantMyContent").html(data);
});
evt.preventDefault();
});
</script>
I would recommend you use AJAX to start with. A good place to being is http://www.w3schools.com/Ajax/Default.Asp
The link comes with a handy AJAX ASP/PHP Example too =))
Good Luck.

Go - How to load a new html form

After processing a jQuery Ajax Post from an HTML form successfully within a Go program, how do I load a new form? I first tried sending the form as the response and the Javascript displayed it, but it did not clear the old (existing) form. I then tried within the HTML Javascript to set the URL using "window.location = 'localhost:8088/MaintForm/'". That resulted in a warning from the browser but did not load the form and did not change the URL. I would like to ideally know both methods - via the Go program acting as a server, and via Javascript. If I manually change the URL, the form loads OK. What I am trying to do is receive a response in Javascript (jQuery Ajax), and then request the new form if the response is positive. I would prefer to do this without changing the URL. As I said above, this partially worked.
You would have to put your original form inside a tag, for example a div, and use your JQuery code to replace the contents of that tag with the new form. This way you are not changing the URL.
This is more of a javascript/JQuery question than a go-specific one.
In javascript:
location.href = '/MaintForm/';
In golang, you can use the http.Redirect function, like this:
http.Redirect(w, r, "/MaintForm/", http.StatusFound)
Please note: this appears to be solved by : I just need to do an "document.write(data);" in Javascript. "Data" contains the new HTML.

Resources