I'm designing a rather long form that will auto-save every couple minutes (i.e., using Ajax, the form data will be inserted or updated into the MySQL database). However, if the user decides to exit the page before submitting the form, I want to make sure I delete the row that was inserted into the database. This is easily do-able if the user simply clicks another link or the form's Cancel button. But I'm concerned about what happens when the user: 1) closes the page, 2) reloads the page, or 3) hits the browser's back (or forward) button. I know how to use the unload event to create a confirmation dialog asking the user to confirm they want to leave the page. But what I don't know is how to make an Ajax call (to delete that row from the database) if the user clicks OK ("Press OK to Continue"). Is there any way to call a function if a user clicks the OK button during the unload event?
window.onbeforeunload = function() {
if ($('#changes_made').val() == 'yes') //if user (partially) filled out the form
{
return "Are you sure?"
if (/*user clicks OK */) //What should the if statement evaluate here?
{
//make Ajax call
}
}
};
$(document).ready(function() {
$(':input',document.myForm).bind("change", function() {
setConfirmUnload(true);
}); // Prevent accidental navigation away
});
function setConfirmUnload(on) {
// To avoid IE7 and prior jQuery version issues
// we are directly using window.onbeforeunload event
window.onbeforeunload = (on) ? unloadMessage : null;
}
function unloadMessage() {
if(Confirm('You have entered new data on this page. If you navigate away from this page without first saving your data, the changes will be lost.')) {
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
success: function(msg){
alert( "Data Saved: " + msg );
}
});
}
}
Make sure you have upgraded version of jQuery. jQuery version 1.3.2 had a bug:
Ticket #4418: beforeunload doenst work correctly
Or use native function:
window.onbeforeunload = function() {....}
Related
I have a page that will generate details of a record. When the user comes to this page, he/she will have to press a 'generate' button to create the details of the record. Since it will take some time to generate the record, the moment the user clicks the button, it will trigger an ajax request.
$("#generate_record_button").on("click", function() {
$(this).addClass('disabled');
// Show some loading messages, and spinner
$.ajax({
url: "<generate-record-url/>",
method: 'get',
data: {id: <recordID>},
cache: false
}).success(function (data) {
// Do something on success
// Show some success messages
// Remove spinner
}).fail(function (data) {
// Do something on failure
// Show some error messages
// Remove spinner
$(this).removeClass('disabled');
});
});
In the code, currently when the user presses the button, the button will be disabled to prevent from potential multiple ajax requests being triggered if user keeps pressing the button. By right, user should only press the button once and just let the ajax handles the request accordingly.
My question is, is there a way to check if the ajax request is still running in the event when the user leaves the page? (Eg: refresh the page, navigate to other page, etc etc). What I would hope to achieve is that if the user re-visits back this page while the ajax is still processing the record (for that particular record ID), the button will remain disabled so that user can't press it and will see some loading messages. Is this possible?
Your user should not leave the page while ajax is running since it will be cancelled.
How about
$(window).on('beforeunload', function(){
if ($("#generate_record_button").hasClass("disabled"))
return 'Are you sure you want to leave?';
})
So basically i have everything ready, but i'd like a pop-up message appear after the user redirect to another page.
so i am currently use jquery
$('#btn_save').click(function (){
$('#message-box').slideDown('slow').delay(3500).slideUp('slow');
});
I do not know if i should use ajax instead, i know i may use route and if(session) to do it but i am new to ajax and will happy to got an example as reference.
Many thanks
UPDATE 1:
This the part of my submit button which redirect the user after submit:
var $btn_save = $("#btn_save");
$btn_save.click(function () {
//todo form validation
if(!$(".sa-alert-name-existed").hasClass('hidden')){
return
}
$.post(api_submit, postData).done(function (data) {
location.href = "/buzz#tab_pane_fbpage";
});
Then we should come to the js part, which popup a message when onclick the submit button
$('#btn_save').click(function (){
$('#message-box').slideDown('slow').delay(3500).slideUp('slow');
});
enter code here
i want to put this dialog box inside the page refresh. i mean. when i refresh the page this must be the out put.
<script>
$(function() {
$("#dialog").dialog({
modal: true,
resizable: false,
buttons: {
"I want to Continue the Exam": function() {
$(this).dialog("close");
},
"I Refresh": function() {
$(this).dialog("close");
}
}
});
});
</script>
As far as I know, when you 'refresh' a page then all the JS objects are destroyed (those that are written in script).In other words the script is re-loaded. So you can't persist your script while the page is in transition.
Type I (classical Single Page App)-
So if you simply want to reload a particular part of the Application then use $.ajax() methods like beforeSend() for showing whatever (alert or best a loading spinner/div) you want during the data request or 'page-refresh'. And then you can hide them on done().
Type II (using routers)
JS frameworks like Angular give you options to reload a particular route of your App without reloading/refreshing your entire app - $route.reload(). You can show/hide some div/directive based on manipulation in your controller.
So you have to use some form of asynchronous scripting to deal with this "PROMPT while REFRESH" situation.
Using $.ajax() to simulate (pseudo code)-
$.ajax({
url: "_URL_to_get_or_post_data__",
beforeSend: function( xhr ) {
$popup.show();
}
})
.done(function( data ) {
$popup.hide();
}
});
Browsers have a security feature that will not let a page prevent users from leaving the page. By leaving a page it means closing tab/browser, navigating to a different page or refreshing. The only way to stop the user is to assign a function to onbeforeunload. Like this:
onbeforeunload = function () { return "You have unsaved data. Are you sure you want to exit?"; }
This message is synchronous, it will stop all javascript running on the page. If user presses ok the browser will leave the page (or refresh) else it will stay on the page.
EDIT
Usage: when user have changed something and have unsaved data - you assign a function to onbeforeunload:
onbeforeunload = function () { return "some message"; }
after the data is saved set onbeforeunload to null:
onbeforeunload = null;
I have a page that lets you Add/Edit/Delete "Project Tasks" and Save the data to a database using jQuery's AJAX function to save the POST data.
I currently have 2 buttons on the page.
Button 1 .save-tasks-ajax-redirect - You click it and it makes a regular non-ajax POST to my backend and you are redirected to another Project page. This button does not have a click event yet. Perhaps the best way might be to simply create a new click event for this button class and then have it call my save function but it could pass in a variable to indicate that it needs to redirect? Before I posted this questions I was sort of hoping to have both button share the same click event and everything but perhaps this is a better idea?
Button 2 .save-tasks-ajax - You click it and it uses AJAX to Save the data and you can remain on the page editing more.
Now my goal is to modify how Button 1 works. Instead of making a regular HTTP POST, I would like for it to also make an AJAX save but when it is done, I would like it to redirect to a project page.
So below I have my 2 button HTML codes. Below that I have my jQuery Click event for my AJAX save button (Button 2) and below that I have my ajaxSaveTasks() function that my button calls to make the save.
I would like to modify this function and perhaps all of this code so that my Button 1 can use the same function to make an AJAX save but somehow it needs to differentiate itself so that it can also do a redirect after the AJAX save is complete.
Looking at the basic code below, how could I modify this to do that?
<button type="submit" class="save-tasks-ajax-redirect">Save Tasks and Return to Project</button>
<button type="submit" class="save-tasks-ajax">Save Tasks and Continue Editing</button>
$(window).load(function () {
// AJAX Save and Continue editing
$('#content').on('click', '.save-tasks-ajax', function () {
console.log('AJAX Save and Continue Editing Button Clicked!');
ajaxSaveTasks();
return false; // avoid to execute the actual submit of the form.
});
});
function ajaxSaveTasks(){
console.log('ajaxSaveChanges() Ran and Tasks Saved.');
// Reset Flag that Triggers Un-Saved Alert on page exit
window.unsavedChanges = false;
// Show a Loading/Saving Spinner
jQuery('#project_tasks').showLoading();
// Display a message to the user that we are Saving
flipNotify.show({
message: 'Project Tasks Saved!',
icon: 'tick',
delay: 2,
sticky: false
});
var url = "index.php?module=apoll_Web_Projects";
$.ajax({
type: "POST",
url: url,
data: $("#editTasksForm").serialize(), // serializes the form's elements.
success: function(data)
{
// Hide Header Un-Saved Changes Div
hideTaskUnSavedChangesHeaderBar()
// Hide Loading/Saving Spinner
jQuery('#project_tasks').hideLoading();
}
});
};
$(window).load(function () {
// AJAX Save and Continue editing
$('#content').on('click', '.save-tasks-ajax', function () {
console.log('AJAX Save and Continue Editing Button Clicked!');
ajaxSaveTasks();
return false; // avoid to execute the actual submit of the form.
});
// AJAX Save and redirect
$('#content').on('click', '.save-tasks-ajax-redirect', function () {
console.log('AJAX Save and Redirect Button Clicked!');
ajaxSaveTasks(function(){ window.location.assign("project.php"); });
return false; // avoid to execute the actual submit of the form.
});
});
function ajaxSaveTasks(callback){
... your code ...
$.ajax({
...
success: function(data)
{
// Hide Header Un-Saved Changes Div
hideTaskUnSavedChangesHeaderBar()
// Hide Loading/Saving Spinner
jQuery('#project_tasks').hideLoading();
if (callback)
callback();
}
});
};
I have a form where people can delete records;
Delete Record 1
Delete Record 2
Delete Record 3
To ensure they are sure, I am using a "Are you sure" confirmation script (Popconfirm) which gives a nice little popup confirmation.
$(".confirm-action").popConfirm();
If the user clicks cancel, nothing happens. If they click 'yes' - the link is processed and the record deleted. This is working as intended.
Now instead of following the link (when the user clicks 'yes'), I want to fire an ajax request:
$('.confirm-action').click(function(event) {
event.preventDefault();
$.ajax({
// Ajax stuff here
});
});
$(".confirm-action").popConfirm();
The problem is when I try this, the functions are fired in the correct order when expected, except the event is null, so the script fails.
How do I "preventDefault()" when the event is null, and/or manually get the event to prevent the link from being followed by the browser?
Edit: JSFiddle showing the problem.
As noted in the comments, the plugin is horrible and plays with _data(events) IE plays with internal event management of jQuery.
If you aren't concerned about the UI, I would suggest you to go with normal confirm() as used in SO.
I've created this for you while typing this answer:
$.fn.nativeConfirm = function (options) {
return this.click(function () {
var bool = confirm(options.text);
bool ? options.yes.call(this) : options.no.call(this);
});
}
Example:
$('a').nativeConfirm({
yes: function(){
alert('yes');
},
no:function(){
alert('no');
},
text: 'Seriously?'
});