0

I have links in a navigation that look similar to this

<a id="navform" href="#" tabindex="-1" onclick="mojarra.ab(this,event,'action','@form','content');return false" class="active"><span>Policy</span></a>

I am checking for form changes and trying to disable the onclick event for the links when there are changes and enable them if once the user saves the form.

$(':input').on('change', function() {
        formChanged = true;
    });

$('nav a').on('click', function(e){
        if(formChanged){
            e.preventDefault();
            $(this)[0].onclick = null;
        }       
    });

I have tried preventDefault and nulling the event according to some answers I found on here, but no luck. Could someone please tell me how to fix this?

UPDATE:

Thanks to all your answers, I got some ideas and figured how to fix it:

if($('.policy-form')){
        $(':input').on('change', function() {
            formChanged = true;
            $('nav a').each(function(){
                var handler = $(this).attr('onclick');
                $(this).removeAttr('onclick');
                
                $(this).on('click',function(){
                    if(formChanged){
                        invokeDialog("warning");
                        formChanged = false;
                        $(this).attr('onclick', handler);
                    }
                });
            });
            
        });
2
  • 1
    why do you have inline handlers when you can have a dedicated handler? Commented Mar 10, 2016 at 19:03
  • The XHTML is done in JSF and I have no control over it. Commented Mar 10, 2016 at 19:05

5 Answers 5

2

Plain JavaScript one-liner

Use

document.getElementById('navform').onclick = null;

This is because only the last onclick defined will run and here we override it with null.

Note that it would be way better if you would just avoid onclick in your HTML, or if you would at least modify mojarra.ab() appropriately, so that it performs any actual actions only when you desire.

Demo:

document.getElementById('one').onclick = null;
<a id="one" href="#" onclick="alert(true)">Doesn't alerts</a>
<br/>
<a id="two" href="#" onclick="alert(true)">Does alerts</a>

EDIT

Vide comment, here is an example of toggling old onclick on and off:

var button = document.getElementById('button');
var oldOnclick = button.onclick;

document.getElementById('toggle').addEventListener('click', function() {
  button.onclick = button.onclick !== null ? null : oldOnclick;
})
<input id="button" type="button" onclick="alert('Test')" value="Alert"/>
<br/>
<br/>
<input id="toggle" type="button" value="Toggle above button"/>

Sign up to request clarification or add additional context in comments.

5 Comments

How can I enable it again?
@ultimatecoder: I've updated my answer, with an example of toggling original onclick on and off.
Thank you but this didn't work either. I however got some ideas from this and solved it on my own.
@ultimatecoder: Are you sure you used it the right way? My demo should work even for IE9+. Do you want to say that the first button still alerts, after second one was clicked? I'm glad that you solved your problem, anyway :).
I don't know why but the onclick retained its event when I did it your way.
1
$('nav a').on('click', function(e){
    $(this).removeAttr('onclick'); // add this line to remove inline onclick
    if(formChanged){
        e.preventDefault();
        $(this)[0].onclick = null;
    }       
});

Comments

1

You can use the .off() method:

$('nav a').off('click');

One good practive is to add an namespace to your events.

$('nav a').on('click.somenamespacehere', function(e){

});

...

$('nav a').off('click.somenamespacehere');

In this case, you can specify later which events you want to remove (with the off method)

Comments

0

You can't do it that way because the on('click' event and the inline one are two different events and there's no way to tell which would happen first. But, you could replace the inline handlers with your own handler like so

on('click', function(e) {
  if (formChanged) {
    mojarra.ab(...);
  }
});

Comments

0

With an inline click function there are many possibilities to control the logical flow or order of executing the functions attached to the same event.

One possibility is to change the inline code so that you can define a first function and based of the result of this you may decide if execute or not the next function.

My snippet:

// assuming the inline onclick function is like:
function mojarra_ab(_this, event, _action, _form, _content) {
  $('<p>Executed function: mojarra_ab</p>').appendTo('body');
}

function myNewClick() {
  $('<p>Executed function: myNewClick</p>').appendTo('body');
  if ($('#yesNo option:selected').val() == 'true') {
    return true;  // return true to execute the mojarra_ab function
  } 
  return false;  // return false if you don't need to execute the mojarra_ab function
}

$(function () {
  $('nav a').attr('onclick', function(index, attr) {
    return 'if (myNewClick() == true) {' +  attr + '}';
  });
});
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

Choose if to run myNewClick and then mojarra_ab: <select id="yesNo">
    <option value="true" selected>True</option>
    <option value="false">False</option>
</select>
<nav>
    <a id="navform" href="#" tabindex="-1" onclick="mojarra_ab(this,event,'action','@form','content');return false"
       class="active"><span>Policy</span></a>
</nav>

1 Comment

This worked partially (and the only one of all answers here). The new function introduced fires but breaks the mojarra_ab(..) function

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.