I have used jquery.dirtyforms with bootstrap modal to notify user that something is not saved in this page. This worked perfectly with anchor links but I have a div
on the page which is actually working as a link to some other page. This div
has data-action
attribute containing the URL of the other page and on click I am setting the data-action
value to window.location.href
to navigate. When I click the div
it gave the confirmation message on default popup of browser instead of Bootstrap Modal. I have given a unique class to the div named tabDiv
. I tried to add the support for div in jquery.dirtyforms.js and written this which did not work:
<div class="sf-active div_Header tabDiv" id="div_Header" data-action="@Url.Action("ViewContract", "Contract", new { Id = Request.QueryString["Id"] })">
<span>First</span>
<i class="i_Header"></i>
ClickMe
<div class="ContraHeader glyphicon"></div>
</div>
$(".div_Header").click(function(evt) {
evt.stopImmediatePropagation();
var url = $(this).attr('data-action');
if (url !== undefined)
window.location.href = url;
});
What I tried to change in Jquery.DirtyForms.Js which does not work
var events = {
bind: function (window, document, data) {
$(window).bind('beforeunload', data, events.onBeforeUnload);
$(document)
.on('click', 'a:not([target="_blank"])', data, events.onAnchorClick)
.on('submit', 'form', data, events.onSubmit)
.on('click', 'div.tabDiv', data, events.onDivCLick);
}, onDivCLick: function(ev){
bindFn(ev);
},
I want it to work on div
click also. Presently it is working but the message on browser's default popup. I want to show the same Bootstrap Modal on this click also.
Using window.location.href
with Dirty Forms is a bit tricky. Fortunately, you can customize the event binding to take control in this case.
Keep in mind, the navigation needs to happen in 2 different cases:
So, it is best to use a common function in both of those cases. It also works out best if there is only 1 event handler to ensure there are no event ordering issues.
For the first case, you just need to insert the code to check the dirty status into your event. You can create your event inside of the bind.dirtyforms
event to gain access to the events
object instance, then simply call events.onAnchorClick(ev)
inside your event at the appropriate time.
Dirty Forms will cancel the event if the form is dirty. So, you need to check whether the ev.isDefaultPrevented()
returns false
. If so, it is safe to fire your navigation.
For the second case, you can take advantage of the fact that Dirty Forms hangs onto the event object until the dialog is closed. If you store the URL in the ev.data
property, you can gain access to it later on in the process. Specifically, Dirty Forms calls the onRefireClick
event handler when (and only when) the user clicks "proceed". So, you can then fire your custom navigation there using the URL you previously stored in the event.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
input.dirty, input.dirty + label, select.dirty, textarea.dirty {
background-color: red;
}
</style>
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/3.0.0/css/bootstrap.min.css" />
<script type="text/javascript" src="//cdn.jsdelivr.net/g/jquery@1.11.3,bootstrap@3.0.0,jquery.dirtyforms@2.0.0(jquery.dirtyforms.min.js+jquery.dirtyforms.dialogs.bootstrap.min.js)"></script>
</head>
<body>
<form action="/" id="dialog-form-thing" method="post">
<input id="text1" type="text"/>
<div class="sf-active div_Header tabDiv" id="div_Header" data-action="http://www.google.com/">
<span>First</span>
<i class="i_Header"></i>
ClickMe
<div class="ContraHeader glyphicon"></div>
</div>
</form>
<script>
$(function() {
function navigate(url) {
if (url !== undefined)
window.location.href = url;
}
/* Event binding code - call before first .dirtyForms */
$(document).bind('bind.dirtyforms', function (ev, events) {
var originalBind = events.bind;
events.bind = function (window, document, data) {
// Attach the original Dirty Forms events
originalBind(ev);
// Attach a custom event
$(document).on('click', 'div.tabDiv', data, function (ev) {
// Store the URL in the event object for later use
var navUrl = $(this).attr('data-action');
ev.data = { url: navUrl };
// Execute the Dirty Forms logic to open the
// dialog if the page has dirty form(s).
events.onAnchorClick(ev);
// If the page has no dirty forms, this
// will return false, causing navigation.
if (!ev.isDefaultPrevented())
{
navigate(navUrl);
}
});
};
var originalOnRefireClick = events.onRefireClick;
events.onRefireClick = function (ev) {
if (ev.data && ev.data.url)
{
// If we previously stored the URL, navigate to it.
navigate(ev.data.url);
}
else
{
originalOnRefireClick(ev);
}
};
});
$('form').dirtyForms();
});
</script>
</body>