jquery dirty record, would like the jquery ui modal - javascript

I'm using this to test if a form is dirty.
It defaults to the standard browser confirmation asking if you are sure you want to navigate away from this page. On the jquery dirtyforms site it has a section that says you can use the jquery ui modal form.
So I tried adding a section (a div) like so:
<div id="unsavedChanges" title="Save Changes?">
<p>You've made changes to this page. Do you want to leave this page without saving?</p>
</div>
And then I added what their code looked like:
$.DirtyForms.dialog = {
selector: '#unsavedChanges',
fire: function(message, dlgTitle) {
$('#unsavedChanges').dialog({ title: dlgTitle, width: 350, modal: true });
$('#unsavedChanges').html(message);
},
bind: function() {
$('#unsavedChanges').dialog('option', 'buttons',
[
{
text: "Stay Here",
click: function(e) {
$.DirtyForms.choiceContinue = false;
$(this).dialog('close');
}
},
{
text: "Leave This Page",
click: function(e) {
$.DirtyForms.choiceContinue = true;
$(this).dialog('close');
}
}
]
).bind('dialogclose', function(e) {
// Execute the choice after the modal dialog closes
$.DirtyForms.choiceCommit(e);
});
},
refire: function(content) {
return false;
},
stash: function() {
return false;
}
};
Although I am not sure where they want me to place that (I originally placed it outside of document.ready. However, after running this and making a change to my form and navigating away I see that it still is using the browser confirmation instead of jquery ui dialog box. What am I doing wrong here?

You can only popup a custom dialog if the user is trying to leave by clicking an anchor or other element on your page.
Then you could just intercept the click on all anchors etc, prevent it, pop up a custom dialog to confirm. In other words, when someone is clicking an element on your page, you're in control and can do pretty much whatever you want.
However, when the user is trying to leave by closing the tab or browser, you can not stop them with javascript, as it would be extraordinary annoying if websites could do that.
The only way to prompt a user that is leaving by closing the tab/browser window is to use the onbeforeunload event, and that event can only be used with the native confirm dialog, there is no way to use a custom dialog or stop the user or do anything else really, as that could lead to certain websites creating systems where you could never really leave the site.

From the README:
Dirty Forms will alert a user when they attempt to leave a page without submitting a form they have entered data into. It alerts them in a modal popup box, and also falls back to the browser's default onBeforeUnload handler for events outside the scope of the document such as, but not limited to, page refreshes and browser navigation buttons.
(emphasis mine)
If you want to show a modal for this kind of things, well, you simply can't. (The reason why is security: it's easy to imagine a page preventing the user to close it whatever they attempt, short of killing the browser instance.)
Additionally, the "but not limited to" bit is intriguing: I would ask the plugin's author for details on what exactly this covers, as it might overlap with your use-case.

Related

How can I warn user on back button click?

www.example.com/templates/create-template
I want to warn users if they leave create-template page. I mean whether they go to another page or to templates.
I use this code to warn users on a page reload and route changes should the form be dirty.
function preventPageReload() {
var warningMessage = 'Changes you made may not be saved';
if (ctrl.templateForm.$dirty && !confirm(warningMessage)) {
return false
}
}
$transitions.onStart({}, preventPageReload);
window.onbeforeunload = preventPageReload
It works as expected on a page reload and route changes if it is done by clicking on the menu or if you manually change it. However, when I click the back button, it does not fire the warning. only it does if I click the back button for the second time, reload the page, or change route manually.
I am using ui-router. When you click back button, you go from app.templates.create-template state to app.templates state.
How to warn if they press Back button?
First of all, you are using it wrong:
from https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload:
Note: To combat unwanted pop-ups, some browsers don't display prompts
created in beforeunload event handlers unless the page has been interacted
with; some don't display them at all. For a list of specific browsers, see the
Browser_compatibility section.
and
window.onbeforeunload = funcRef
funcRef is a reference to a function or a function expression.
The function should assign a string value to the returnValue property of the Event object and return the same string.
You cannot open any dialogs in onbeforeunload.
Because you don't need a confirm dialog with onbeforeunload. The browser will do that for you if the function returns a value other than null or undefined when you try to leave the page.
Now, as long as you are on the same page, onbeforeunload will not fire because technically you are still on the same page. In that case, you will need some function that fires before the state change where you can put your confirm dialog.
How you do that depends on the router that you are using. I am using ui-router in my current project and I have that check in the uiCanExit function.
Edit:
You can keep your preventPageReload for state changes in angular. But you need a different function for when the user enters a new address or tries to leave the page via link etc.
Example:
window.onbeforeunload = function(e) {
if (ctrl.templateForm.$dirty) {
// note that most broswer will not display this message, but a builtin one instead
var message = 'You have unsaved changes. Do you really want to leave the site?';
e.returnValue = message;
return message;
}
}
However, you can use this as below:(using $transitions)
$transitions.onBefore({}, function(transition) {
return confirm("Are you sure you want to leave this page?");
});
Use $transitions.onBefore insteadof $transitions.onStart.
Hope this may help you. I haven't tested the solutions. This one also can help you.

Confirm redirection from page in javascript

i am working on asp.net site that contains say three pages
page1.aspx
page2.aspx and page3.aspx
I want if user redirects from page1, alert box asking for confirmation should come. For this i have written following code
window.onbeforeunload = function () {
return 'Are you sure you want to leave?';
};
But this code run on every postback to server including pressing F5.
I want this code to run only when user redirects to any of remaining two pages
how can do this ??
try this code in javascript onload event in the pages only
if(confirm("Are you sure you want to leave?"))
{
//redirect to next page
return false
}
Handling in window.onbeforeunload may not be the straight forward way to do it since the alert message will be shown each and every time you load the page.
What you could do instead is call the confirmation js function in the from the DOM object that could possibly take the user to the different page.
For instance, let us suppose the below anchor tag takes the user to page two:
<a id="pageTwoAnchorTag" runat="server" href="~/Page2.aspx">Page 2</a>
you could add the below onclick event to get your confirmation when the user wants to go the page 2:
<a id="pageTwoAnchorTag" runat="server" onclick="return confirm('Are you sure you want to leave?')" href="~/Page2.aspx">Leave Records</a>
Only asking for confirmation in a couple of places might not be fully satisfying, since it will not trigger in all desired cases. For example, when you close the browser tab or window, your data will be lost.
I suggest to do the opposite: Register for the onbeforeunload as you already do, but include a "guard" which you disable on any action that should not trigger the confirmation (i.e. in postbacks):
window.shouldconfirm = true;
window.onbeforeunload = function () {
if (shouldconfirm) {
return 'Are you sure you want to leave?';
}
};
Register for the events that occur before a postback is executed (e.g. button click events, etc.) In those places, disable the confirmation:
window.shouldconfirm = false;
I am slightly surprised that the postbacks trigger the onbeforeunload event. I though to remember that on form posting the event is not triggered, and that a ASP.NET postback is implemented as a form post action.

opening jquery mobile popup on ajaxStart()

I want to show a revolving loader on ajaxStart. I've used a popup for this so that the background fades out and becomes inactive. That said, if there are other ways to achieve this (instead of using a popup), id be willing to try them out too.
The problem is, while the same function containing the AJAX call is executed on both page-load and a button click, the loader only shows up the first time - on page load. I put some console logs and verified that the ajaxStart and ajaxComplete do get triggered, but the pop-up fails to open when the AJAX call is made following the button click.
JavaScript :
$(document).ready(function(){
$( document ).ajaxStart(function() {
$("#loader").html("<img src='../images/ajax-loader.gif'/>").popup("open");
}).ajaxComplete(function() {
$("#loader").popup("close");
});
// do other stuff
loadData();
$("#button").click(function(){
loadData();
});
});
function loadData(){
//make an ajax call to fetch data
}
HTML:
<div data-role="popup" data-shadow="false" data-corners="false" class="loader1"
id="loader" data-overlay-theme="a" data-theme="none" data-dismissible="false" >
</div>
What could be the issue, or are there other solutions altogether to achieve the desired results?
First, the short answer: jQuery Mobile only supports one active popup at a time (for now). The documentation says:
Note: Chaining of popups not allowed
The framework does not currently
support chaining of popups so it's not possible to embed a link from
one popup to another popup. All links with a data-rel="popup" inside a
popup will not do anything at all.
I bumped against this issue a few times in the past and had to hack my way around it. The following code is the solution I'm currently using and works quite well so far (with jQuery Mobile 1.3.2):
$(document).on("mobileinit", function() {
$.widget("mobile.popup", $.mobile.popup, {
_trigger: function(type, event, data) {
return this._suspended ? undefined : this._super(type, event, data);
},
_openPrereqsComplete: function() {
this._super();
delete this._suspended;
},
open: function(options) {
var activePopup = $.mobile.popup.active;
if (activePopup) {
activePopup._suspended = true;
activePopup._close(true);
this.element.one("popupafterclose", function() {
activePopup.open();
});
}
this._super(options);
}
});
});
In a nutshell, that code extends the popup widget in-place to introduce a "suspended" state. All events are muted if a popup widget is in that state.
Then, the open() method is overloaded to detect if another popup is already active. If that's the case, it suspends and closes that popup (without performing any animation, so it is closed right away), then opens the new one and schedules the un-suspending and re-opening of the previous popup when the new one is closed.
Note that code binds to the mobileinit event, so it has to run after jQuery is included but before jQuery Mobile is included. Otherwise, it will be too late to extend the popup widgets that were instantiated during page initialization.

Closing jquery modal window conditionally from ASP.net code-behind

I have an ASP.net page with a link to open a jquery-based modal window (that uses colobox jquery plugin). The content of that window in loaded from another aspx file (it loads an iframe). I want to close that window when the user presses an asp:button and if some condition in my code-behind went well.
I tried many ways to close that window from code-behind like these ways:
Page.RegisterStartupScript("X", #"$(this).dialog('close');");
Page.RegisterStartupScript("X", #"var win = window.open('','_self'); win.close();");
btnDone.Attributes.Add("onclick", #"var win = window.open('','_self'); win.close();");
btnDone.Attributes.Add("onclick", #"window.open('../px/nsk.aspx', '_self', null); window.close(); ");
System.Web.HttpContext.Current.Response.Write("<SCRIPT LANGUAGE='JavaScript'>");
System.Web.HttpContext.Current.Response.Write("self.close();");
System.Web.HttpContext.Current.Response.Write("</SCRIPT>");
but non of them can close that modal window. I'm testing on latest version of firefox.
the code behind can be supposed as sth like this:
// do some database works
if (condition)
{
// close this modal window
}
I also tried methods from jquery but none of them were a success.
Can you please telling me how can I close this window?
The other answers given provide specifics; this 'answer' attempts to be more conceptual/consultative.
Closing the Window
Closing the colorbox window is done on the client side. Both #KennyZ and #Farshid provide details on how to do this. By default, ColorBox is going to close on the press of ESC or its EXIT ui element (if used.) It's also possible to close the box programmatically, which sounds like what you need to do.
Where is the Close Action Invoked?
#KennyZ proposes an Ajax call to determine if "some condition in my code-behind went well"; that presumes you cannot tolerate a full page refresh (which seems reasonable to me) but it's something for you to decide.
If the determination of "went well" can only be done on the server, then you're looking at Ajax or a full page refresh.
Alternatively, if there is a way to make the determination on the client side, you won't need to reach back to the back end at all. Just close the colorbox window using js.
If you can provide more details about what the action is that controls closing/not closing the ColorBox window, maybe the community can help even more.
The problem seams to be solved this way:
Page.ClientScript.RegisterStartupScript(GetType(),
"CloseKey", "parent.$.colorbox.close();", true);
Use jQuery dialog with a div instead of an iframe.
Then you can use an Ajax post to run the serverside code and look at the results to decide what to do with the dialog.
Declare the dialog:
$(document).ready(function () {
jQuery("#MyDialog").dialog(
{
bgiframe: true,
autoOpen: false,
modal: true,
width: 800,
position: ['center', 100]
}
);
});
Populate the dialog and open it:
$('#OpenMyDialog').click(function () {
$.post($('url_for_dialog_contents'), function (data) {
$("#MyDialog").empty();
$("#MyDialog").append(data);
}, null, "html");
$('#MyDialog').dialog('open');
return false;
});
Submit the dialog:
$('#SubmitMyDialog').click(function () {
$.post($('url_for_dialog_action'), function (data) {
if (data.success == true) { $('#MyDialog').dialog('close'); }
}, null, "json");
});
I'm sure you'll need a lot more code in the submit dialog, but this is the general idea.

How to implement a isDirty flag onLeave for a single page application?

I have a single page application written in MVC4 that uses pjax() to push html into various s in my page. I have one sub-form that allows the user to edit the data and it if the user changes the data an isDirty flag gets set in javascript to trigger an alert at the bottom of the page that there are un-saved updates. I would also like to implement an additional warning when the user tries to leave the page without saving. If I use a traditional onbeforeunload function like this
window.onbeforeunload = function() {
if (isDirty) {
return 'You have unsaved changes!';
}
return null;
};
it calls the alert if I try to close the page or navigate away from the site entirely but if the user clicks on one of my links that re-populates the with some different information it does not trigger because you are not actually leaving the page. How can I architect it so that one of these pjax() links causes an alert similar to if I close the page?
You could subscribe to a global event that fires before a pjax request:
$(document).on('pjax:beforeSend', function() {
if (isDirty) {
return confirm('You have unsaved changes! Are you sure you want to continue?');
}
return true;
});
You could add a delegated event handler onto the links in the page. You just have to make sure the handler is bound to links that may load a "new page".

Categories

Resources