3

I'm using jQuery but dealing with markup produced from JSF pages. A lot of the elements have onclick attributes provided by the JSF code (which isn't my realm).

Example:

<div onclick="[jsf js to submit form and go to next page]">submit</div>

I'm trying to add some client side validation with jQuery. I need something like this pseudo code:

$('div').click(function(e){
  if(myValidation==true){
     // do nothing and let the JS in the onlick attribute do its thing
  } else {
     $error.show();
     // somehow stop the onclick attribute JS from firing
  }

})

Is there a best-practice for handling this?

One thought I had was that on page load, grab the onclick attribute's value, delete the onclick attribute from the object, then...well, that's where I get lost. I could cache the JS as text in a data- attribute, but I'm not sure how to fire that off later.

DA.
  • 39,848
  • 49
  • 150
  • 213

5 Answers5

3

Just use eval to run onclick attribute code in your jQuery click event if you want it. You need to remove onclick attribute

<div onclick="alert('hi');">submit</div>

-

$(document).ready(function() {
    var divClick = $('#theDiv').attr('onclick');
    $('#theDiv').removeAttr('onclick');
});

$('#theDiv').bind('click', function(e) {
    if (myValidation == true) {
        // do nothing and let the JS in the onclick attribute do its thing
        eval(divClick);
    } else {
        $error.show();
        // somehow stop the onclick attribute JS from firing
        e.preventDefault();
    }
});
user193130
  • 8,009
  • 4
  • 36
  • 64
Mohsen
  • 64,437
  • 34
  • 159
  • 186
  • but I don't want to run it at all. – DA. Sep 21 '11 at 23:25
  • Edited, take a look. When you bind events via jQuery it don't run the onclick code if you preventDefault – Mohsen Sep 21 '11 at 23:26
  • Edited, take a look, you need to remove onclick – Mohsen Sep 21 '11 at 23:31
  • are you sure? Here's a sample that, at least in Firefox, seems to indicate onclicks fire before any bound jQuery event: http://jsbin.com/ubipis – DA. Sep 21 '11 at 23:35
  • ah! Sorry, I posted before I saw your addendum. Yes, I think that might work. Trying now... – DA. Sep 21 '11 at 23:35
  • actually, I think the solution is that I need to REMOVE the onclick completely, cache it in a variable then eval() it if I need it. So I think what you have is close! – DA. Sep 21 '11 at 23:36
  • Yep. That seemed to work. So the key to your answer is to add this line after caching the attribute: `$('#theDiv').removeAttr('onclick')` – DA. Sep 21 '11 at 23:42
  • Yes, agreed. I'm going to edit. Another thing: I really understand you! I work in same shi**y environment with tons of onclicks.... :D – Mohsen Sep 22 '11 at 00:09
  • Thanks for the help! Yea, the onclick is the bane of the jQuery fan. ;) – DA. Sep 22 '11 at 00:13
3

Either return false or use:

e.stopPropagation()

or

e.preventDefault()

Depending on your needs.

Ariel
  • 25,995
  • 5
  • 59
  • 69
  • 3
    This is getting a lot of up votes, but in and of itself does not seem to be a solution as onclick events fire before any bound jquery events run. In other words, the onclick fires before I can even tell it to preventDefault – DA. Sep 21 '11 at 23:43
1

EDIT

You can save original event:

var originalEvent = $('div').attr("onclick");
$('div').attr("onclick", false);

$('div').click(function(e) {
        if (false) {
            // do nothing and let the JS in the onlick attribute do its thing

            eval(originalEvent);
        }
        else {
            alert("error");
            // somehow stop the onclick attribute JS from firing
        }

    });

take a look at this http://jsfiddle.net/j4jsU/

Change if(false) to if(true) to see what hepens when form is valid.

Goran Obradovic
  • 8,951
  • 9
  • 50
  • 79
  • 1
    It appears that inline onclick attribute JS fires before any bound jQuery event handlers do. So I think part of the solution is that I need to get rid of the onclick attr altogether on page load so it's not even there. – DA. Sep 21 '11 at 23:23
  • here, if i remember correctly, it is the `return false` that's stopping the event bubbling (to be clear). –  Sep 21 '11 at 23:24
  • I have changed answer based on jsfiddle experiment – Goran Obradovic Sep 21 '11 at 23:33
  • The problem is that the onclick JS will fire before any bound jQuery event. Example: http://jsbin.com/ubipis – DA. Sep 21 '11 at 23:34
  • 1
    See updated solution, I have thought that this might not work, as there is no propagation to inline event here that you can cancel. The trick is in $('div').attr("onclick", false); that removes inline event, so you can call it when you want. – Goran Obradovic Sep 21 '11 at 23:38
0

I like e.stopProgation() and e.preventDefault(), but if you do not prefer that strategy, you could also manually remove the onclick() attribute and manually call the function it was using upon successful validation.

Different strokes..

fdfrye
  • 1,099
  • 7
  • 14
0

Why can't you do something like:

div=document.getElementById('test');
oldClick=div.onclick;
bol=false;
div.onclick=function(){
    if(bol){
        oldClick();
    }
    else {
       alert('YOU SHALL NOT RUN INLINE JAVASCRIPT'); 
   }
}
mowwwalker
  • 16,634
  • 25
  • 104
  • 157