I am developing a web app and want to make the back button in the browser more app like.
A user goes through these steps to post a message:
List all messages -> read one message -> write reply -> gets back to message after reply
If the user then clicks the back button he will get back to the page were he wrote the reply. The prefered action would be to get back to the list of all the messages.
I've tried to use the HTML5 History API to remove the history of "write reply" and "read one message" after posting, but it doesn't seem to be possible to do that.
Are there any other way make it behave like I want, or should I just leave it as it is? I know you shouldn't mess with the back button, but I really think this would make it more logical.
you can try to do in this way:
After the user wrote the reply you can execute this js
// 1) push a fake state in the history
history.pushState({ foo: "test" }, "test", "test.html");
// 2) add a listener when the user press the back button
window.addEventListener('popstate', function(event) {
//redirect user where you want
window.location.href = '...';
}, false);
Keep in mind that the code #point1 will change your URL in the address bar, so if you're using the URL with some fragments or other info in the query string you must deal with them.
For the code #point2, if you're in a single page web app, you must remove the listener once finished this operation.
However this is a possible solution but without know the environment I don't know if can suit your request.
Hope this can help!
Related
I'm building a contact form for my website and I would like users to enter their information, click submit, have the information process with php and to just have a message display on the bottom of the form. Originally, I was redirecting to another page and the form was working properly, but now I just want to append a small message and can't get it to work.
This is what I have currently in my contactengine.php file for it to process all the variables and send the email.
if ($success){
THIS IS WHAT I DID BEFORE THAT WORKED BUT HAS TO REDIRECT
// print "<meta http-equiv=\"refresh\" content=\"0;URL=index_thanks.html\">"; //
//BELOW IS WHAT I WANT TO OCCUR
<script type="text/javascript">
$("#contact-area").append("Thanks for your message!")
</script>
}
You don't need JavaScript for this. JavaScript is great, but it should only be used where necessary, since it can add some brittleness to the user experience.
Here's a possible design approach:
Set up a POST form
Process the form, set a session variable to thank the user, and redirect to the form again. This switches the browser from POST to GET mode†, and is usually as simple as this:
header('Location: http://yourdomain.com/form.php');
exit();
Render the form as usual. If a session variable is set to thank the user, render the thank you message, and unset the session variable‡
I wouldn't use a <meta /> refresh here - it needs to load more data to work, and is more fiddly to implement.
† The POST-redirect approach is a common design pattern in web development. There are plenty of resources about this on the web, if you are unfamiliar with it. It fixes problems associated with rendering web content inside a POST method, particularly in relation to page refreshing and using the back/forward buttons.
‡ These temporary session variables are sometimes known as flash variables. They exist from one HTTP operation to the next, and are erased at the end of the second operation.
You cannot put JavaScript inside of your PHP code. However, I will give you an explanation of what you need to do.
On the client side, bind an event for the click, then
$('form button').click(function() {
$.post('file.php', {'object': 'property'}, function(success) {
if(success) {
$("#contact-area").append("Thanks for your message!")
}
});
});
On the server side, you will process this:
//file.php
$sentByAJAX = $_POST['object'];
return true;
I heard that this is bad idea but I'll try to explain what I want to achieve:
On my site a user fills some information and then goes to another service which handles user payment. So after the user pays using credit card he got redirected to special $successUrl again to my site where he sees successful payment message. My boss wants that after payment if the user clicks back button (being on success page) instead of going to payment service again he have to be redirected to main page.
How to achieve that? I can't thought of a good solution. Only something like catch back button event on this page and redirect to index page
I think the only way to to it is with javaScript
You can bind to "navigate" event.
$(window).on("navigate", function (event, data) {
var direction = data.state.direction;
if (direction == 'back') {
window.location.href='http://google.com';
event.preventDefault();
}
});
You can make the success page, let's call it SuccessRedirect, redirect the browser (using javascript or HTML meta header, you can't use a HTTP header) to another page, SuccessActual, that displays the success message.
On the first visit to SuccessRedirect page set a cookie, so that if someone visits it the second time (i.e. after clicking the Back button) and the cookie is already set, instead of redirecting to SuccessActual it redirects to the homepage.
The cookie name should include some kind of payment transaction id, so that you display the success page for every payment transaction.
It's a bit hacky and it won't work if someone quickly clicks 'Back' multiple, but hey, it might work well enough.
I've coded some custom navigation buttons into the project I'm working on, via javascript - they essentially copy the browser button functionality (brief wasn't initially clear on why separate buttons were required, but they asked for them):
function goBack() { window.history.back(); }
function goForward() { window.history.forward(); }
However, as the functionality is the same as the browser back button, the website asks if I want to resubmit POST data if I go back to a page with said POST data, which is undesirable. Ideally, to fit with the current site setup (all POSTs submit to the originating page, which checks for POST data and performs the relevant submissions to the database), I want to clear the POST data so there is no request to resubmit.
I'm not familiar with the Post/Redirect/Get (PRG) that people might recommend, and it doesn't seem to cover the concept of continually pressing "back"; if you submit a form, you post to a page which handles the post action, then redirects to a GET page - but the redirect is still in the history, meaning if you go back, surely you would hit the redirect page and just be sent "forward"? Plus, PRG seems mostly centred on page refreshing, which is not what I'm looking for at the moment.
The concept of PRG also seems to be due to the browser back button not allowing for additional code to control POST data, so coders have to make the best of what they can access.
With my relative freedom of having a custom back button which could allow for manipulation of POST/session/cookie data, I'd consider there should be some method of calling a global session variable or cookie on back button press, which then gets picked up on the previous page load to unset the POST data and the global session variable/cookie, but my attempts to implement something like this have not succeeded - they've been simple single-line setcookie('back', true) or set($_SESSION['back']=true) PHP snippets within goBack(), with PHP earlier in the page:
<?php if (isset([either set cookie or set session variable]) {
unset([either set cookie or set session variable]); // also tried changing 'true' to 'false' here
unset($_POST);
}?>
Is this kind of behaviour possible and I'm just looking at this from the wrong angle, or is the only way to do a successful back action while suppressing POST to re-engineer the site to use PRG, which will be comparatively significant legwork? Is there some other point in a page load/POST submit that would allow for clearing the POST data, to allow for the back button functionality I'm looking for?
EDIT
I, as an example, navigate to site.com/stuff/edit/[an ID], to edit an item of stuff. The first time I visit, there is no POST data, so the PHP check of isset($_POST) returns false and the page is simply rendered with a form which is populated by a GET.
I amend in the form and press submit. The submit sends the POST data to the target page; this is STILL site.com/stuff/edit/[an ID]! However, because there is now POST data, the PHP picks this up, validates it on the page (you'll see why later) and performs backend model and controller functions to update the item to the database serving the site.
Depending on whether the update was successful, the page then renders the form again, with the information which is retrieved from a GET, which pulls the information from the server (amended or otherwise) and either a success or fail message.
If I want to add a new item, I navigate to site.com/stuff/new; this navigates to the same page as site.com/stuff/edit, but PHP code determines the masking URL and renders different aspects of the code to look like a different page with a different POST action - it also notes there is no ID passed in.
I add an item, and the POST redirects back to the same page; this time, though, there is no Id from the server, meaning the code behind picks up the fact it is a new entry, and performs an insert. It then either displays a success message with a link to view/edit the new item, or a failure message with a prepopulated form to reduce retyping the new item into the form.
I hope this has helped show how this page works; its not necessarily how I would have written the site, but I've inherited the work from an ongoing situation and work with others who code in this way, so I need to be consistent or make unobtrusive changes rather than radical redesigns of in-use code.
I think this should do the job:
function goBack() {
var referrer = document.referrer;
if(referrer != '') {
window.location = referrer;
} else {
window.history.back();
}
}
I'm working on a messaging system like Facebook. I do have on left a list of conversation, and on right a box where i load the messages, just like facebook does.
The basic system is complete (PHP/MySQL), and here some information on how it is structured:
messages.php - Main page, based on url parameters. Rewrited with.htaccess:
Examples:
URL = http://www.domain.com/messages/ - Right Box: Display form to send new message.
URL = http://www.domain.com/messages/Username - Ajax call to getUserMessages.php to load Messages between Logged in user and
Username and show them on the Right Box.
getUserMessages.php - Get from database messages between Logged in user and user selected. It does Output HTML ready to be displayed.
Now the system is partially Ajaxified, and i want it to be, just like Facebook does.
At the moment the Ajaxified part is:
When a user is vieweing a conversation, it display automatically new messages, and also update the conversation list with the last message.
If the user is not viewing a conversation, it does get new messages received and update the conversation list.
This is done with a PUSH service, to give Real Time experience to users.
I want to improve this, and make it to act like that:
The user click on the Conversation List, and it load the messages on the right Box, and also change the URL on the Address Bar, withut reload the entire page.
I can easily do the part to load messages when user click a conversation, but before i start i have two question:
1. How i do change the Address URL while displaying a User Conversation WITHOUT reload the page?
I found the answer.
2. How i do cache the conversations ? So if a user switch between two conversation, it does not call again the php file and query the database for all the messages, but appending only new messages (Maybe via another php File to fetch only Unread Messages)
EDIT
I comed up with a solution:
When a user open a conversation, i cache the entire Ajax response (that is HTML) in a variable, like messages-n, Where n is the user_id of the conversation selected, then if the user click again on that conversation, i check if messages-n is set, if it is, i print it and run an ajax request to get only unread message and append them.
That's only in my mind i didn't made it to actual code.
Could work well?
Solved 1/2 :
1. To change Address URL i'm using the HTML5 .pushState() event.
Since HTML5 Browsers implement the pushState method in different way, to have a Cross-Browser solution, and have support for HTML4 browsers with hash Fallback, i used Hystory.js.
2. To cache messages, i haven't found a solution yet, nor i tried to do it for now.
But as #Christopher suggested, i changed the Ajax response from HTML to Json.
If i find it i will update my answer.
I have a members site. Every web page's header bar will have the following 2 options depending the user is logged in or not:
Option 1) if the user is logged in, it will have the following 2 links:
"user12345"
"logout"
Option 2) if the user is log out, above 2 links will become:
"login"
"register"
The page has some Javascript code which will check a user cookie. If the user cookie exists, if will display option 1), otherwise option 2). There is no problem with the Javascript. It shows above options correctly.
Here's the problem. I use a server side script (perl) to do the "logout" function. The script will delete the cookie and re-direct back to the original page. I am hoping the page will show option 2), but it doesn't. It still shows option 1). The page needs to be refreshed to show option 2). This is confusing because users have clicked the logout link, yet when they return to the page, they still see their usernames there. They need to refresh the web browser in order to see that they have logged out.
Option 2) should show on the page upon clicking the "logout" link. But I simply have no idea how to get this done successfully.
Please provide your expertise to fix this problem.
First, I would suggest breaking the problem down so that you can test the logout functionality separate from the page redirect.
Modify your Perl script so logout doesn't redirect.
Login and then click logout.
Use a Chrome or Firefox extension that lets you view cookies. Verify that the cookie has been deleted.
If everything checks out here, I would suggest that you then reconnect the redirect and repeat the above steps:
When your page redirects and you don't see the login | register buttons, check to see if the cookie was deleted, if the cookie appears, then there may be something being cached in the code after the redirect.
As an alternative, you could use the document.referrer to capture your logout URL in your JavaScript code and also use this to determine if you should show the login | register buttons. For instance:
if(document.referrer = "/logout" || /* existing check of cookie goes here */) {
// show login | register
} else {
// show username, etc.
}
If possible, the best solution usability-wise would be to turn your logout url into an AJAX call so you don't need to reload the page. This would be better than the above solution because you could check the response object to determine if the logout operation was a success. If so, you could then dynamically replace the header bar with the correct text.
An AJAX example, using jQuery.ajax, is as follows:
$.ajax({
url: '/logout',
success: function(data) {
if(data.logout == true) {
// user is logged out
}
},
error: function(jqXHR, textStatus, errorThrown) {
/* problem with logout */
}
});
Your perl logout script will need to return a JSON object as a String, if successful:
{"logout":true}
There are other ways of making AJAX calls and transferring data to/from the server, and you can find those examples doing a search on Stackoverflow for "AJAX".
BlockquoteFirst, I would suggest breaking the problem down so that you can test the logout functionality separate from the page redirect...
I've fixed the problem without the use of AJAX call.