Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Detecting a KeyPress on a Form 1

Status
Not open for further replies.

AndrewMozley

Programmer
Oct 15, 2005
621
GB
I am creating a standard form class for maintenance of a single table. At preset I have buttons for Edit, Delete, Add, Save, Revert - shall put them on a toolbar in due course, but I am just trying to get off the ground, with help from several books including Hentzen's The Fundamentals (1997 !).

When the user is editing the current record, I wish to enable the Save and Revert buttons, but I do not want to do that until he actually makes a change to one of the text boxes.

So I had thought that I would use the Keypress() event of the form, but that does not appear to fire when I key something into a text box (The Keypress method on the textbox itself does indeed fire).

Is there a way that I can do this, without having to put code into a method for every textbox?

Sorry this is all such basic stuff! Andrew
 
For a longer answer, I would add:

- What exactly does your Revert button do (or, more precisely, what does the user expect it to do)? I would expect it to cancel all the edits made so far, and then take the form out of edit mode. If that's right, then you need to keep it enabled the whole time, in case they want to get out before they've made any edits. (I'd also change the caption to Cancel, but that's another story).

- Although it's more effort, I would use the InteractiveChange rather than the Keypress. The main reason is that Keypress fires for any valid key, not just those that cause the data to be edited (so, it can include cursor keys, for instance). With InteractiveChange, you know that the data has actually changed. On the other hand, using InteractiveChange means that you have to test it in every editable control on the form. But that's easy if all your controls derive from the same base classes.

Just something to think about.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
To detect changes in data is easy, if you buffer changes, before saving.

With Table Buffering mode you check any alias this way:

Code:
Go Top in (cAlias)
If GetNextModified(0,cAlias)=0
   * no changes
Else
   * pending chagnes
Endif

This includes the cases a user edits a value and then changes it back to the originalvalue, but that's also true for an approach checking via KeyPress or InteractiveChange of any control.

The good thing is, if you really want to dig into that problem, you can check OldVal() against cAlias.Field and see if there really is a change in a field.

The other good thing about the buffering approach is, it doesn't matter what kind of GUI is used, as long as changes are made to buffered aliases, you can detect that. And you can TABLEREVERT() to cancel changes on the level of records or the whole table.

Bye, Olaf.

 
Thanks Mike - I should have looked at that! Both your other suggestions are helpful. So the rules of the game are that Revert is active as soon as I get into Edit or Add Mode, but the Save key is only enabled once the user has made a change.

Andrew
 
Andrew said:
So the rules of the game are that Revert is active as soon as I get into Edit or Add Mode, but the Save key is only enabled once the user has made a change.

Yes, that's exactly right (except that I'd name it Cancel rather than Revert; after all, if they want to come out of edit mode before they've made any changes, there will be nothing to revert).

Also, Olaf's code is worth keeping in mind. I wouldn't use it to decide whether or not to enable the buttons. But it is very useful to call it from the QueryUnload, so you can check for unsaved edits when the user closes the form.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips, training, consultancy
 
Be careful with Olaf's GetNextModified() code. It's good and I've used it myself in the right circumstances. The problem is that with row buffering (which I don't recommend), moving the record pointer commits changes which MAY not be your intent.

The other thing you need to account for when using getnextmodified(), curval(), and all the other change detection options is that the buffer and underlying data source will not reflect interactive changes in a control until that control loses focus.

This whole topic seems like it should be a no-brainer but there are a million moving parts and each of them affects many others. Taking one from column A and one from column B is a viable strategy in a Chinese restaurant but not here. :)
 
Dan has a few points there, but what makes it a bit easier is:

Use table buffering only, you can still Tableupdate() a single row or all the buffer, so you are in control. Then you can also GO TOP without fearing the triggering of rules etc. Forget about row buffering and that beast is already much tamer.

Many went that route and built toolsets, which handle the problematic "moving parts". Eg before saving: IF vartype(_screen.activecontrol)="O" then _screen.activecontrol.Setfocus() endif.
This causes the full event loop of valid, lostfocus, when and gotfocus, so the final change is saved.

And there is a very simple solution to save via a save button click, as that automatically also moves the focus to it.

Yes, there is a lot to learn, but it also solves more than just the change detection, a user can really revert changes and make a whole change or none to the database, transactional processing. autoincremental integers are more problematic, but can be solved by using GUID/UUID as keys. Table and field rules are less problematic, as you delay their check to the save. You rather skip field and record validations but use a validation method checking all buffered data for consistency.

To me there are more bonus than malus, but it may really be a matter of how you did things so far and a matter of taste.

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top