This morning my colleague asked me if I could help him debug some jQuery he was using. First off, I wasn’t to familiar with his dev environment and tools(Visual Studio 2010) as I’m familiar with ORACLE Application Express. It did bring back memories for me, those were the days when running code with breakpoints in VBA for Excel was the norm.
The Scenario:
User has a screen with some details of a record, It also has a checkbox to confirm they want to delete the record and a Button(id = “Click”) to submit
The Mission:
User has to tick the checkbox before clicking on the button. If the user doesn’t tick the box but clicks the button, a string containing some error message should be returned from the server.
The Code:
<code>
<script type="text/javascript">
$(document).ready(function(){
$(function(){$('#click').click('/myurl/errmsg/');});
});
</script>
</code>
Apparently it was working when the inner part of the .ready() function was placed in a onload event. Firstly $(function(){}); is short hand for $(document).ready() so thats not needed. Not only is is needed but it doesn’t make sense, its basically trying to execute code that will execute(double execute) when the DOM is ready.
DID YOU KNOW?
By placing your script at the bottom of the page, you remove the need to wrap it in either $(document).ready() or $(function(){}) because by the time the browser starts processing your script the DOM you will be operating on has already been loaded and ready to be worked on.
Removing that leaved us with the following:
$(document).ready(function(){
$('#click').click('myurl/errmsg/');
});
Looking better but even this would not work:
- The click method isn’t being passed the right arguments.
- What if the #click button is only added some time after the the first rendering of the page.
Firstly, my colleague was under the impression that if he passed a URL (or part of a url) the click event would make an ajax request. I pointed him to the official API documentation(http://api.jquery.com/click/). Clearly not the right arguments. Also what he wasn’t aware of was that by clicking the button it was causing the click event to bubble up through the DOM and then submitting the page which is the default action for a button.
So inside the function we now have :
$('#click').click(function(event){
$.ajax({
type: 'POST',
url: 'myurl/errmsg/',
success:function(data){
//do what ever you want to do with the data that is returned
}
});
event.preventDefault;
});
Even this isn’t brilliant because if you wanted to re-use the same code but perhaps triggered by another element or event you would need to copy or rewrite it. So it would be better to write it as a named function and then call that named function directly from the click event.
Secondly, this binding of the click event would only occur if the element was available at the time the page was first rendered. So if there was another ajax call that maybe returned HTML which contained this button and was then injected into the page, the click event would not be attached to it. I highly recommended they delegate events at a highly level in the DOM using .delegate() jQuery method. I would have suggested they use the newer .on() method but they were using jQuery 1.5 and couldn’t update their version at this point in time.
I think looking at this code I realised just how far I’ve come over the last couple of years (pre-2009) watching yayQuery (http://yayquery.com/), #jquery IRC channel and various other sources. Its quick to forget how some terminology and concepts were difficult to start with until you get your head around them and then becomes second nature once you do.
I think is important not to forget that everyone has to start some where so I urge the community to remember the following:
EVERYONE WAS A NOOBIE AT SOME POINT.