I've been thinking a lot about how to design my interfaces so they are easier to use. Most of my applications allow a user to search for an item (a customer, supplier, invoice, and so on) with a variety of different search parameters. When the results appear the user can sort them by any column and edit the item from the properties screen (accessed by double-clicking on the item). Nearly all of my property windows contain various text and combo boxes that a user can edit. The window also contains a 'Save' button, an 'Undo' button, and a 'Close' button. If the user changes a property and then clicks 'Close' without saving, I prompt them with a 'Are you sure want to discard changes?' dialog. Here lies the problem. If a user took the time to change something wouldn't they just expect it to be saved? It seems like forcing the user to constantly click 'Save' then 'Close' is a real hassle. Here is the model I want to go to. I want to remove the 'Save' button off of all my screens. When a user clicks 'Close' the changes will be automatically changed. Also, the 'Close' button should not be clickable if the user has made a change that has broken error rules. Now here comes the tricky part. I want the undo button to be able to undo let's say the last few sets of changes, but I wan't them to be undoable even if several hours or days have passed. I want them to be undoable even if the application has been closed. Basically, I want a way to keep the last few sets of changes to an object stored in the database. I'm not talking about a complete audit, I don't want to waste tons of space keeping track of everything that has ever happened just the last few changes. Then, when a user clicks undo I want the last set of changes to come back. I'm not sure how the undo interface should work, should it just update all the fields with last version or should I implement a common undo box that shows the differences and allows the user to pick which properties they want to revert? I'm reminded of the 'Previous Versions' tab in Windows Server 2003 and Vista that let's you easily recover old versions of documents. So basically I'm talking about extending n-level undo so that at least some of its data is saved into the database with the object and that it is retrieved again with the object. Does this sound doable? or just plain crazy?
No. I have not received specific requests for this solution. However, while observing users I constantly see them forget to click Save. They are then confronted with an 'Are you sure?' box. In this specific application a user will open one window edit only a couple of fields. Then, close that window and do the same to another. It just occurred to me that if I could remove the save buttons and just implicitly save everything that it would really cut down the number of clicks required over the course of a work day. Then I started thinking about how a more advanced undo would be needed because my users make mistakes all the time. I don't like the idea of keeping the 'Save' button. I think that it may be difficult to get users to realize they don't need to hit it. Perhaps I should autosave changes on a regular interval just in-case they leave the window open and walk away for a while.
Sounds like 3 distinct problems, here are some ideas based on similar issues we are dealing with:
1. Save and Close as two separate UI actions less effiecent than a single action. As a simple solution in our application we have a "Save & Close" along with "Save" and "Cancel" (X being a "Cancel"). Users are trained and get used to Save&Close pretty quickly and is thier primary choice.
2. Users saving but with errors that should be rolled back. We have this issue as well, and being legal in nature our next verison we are going to most likely move to a fully versioned data model, where by all updates are really copy-inserts and primary keys are an ID and a version number toghether. Yes this impacts space and performance, but for our needs this solves many issues, such as this one and things like concurrent edits and permanent records for linked entities. Think source control, we as developers can't live without it, well our users really need it for thier business data.
3. Possible data loss by leaving the client unattended and have some sort of system failure during that time. Again we have this issue and are looking at different options, perhaps saving a temp file like Word or VS does, and if you re-open the client it sees the temp file and says hey do you want to recover, or perhaps storing these "intermediate" versions in the db as well, similar to shelving it Team Foundation but automatic, yet not fully "checked-in".
Justin
This is a somewhat philisophical point that has been debated and explored in the past with computer systems. Our current computing model is really based on Unix(processes with isolated memory, hirearchal file system, etc). There have been other models that use such things as orthogonal persistence. This is where you really don't have "save", that is the programmer or the user really need not be exposed to such physical constructs as committing data from ram to disk. There where systems that you could yank the plug, and when plugged back in came back to the exact state they were. No real need for a file system you just had objects that once created where persistent until destroyed, ram was just a cache to the real memory your hard disk.
Why should my grandmother have to remeber "save" her document why can't it just be created edited, rolledback, destroyed? But I digress.
With CSLA you will have to implement this orthogonal persistence yourself, such that every property set might have to trigger a update to a persistent store, or perhaps do this in batches on timed intervals if your not worried about each and every property change being committed in lieu of performance. This could be stored in a DB although if it's just short term non roaming then perhaps the local filesystem would be a better place to serialize the objects.
Bottom line current persistent storage is many orders of magnituded slower than ram, and making your objects commit every change to a persistent store can be difficult while still mantaining performance.
Justin
Copyright (c) Marimer LLC