In an app I created some 10 years ago, disabling is the approach I took. Each form has a Save, Cancel and Close button. Save and Cancel are both disabled until changes have been made. Close is always available and will prompt to save or cancel when changes were made.
At the time I thought it was the right way to do things. Now, every time I open an edit form and want it to go away, it irks me that I have to use close and can't just use ok or cancel.
I think the form should figure out what to do:
- ok + changes => save
- ok + no changes => close
- cancel + changes => close
- cancel + no changes => close
- close + changes => prompt
- close + no changes => close
The close button will be removed in the near future, but the functionality and behaviour remain as on a desktop you will always have the "X" button by which you can close a form. The inclusion of a separate close button was really to provide a bigger target...
Just for good measure, here is Joel's view on disabling/hiding menu items (which is "DON'T") http://www.joelonsoftware.com/items/2008/07/01.html
I have come to the conclusion that it applies to buttons as well.
In response to JohnGB's comment
The back button in a browser never submits a form, it always has the implicit meaning of a cancel. Any app, whether on a desktop, in a browser or on a mobile, that supports "back" navigation should really stick to that unwritten standard. And it doesn't even matter whether you follow an explicit save or an auto-save paradigm. It just means that using an explicit save paradigm you will have to provide a "save" button and in an auto-save paradigm "back" is just that "back".