Productivity

A case study: Why “meeting for meeting’s sake” is bad

February 1st, 2010

source: mitopencourseware / flickr

We all know meetings are bad (if you don’t, then you’re in the wrong place). But “meeting for meeting’s sake”, a repeating meeting that occurs regardless of an agenda or need, is not only really bad, but potentially destructive.

This is the story of one such meeting. The meeting was a monthly meeting with only a vague description. This instance of the meeting had no agenda until just 30 minutes prior to the meeting’s start. Nobody came prepared, nor did anybody know what to expect. On top of that, important participants were missing, as they were in another meeting.

In my mind, this was a meeting that had every reason to be postponed, if not completely canceled. Unfortunately, the decision was made to hold the meeting anyway.

The topic was controversial. Being that there was only a 30 minute lead time on what the meeting was going to be about, those opposed to the topic had absolutely no time to formulate a response and alternative solution. Those in favor had no idea of the opposition they were about to face.

The conference room was a tinderbox; emotions got heated very quickly. Those opposed reacted from pure gut instinct because they did not have solid facts to work with and had to reach for arguments against. Those in favor reacted emotionally, also due to the lack of preparation, as they were unaware of the hastily arranged, albeit unintentional, ambush awaiting them.

The meeting ended slightly prematurely, with all sides leaving angry. This meeting did more damage than anything else.

What should have happened? There were two major, if not fatal, mistakes made. First, the meeting should have never occurred because there were people who needed to be there who were double-scheduled, and had to go to another meeting. Those people had important information that could have made the meeting go smoother. Secondly, there should have been an agenda for the meeting published several days ahead of time. This would have allowed the opposition to come up with fact-based arguments and an alternative solution, as well as given the proponents time to realize there was an opposition, and to make preparations for that.

When you find yourself scheduled to attend a ‘meeting for meeting’s sake’, don’t just think that you’ll be wasting time. You could be damaging workplace relationships and putting your projects in peril.

General

Windows 7 windows-key trickery

January 30th, 2010

The Windows 7 Whopper (Wikimedia commons)

As with many great discoveries, I some interesting Windows 7 window behaviors by accident. I was trying to move the cursor by word (control + right arrow), when I accidentally hit the Windows key instead of the control key, and the active window went flush with the right side of the screen, and expanded to fill the right half of the screen.  This is much like the behavior when dragging a window to the right side of the screen, except that it works even when you have two monitors.  Here’s a recap of the key combos I found:

Windows key + right arrow key: Right side of window becomes flush with right side screen, expands to the top and bottom of screen, left side of window is in the horizontal center of the screen.

Windows key + left arrow key: Left side of window becomes flush with left side of screen, expands to the top and bottom of screen, right side of window is the horizontal center of the screen.

Windows key + up arrow key: Window fully maximizes to the screen.

Windows key + down arrow key: Window minimizes.

General

How to transfer files to your Kindle via wireless…for free

January 28th, 2010

A common misconception about the Kindle is that the only way to get content is via Amazon’s Kindle store. However, the truth is that you can put your own content on the Kindle. You can do this if you have the right tools (such as Mobipocket Creator) and transfer files via USB, or you can have a .pdf, HTML or text file coverted to Kindle format by using a Kindle email address, which will be pushed to your Kindle via Whispernet. If you use Amazon’s conversion and transfer service, you have to pay $0.15 per megabyte.

If you want to transfer via wireless, you can use Dropbox, the online file syncing service, to do just that. If you have a Dropbox account, you can use the Kindle’s built-in (experimental, and only in the U.S.) browser to get to dropbox.com, log in and start downloading files.

A word of warning though: The Kindle only supports certain types of files. I’ve used this method to transfer .mobi and .prc files, and it should work for .pdf  and text files. But don’t expect your PowerPoint slides to magically appear.

The most time consuming part of the process is the initial set up of the browser. The Kindle wasn’t built to be an Internet tablet (oh, if only somebody would make one, that would be so cool), and the browser is a bit clunky. It’s about as fast as 40 degree molasses. But it does work, supports JavaScript and cookies, and will do the job. Eventually.

Open the browser on the Kindle by selecting ‘Experimental’ from the menu, and then select the ‘Basic Web’ link. Select ‘Enter URL’ from the menu and go to dropbox.com. What you get is difficult to read:

Those two small boxes near the top of the screen are the email and password fields. They do not render correctly on the Kindle, and you will not be able to see everything you’re typing, so be careful as you enter your registered email address and password. Be sure to check the ‘Remember me’ check box so you only need to do this once.  Once that’s done, go to the Login button and click it.  After a successful login, you’ll see your Dropbox home page that’s…blank. Fret not. Since the Kindle’s screen isn’t wide enough to show the full page, you’ll need to click the Kindle’s ‘Next Page’ button to get to a page that’s…mostly blank. Still don’t fret.

I believe this happens because the Dropbox home page uses Ajax to display your files, and the Kindle just can’t handle it. But you can still get to your files by clicking on the ‘Recent Events’ box (in reality, it’s a tab). This is more or less a static HTML page that shows the most recent changes made to your Dropbox.

When you click on one of the links, it will start downloading in the background, provided it’s one of the supported types of files. When it’s completed, you’ll be able to see the downloaded file on the Kindle’s home page.

Why would you want to do this?

This method is slower than transferring files via USB, but if you don’t have the USB cable handy when you need to transfer something, it works in a pinch.

Personally, I use Instapaper to save longish web pages, and use their Kindle export feature to read them when I have time. I save the .mobi files generated by Instapaper in my Dropbox folder on either my desktop PC or laptop (and since Dropbox synchronizes both, it doesn’t matter which), and then download the .mobi files as I have time to read them.

Methodology

Eureka II: Why pair programming rubs me the wrong way

January 26th, 2010

I’ve never liked the idea of pair programming.  I was involved with it once, and it was a complete cluster [expletive deleted]. But even ignoring those experiences, I still have a visceral reaction to hearing the words “pair programming”. It wasn’t until I read a blog titled “50 Strategies For Making Yourself Work” that it dawned on me.  It was the following quote:

You’ll be less likely to slack off if someone else is counting on you to perform.

What’s interesting is that this wasn’t an article about pair programing; it didn’t even have anything to do with software development.  But as I read this, I had the mental image of somebody standing over my shoulder, watching every little thing I did. I don’t work well in that situation. Yes, performance anxiety. Things that would have taken me five minutes to complete would then become ten.

I think the visceral reaction comes from the lack of trust that pair programming communicates. “You’ll be less likely to slack off if someone else is counting on you to perform” means “you cannot be trusted to work on your own, so we’re going to set someone right beside you and have them watch your every move.” In my mind, knowing that someone is depending upon me to get something to them by the end of the day is all I need to get things done; I don’t need someone to watch over me as I do it. If knowing someone depends upon your work doesn’t keep you from slacking off, why would someone staring over your shoulder?

What are the other reasons?

  1. You’ll have to have a 100% increase in productivity just to break even. Because there will now be two people doing the work of one, that “work unit” will need to become 100% more productive. While I do see some productivity increases in pairing (for example, catching the mistake of using a = instead of a ==, or other similar ‘typo’ bugs), but I cannot imagine how paring would double productivity. And if the pair does manage to double their productivity, that’s just breaking even. No benefit.
  2. You lose your individuality. You’re now basically working with a punch clock, given that you have to coordinate your time with your pair. Let’s say you’re used to varying your commute time based upon traffic conditions. No more, now that you have to arrive (and leave) with your pair. Need to duck out to see your kid’s school play, go to the doctor, just get out of the office for a while and grab a coffee. Nope, no way, nada. You’ve become a sycophant in the corporate rat race. Yes, the people you use to laugh at. Now you’re one of them, thanks to pairing.
  3. With the loss of individuality comes the loss of creativity. Having a pair will impact your trial-and-error process (because nobody likes to have people watch their failures, and trial-and-error is more error than anything else), as well as the time you just need to sit there and think something out. Yes, sometimes a pair will be useful when thinking something (particularly with the hard stuff), but most of the time it isn’t.
  4. Interrupaloosa! You’ve managed to figure something out, you’re typing away wildly, your hands barely keeping up with your thought process when: “Um, hey, wait. What does that do?” says your pair. The sound you hear are the boxcars of your thought process being crushed as the train flies off the tracks. Interruptions from the general business day are bad enough, but when you’re joined at the hip by an endless stream of interruptions, you’re productivity is going to plummet. Just like your train of thought goes rolling end over end down the steep canyon.

So there you go. There are my reasons for not liking pair programming. I’m standing by, awaiting the Agile police to come and take me away for having the audacity to doubt The One True Methodology.

Productivity

Eureka! The maker vs. the manager

January 22nd, 2010

Sometimes I’ll just be sitting there minding my own business, when all of the sudden, WHAM! — something comes along that’s so obvious that it results in a “Eureka!” moment (it’s happened twice in the last couple of weeks, so expect another post just like this soon). This time the WHAM came while crawling through my RSS reader, when I found a blog post titled “Maker’s Schedule, Manager’s Schedule“.

If you’ve read very far on this site, you’ll know I despise meetings. Horribly. I view meetings as a productivity sink; there’s no way I can be more productive in a meeting, and, many times, I am completely unproductive in a meeting.  I would hear people talking about their day being fully booked — and are excited about it! I couldn’t grasp why someone would be excited about it. These same people believe there isn’t a single problem a meeting can’t solve, when, in my mind, meetings only create problems.  Why are my observations about meetings so disjointed with these other people.  Is there something wrong with me? With them?  The answer is “neither.”

The “Maker’s Schedule, Manager’s Schedule” eureka! moment made me realize that there are two distinctly different types of people when it comes to meetings.  Worse, neither side understands the other. Nor do they try.

In order for makers to help managers understand, we must communicate with them. We must let them know how a single meeting could potentially ruin an entire day. Hopefully you can find a manager that has, hopefully recently, been a maker. They will become your champion. Remind them of the joy of a meeting-less day and how much they were able to get done, and that satisfaction that provided.

You’re not going to be able to get out of all meetings, unfortunately.  There are two things that can be done to assist in your goal of unfettered making time: 1) Minimize your meetings, and 2) Coalesce your meetings.

Minimize your meetings

Minimize both the number and length of meetings. Ask if you really need to be in the meeting, and explain the benefits of what you’ll be able to accomplish if you don’t attend. Do not fall into the trap of the default hour meeting time. Challenge the meeting organizer to reduce a meeting down to 30 minutes, or to 45 if that doesn’t work. Just because your meeting software defaults to hour-long meetings doesn’t mean you have to follow their cue.

Coalesce your meetings

Think of your calendar as a hard disk defragger display. Get the meetings to all form consecutive blocks such that you don’t have an hour meeting, an hour break, and then another hour of meeting.  That hour break in the Calendar. Source: library_chic / flickrmiddle is useless because you’re not going to be able to really get up to speed before you need to start slowing down for the next meeting. Hopefully you can coalesce all your meetings together in the morning, so you’ll have a wide-open afternoon to work. (Or maybe that’s just me; I wouldn’t like my prospects for the day if I knew my entire afternoon was filled with meetings.)

Move meetings to natural boundaries, such as the hour before or after lunch. If I know there’s a meeting scheduled at 2, I’ll postpone my lunch until 1:15 or so. Don’t allow a meeting to fall right in the middle of your morning or afternoon. However, do not try to create a designated “meeting zone” during the day. Some managers will think all available time within that block of time will need to be filled with meetings. Instead, create a “do not meet” time in which meetings cannot be scheduled, allowing the makers to make and the managers to plan their next batch of  meetings.

Understanding the manager mindset

Managers usually schedule meetings to get information of one type or another. Here are a few quick ideas to provide information without having a meeting, to shorten meetings, or to get uninvited to meetings.

Suggest an alternative to a meeting. For example, if you’re asked if you’re going to be free for a meeting, respond by asking to talk about it now. Without the formality of the meeting, and the inclusion of  unnecessary people (who tend to elongate the meeting), you’ll spend less time addressing the issue.

Try a preemptive strike. If you’re scheduled for a meeting, and you see only one issue for you during the meeting (you only attend meetings with an agenda, right?), go directly to the meeting owner’s office/cube, and give them the information they need, then excuse yourself from the meeting. Follow up with an email to all the invitees.

Do not attend a meeting without an agenda. As mentioned above, you should never go to a meeting that doesn’t have a published agenda. Without it, how do you know when you’ve answered the organizer’s questions, or fulfilled their need to know? By balking at attending an agenda-less meeting, you’re actually helping the manager get in the habit of creating agendas, which will be a win for everyone.  Once you have the agenda, become an agenda hawk. If conversation goes off topic, bring attention to it and get the meeting back on course, even if it’s not your meeting.

If all else fails, become a pain in the ass. If you’re continually getting invites to unproductive meetings from a single individual, it might become necessary to go negative. Start coming up with action items for the manager, forcing them to look through the eyes of a maker for a bit. Go medieval on the meeting’s ass by being a stickler for starting and ending times, and for sticking to the agenda (see above).

Hopefully with these ideas, your meetings will become less frequent, and those you still have will be less of a waste of time.

General

What the iPhone really needs

January 20th, 2010

In a word, multitasking. It’s the 21st century. The era of the uniprocess computing device ended years ago. It doesn’t necessarily need to provide RPC; even if it was a faux-multitasking that just saved application state so you didn’t lose your work when a phone call came in. Something similar to MultiFinder from the mid-80’s genre of Macs would do just fine.

A better e-mail app, at least better notifications. As a former Blackberry user, I miss the ability to assign different notification ‘ringtones’ to each email address, and then a separate tone for high priority emails. I cannot believe that your only choice for an email tone is the default, or none. Yes, I realize this can be done with a jailbroken phone, but I actually use my phone for semi-important things, and don’t want to run the risk of bricking it.

And that’s it. I love my iPhone, and the two items above are the only blemishes I could find.  Here’s hoping there really is an iPhone 4.0 lurking out there that solves these issues…

Web Standards

HTML field hints with progressive enhancement

January 18th, 2010

Genesis, a progressive rock band (source: thisisbossi/flickr)

Adding “hints” inside input elements has recently come into fashion.  This is achieved by putting helpful instructions inside input elements that disappear when that element receives focus by the user either clicking in the field, or using the tab key to navigate to the field.  I’ve resisted doing this because I found it makes the form “noisy”, and have always preferred using tool tip functionality by using the ‘alt’ tag. Another reason I haven’t used that method is because I’ve never seen an implementation that behaved properly in the absence of JavaScript. This is due to lack of adherence to the principle of “progressive enhancement“. Here, I show how to add these ‘disappearing field hints’ in such as way as to not be obnoxious when browsing without JavaScript.

But who doesn’t use JavaScript in this day and age?

I don’t, sometimes. I use a Firefox extension called “NoScript” that allows only sites that have been whitelisted to execute any JavaScript.  If I visit a site that’s new to me (for example, after doing a Google query or following a link from Twitter), it’s done with JavaScript off until I know the site is safe. So other than my paranoid surfing habits, what other scenarios could involve using a browser without JavaScript? Perhaps a screen reader for those with difficulty seeing (although it’s becoming more likely for screen readers to support JavaScript)? Perhaps a mobile browser that has had JavaScript turned off due to bandwidth restrictions? But the question “Who doesn’t use JavaScript” is beside the point. The principle of progressive enhancement stipulate that your site should remain as coherent as possible when JavaScript (and for that matter, CSS) is turned off.

What happens when using hint text without JavaScript

If I visit a site that uses field hints, something like the following happens:

The ZIP code field for accuweather.com when visiting without JavaScript on, and starting to type in my ZIP code

In the example given, I went to AccuWeather, clicked on the ZIP code field and started to enter my ZIP code. However, the “hint” text didn’t disappear, and my ZIP was embedded inside the hint text.  In situations like this, I end up needing to manually erase all the hint text and then enter what I wanted to search for.  That’s not how it should work. If JavaScript is used to clear the field upon gaining focus, then JavaScript should also be used to populate the hint text. The implementations I’ve looked at appear to set the field’s value attribute manually, meaning that the hint will still appear when JavaScript is off, and will remain there when it gains focus.

My example

I’ll make a very simple example to show how these types of fields should be implemented.  My goals are: 1) To degrade gracefully when JavaScript isn’t available, and 2) Make the hint text look different so that the user can tell the difference between what’s a hint and what is user-entered data. Doing this will also help the implementation of removing the hint when it gains focus; I’ll explain later.  Here’s my sample form:

My simple, base form for this example

And now, the code to create this very simple form:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Field hints</title>
</head>
<body>

<form action="#" method="post">
<fieldset>
<label for="search">Search</label>
<input id="search" name="search" type="text" size="40" maxlength="40" value=""/>
<input id="submit" name="submit" value="Search"/>
</fieldset>
</form>

</body>
</html>

Step 1: Styling the hint

In the AccuWeather example above, the hint text looks exactly the same as user-entered text, so the user cannot distinguish between the hints and the data they entered. Some sites use either a different color or style of font (or both), and I like this approach. So the first step will be to create a class style that can be applied to the search field when it’s displaying a hint.  Let’s make the text a light gray and italic. Add the following to your CSS file:

.showhint {
 color: #CCCCCC;
 font-style: italic;
 }

Any field in your form will need to have the class “showhint” assigned to it as a part of the page setup.  Do not, under any circumstances, set this class in the HTML. To support progressive enhancement, we need to separate content and actions; let JavaScript take care of setting and unsetting the class for this element.

Make the hint text color dark enough to be read, but light enough to really make it stand out from the rest of the text in your form.  When the field gets focus, this style will be removed, and the field will revert back to the standard styles inherited from the form.

Step 2: Adding the jQuery ready handler

I’ll use jQuery in this example, but just about any JavaScript framework will be able to handle this. Code passed to the jQuery’s ready function will be executed once the page has been fully loaded. This code will be responsible for setting the hint style to the search field, as well as setting up the hint:

<script type="text/javascript" src="./js/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
//<![CDATA[
 $(document).ready(function() {
   $("#search").attr("class", "showhint");
   $("#search").val("Enter search terms here");
});
//]]>
</script>

Note that the first line includes the jQuery script.  Without that, all the $() calls would fail. This code will execute only if JavaScript is enabled.  If JavaScript is not enabled, the style will remain the same, and the hint text will not be added; all the user will see is a blank search field, which they can start entering search text without needing to manually clearing the field themselves.

Step 3: Handling gaining focus

The rule is that the hint text should disappear when the field gains focus if the hint text is present. That last clause is there to prevent any user-entered data from getting wiped in the event the user clicks on or tabs to the search field again. In other words, just clearing the search field every time it gains focus will not solve the problem.  In the example, the hint text is “Enter search terms here”, so on focus, all we need to do is check if the search field’s value is “Enter search terms here”, and clear it if it is, right? Well,consider what would happen if the user was actually searching for “Enter search terms here”. Unlikely yes, but determining if the hint is being displayed based upon the value of the field just isn’t the right thing to do.

Remember earlier when I said that applying a class to the input field will help out with the implementation of removing the hint text? This is where I explain why. Instead of looking at the content of the field, look at the class of the field. If the class is “showhint”, then it’s in “hint mode”, and we should reset the text and class. Create a focus handler for the search field that will look at the field’s class, and if it’s in hint mode, remove the hint text and the class, causing the field to become blank, and inherit the form’s styles:

$("#search").focus(function() {
 var className = $("#search").attr("class");
 if (className == "showhint") {
   $("#search").val("");
   $("#search").attr("class", "");
 }
 });

That basically completes our task. A user with JavaScript will see the hint, and the hint will disappear when the field gains focus. A user without JavaScript will see a blank field. But if we really wanted to get fancy, we could reset the search field back to hint mode if the user didn’t enter anything into the field:

$("#search").blur(function() {
 if ($("#search").val().length == 0) {
   $("#search").attr("class", "showhint");
   $("#search").val("Enter search terms here");
 }
 });

So if a user tabbed into a field with a hint, then didn’t enter anything before tabbing into the next field, the hint text in field would reappear.

What good will this do if my form submit requires JavaScript?

I’d first reconsider why your form would *need* JavaScript. The most likely reason is validation, but you shouldn’t depend solely on JavaScript validation before taking action on a request; there should be some additional validation going on in the back end (server side) code. But, for whatever reason, you absolutely, positively need JavaScript, note it in an <noscript> block that displays at the top of the page so the user knows you need JavaScript to use the page. Given the above search field example, if JavaScript was required to fire off the search, then perhaps the search HTML should be hidden from those without JavaScript.

Examples

General

Rekindled (or, “Economically feasible”)

January 7th, 2010

Jeffrey Zeldman points out that there may not be enough money in e-books to properly QA the e-books; what you see on a Kindle may not be what is in the printed version of the book due to conversion errors and defects in the tools. And he’s right: A printed book is different than an e-book in many ways. However, the differences aren’t just all negative there are positive differences as well.

If a paper book is printed with errors, it stays that way. Publishers do not recall books to fix their errors, as it wouldn’t be economically feasible, just as it’s currently not economically feasible to do a full QA on e-books.  But the economies flip for correcting errors in e-books. Being software, e-books can be updated, unlike paper books, and, as a result, they can be corrected and updated in an economically feasible way. In fact, since we know Amazon can do things to books without our knowledge, it would be easy to update the errors in e-books on-the-fly.

Because some books are scanned (older books, mainly), there are scan errors that do not go corrected (A personal experience is with Robert B. Parker’s Promised Land, where the word ‘me’ is substituted for ‘the’ liberally throughout the book). And because publishers are getting much less revenue from e-books than printed books, they’re not interested in applying the QA necessary to correct the errors. When print starts bringing in less revenue that e-books, watch for the error rate trend to reverse.

Update Jan. 8, 2010: Well, this is embarassing. Yes, books DO get recalled (source: New York Times).

Methodology

Why unit testing alone is not enough

January 6th, 2010

Sometimes we can fall into a false sense of security when we see all our unit tests pass. But sometimes we forget that the application must also run, and unit tests do not cover that.

facepalm

Urgh.

There was a refactoring push recently to smooth out the build process for a web application I work with. The .war file being generated was getting bloated, and it was due to many unneeded .jar files being included during the build. The refactoring process involved using some dependency-checking functions with maven. It was a labor-intensive and iterative process. After a few days, it was thought that the effort had completed. After all, maven was no longer complaining about either unreferenced .jars, or required .jars not being found. Not only were there no compile errors, there weren’t any warnings, either. Things looked very good.

That is, until we deployed and tried to start the server. The application server barfed almost immediately after starting the application. The problem: overzealous removal of .jar files from the project’s .pom file. The root problem was that we were looking at compile-time dependencies to determine if .jar files could be removed, we weren’t taking runtime dependencies into account. The fix was to include the dependent .jar files with a “runtime” scope in our .pom files.

The moral of this story is that while unit tests are great, and an amazing tool to reduce project defect count (particularly when used in conjunction with Test Driven Development), it’s not the end-all test tool. In this case, the .pom files, as well as any other changes from the refactor, should not have been committed to source control until after the application was actually deployed (locally, on the developer’s workstation), and put through it’s paces.

Web Standards

Do NOT click that button!

January 5th, 2010

star5112 / flickr

Ever click on a button, decide you’re doing the wrong thing, and then move the mouse outside the button? I have, and when it’s implemented incorrectly, it drives me nuts.  It’s all due to using the JavaScript events onMouseDown and onClick incorrectly.

The button that won’t unclick: onMouseDown

Accidentally click the button below (click inside the button, then realize the horror of doing it, and then try to drag out of the button area):

This kind of button implementation annoys the crap out of me. There’s nothing you can do if you accidentally click the button, because by the time you realized you made a mistake, action already started. That’s because the button’s action is triggered by an onMouseDown event. Regardless of what happens next, that event is going to fire. So you cannot “cancel” the action by dragging the mouse out of the button and releasing the mouse button. The event has already fired and the action already started.

There’s a similar issue with the iPhone implementation of buttons. If you tap a button, but do not release, and drag out of the button, the button’s action will fire when you move outside the button. What’s interesting about this is that I cannot duplicate that scenario with a web browser. It appears that a onMouseUp event for a button is fired only if the mouse is still within the button, even if the corresponding onMouseDown event was inside the button.

The button that will click when it shouldn’t: onMouseUp

So that means it’s OK to use onMouseUp to trigger actions when a button is clicked, right? NO! With the button below, click outside the button, then drag to an area inside the button, and let the mouse button go:

The right way: onClick

While less annoying than the original button, it’s not correct behavior. A button should only have it’s action triggered if the mouse button is pressed and released within that button. That’s the onClick event, as implemented by this button.

Do both of the prior tests with this button. The only time you’ll see an alert is if you press the mouse button down, and then release it while inside the button. In fact, you can click inside the button, drag outside of it, drag back in, and then release the mouse button, and it will still work.

This is how your buttons should look in HTML:

<input type="button" value="Edit" onclick="javascript:theAction();"/>

Doing this means your buttons won’t fire too early. Also note that this isn’t an issue when using “submit” type buttons, as their behavior is automatically onClick.