How can I get the sender of an onSubmit event in any browser? Or at least in FF and IE?
Esp. as event.srcElementin IE seems to be the target?
Well, isn't there anything like explicitOriginaltarget in browsers other than FF?
I'm looking for any solution in pure javascript, no JQuery.
What I want to do:
I've got a form. And depending on the sender I want to do differnt actions in the onSubmit(event) routine.
What I got in my init function:
var top_most_form = document.getElementById("upper_menu_form");
top_most_form.onsubmit=function(event){
var target = <apparently magical things have to happen here>;
if ("upper_menu_form" == target.id) {
AddSpinner();
AddStarttimeToForm();
AddThruputToUpperForm();
} else {
return false;
}
Here you have a function. You just need to evaluate wich parameter is present in your event object
function getTarget(e){
e=e||window.event;
return (e.target||e.srcElement);
};
See: jQuery - how to determine which link was clicked
Related
I am trying to remove event using window.removeEventListener which I have added using window.addEventListener for event beforeunload but it is not getting removed. I am trying following code
addAlertWithListener(){
window.addEventListener('beforeunload', (event) => {
// Cancel the event as stated by the standard.
event.preventDefault();
// Chrome requires returnValue to be set.
event.returnValue = 'You are currently in edit mode. Are you sure you want to refresh the page?';
},true);
}
It is being added but when I am trying to remove the same function using below code :
removeAlertWithListener() {
window.removeEventListener('beforeunload', null,true);
}
It still gives alert message. Am I missing something over here? I tried with and without last param. None of the thing seems working here.
addEventListener and removeEventListener are implemented in a weird way in JavaScript, they need exactly the same parameters in order to retrieve the registered listeners. That's different from, like, setTimeout where an id is returned.
In Angular, usually I do something like this:
private readonly BEFORE_UNLOAD_PARAMS = ['beforeunload', (event) => ..., true];
private isBeforeUnloadActive: boolean = false;
addAlertWithListener() {
if (this.isBeforeUnloadActive) return;
window.addEventListener(...this.BEFORE_UNLOAD_PARAMS);
this.isBeforeUnloadActive = true;
}
removeAlertWithListener() {
window.removeEventListener(...this.BEFORE_UNLOAD_PARAMS);
this.isBeforeUnloadActive = false;
}
The flag will prevent the listener to be registered twice
I'm stuck working out which one of these I should be using: beforeunload or onbeforeunload They both seem to be doing very similar things, but with different browser compatibility.
Some context:
I have a form. On page load I serialise the form and save it in a variable. If the user leaves the page I serialise the form and compare the two, to see if there's been any changes. However, if the form is submitted then the event should not be fired.
Example 1
I have this working as expected. I just don't understand the differences between the two:
window.onbeforeunload = function(e) {
if(strOnloadForm != strUnloadForm)
return "You have unsaved changes.";
}
With this line to stop it firing when you save the form (bound to .submit())
window.onbeforeunload = null;
Example 2
window.addEventListener("beforeunload", function( event ) {
if(strOnloadForm != strUnloadForm)
event.returnValue = "You have unsaved changes.";
});
With this line to stop it firing when you save the form (bound to .submit())
window.removeEventListener("beforeunload");
What the documentation says
I've read the documentation for onbeforeunload and beforeunload.
Under the onbeforeunload section Notes it states:
You can and should handle this event through window.addEventListener() and the beforeunload event. More documentation is available there.1
Which makes me think I should be using the latter. However the documentation for removeEventHandler says this:
addEventListener() and removeEventListener() are not present in older browsers. You can work around this by inserting the following code at the beginning of your scripts, allowing use of addEventListener() and removeEventListener() in implementations which do not natively support it.2
Could somebody please shed some light on the differences for these please, and the best one to use?
1https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#Notes
2https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener#Polyfill_to_support_older_browsers
window.onbeforeunload = function () {/**/} will override any existing handlers and replace it with your own.
window.addEventListener("beforeunload", function () {/**/}); will add a new handler.
addEventListener is far preferred. In older browsers (that is: IE6 maybe IE7) you can use attachEvent.
You'll commonly see code like:
function addEvent(object, event_type, event_handler) {
if (object.addEventListener) {
object.addEventListener(event_type, event_handler, false);
} else {
object.attachEvent("on" + event_type, handler);
}
}
I have a page that is checking the state of controls in a jQuery load function.
This was working perfectly but have now noticed that it doesn't in IE.
$g(window).load(function() {
var one = $find("<%= rb1.ClientID%>");
var two = $find("<%= rb2.ClientID%>");
alert(1);
if (one.get_checked()) {
alert(2);
$g('[id$="div1"]').hide();
$g('[id$="div2"]').show();
}
else if (two.get_checked()) {
alert(3);
$g('[id$="div1"]').hide();
$g('[id$="div2"]').show();
}
});
In IE the contol state checks are never hit (i.e. I never see an alert for 2 or 3 but do see the alert for 1)
In other browsers I don't have any problems and all works as expected. Is there a better way for me to implement the above.
Thanks.
You can use jquery for check the checked status.
isOneChecked = one.is(':checked');
or use javascript.
isOneChecked = one[0].checked;
It seems that this is a problem with the Telerik controls. In order to get around the issue I am calling a function on the radio button controls OnClientLoad command rather than the window.onload
I have a Dojo SubmitButton with jsId="saveParamButtonWidget". I overrided its onClick method by putting:
saveParamButtonWidget.onClick = editParam
I defined the editParam() function like this:
function editParam(eventObj) {
dojo.stopEvent(eventObj);
// ...
}
dojo.stopEvent() is supposed to stop event bubbling and default processing. However, the browser will submit the form anyway. I also tried with the following:
function editParam(eventObj) {
eventObj.stopPropagation();
eventObj.preventDefault();
// ...
}
Same thing. The only way I've managed to prevent form submission is by returning "false" from the event handler:
function editParam(eventObj) {
// ...
return false;
}
Can someone tell me why the first two ways did not work? Thanks.
Okay, after doing some digging through the source, I believe I can answer your question definitively.
The reason dojo.stopEvent() doesn't work, but return false does, is entirely due to how dijit.form.Button is coded. If you're interested, it's time for a little field trip. Keep your hard hats on.
When a dijit.form.Button is clicked...
The button's _onButtonClick method is invoked. (This is hooked up in the template, to the special ondijitclick event which captures not only mouse click but also certain keypresses, for a11y purposes.)
The _onButtonClick method first invokes the _onClick method, which, presuming the button is not disabled (which it's not in this case), invokes and returns the result of the onClick method. This is of particular interest since it's the method you're overriding!
Coming back to _onButtonClick, if _onClick returned precisely false (e.g. if your onClick handler returned false), _onButtonClick immediately bails out. This is why returning false makes your code work as desired. But what happens if it doesn't bail out there? Let's follow the trail further...
Next, _onButtonClick checks whether this button not a descendant of an actual HTML form, but is a descendant of a widget with an _onSubmit method (duck-typing). I'm assuming that in your case it is inside a real form (dijit.form.Form counts), so we'll skip over this. (I am under the impression that this code path wouldn't actually end up submitting, whereas yours apparently does.)
One final condition is checked: if the button has a valueNode defined (it does), the click method of this node is invoked. Unfortunately, this produces an entirely new event object on an invisible input type="submit" node under your form, and thus anything you tried to tell the original event is rendered immaterial, and the form goes on to submit! This is why dojo.stopEvent did not work - this code in dijit.form.Button pays it absolutely no heed.
I cooked this up as a somewhat-limited proof of concept (be sure to open firebug/etc. to get the logs): http://jsfiddle.net/Bf5H8/
Perhaps this is something that should be logged as a bug, but I suppose the initial thought may have been that supporting the well-known return false mechanism would be enough.
All this being said, it's quite possible that overriding onSubmit of the form is more in-line with your interests than overriding the button's onClick anyway (as S.Jones suggested), but at least this should solve the mystery.
Interesting question. +1
I believe you have to use dojo.connect to connect your function to a DOM event to get access to those methods with an event object.
See: The Event Object (DojoTollkit.org Reference Guide)
The Event Object
When you connect a function to a DOM
event with dojo.connect,
Dojo passes your function a normalized
event object. This means that,
regardless of the client's browser,
you can count on a set of standard
attributes about the event and a set
of methods to manipulate the event.
Assume that your function has been
called by dojo.connect and takes an
argument named event, like:
dojo.connect(dojo.byId("node"), "onclick", function(event){
// the var 'event' is available, and is the normalized object
});
...
Dojo normalizes the following methods with an event object:
event.preventDefault — prevent an event's default behavior (e.g., a link from loading a new page)
event.stopPropagation — prevent an event from triggering a parent node's event
Additionally, dojo.stopEvent(event)
will prevent both default behavior any
any propagation (bubbling) of an
event.
That said, placing a function like the one below in your form to perform some logic before submitting it, is a fairly clean, easily understood & maintainable approach.
<script type="dojo/method" event="onSubmit">
if (!this.validate()) { // or whatever else you'd like to evaluate
// insert calls here...
return false;
}
return true;
<script>
Cheers.
I had the same issue for using dojo.stopEvent
This issue is solved the form submission issue like this - here it is a simple form used to connect through dojo:
this.formId = dojo.byId("formId");
dojo.connect(this.formId, 'onsubmit', function(evt) {
var val_main = validate_this_form(0);
if(val_main == false)
dojo.stopEvent(evt);
});
I need to warn users about unsaved changes before they leave a page (a pretty common problem).
window.onbeforeunload = handler
This works but it raises a default dialog with an irritating standard message that wraps my own text. I need to either completely replace the standard message, so my text is clear, or (even better) replace the entire dialog with a modal dialog using jQuery.
So far I have failed and I haven't found anyone else who seems to have an answer. Is it even possible?
Javascript in my page:
<script type="text/javascript">
window.onbeforeunload = closeIt;
</script>
The closeIt() function:
function closeIt()
{
if (changes == "true" || files == "true")
{
return "Here you can append a custom message to the default dialog.";
}
}
Using jQuery and jqModal I have tried this kind of thing (using a custom confirm dialog):
$(window).beforeunload(function () {
confirm('new message: ' + this.href + ' !', this.href);
return false;
});
which also doesn't work - I cannot seem to bind to the beforeunload event.
You can't modify the default dialogue for onbeforeunload, so your best bet may be to work with it.
window.onbeforeunload = function() {
return 'You have unsaved changes!';
}
Here's a reference to this from Microsoft:
When a string is assigned to the returnValue property of window.event, a dialog box appears that gives users the option to stay on the current page and retain the string that was assigned to it. The default statement that appears in the dialog box, "Are you sure you want to navigate away from this page? ... Press OK to continue, or Cancel to stay on the current page.", cannot be removed or altered.
The problem seems to be:
When onbeforeunload is called, it will take the return value of the handler as window.event.returnValue.
It will then parse the return value as a string (unless it is null).
Since false is parsed as a string, the dialogue box will fire, which will then pass an appropriate true/false.
The result is, there doesn't seem to be a way of assigning false to onbeforeunload to prevent it from the default dialogue.
Additional notes on jQuery:
Setting the event in jQuery may be problematic, as that allows other onbeforeunload events to occur as well. If you wish only for your unload event to occur I'd stick to plain ol' JavaScript for it.
jQuery doesn't have a shortcut for onbeforeunload so you'd have to use the generic bind syntax.
$(window).bind('beforeunload', function() {} );
Edit 09/04/2018: custom messages in onbeforeunload dialogs are deprecated since chrome-51 (cf: release note)
What worked for me, using jQuery and tested in IE8, Chrome and Firefox, is:
$(window).bind("beforeunload",function(event) {
if(hasChanged) return "You have unsaved changes";
});
It is important not to return anything if no prompt is required as there are differences between IE and other browser behaviours here.
While there isn't anything you can do about the box in some circumstances, you can intercept someone clicking on a link. For me, this was worth the effort for most scenarios and as a fallback, I've left the unload event.
I've used Boxy instead of the standard jQuery Dialog, it is available here: http://onehackoranother.com/projects/jquery/boxy/
$(':input').change(function() {
if(!is_dirty){
// When the user changes a field on this page, set our is_dirty flag.
is_dirty = true;
}
});
$('a').mousedown(function(e) {
if(is_dirty) {
// if the user navigates away from this page via an anchor link,
// popup a new boxy confirmation.
answer = Boxy.confirm("You have made some changes which you might want to save.");
}
});
window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
// call this if the box wasn't shown.
return 'You have made some changes which you might want to save.';
}
};
You could attach to another event, and filter more on what kind of anchor was clicked, but this works for me and what I want to do and serves as an example for others to use or improve. Thought I would share this for those wanting this solution.
I have cut out code, so this may not work as is.
1) Use onbeforeunload, not onunload.
2) The important thing is to avoid executing a return statement. I don't mean, by this, to avoid returning from your handler. You return all right, but you do it by ensuring that you reach the end of the function and DO NOT execute a return statement. Under these conditions the built-in standard dialog does not occur.
3) You can, if you use onbeforeunload, run an ajax call in your unbeforeunload handler to tidy up on the server, but it must be a synchronous one, and you have to wait for and handle the reply in your onbeforeunload handler (still respecting condition (2) above). I do this and it works fine. If you do a synchronous ajax call, everything is held up until the response comes back. If you do an asynchronous one, thinking that you don't care about the reply from the server, the page unload continues and your ajax call is aborted by this process - including a remote script if it's running.
This can't be done in chrome now to avoid spamming, refer to javascript onbeforeunload not showing custom message for more details.
Angular 9 approach:
constructor() {
window.addEventListener('beforeunload', (event: BeforeUnloadEvent) => {
if (this.generatedBarcodeIndex) {
event.preventDefault(); // for Firefox
event.returnValue = ''; // for Chrome
return '';
}
return false;
});
}
Browsers support and the removal of the custom message:
Chrome removed support for the custom message in ver 51 min
Opera removed support for the custom message in ver 38 min
Firefox removed support for the custom message in ver 44.0 min
Safari removed support for the custom message in ver 9.1 min
Try placing a return; instead of a message.. this is working most browsers for me.
(This only really prevents dialog's presents)
window.onbeforeunload = function(evt) {
//Your Extra Code
return;
}
You can detect which button (ok or cancel) pressed by user, because the onunload function called only when the user choise leaveing the page. Althoug in this funcion the possibilities is limited, because the DOM is being collapsed. You can run javascript, but the ajax POST doesn't do anything therefore you can't use this methode for automatic logout. But there is a solution for that. The window.open('logout.php') executed in the onunload funcion, so the user will logged out with a new window opening.
function onunload = (){
window.open('logout.php');
}
This code called when user leave the page or close the active window and user logged out by 'logout.php'.
The new window close immediately when logout php consist of code:
window.close();
I faced the same problem, I was ok to get its own dialog box with my message, but the problem I faced was :
1) It was giving message on all navigations I want it only for close click.
2) with my own confirmation message if user selects cancel it still shows the browser's default dialog box.
Following is the solutions code I found, which I wrote on my Master page.
function closeMe(evt) {
if (typeof evt == 'undefined') {
evt = window.event; }
if (evt && evt.clientX >= (window.event.screenX - 150) &&
evt.clientY >= -150 && evt.clientY <= 0) {
return "Do you want to log out of your current session?";
}
}
window.onbeforeunload = closeMe;
<script type="text/javascript">
window.onbeforeunload = function(evt) {
var message = 'Are you sure you want to leave?';
if (typeof evt == 'undefined') {
evt = window.event;
}
if (evt) {
evt.returnValue = message;
}
return message;
}
</script>
refer from http://www.codeprojectdownload.com
What about to use the specialized version of the "bind" command "one". Once the event handler executes the first time, it’s automatically removed as an event handler.
$(window).one("beforeunload", BeforeUnload);
Try this
$(window).bind('beforeunload', function (event) {
setTimeout(function () {
var retVal = confirm("Do you want to continue ?");
if (retVal == true) {
alert("User wants to continue!");
return true;
}
else {
window.stop();
return false;
}
});
return;
});