Confirmation box for the back button- ReactJs - javascript

I have used the following code for the confirmation box on browser back button click.
I am using routing without hash.
window.history.pushState(null, null, window.location.pathname);
window.addEventListener("popstate", this.onBackButtonClick);
onBackButtonClick = (event) => {
debugger;
event.preventDefault();
this.goBackButtonHandler();
};
goBackButtonHandler = () => {
if (this.state.isEditDirty) {
this.setState({ showDirtyDialog: true });
} else {
window.history.back();
}
};
I am facing the following two scenarios
I am binding pushstate and popstate multiple times for text field dirty. So when I click on the browser back button, the history change but url is not changing.
When I bind only one time when user type in text field, the solution is working as expected. But first time the confirmation box is showing with prevention of go back. On the second time, even the confirmation box is showing the page loaded in the back.

Related

JavaScript confirm dialog box keeps on regenerating on cancel event

SCENARIO: I just want to warn user on window change; so I've used jQuery's window blur & JavaScript's confirm dialogue box. When user will click OK button the application will redirect to another page & when user will click CANCEL button nothing will happen. He can continue his work on the same page.
ISSUE: OK button is working perfectly but when I click on the CANCEL button, the browser keeps on regenerating the dialogue box. How do I stop that?
CODE:
$(window).blur( function (e) {
var closeWindow = window.confirm("Your test will be cancelled if you switch the tabs.");
if (closeWindow) {
// redirect to another page
}
else {
// do nothing.
}
});
As #ROAL explained, the first blur event is because of actual blur, and rest are because of the browser trying to move away from the tab. A simple solution for this would be to use a flag to distinguish between the user generated event and the browser generated event. Give this a try:
var manualCancellation = false;
$(window).blur( function (e) {
if(!manualCancellation ){
var closeWindow = window.confirm("Your test will be cancelled if you switch the tabs.");
console.log(e);
if (closeWindow) {
// redirect to another page
}
else {
manualCancellation = true;
// do nothing.
}
} else {
// Reset the value of manualCancellation so that the event is fired the next time.
manualCancellation = false;
}
});

Back button Event Listener

I have a Single page application. In that at the first instance I am displaying the Input page and the Output Div is hidden at that point of time.Later on when the Input data are submitted I hide the Input data and Use ajax call to calculated the the output and display the output result in the Output div. So basically the same page is present both for input and output page. Now I have a back button, when users click on that the Input div is shown and Output div is hidden.
$("#renderOutput").on("click", "#chngeIcon", function () {
$('#renderOutput').hide();
$('#InputPage').show();
});
Since it is a single page application if user click on the browser back button, than it is taken to previous visited site. I want to make back button to behave similar to my back button. Please help me.enter image description here
You can try popstate event handler, e.g:
window.addEventListener('popstate', function(event) {
// The popstate event is fired each time when the current history entry changes.
if ($("#InputPage").is(":visible") == false) {
// Call Back button programmatically
history.back();
// Uncomment below line to redirect to the previous page instead.
// window.location = document.referrer
} else {
// Stay on the current page.
history.pushState(null, null, window.location.pathname);
$('#renderOutput').show();
$('#InputPage').hide();
}
history.pushState(null, null, window.location.pathname);
}, false);
Hope that helps

Disable submit button on a page when browser back button is clicked

I need to Disable Submit button(s) on the page when browser's back button is clicked. This should be generic meaning in which ever page I place this script, it should disable all the Submit buttons on that page when the user hits the browsers back button.
You should be able to achieve that using window.history.pushState and popstate (See below sample).
For compatibility refer to this
For complete documentation refer to this
jQuery(document).ready(function ($) {
if (window.history && window.history.pushState) {
window.history.pushState('forward', null, null);
$(window).on('popstate', function () {
//Add logic here
});
}
});

How to trigger onbeforeunload with back button in an ajax based application?

I have an ajax based application (ie no page 'reloads` when getting new data).
Initially I wanted to find a way to prevent navigation when unsaved data was present on a form.
I came across window.onbeforeunload.
That didn't work when clicking a links (where content is loaded via ajax and pop/push state changes the url).
I added some handling of the a links but need to use the default window.onbeforeunload to cover the standard means of leaving a page (ie manually entering a new URL or using the back/forwards buttons).
The code below works for:
a links
page refresh
manually entering a new url
But is not triggering window.onbeforeunload when using the back button (in Chrome and Firefox).
Is there something awry with the implementation below or is window.onbeforeunload not meant to be triggered when using the back button?
var save_state = true;
// on entering data into an input field, the save button fades in
// and the save_state changes
$(document).on('keypress', '.class1 input', function() {
if (save_state) {
$(".save_button").fadeIn();
save_state = false;
};
// bind the click event to 'a' (overiding normal link behaviour)
$( "a" ).bind( "click", function(e) {
if (save_state == false) {
e.preventDefault();
alert("Save before leaving.");
// stop the other 'a' bound handlers from being triggered
e.stopPropagation();
return;
}
});
// also cover standard actions when user tries to leave page
// (back/forward or entering a new url manually etc)
window.onbeforeunload = function() {
return 'Save before leaving.';
};
});
// when clicking save, fade out the button and revert the save_state
$(document).on('click', '.save_button button', function(e) {
e.preventDefault();
$(this).parent().fadeOut();
save_state = true;
// 'unbind' onbeforeunload
window.onbeforeunload = null;
});
Edit:
After reading this post, I think it is based on the ajax nature of the app:
As long as you stay within your app, because it's a single-page app,
it doesn't by definition unload, so there's no beforeunload event.
So I think I may need to look at other ways to trigger the event on back/forwards buttons.
I looked in to triggering window.unload on popstate but didn't have any luck with that.
I ended up changing the logic so that as soon as changes were made, they were saved in the database.
I was using selectize.js for the form input handling and just added some extra calls to it.
In selectize.js (here):
if ($target.hasClass('create')) {
self.createItem();
} else {
value = $target.attr('data-value');
became:
if ($target.hasClass('create')) {
self.createItem();
$(".saved_message_div").fadeIn(400).delay(2000).fadeOut(400); // new
updateDatabaseFunction(); // new
} else {
value = $target.attr('data-value');
$(".saved_message_div").fadeIn(400).delay(2000).fadeOut(400); // new
updateDatabaseFunction(); // new
AND (here):
while (values.length) {
self.removeItem(values.pop());
}
self.showInput();
became:
while (values.length) {
self.removeItem(values.pop());
}
$(".saved_message_div").fadeIn(400).delay(2000).fadeOut(400); // new
updateDatabaseFunction(); // new
self.showInput();
And in my own script, the prompt for deleting selectize.js items stayed the same:
onDelete: function(values) {
confirm(values.length > 1 ? 'Are you sure you want to remove these ' + values.length + ' items?' : 'Are you sure you want to remove "' + values[0] + '"?');

Preventing users from accidentally navigating away from unsaved pages

I got the snippet below from this SO post, and it works when a user tries to reload the page or close the browser etc. but if the user clicks on a link then it lets them naivagate away, and then incorrectly starts displaying the message on the wrong page. I am using pjax for the links.
$(document).ready(function () {
$('textarea').change(function () {
window.onbeforeunload = function () { return "Your changes to the survey have not been saved?" };
});
});
You should use onbeforeunload like this, inconditionally:
<script type="text/javascript">
saved=true; // initially, it is saved (no action has been done)
window.onbeforeunload = confirmExit;
function confirmExit() {
if (!saved) {
return "You did not save, do you want to do it now?";
}
}
</script>
It is not safe to handle this event only when another event is fired. The onchange event of your textarea here probably don't fire before you click on a link so the window won't handle the onbeforeunload at all. The link will work as expected: you will get redirected.
To deal with the saved flag, you could listen to what happens in your textarea, for example, when the user is actually typing something:
$('textarea').keyup(function(){
saved=false;
});
Then, if you save the data in ajax, the save button could set it back to true:
$('#btnSave').click(function(){
// ajax save
saved=true;
});
Otherwise, it will load the next page with the saved flag on.
what about something like the following?
Listening on all <a> links and then, depending on whether the variable needToSave is set to true, showing the message or letting it go.
var needToSave = false; // Set this to true on some change
// listen on all <a ...> clicks
$(document).click("a", function(event){
if (needToSave == true) {
alert("You need to save first");
event.preventDefault();
return;
}
});
UPDATE (as per Roasted's suggestion) this should trigger the unload event every time the link is clicked and perform your existing logic:
// listen on all <a ...> clicks
$(document).click("a", function(event){
$(window).trigger("unload");
});
jsFiddle here - http://jsfiddle.net/k2fYM/

Categories

Resources