preventDefault function: What is the real utility? - javascript

I'm newbie in jquery and saw a piece of code with something strange given the functionality of a method, the "preventDefault". Well, to test, i created a test page and made two functions with "preventDefault" inside of it.
I have two questions on the same subject, i hope you can answer me.
$(document).ready( function( ) {
$('a').click( function( event ) {//Func 1
event.preventDefault( );
});
$("#ok").click( function( event ) {//Func 2
event.preventDefault( );
alert("Wut");
//...
});
});
1- Why, in the second function, the "alert( )" runs even if i comment "event.preventDefault( );" and the first function does not happen the same? If i comment "event.preventDefault();" in the first function, the link doesn't work!
I found it strange because regardless of the method "event.preventDefault();" whether or not commented in the second function, the "alert" works the same way. I think even what comes after "alert" would run.
2- What is the real utility of this method, "event.preventDefault ();"? Why, in the second function, it seems to be useless. Can you give me some example of when it might be useful?
Thanks!

The purpose of preventDefault is to prevent the browser's default action related to the event. Your alert isn't the browser's default action, and is unaffected. Following a link is the browser's default action, and so preventing the default prevents following the link.
preventDefault is crucial in many situations. For instance, when handling a form's submit event, we need preventDefault (directly or indirectly) if we do client-side form validation and the form isn't valid; otherwise, the browser would submit the invalid form.
(I said "directly or indirectly" above because jQuery handles the return value of event handlers in a special way: If you return false, it calls preventDefault and stopPropagation for you.)

It prevents the default action of the control. If it a link, it stops the link being followed. If it is a form submission, it prevents the form from being submitted.
It doesn't interact with other JS event handlers on the same element.
Examples of situations where you might use it:
Stopping the browser following a link because you have used Ajax and pushState to load the content and update the URL
Stopping the browser from submitting a form because you have tested the data entered and found a problem with it

The .preventDefault() function prevents the browser from carrying out the normal implicit behavior of an interactive element. If you click on an <a> tag, then apart from anything your JavaScript does the browser will attempt to follow the "href" value and reload the page. That's the "default" behavior that the function name refers to.
Your alert() runs because .preventDefault() has nothing to do with the code in your event handler. If you want to "abort" an event handler, you'd just return from it.
Note that jQuery also gives you .stopPropagation() and .stopImmediatePropagation() to cancel the process of event bubbling. Those also have no direct effect on the code in your event handler.

event.preventDefault() disables the default behaviour of the event. In case of an link the redirect. It does not effect your own code, in this case the alert() call.

Related

javascript object object on a href="javascript:..." call

I do have a simple script which is not working properly or as expected.
<script>
function modify_val(target, valeur)
{
$(target).val(valeur)
}
</script>
$row->movie2 ($row->counter relations)
The javascript is working properly as the targeted input value is modified but the page is "redirected" after the click with a page containing:
[object Object]
Why is there a print ? I don't understand... The OnClick method behave the same. href or OnClick="javascript:$('#type1').val('$row->movie2');" also behave the same.
Do you have any idea ?
PS : the page is in https mode.
The return value of an event handler determines whether or not the default browser behaviour should take place as well.
<script>
function modify_val(target, valeur)
{
$(target).val(valeur);
return false;
}
</script>
Change your HTML as. I would suggest you to use onClick attribute
$row->movie2 ($row->counter relations)
Demo
<a href=\"javascript:$('#type1').val('$row->movie2'); void(0);\">
works... Guessing as Mate suggested that a return is mandatory
You probably need to stop the default action of the link by passing the event object and calling preventDefault() or simply returning false from your inline event handler.
function modify_val(target, valeur) {
$(target).val(valeur)
return false;
}
See this post for info on returning false from an inline event handler: What's the effect of adding 'return false' to a click event listener?.
For the cleanest code, I'd recommend not using an inline event handler at all and simply use jQuery (which you seem to already have available) to install a click event handler and keep your code and HTML much more separate (generally considered a good practice). jQuery also allows you to return false from the event handler to prevent the default behavior.
See this article on Unobtrusive Javascript for more info on keeping your HTML and Javascript separate.

preventdefault not preventing when its inside button

I could not make preventdefault to prevent action. I apologize if the answer is too easy but I simply cant find the error. why is it not preventing from entering the link? jsfiddle given below.
http://jsfiddle.net/zwY5p/34/
$('#theForm').click(function(e) {
event.preventDefault();
alert('FORM!');
});
e != event
$('#theForm').click(function(event) {
event.preventDefault();
alert('FORM!');
});
The parameter passed to the handler function is what you need to execute preventDefault on. In your code, you are passing e but calling preventDefault on event.
preventDefault prevents the default browser action. It does not cancel the inline JavaScript, since that runs first. If you have to override that, just remove it (no event listener necessary):
$('#theForm').removeAttr('onclick').
your event parameter name e and the variable you are using event are different,
$('#theForm').click(function(event) {
event.preventDefault();
alert('FORM!');
});
Other than the errors pointed out on other answers there's another small issue, specifically in your markup declaration:
<!-- Use either the closing tag or the slash (/) in the opening tag -->
<button id="theForm" onclick="location.href='http://www.example.com'" />
go to google
</button>
On the topic, you have two different handlers attached to the button element, they are both handling the click event but they are still different and separate things. jQuery won't know about the handler defined in the markup:
var btn = document.getElementById('theForm');
jQuery._data( btn, "events" );
will return an array with a single element which is the handler added via jQuery.
Now you have to re-evaluate the need of two different handlers for the same element and event and apply conditions. Do you really need to do it this way?
You're using 2 'click' events.
You end up using preventDefault once, and it's used after the 1st click event has ran.
If you make your button an href, then your preventDefault will be working.
It will also make more sense, as the JS will be separated from the HTML markup.
Also, of course you must use the same parameter name. (function(event), with event.preventDefault for example).
If you are passing "e" as an event to the function then you should prevent the default action only for that "e" that you have passed and not for "event".
$('#theForm').click(function(e) {
e.preventDefault();
alert('FORM!');
});
jQuery preventDefault() method: http://api.jquery.com/event.preventDefault/

jQuery Adds Extra '#' to URL?

I noticed sometimes that when I use jQuery, a extra '#' gets added to the end of my URL after a jQuery function is called. For example, the URL 'www.mywebsite.com' will change to 'www.mywebsite.com/#' once a jQuery function is initialized. The same for 'www.testsite.com/users.php', is changed to 'www.testsite.com/users.php#'.
Why does jQuery add the '#'?
If your function is running from a link onclick, you need to use event.preventDefault()
See http://api.jquery.com/event.preventDefault/
Probably you're getting this when handling a click event. If you don't want that happens, just add event.preventDefault() or return false at the end in event handler function.
Usually this is because you have a dummy link with a jQuery click handler. It's common to see links with an href of # that are only used to trigger some JavaScript.
Go
Resolve this easily by making a habit of calling e.preventDefault() in your click handlers:
$(function() {
$(".button").click(function(e) {
e.preventDefault();
...
});
});
You can also use return false, but that has the added effect of stopping event propagation. I like to add e.stopPropagation() explicitly if I also want that effect. It makes the code and it's intended effect more explicit and clear for future developers (or myself in 6 months).

How can I trigger an element's default event within an event handler?

I have an HTML button that needs to check several conditions, and if they pass allow the default action to occur.
The following works in Firefox, but it fails in IE. I setup a click handler on the button:
Ext.get('send').on('click', handleSend, this, {
preventDefault: true
});
which pops up one of several message boxes if one of the conditions isn't met. If all conditions are met, I remove the click listener from the button and click the button again:
Ext.get('send').un('click', handleSend, this);
Ext.getDom('send').click();
As far as I can tell, it fails in IE (and possibly other browsers) because click() isn't a standard function for a DOM element.
If the default action were a simple form submit, I could just do that after the checks pass, but we're using Tapestry 4 with a listener, which doesn't get executed on a normal form submit.
I've tried submitting the form with
tapestry.form.submit('composeForm', 'doSend');
but the doSend listener isn't getting called.
Conditionally allowing the default event is the best solution I've come up with, but there are a couple of options that may be possible:
Is there some other way to cause a Tapestry 4 listener to be fired from within Javascript?
Is there any way to recognize the normal form submit in my Tapestry Page and thereby trigger the listener?
JSFiddle added
In this jsfiddle, the default action is to submit the form; this is prevented when the checkbox is unchecked. When checked it removes the handler, but the call to click() doesn't work in IE.
Is there a way to simulate a click in IE?
Update
Another snag in the problem is that I have to display an 'are you sure' dialog, so in order to give them time to answer, the event has to be stopped. If they click OK, the default action needs to occur. JSFiddle doesn't seem to have ExtJS widgets like MessageBox, so I'm not sure how to demo this behavior.
At #Ivan's suggestion I tried
Ext.getDom('send').fireEvent('onclick');
but it returns false, meaning the event is being cancelled somewhere. I then tried
var evt = document.createEvent("Event");
evt.initEvent('click', false, false);
var cancelled = Ext.getDom('send').fireEvent('onclick', evt);
but IE9 says that document.createEvent doesn't exist, even though this is how MSDN says to do it.
If all conditions are met, I remove the click listener from the button
and click the button again:
Don't.
You should rather check the conditions in the click handler and call stopEvent there like so:
Ext.get('send').on('click', handleClick);
function handleClick(e) {
if (condition) {
e.stopEvent();
}
}
Internet explorer does not support click. You should use fireEvent method instead e.g.
Ext.getDom('send').fireEvent('onclick');
That should work for IE. For other browsers I guess click is ok. Anyway If I should do similar task I'll try to write an adapter for tapestry and use tapestry javascript library.
There's a listener parameter on Form components; from the Tapestry 4 doc:
Default listener to be invoked when the form is submitted. Invoked
only if another listener (success, cancel or refresh) is not invoked.
Setting this parameter to my listener method like so:
<binding name="listener" value="listener:doSend" />
causes a Tapestry form submit
tapestry.form.submit('myFormId');
to trigger the listener.

javascript commands not all firing

I have a very simple JavaScript function:
function insertPost()
{
document.postsong.submit()
parent.document.getElementById('postSongButton').disabled = true;
}
Both commands in it work but only the first one will fire. This is true when they switch places also. Only the first one will fire...
document.postsong.submit()
Submits the form, takes focus away from the function, function ends there
parent.document.getElementById('postSongButton').disabled = true;
Disables the button, so perhaps it is that there is then nothing to submit the form.
Not too sure if disabling the form button would stop the event from bubbling, but I suspect that the nature of these two lines will lead you to separating them, and having the second one in another event handler.
Hope this points you in the right direction.
EDIT: On further inspection, I found that the real source of the problem is the line:
document.postsong.submit()
Here are the results of my tests in different browsers. If the line previous to the submit() is "button.disable = true", and the button type="submit":
Firefox disables the button and submits the form.
Chrome disables the button, but does not submit.
IE does not disable the button, but it does submit the form.
This explains the behavior you have been experiencing. Having parent before getElementById does not hurt anything, but it is not necessary. Change the code in your insertPost() function to this:
function insertPost(){
document.getElementById("postSongButton").disabled = true;
document.forms["postSong"].submit();
}
Did you check the casing of the html element?
on click of the button you are calling the funcion insertPost().so what you have to do first disabled the button and then submit the form.one think i didnt understand why are using parent of object.
function insertPost()
{
parent.document.getElementById('postSongButton').disabled = true;
document.postsong.submit();
}
You are using parent.document.getElementById(...
Just check if you are referring to the button correctly. i.e. if the parent reference you are using is correct. i.e if the button is in same page as the form or in the parent.
And yes, first you have to disable the button and then trigger the submit action for the form. When you do it the other way, you might end up navigating away to a different page and the disabling line may never execute.
But, since you said, disabling doesn't work for you at all, I thought if you were using wrong reference. Did it give any javascript errors for you when you tried to disable it?

Categories

Resources