132

jquery toggle calls preventDefault() by default, so the defaults don't work. you can't click a checkbox, you cant click a link etc etc

is it possible to restore the default handler?

Stijn de Witt
  • 40,192
  • 13
  • 79
  • 80
  • Can you give some example code? – Jojo Oct 12 '09 at 04:34
  • 5
    The question in the title is a fantastic one! Too bad the actual question is not... I was hoping to find here, the answer to how (if at all possible) we can 'unset' the effect of `preventDefault` after it has been called. Currently this question is actually 'how do I unbind an event listener with jQuery?'. – Stijn de Witt Oct 21 '16 at 20:39

20 Answers20

84

In my case:

$('#some_link').click(function(event){
    event.preventDefault();
});

$('#some_link').unbind('click'); worked as the only method to restore the default action.

As seen over here: https://stackoverflow.com/a/1673570/211514

Community
  • 1
  • 1
klaus
  • 1,806
  • 17
  • 20
  • 3
    If this element have another click handler, you unbind all events attached not only prevented handler... – Aure77 Dec 30 '16 at 16:38
59

Its fairly simple

Lets suppose you do something like

document.ontouchmove = function(e){ e.preventDefault(); }

now to revert it to the original situation, do the below...

document.ontouchmove = function(e){ return true; }

From this website.

Stacked
  • 6,892
  • 7
  • 57
  • 73
foxybagga
  • 4,184
  • 2
  • 34
  • 31
16

It is not possible to restore a preventDefault() but what you can do is trick it :)

<div id="t1">Toggle</div>
<script type="javascript">
$('#t1').click(function (e){
   if($(this).hasClass('prevented')){
       e.preventDefault();
       $(this).removeClass('prevented');
   }else{
       $(this).addClass('prevented');
   }
});
</script>

If you want to go a step further you can even use the trigger button to trigger an event.

jdgregson
  • 1,457
  • 17
  • 39
Val
  • 17,336
  • 23
  • 95
  • 144
  • I am pretty sure it is - I did this on a design recently. At first on a click of a button I prevented the scroll in an iphone by adding e.preventDefault to on touchmove event and then after the animation was done I returned true and it worked like a charm. – foxybagga Mar 05 '12 at 19:48
11
function DoPrevent(e) {
  e.preventDefault();
  e.stopPropagation();
}

// Bind:
$(element).on('click', DoPrevent);

// UnBind:
$(element).off('click', DoPrevent);
Atara
  • 3,523
  • 6
  • 37
  • 56
  • The way it worked for me was: $(document).off('touchmove'); $(document).on('touchmove', function() { return true;}); – rogervila Aug 03 '16 at 14:26
9

in some cases* you can initially return false instead of e.preventDefault(), then when you want to restore the default to return true.

*Meaning when you don't mind the event bubbling and you don't use the e.stopPropagation() together with e.preventDefault()

Also see similar question (also in stack Overflow)

or in the case of checkbox you can have something like:

$(element).toggle(function(){
  $(":checkbox").attr('disabled', true);
  },
function(){
   $(":checkbox").removeAttr('disabled');
}) 
Community
  • 1
  • 1
adardesign
  • 33,973
  • 15
  • 62
  • 84
9

You can restore the default action (if it is a HREF follow) by doing this:

window.location = $(this).attr('href');

kris
  • 11,868
  • 9
  • 88
  • 110
crmpicco
  • 16,605
  • 26
  • 134
  • 210
  • 2
    ideas was right but code out of the box didn't work for me (unless it is just a syntax change in jquery) i used: window.location = $(this).attr('href'); – Modika Jan 23 '15 at 12:09
4

if it is a link then $(this).unbind("click"); would re-enable the link clicking and the default behavior would be restored.

I have created a demo JS fiddle to demonstrate how this works:

Here is the code of the JS fiddle:

HTML:

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<a href="http://jquery.com">Default click action is prevented, only on the third click it would be enabled</a>
<div id="log"></div>

Javascript:

<script>
var counter = 1;
$(document).ready(function(){
$( "a" ).click(function( event ) {
  event.preventDefault();

  $( "<div>" )
    .append( "default " + event.type + " prevented "+counter )
    .appendTo( "#log" );

    if(counter == 2)
    {
        $( "<div>" )
    .append( "now enable click" )
    .appendTo( "#log" );

    $(this).unbind("click");//-----this code unbinds the e.preventDefault() and restores the link clicking behavior
    }
    else
    {
        $( "<div>" )
    .append( "still disabled" )
    .appendTo( "#log" );
    }
    counter++;
});
});
</script>
Rahul Gupta
  • 9,775
  • 7
  • 56
  • 69
2

Test this code, I think solve your problem:

event.stopPropagation();

Reference

Alireza MH
  • 573
  • 8
  • 25
  • you have to stopPropagation on a handler that occurs before the handler that prevents default. You can do this on the capturePhase if your other handler is registered on the bubble phase. – Vitim.us Mar 14 '17 at 19:22
2

The best way to do this by using namespace. It is a safe and secure way. Here .rb is the namespace which ensures unbind function works on that particular keydown but not on others.

$(document).bind('keydown.rb','Ctrl+r',function(e){
            e.stopImmediatePropagation();
            return false;
        });

$(document).unbind('keydown.rb');

ref1: http://idodev.co.uk/2014/01/safely-binding-to-events-using-namespaces-in-jquery/

ref2: http://jqfundamentals.com/chapter/events

Rajkumar Bansal
  • 323
  • 2
  • 10
2

If the element only has one handler, then simply use jQuery unbind.

$("#element").unbind();
Shawn W
  • 566
  • 4
  • 13
1

Disable:

document.ontouchstart = function(e){ e.preventDefault(); }

Enable:

document.ontouchstart = function(e){ return true; }
Brynner Ferreira
  • 1,527
  • 1
  • 21
  • 21
1

The Event interface's preventDefault() method tells the user agent that if the event does not get explicitly handled, its default action should not be taken as it normally would be. The event continues to propagate as usual, unless one of its event listeners calls stopPropagation() or stopImmediatePropagation(), either of which terminates propagation at once.

Calling preventDefault() during any stage of event flow cancels the event, meaning that any default action normally taken by the implementation as a result of the event will not occur.

You can use Event.cancelable to check if the event is cancelable. Calling preventDefault() for a non-cancelable event has no effect.

window.onKeydown = event => {
    /*
        if the control button is pressed, the event.ctrKey 
        will be the value  [true]
    */

    if (event.ctrKey && event.keyCode == 83) {
        event.preventDefault();
        // you function in here.
    }
}
0

I had a problem where I needed the default action only after some custom action (enable otherwise disabled input fields on a form) had concluded. I wrapped the default action (submit()) into an own, recursive function (dosubmit()).

var prevdef=true;
var dosubmit=function(){
    if(prevdef==true){
        //here we can do something else first//
        prevdef=false;
        dosubmit();
    }
    else{
        $(this).submit();//which was the default action
    }
};

$('input#somebutton').click(function(){dosubmit()});
Gyula
  • 1
  • 1
  • 1
    General note: While some coders feel `if (predef == true)` is more explicit, you are adding 7 characters to your JS code for no reason. `if (prevdef)` is just as readable. Also, you have added a redundant anonymous event handler when `.click(dosubmit)` does the same thing as `.click(function(){dosubmit()})` as no parameters are passed. – iCollect.it Ltd May 07 '17 at 12:20
  • Correct me if I'm wrong but this does not seem to prevent the default action anyways. So it means the default action could still execute before your custom code does. – Max May 06 '21 at 15:40
0

Use a boolean:

let prevent_touch = true;
document.documentElement.addEventListener('touchmove', touchMove, false);
function touchMove(event) { 
    if (prevent_touch) event.preventDefault(); 
}

I use this in a Progressive Web App to prevent scrolling/zooming on some 'pages' while allowing on others.

TennisVisuals
  • 427
  • 5
  • 8
0

You can set to form 2 classes. After you set your JS script to one of them, when you want to disable your script, you just delete the class with binded script from this form.

HTML:

<form class="form-create-container form-create"> </form>   

JS

$(document).on('submit', '.form-create', function(){ 
..... ..... ..... 
$('.form-create-container').removeClass('form-create').submit();

});
Clíodhna
  • 818
  • 1
  • 15
  • 29
Dumitru Boaghi
  • 183
  • 2
  • 4
0

in javacript you can simply like this

const form = document.getElementById('form');
form.addEventListener('submit', function(event){
  event.preventDefault();

  const fromdate = document.getElementById('fromdate').value;
  const todate = document.getElementById('todate').value;

  if(Number(fromdate) >= Number(todate)) {
    alert('Invalid Date. please check and try again!');
  }else{
    event.currentTarget.submit();
  }

});
azhar
  • 351
  • 3
  • 13
0

Worked as the only method to restore the default action.

$('#some_link').unbind();

John Smith
  • 55
  • 7
-1

This should work:

$('#myform').on('submit',function(e){
    if($(".field").val()==''){
        e.preventDefault();
    }
}); 
camille
  • 16,432
  • 18
  • 38
  • 60
-3
$('#my_elementtt').click(function(event){
    trigger('click');
});
T.Todua
  • 53,146
  • 19
  • 236
  • 237
-10

I'm not sure you're what you mean: but here's a solution for a similar (and possibly the same) problem...

I often use preventDefault() to intercept items. However: it's not the only method of interception... often you may just want a "question" following which behaviour continues as before, or stops. In a recent case I used the following solution:

$("#content").on('click', '#replace', (function(event){ return confirm('Are you sure you want to do that?') }));

Basically, the "prevent default" is meant to intercept and do something else: the "confirm" is designed for use in ... well - confirming!

elb98rm
  • 670
  • 6
  • 21