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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Modifying a character field in a grid to cause an action

Status
Not open for further replies.

Bryan - Gendev

Programmer
Jan 9, 2011
408
AU
I am Updating my ten year old app!

I have a grid on a form offering the user a chance to edit 3 of the fields - to set a flag if they make a change.
One field is a Memo and I have a class to do that but I need a similar class for a character field. If I use the Modify FIELD command i get a new grid with all of the fields listed- I just want to change one just as the Modify Memo allows me to do.

My code for the Memo field modifier is

Define Class gs_captionedit As TextBox
Height = 17
ReadOnly =.F.

Procedure Click
thisfield = mycursor.caption
Modify Memo Caption SAVE
IF !mycursor.caption = thisfield
isupdated = .T.
endif
Thisform.grid1.Refresh()
Thisform.grid1.SetFocus()
Endproc

ENDDEFINE

What is the command to modify and save the new field value please?

GenDev
 
First, it is unusual to use MODIFY MEMO within an application. You would normally use an edit box control to modify large chunks of text.

And on that basis, you would use a textbox control to edit ordinary character strings. You already have a textbox. So what exactly are you asking?

If you want to know how to detect a change in the textbox, you would normally do that by setting a flag from the InteractiveChange. The flag would normally be a property of the form. Using InteractiveChange rather than Click is preferable, as it is possible to click on a control without changing.

The only (small) snag with this is that it won't detect an Undo. In other words, if the user makes a change (in which case you will set the flag) and then undoes it (with CTRL+Z), the flag will not get unset. In practice, I doubt that would be a problem, but you could program round that if necessary.

If I have misunderstood your question, perhaps you could clarify it.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
If your data is buffered, another way of detecting a change would be to call GETNEXTMODIFIED(). Pass it 0 as the record number, and then the alias of the table. If it returns non-zero, it means that the data has been modified since it was last saved.

This is a reliable method, but it does not tell you in which control the data was modified - only that it was modified. (Which is probably what you want.)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
On one side, you don't need a class for text fields. The user can edit a text field in the grid.
On the other side, you can only use Modify Memo <fieldname> for Memo fields, not for any other fields, so that can't work.

Actually, you don't have a problem. Just let the user edit the text field in the grid.


Chriss
 

Just to clarify the grid is coded on a form in a prg.
Their are 3 fields that can be modified - one is a Memo field controlled by the
Define Class gs_captionedit As TextBox code above.
A changed value in the field sets isupdated = .T.

I am looking for a method to change updated to .T. in the other 2 chr fields if they are changed.

I can only code to the level of my experience <G> and the help of Mike and Chris and others here.

GenDev

 
If a user edits a value in a textbox, then the textbox interactivechange event happens. So in that event you can set isupdated.


Chriss
 
You could apply the same event when you change from your modify memo based class to an editbox in the grid, instead.

It's not mandatory, you can stick t what you have - it's even less urgent to change this (from my point of view) than the choices you had in thread184-1829464 to either link to a class library in HOME() or copy it over into your project.

In this case using an editbox instead of your previous class, like Mike also encouraged would just make editing seamless. There's still a pro argument for using the eidtor MODIFY MEMO pops up against an editbox integrated into the grid: The popup editor can be large and display a long text. To have an editbox in the grid merely to also use its InteractiveChange event to detect changes and set the IsUpdated flag variable you use, is not that big of an advantage. On the other hand only being able to see the whole text when it pops out is also not the most elegant way to handle all this.

You could go with a third solution in the notion many developers use: Not use a grid for editing at all, every element the grid shows that should be editable could be repeated as single control outside the grid in a size appropriate for the values and just picking a record in the grid these additional single controls can make the values editable. That's almost a best practice.

I personally wouldn't consider an editable grid cell a lapsus of a VFP application, as long as the value is short enough. And in case of a crowded complex form a popup is also a good way to cope with that, and unlike Mike Lewis I don't consider MODIFY MEMO unelegant, the caption will be a bit technical, but instead using a form with an editbox and programming init and unload etc is far fetched in comparison to using MODIFY MEMO, which does its job.

---------

Besides all that Mike Lewis also already mentioned there are inbuilt was of coping with detecting changes without needing an own IsUpdated variable to flag that. When using buffering you have functions like GETNEXTMODIFIED(), OLDVAL() and CURVAL(), and GETFLDSTATE() to detect changed fields. Even with more states than just changed or not changed. Besides, the actual reason you maintain that flag likely is to know whether you need to store changes back into the DBF. Well, that's simply a TABLEUPDATE() for either the current record or all changes, which would handle that in case you'd use buffering.

Well, and not using buffering but a flag points out to me, you're not using the actual DBFs that finally store the entered data, otherwise unbuffered use would mean the user writes to these DBFs, whether you detect it or not and the changes are directly stored. So you're instead using cursors and program the buffering yourself this way, it seems.

Anyway, thanks for the feedback it helped and no need to sacrifice the weekend to start changing the system. It's not really saving the overhead you did for your manual buffering and flagging changes by undoing all that and instead use the standard solution that needs less code, even when considering future maintenance of the code. It works.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top