Reputation: 4040
I am building a JQuery Mobile application based on a MVC framework.
My problem is that I cannot send "redirect" directives (either HTTP, Javascript, META-refresh) to the browser.
It results in the browser displaying a single line : "undefined".
Here is the code for the redirect on the server side :
<html><head>
<script>location.href='$url'</script>
</head></html>
I know that I can fix the problem by using data-ajax=false
, but i don't want that since :
Is there a way to make JQuery Mobile handle correctly one kind of redirect ? either HTTP, HTML META or Javascript ?
Upvotes: 7
Views: 2654
Reputation: 145890
Looks like this would be a better solution - from the jQuery Mobile demos.
Basically you set a http header in your redirect and look for it on pagecontainerload
. This should avoid weirdness with browser history.
Here's a a href
to get to the page
<a href="redirect.php?to=redirect-target.html"
data-role="button" data-inline="true">Redirect</a>
In PHP you do this
<?php
// ************************************************************************
// The two-second sleep simulates network delays, hopefully causing a
// loading indicator message to appear on the client side.
// ************************************************************************
sleep(2);
$dst = ( isset( $_GET[ "to" ] )
? $_GET[ "to" ]
: ( isset( $_POST[ "to" ] )
? $_POST[ "to" ]
: false ) );
if ( $dst ) {
// **********************************************************************
// The crucial line: Issue a custom header with the location to which the
// redirect should happen. For simplicity, we simply redirect to whatever
// location was specified in the request's "to" parameter, but real-world
// scripts can compute the destination based on server-side state.
//
// NB: This is not a HTTP redirect. As far as HTTP is concerned, this is
// a normal request/response cycle with a status code of 200.
// **********************************************************************
header( "X-Redirect: " . $dst );
}
?>
Then in your javascript you do this to intercept the URL and reset it.
$( document ).bind( "pagecontainerload", function( e, triggerData ) {
// We can use this event to recognize that this is a redirect. The event is
// triggered when jQuery Mobile has finished loading a page and inserting
// it into the DOM, but before it has altered the browser history. In this
// example the server helpfully returns a custom header. However, if you
// don't have access to the server side, you can still examine
// triggerData.page, which contains the page that was loaded, but which
// has not yet been displayed or even recorded in the browser history. You
// can also examine triggerData.xhr which contains the full XMLHTTPRequest.
// If there is a way to recognize that this is not the expected page, you
// can discard it and issue a second load() call for the page that really
// needs to be displayed to the user, reusing the options from the overall
// page change process.
var redirect = triggerData.xhr.getResponseHeader( "X-Redirect" );
if ( redirect ) {
// We have identified that this page is really a redirect. Thus, we load
// the real page instead, reusing the options passed in. It is important
// to reuse the options, because they contain the deferred governing this
// page change process. We must also prevent the default on this event so
// that the page change process continues with the desired page.
$( e.target ).pagecontainer( "load", redirect, triggerData.options );
e.preventDefault();
}
});
Note: at time of writing there was a broken link on the jquery demos page for this demo so I had to find it on github
https://github.com/jquery/jquery-mobile/blob/master/demos/navigation-php-redirect/index.php https://github.com/jquery/jquery-mobile/blob/master/demos/navigation-php-redirect/redirect.php
The demo for 1.3 is still working http://demos.jquerymobile.com/1.3.0/docs/examples/redirect/
Upvotes: 1
Reputation: 4040
With help from the JQuery mobile community, I have came up with an elegant solution that can handle both standard HTML redirection (data-ajax="false"
) and JQM page transitions.
The trick is that, when doing JQM transitions, JQM loads the result HTML with javascript; searches for a page `data-role='page' and replaces it in the DOM : It ignores the HTML header.
Hence, we have to put a standard Javascript redirection in the header, and a JQM page load in a dummy page.
Here is the code of the redirection method in my MVC template :
<html>
<head>
<!-- HTML reload (for data-ajax=false) -->
<script>
location.href='<?= $url ?>'
</script>
</head>
<body>
<!-- Change page : JQueryMobile redirect -->
<div data-role="page" id="redirect">
<script>
$.mobile.changePage('<?= $url ?>');
</script>
</div>
</body>
</html>
I hope this helps someone.
Upvotes: 8