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

Checkbox Interactive Change

Status
Not open for further replies.

tkee

Programmer
Feb 6, 2004
55
US
I have code in a checkbox (in a grid) in the interactive change method. It validates the data, but is not in Validate because I want it to happen as soon as they click in the checkbox. The value of the checkbox control source, a logical cursor field, may be changed from true to false in the interactive change code. When it is, the checkbox still shows as checked even though the underlying value has been changed. I have refreshed. I have debugged and checked the field value. Everything works exactly as I want but the check stays in the box. Any ideas of where else to look or a better way of doing it?
 
Whether the table is buffered or not, the table value will only change after Valid returns .T. and the checkbox lost focus.
Within CheckBox Interactive Change you can only test THIS.VALUE, not the underlying tables logical field.

Bye, Olaf.
 
The value of the checkbox control source, a logical cursor field, may be changed from true to false in the interactive change code.

That's not the correct way to do it. Given that the checkbox is bound to a logical field (via its control source), then the act of clicking on the checkbox will itself update the table. You don't need to do it in the InteractiveChange code.

But you also say that the purpose of the checkbox is to validate the data. I don't get that. How does a checkbox validate data? If you mean that you want to programatically set or clear the checkbox to show whether the data is valid or not, then why do you want the user to click on it? It would make more sense to make the checkbox read-only.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Olaf's explanation makes sense, so maybe I need to find another way to accomplish my task. I have a table of court costs. On my form it splits these into three cursors and adds a logical field so that I can show three grids with check boxes so they can check which ones apply. I split them into three grids so that I can have three columns of values. Some of the costs can be applied only to cases breaking certain laws. Some are mandatory and some depend on circumstances, so the user can click the checkbox to choose whether or not to apply those optional costs to the case. Currently when they click in the checkbox my checkbox interactive change calls a method that updates the quantity to one and checks to see whether the cost can be applied to that particular case. If not, then I want to give them a message and to uncheck the box. I change the quantity to zero, so that part works, but the check mark stays. I know Valid would work, but I need it to change when they click in the checkbox, not when they click someplace else. Thanks for your help.
 
Within each grid, is it only the checkbox which updates the underlying data, and not any of the other fields?

If that's the case, then the way to handle this would be to row-buffer the underlyng cursor. Keep the checkbox bound to the logical field (as you already do). If, when they click the checkbox, your test fails (that is, you determine that they cannot apply the costs to the particular cae), then give them the message and then revert the buffer (using TABLEREVERT()). If the test succeeds, commit the buffer (using TABLEUPDATE()).

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
The only thing I say is you can't determine the checkbox value, which will be stored to the logical if allowed by Valid by reading THIS.Value within a checkbox interactivechange event. The table.logicalfield value still is the old one. Storage of a controlsource does NOT happen within InteractiveChange, what changes with each keystroke or click or other interactive change triggering the event is a controls value property. programmaic changes are also not triggering the interactivechange event, that's why Mike asks about other sources of change.

I think you assume reading the underlying value gives you the current value, but the most current value of a control always is its value property, not it's controlsource. If that wasn't the case and every interaction would already change the underlying field, what would be the point of the valid event returning 0 or .F.?

Also note, whenever you verify what I say by looking into a browse window of the underlying table, you cause the valid to run when you click on the browse and thus already store the value. This is almost as they say in physics an observer falsifying the experimental result by being there or not.

In very many cases it is wise to look at the recordsource of the grid instead of grid control, especially when looking at other rows than the current one, as the grid controls only visually are copied per row, the column controls only are actively working on the current row. But the most current value the user sees from a control and your code also can read is the control.value, also outside grids, that's just naturally from the meaning of events.

So whenever you want to react to the user control showing and hiding this with checking and unchecking a checkbox, you look into the checkbox.value, not into the checkbox controlsource, that's still having the old value no matter what buffer mode you use or not.

Put this and only this into a checkbox interactive change bound to a logical field of a table via controlsource:
Code:
MESSAGEBOX("This.VALUE: "+TRANSFORM(This.Value)+CHR(13)+"crsLogicl.lField:"+TRANSFORM(EVALUATE(This.Controlsource)))
You will see they always will be inverse, the checkbox VALUE will be what you expect the value to become from the click, the underlying table field still has its old value.
Notice, what is confusing is, visually the checkbox does NOT yet show its VALUE, this may be partly because of the modal messagebox not yet allowing the checkbox to refresh, but more likely is because your event code now may interfere and change the value. Not so useful within a checkbox only toggling between two values, but more generally waiting with the visual display of the interactively changed value until this event is through saves to refresh the visual appearance twice in case code overrides the value.

When you said:
tkee said:
When it is, the checkbox still shows as checked even though the underlying value has been changed
Did you actually verify that with such a messagebox? Then you now know why that shows two differing values. It's not because the controlsoruce has a bug, it's because you expect it to update eaerlier than it does.

Is that now more clear, perhaps? Generally, I know developers (even experts sometimes) expect a table gets the new value with each single interactive change, at least in case of unbuffered tables where there is no buffering going on at all, but that's not the case. The control only updates its controlsource when the valid events occurred and allowed the update.

And as a sidenote: A controls display also doesn't change it's display value when the controlsource changes its value, that's not triggering a cascading event in all bound controls, it's when a control gets focus it refreshes, or when you do Thisform.Refresh(). You can verify the latter, simply put Thisform.Refresh() into the checkbox interactivechange event, and since it rereads the controlsource value, it then will become readonly/disabled in a very subtle way.

Bye, Olaf.
 
Thank you for your explanations. I realized that the value of the field had not been changed yet. Since the field is logical, I knew the new value would be opposite of the current value since they were assigned only true or false. Buffering and rolling back would have worked and the suggestion made me think, so what I wound up doing is reassigning the logical field in Valid according to the value of the quantity field - zero is false, anything else is true. The logical cursor checkbox is really just a toggle to quickly change the quantity back and forth from one and zero and update the line item total and the grand total. I really appreciate the help I always get solving problems on Tek-Tips. Thanks so much for sharing your time and knowledge!
 
Just want to point out that you'd make things easier on your users if you only show or only enable those checkboxes that are relevant to the present case. Why let the user do the wrong thing and then tell her it's wrong?

Tamar
 
That's a great point. I never thought of it because they are so used to everything being on their old printed form I'm not sure they could adjust. We have just weaned them from circling relevant items on a paper list and using a calculator. It is definitely food for thought.
 
What you describe also rather asks or a button than a checkbox, doesn't it? Surely also a concept not working on paper forms, but that's what people will get used to in interactive forms versus paper forms,

Bye, Olaf.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top