Tuesday, March 20, 2012

jquery onclick handler

Well today I was working on what I thought would be a simple problem to solve and perhaps for the javascript/jquery gurus out there it is. However, it took sometime to get this simple task to work across browsers so I thought I would sum up my findings.

The Problem


We have a legacy web application with several input submit buttons that are used to launch download report actions. Some of these buttons will just submit their parent form action and others will have inline onclick handlers defined.


  • Example of submitting form:
    <input type="submit" name="DownloadRemit" value="Download Remit">
  • Example of inline onclick handler:
    <input type="submit" onclick="document.myForm.action='/sample1.php'; document.myForm.submit(); return false;" name="DownloadSummary" value="Download Summary">


Now we needed to intercept the onclick event and first prompt the user to acknowledge the download before sending down the report.

The Solution


The basic idea was to just use a jquery selector to select each of the Download buttons, and intercept any current onclick handler and inject the confirm prompt to acknowledge the download and allow user to cancel. Actually, the cancel was the hard part, I was easily able to intercept and prompt but cancel wouldn't work. Even with the common answer to "return false;" in the click handler.

Finally, the following script was our solution, using a dynamic closure.

<script>
function postConfirmation(){
var text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ';
return confirm(text);
}
$(document).ready(function() {
/*
at startup we find all the download buttons and change their
onClick event to point to our new function postConfirmation;
*/
$('input[name^="Download"]').each( function(idx,obj){
var objOnClick = $(this).attr('onclick');
var callbackFn = function () {
if (postConfirmation()){
if(objOnClick) {
objOnClick();
}
}else{
return false;
}
};
$(this).click(callbackFn );
obj.setAttribute('onclick',null);
});
});
</script>