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

Grid Picklist 2

Status
Not open for further replies.

TheLazyPig

Programmer
Sep 26, 2019
96
PH
Hi!

I have a table where when clicked a specific row the deptname and cashier should automatically view in the responding textbox below. Also, the user can edit the column Cashier from the Cashier textbox. However, I haven't found a solution to my problem.

update_mailsys_btycrl.png



Thank you!!!
 
Well, the grid ould be boud to the whole table and the textboxes to the specific fields.

When the user clicks in the grid, that record becomes the active record and the single textboxes display and modify the single fields of that record.

There's even no code necessary to achieve that. Where is your problem, actually?

Chriss
 
My problem is I don't know how to bind the table and textbox.

Do I need to use SET FILTER TO?
 
The grid looks like you already set it's recordsource. The header display the field names.

The textbox.controlsource needs to be set to 'tablename.fieldname'

No, you don't need to set filter to.

Chriss
 
I will add the 'tablename.fieldname' in textbox SET FOCUS procedure?
 
You set the controlsource to 'tablename.fieldname' at design time already. Of course adjusted to the table and fieldname. I don't know your table name, but the field name seems to be deptname for the txtDeptname and cashier for the txtCashier textbox. You set it then already, because it's already the controlsource you'll want from the start on, and it doesn't change. What changes is the value of the fields, when you edit them with the textboxes or it changes because you click on another record in the grid and the record pointer moves.

Chriss
 
Hello,

Chris, you are right.


I would do it a little bit different, because I see the buttons and do not want to explain buffering and tablerevert() :)

Click on edit :
thisform.txtdeptname.value = tablename.deptname
thisform.txtdeptname.cashier = tablename.cashier
thisform.grid.enabled = .f. && no more clicks
thisform.cmdsave.enabled = .t.
thisform.cmdcancel.enabled = .t.
this.enabled = .f.

click on save
* checking values ?
repl tablename.deptname with thisform.txtdeptname.value
repl tablename.cashier with thisform.txtdeptname.cashier
this.enabled = .f.
thisform.cmdcancel.enabled = .f.
thisform.cmdedit.enabled = .f.
thisform.grid.enabled = .t.

click on cancel
this.enabled = .f.
thisform.cmdsave.enabled = .f.
thisform.cmdedit.enabled = .f.
thisform.grid.enabled = .t.

Regards
tom


 
Okay, Tom,

what you show is just how little code is necessary to implement the controlsource feature. I don't see how you have to explain buffering and tablerevert, the controlsource works with and without buffering. It would be a matter to how edit and save buttons work. With a controlsource you don't need them.

It's a matter how important you consider the ability to control an edit mode and the point of saving changes. And how important you then consider ensuring nobody else can edit concurrently or not. No specifica about all of that is given, but it's all possible on top of a form using the controlsource mechanism.

I wonder if you consider the controlsource a bad idea. In part I do. It acts confusing depending on what else is set and used and it doesn't even save much coding.

Chriss
 
Hi Chris,

as mentioned in my mail ("your are right", english is not my native language) I agree with you on using controlsource.

I just thought that for implementing edit/save/cancel my code is easier , without cancel/save your code is easier.
Since many years we never use a field directly as a controlsource, but do a scatter memo name thisform.odat and use thisform.odat.fieldname as controlsource, then after valdation, manipulation , calc we do the gather memo name thisform.odat.

Its foxpro.
There are alwys multiple ways to handle it

Best regards
tom
 
Okay, so you are just not binding directly to the table.

To go into the direction of n-tier you can add buffering and/or use views instead of directly the table. Scatter to a name is reviving the old memvar style with new means.
So in short, yes, there always are multiple ways.

The record object doesn't replace the alias for a grid, though. So I think learning about databinding can't really avoid several topics in the long run.

I'd rather not teach about the value, the value is just a means of holding something that actually comes from a DBF file or even remote database, if it isn't something you enter just for search purposes or to save it into a database. Learning about textbox.value makes people think acting on a grid.column.text.value is the same, which it isn't, you better learn to act on the workareas and fields. Controls merely make that accessible.

Chriss
 
Thanks for all the replies. I already added the controlsource of each textbox as Sir Chris said. However, the textbox values won't refresh when clicking on different rows in the grid. I have added a Refresh button beside the Edit button. Then I found that when I click the refresh button after I choose a row the textbox is updated.

Why is when I clicked the edit button to enable the cashier textbox without clicking the save button the data from the table is updated when pressed enter?

Is it possible that after I saved the new cashier edited from the textbox the table will refresh itself with the updated data??

Thank you!
 
The controlsource is a twoway binding - read and write. You in fact need no save button, as leaving the textbox saves the value in it.
If you follow the discussion I had with Tom you'll see I already mentioned it.

The refresh problem is just that, you don't need a refresh button, once you pick a record and click on a textbox, the textbox will refresh when it is focused. If you don't like this late just-in-time refresh and want an instant refresh when picking the record in the grid, go into the code of the AfterRowColChange event of the Grid and put in

Code:
Thisform.Refresh()

I created a short version as demo:
Code:
oform=NEWOBJECT("gridform")
oform.Show()
Read events

DEFINE CLASS gridform AS form
	Height = 300
	Width = 391
	DoCreate = .T.
	Caption = "Gridpick"
	Name = "gridform"


	ADD OBJECT grid1 AS grid WITH ;
		ColumnCount = 2, ;
		DeleteMark = .F., ;
		Height = 200, ;
		Left = 24, ;
		Panel = 1, ;
		RecordSource = "GridDAta", ;
		ScrollBars = 2, ;
		Top = 24, ;
		Width = 333, ;
		Name = "Grid1", ;
		Column1.Width = 150, ;
		Column1.Name = "Column1", ;
		Column2.Width = 150, ;
		Column2.Name = "Column2"

	ADD OBJECT text1 AS textbox WITH ;
		ControlSource = "GridData.Col1", ;
		Height = 23, ;
		Left = 36, ;
		Top = 240, ;
		Width = 143, ;
		Name = "Text1"

	ADD OBJECT text2 AS textbox WITH ;
		ControlSource = "GridData.Col2", ;
		Height = 23, ;
		Left = 183, ;
		Top = 240, ;
		Width = 134, ;
		Name = "Text2"


	PROCEDURE Load
		Create Cursor GridData (Col1 char(10), col2 char(10))
		Insert into GridData VALUES ('hello','world')
		Insert into GridData VALUES ('foo','bar')
		Go Top
	ENDPROC


	PROCEDURE grid1.AfterRowColChange
		LPARAMETERS nColIndex
		thisform.Refresh()
	EndProc
	
	Procedure Unload()
	   Clear Events
	EndProc 

ENDDEFINE

Now it depends on what exactly you want with an edit mode and save to modify the form code from here. All users I talked with won't like to have an edit mode and save when it can be automatic. The were used to such things in some legacy applications they had which obviously was made by someone using the VFP application wizard, but once they got introduced to an interface that simply enables them to work freely they didn't want that hassle anymore. I see pros and cons with both approaches, I'm not forcing this on you.

If you, again, follow the discussion I had, you'd see I suggest the editbutton could simply switch from readonly=.t. to readonly=.f. controls. That, of course, requires the two textboxes to be set as readonly=.t. at start.

A save button is really unnecessary. What you can introduce as a way to hold data before saving was also already discussed by Tom and me. You can go to buffering, or you don't bind the textboxes to the table itself but to variables or properties of an object created as a copy of one record. And then you'd have to do something in the save to put that back into the table.

Chriss
 
The reason why I wanted to have a save button is to create the history of updates. Therefore, I removed the save button but retain the edit. Thank you. :)
 
Oh, I forgot to ask how to view only the deptname and cashier in the grid? Without removing the other column in the dbf table.
 
Hello,

I agree with Chris , "it depends".

Our customers want an explicite "SAVE IT" button, so they can do accidently changes in a textbox, but then just press cancel. And they want a log who did when a change.
This can be done with triggers,... but we did it with having a controlsource which is not directly bound to the field. And often our grids use cursors from sql querys, so a controlsource = filename would not work without code.

For refresh : see Chris' example.

For having fields but not show in the grid :
You can change columncount in designer and setup controlsource / header for the columns you want, for us, thats the usual way.
Or remove a columns after grid is ready.
Or set the column to visible=.f.
Or construct the grid within source, see chris example and add .controlsource=as you want for each column.

Regards
tom



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top