Archive for October, 2009

On forms, submit buttons and browsers

Tuesday, October 20th, 2009

Aah, ambiguity! What a tricky devil you are. The W3C Recommendations are normally very specific and not at all ambiguous, but when things are left open to interpretation you can be fairly sure of varying results.

Bad form, old chap

Have a look at this form:

<form action="wherever.html" method="post">
    <label for="firstname">First name</label>
    <input name="firstname" id="firstname" type="text" />
 
    <input type="submit" name="proceed" value="Proceed" />
 
    <input type="submit" name="back" value="Back" />
</form>

What gets submitted when you hit Proceed? Well yes, firstname is included as is proceed, but is back? What gets submitted when you hit Back, as the second submit button in the form?

Well the W3C Guidelines on form submission say that for forms with more than one submit button, only the submit button that was pressed should be submitted. This seems fair enough.

But what gets submitted when you press enter from within the text field?

The W3C has no recommendation for this! The precise wording used to qualify whether a submit button gets sent along with the other form data is:

If a form contains more than one submit button, only the activated submit button is successful.

…where ‘activated’ means having been clicked on to submit the form and being ’successful’ refers to the selection process for including form elements in the request.

Pressing the right buttons (or not, as the case may be)

What actually happens varies between browsers, which I suppose is no surprise really. The surprise is which browsers do what.

We see two behaviors here:

  • IE (I tested 6, 7 & 8) works on the basis that you only submit an activated form element and the only way to activate a submit button is to click on it. Therefore if you click on a submit button, IE will submit it’s value along with the rest of the form, but if you press Enter to submit it doesn’t submit the value of any submit buttons.
  • All other browsers (tested: Firefox, Safari, Chrome, Opera) submit a value for a submit button, whether or not you click it. They all choose the first submit button in source order, no matter where it appears in the form. Thank goodness that’s consistent!

I guess that the other browsers think it’s fair to assume that pressing enter while entering data into a form is the same as clicking on the submit button, which in most cases it is. But what happens when you’ve got two or more submit buttons? How do you know which button the user wanted to click? How can the developer predict that, supposing they even know about this peculiarity? Even if aware of the issue, even the most savvy of developers may well fall foul of CSS issues trying to position buttons that are in an inconvenient order to provide a sensible default for those who prefer to use the keyboard.

Yes, this time I think IE got it right!

How to fix the problem

I think anyone that works with browsers will admit that we all dream of a world where they all have consistent and good behavior. But failing that, consistent behavior would be nice.

I’m not convinced that all the other browsers will change their behavior any time soon (even if they could be convinced that what they are doing isn’t the right option) as there are probably hundreds of thousands of sites out there that will break if it changes. So the best thing to do is to ‘fix’ IE to behave the same.

Here’s the code:

<form action="wherever.html" method="post">
    <label for="firstname">First name</label>
    <input name="firstname" id="firstname" type="text" />
 
    <input type="hidden" name="submit_button" value="Proceed" />
    <input type="submit" name="submit_button" value="Proceed" />
 
    <input type="submit" name="submit_button" value="Back" />
</form>

You’ll notice I changed a few things around! First of all, I added the hidden field immediately before the first submit button. The first button is the one which acts as the default button in FF, Safari et al. and so we are making it do the same in IE. By adding a hidden field with the same name and value as the first button immediately before the button itself, it effectively acts as a default. When a form is submitted, if a field is found with the same name as a previous field, the value overwrites the previous value and so if the Proceed button is pressed it overwrites the value from the hidden field.

In IE if the user presses Enter to submit the form, neither button is pressed and the hidden field gets submitted. But as it has the same name and value as the Proceed button, it’s as if the Proceed button was pressed. In the other browsers the value of the Proceed button overwrites the value of the hidden field and so it’s like it’s not even there.

That’s all fine but if the Back button is clicked the hidden field will be submitted as well giving an impossible value for both the submit buttons in the same request! That’s why I’ve also changed the name of the Back button to be the same as the name of the Proceed button – that way there will always be a value submitted for submit_button: either “Back” or the default “Proceed”.

Notice I didn’t call any of the fields “submit“. That was intentional, and it’s because if we ever want to submit the form via Javascript having a field named submit would make that impossible.

But is it really a problem?

That solution is a bit clunky to be honest. Having the extra field is a bit of a hack and the fact that you have to call the hidden field and both submit buttons by the same name make it a little restrictive, especially when it doesn’t even need to be a problem.

Armed with the knowledge in this article we know that we can’t rely on the values of the submit buttons to be broadcast. If we don’t know which button has been clicked, we simply choose a default action and perform that unless we detect the alternative action. In PHP and for the first form it would go something like this:

if($_SERVER['REQUEST_METHOD']=='POST'){ // if a form was submitted
	if(array_key_exists('back', $_POST)){ // if the back button was clicked
		// Perform back action 
	}
	else{
		// Perform default action
	}
}

So long as you don’t assume the button to be clicked in order to perform the default action, life will be good!

How to stop a Mighty Mouse scroll ball sticking

Saturday, October 3rd, 2009

Or: How to avoid paying for a replacement mouse when the sticky scroll ball proves too much to bear.

Impeccable timing

I couldn’t really have timed this better. Rumours have just started to emerge about a new mouse and keyboard from Apple in time for the also-rumoured new line of iMacs to be announced at the forthcoming Apple event. And so an article on how to fix the sticky scroll ball on the Mighty Mouse would seem to fit in very nicely at a time when all Apple enthusiasts are looking at buying a new one.

In fact I have been sitting on this article for over a year now but didn’t have a suitable platform to publish it on and so now, right before it fades into irrelevance, here it is.

Requirements

To perform this feat of frugality you will need:

  • A flat, non-scratchy object (like a plastic ruler)
  • A small Philips screwdriver
  • A small flat headed screwdriver
  • Some glue that is good for plastics
  • A certain amount of patience
  • The ability to work with tiny objects

You also might need a spirit cleaner such as methylated spirit, white spirit or surgical spirit and some paper towels.

Crack open the mouse

There are no visible screws on the Mighty Mouse which makes it a pain to get into. A pain but not impossible. Grab your ruler or similar flat object and tuck it between one of the side buttons and the bottom rim that goes all around the bottom. Slide it around the edge to detach the rim from the mouse. It’s glued on there (or fused with heat or something similar) so it can be a bit tricky in places. Just go slowly and carefully and it should come off intact.

Prising the mouse open with a ruler

Prising the mouse open with a ruler

This is the step that made me the most nervous. Don’t worry, it’s all OK from here on! And if it makes you too nervous just remember how damn annoying that sticky scroll ball is and how you were probably just going to chuck it away anyway.

Rimless wonder

Once you have detached the rim it should look something like this.

The mouse with no bottom rim

The mouse with no bottom rim

The bottom half is still attached to the main enclosure but not by much. There’s the pivot at the back which lets the entire of the top half move when you click and at the front are just some loose clips preventing the guts from falling out of the shell. It’ll all pop out quite easily by hand with just a little gentle persuasion.

Detach the wires

Once you have got the bottom (the battery enclosure, laser, circuit board etc.) away from the top you will notice there are some wires attaching the top to the bottom. These need to come off because it makes it a lot easier to work with.

Disconnecting the top from the bottom of the mouse

Disconnecting the top from the bottom of the mouse

Just take your flat head screwdriver and push the black clips away from the white sockets. The ribbon wires will just slide out easily after this.

The bottom of the mouse, wires off

The bottom of the mouse, wires off

Top-up

This is the inside of the top of the mouse. Look at those crazy pickups! Somehow they can tell where your fingers are. Very clever.

Inside the top of the mouse

Inside the top of the mouse

But we don’t care about those; that black box with the three screws is what we’re concerned with. Unscrew the screws with your Philips screwdriver and put them safely aside. This is what you’re left with.

The scroll ball in its enclosure

The scroll ball in its enclosure

Very nice, but what we’re after is in that box of tricks. Fortunately the cross-shaped white lid will just pop off. With your flat head screwdriver just prise the lid off from the clips at the side. Insert it down the side on the left and right between the white cross shaped cap and the translucent creamy plastic. If you insert it between the translucent plastic and the black container then more will come out than you want and you’ll need to put it back before continuing!

The top of the scolling enclosure removed

The top of the scolling enclosure removed

Here’s the problem! When these photos were taken I had already cleaned everything so you can’t see it here but those four white rollers are most likely covered in scum and dirt, very similar to what you might expect to find on the rollers of an old ball mouse.

Cleaning up

Take the ball out of the enclosure.

The scroll enclosure without the scroll ball

The scroll enclosure without the scroll ball

Now take the rollers out. Here’s what you should be looking at:

The scroll enclosure with no ball or rollers

The scroll enclosure with no ball or rollers

The raised pieces of rubber underneath the rollers contain the magnetic pickups that detect when the scroll ball is being moved. Clever stuff.

Here are all the parts of the scroll enclosure. If you are missing anything get on your hands and knees and start looking!

The parts of the scroll enclosure laid out

The parts of the scroll enclosure laid out

Clean all the rollers. Scrape all the crud off with your fingernail. Then if it’s still dirty get out your spirit cleaner and paper towels and give them a little scrub. Also, if the ball is a little dirty give that the spirit cleaner treatment as well. It won’t hurt it!

Close up of a roller from the scroll enclosure

Close up of a roller from the scroll enclosure

Reassembling your mouse

Here’s the fiddly part. Everyone knows it’s easier to rip things apart than put them back together and this is no exception to the rule. The fiddlyest part is getting this scroll enclosure back together. This is mainly due to the rollers and getting them into position. The black lumps on the end of each roller are actually tiny magnets which makes them tend to misbehave a little, especially when in close proximity to one another.

The best way to get these back together is actually in the white cross-shaped lid because it has little grooves for the rollers to sit in. Place the ball in there first and then add each roller, one by one.

Reassembling the scroll enclosure contents in the lid

Reassembling the scroll enclosure contents in the lid

Make sure you add them the right way around! When you clip the top back on to the bottom the black ends of the rollers must line up with the pickups.

Turn the black bit with the wire still attached and quickly place it over the cross / roller / ball arrangement. Press down, making sure it’s all aligned well. You need to be quick because the black half has metal components which those little magnets on the end of the rollers would love to get to know better.

Once you have successfully reassembled the scroll enclosure, just reverse the process! Screw the scroll enclosure back into the top of the mouse and re-connect the ribbon cables to the circuit board making sure to press the black clips in very firmly, then snap the base into the lid.

All you have to do now is glue the rim back on. Make sure you don’t use too much glue in case you have to do this again! Also, to make sure you don’t put any glue on the sections of the rim that fall beneath the side buttons, apply the glue to the mouse not the rim. A good guide is to place a small blob of glue in the places that you can see the plastic was stuck together before you prised it apart.

All done!

Just wait for the glue to dry and you’re all good to go. Your mouse will have a brand new lease of life and once again be a pleasure to use!