Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 14 total
Thread How to cancel a change to a field?
Thu, Mar 22 2007 6:51 PMPermanent Link

"Adam H."
Hi,

Sounds like an easy question - but it's got me stumped.

I've got a TdbCheckbox connected to a TField on a dataset (True/False
value). If the user chooses to tick the box, making the value true - I want
to be able to run a number of 'checks' right then, to see if the result is
valid. (ie - making sure that other things have been done first, and
aborting the change if not).

I've tried the OnChange event of the TField, and doing an ABORT if I want to
cancel the change.
I've tried the OnValidate event of the TField, and Raising and Exception if
I want to cancel the change.
I've tried the Onchange event of the TField, and doing "Field.value :=
False" if I want to cancel the change.

The first two don't actually abort the change - they leave the change there,
but keep triggering if the user tries to move off the checkbox until the
user unticks the checkbox. (So, OK - in short it does do the job in the
end - but I feel it's unfriendly. I want the application to actually uncheck
the box for them).

I would like to be able to trap the TField itself (and not the checkbox)
just incase later that same field is added to a grid, or other VCL
components.

Is this possible / simple to do? Am I missing something really simple here
that I'm going to kick myself about later?

TIA

Adam.

Thu, Mar 22 2007 7:39 PMPermanent Link

"Ralf Mimoun"
Adam H. wrote:
> Hi,
>
> Sounds like an easy question - but it's got me stumped.
>
> I've got a TdbCheckbox connected to a TField on a dataset (True/False
> value). If the user chooses to tick the box, making the value true -
> I want to be able to run a number of 'checks' right then, to see if
> the result is valid. (ie - making sure that other things have been
> done first, and aborting the change if not).

You don't want to cancel the Post, just set the value back? I'd use
OnBeforePost and MyField.Value := MyField.OldValue.

Ralf
Thu, Mar 22 2007 8:30 PMPermanent Link

"Adam H."
Hi Ralf

> You don't want to cancel the Post, just set the value back? I'd use
> OnBeforePost and MyField.Value := MyField.OldValue.

Thanks for your reply. Unfortuantly, the problem there is, that the user is
allowed to continue making modifications until they actually post the
changes to that record. I'm wanting to pull the user up and revert the
change when the user tries to change the field - at the point of change, and
not later down the track, when they've finished the entire record.

Cheers

Adam.

Fri, Mar 23 2007 11:27 AMPermanent Link

Chris Erdal
"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> wrote in
news:5B6BB42A-5D44-42C6-A7EC-4CC676A0E3D0@news.elevatesoft.com:

> Hi,
>
> Sounds like an easy question - but it's got me stumped.
>
>
> I would like to be able to trap the TField itself (and not the
> checkbox) just incase later that same field is added to a grid, or
> other VCL components.
>
> Is this possible / simple to do? Am I missing something really simple
> here that I'm going to kick myself about later?

Adam,

 I found a useful unit somewhere a while ago, with lots of helpful
functions to simplify using RTTI - Run-time type information.

Here's the unit's first few lines:
---------------------------------8<--------------------------
unit clRTTI;
{
Author: Chris Lichti
Email:  chlichti@mindspring.com
February 2, 2001

clRTTI is a utility unit that wraps Delphi's Run-Time Type Information in
a set of easy-to-use classes:
---------------------------------8<--------------------------

one function I use is:
---------------------------------8<--------------------------
function TrtWrapper.HasProperty( PropertyName: string ): boolean;
begin
 Result := IsPublishedProp( ObjClass, PropertyName );
end;
---------------------------------8<--------------------------

You need to include typinfo, and you can thus test whether the active
control has e.g. a property called 'Field'. You call this in the Form's
onKeyDown and also OnMouseDown with Form.KeyPreview set, and then if the
control has your particular field you can do further checking of the
Field's current value (which hasn't yet changed) against the control's
new state/value depending on what kind of control it is.

It can get rather heavy when you want to check on grids, check-boxes,
etc, but it's possible! The trick is to go back up through the control's
ancestors until the field is added, and you end up with only needing half
a dozen or so cases of how to deal with it.

Hope this helps.

--
Chris
(XP-Pro + Delphi 7 Architect + DBISAM 4.25 build 3 + EDB 1.00 build 6)
Fri, Mar 23 2007 12:06 PMPermanent Link

Sean McCall
Adam,

How about this (you can use the field tag or a form variable to check
for recursive entry:

procedure MyField.OnFieldChange(...)
begin
  if MyField.Tag = 0 then begin   
    MyField.Tag := 1;
    try
      if MyField.AsBoolean = True then begin
         ... do what you want to do
         MyField.AsBoolean := False;
      end; {if set to true}
    finally
      MyField.Tag := 0;
    end; {try-finally}
  end; {if first time called}
end; {procedure}

Sean

   


Adam H. wrote:
> Hi,
>
> Sounds like an easy question - but it's got me stumped.
>
> I've got a TdbCheckbox connected to a TField on a dataset (True/False
> value). If the user chooses to tick the box, making the value true - I want
> to be able to run a number of 'checks' right then, to see if the result is
> valid. (ie - making sure that other things have been done first, and
> aborting the change if not).
>
> I've tried the OnChange event of the TField, and doing an ABORT if I want to
> cancel the change.
> I've tried the OnValidate event of the TField, and Raising and Exception if
> I want to cancel the change.
> I've tried the Onchange event of the TField, and doing "Field.value :=
> False" if I want to cancel the change.
>
> The first two don't actually abort the change - they leave the change there,
> but keep triggering if the user tries to move off the checkbox until the
> user unticks the checkbox. (So, OK - in short it does do the job in the
> end - but I feel it's unfriendly. I want the application to actually uncheck
> the box for them).
>
> I would like to be able to trap the TField itself (and not the checkbox)
> just incase later that same field is added to a grid, or other VCL
> components.
>
> Is this possible / simple to do? Am I missing something really simple here
> that I'm going to kick myself about later?
>
> TIA
>
> Adam.
>
>
Fri, Mar 23 2007 5:38 PMPermanent Link

"Ralf Mimoun"
Adam H. wrote:
> Hi Ralf
>
>> You don't want to cancel the Post, just set the value back? I'd use
>> OnBeforePost and MyField.Value := MyField.OldValue.
>
> Thanks for your reply. Unfortuantly, the problem there is, that the
> user is allowed to continue making modifications until they actually
> post the changes to that record. I'm wanting to pull the user up and
> revert the change when the user tries to change the field - at the
> point of change, and not later down the track, when they've finished
> the entire record.

What if you put that code in OnChange? You might have to add some test to
avoid an infinite loop, but it should work.

Ralf
Sat, Mar 24 2007 5:36 AMPermanent Link

"Iztok Lajovic"
Adam,

I would make a memory table with identical field definitions and populate it
with the record to be updated. All modifications to that record can be done
independently and at the end you decide if you want to put the modifications
to original record by copying all fields.

Iztok Lajovic

"Adam H." <ahairsub4@rREMOVEMEspamSTOPPER.jvxp.com> je napisal v sporočilo
news:F78B8C17-3BC0-47E0-95A8-DEE65690A902@news.elevatesoft.com ...
> Hi Ralf
>
>> You don't want to cancel the Post, just set the value back? I'd use
>> OnBeforePost and MyField.Value := MyField.OldValue.
>
> Thanks for your reply. Unfortuantly, the problem there is, that the user
> is allowed to continue making modifications until they actually post the
> changes to that record. I'm wanting to pull the user up and revert the
> change when the user tries to change the field - at the point of change,
> and not later down the track, when they've finished the entire record.
>
> Cheers
>
> Adam.
>

Sat, Mar 24 2007 8:19 AMPermanent Link

"Ralf Mimoun"
Btw,

if you don't want a user to change a field, then mark it as read only or
disabled. As a user, I'd search tar and feathers for the developer who let
me (not) change something without a hint.

Ralf
Sun, Mar 25 2007 6:26 PMPermanent Link

"Adam H."
Hi Iztok,

Thanks for your suggestion,

> I would make a memory table with identical field definitions and populate
> it with the record to be updated. All modifications to that record can be
> done independently and at the end you decide if you want to put the
> modifications to original record by copying all fields.

Unfortuantly, the same problem will occur on the memory table - it's not
going to 'trap' the field at the time the *individual field* is changed, but
rather when the record is updated.

I'm wanting to stop the user dead in their tracks at that particular field,
before they continue and finish the rest of the record.

Best Regards

Adam.

Sun, Mar 25 2007 6:27 PMPermanent Link

"Adam H."
Hi Chris,

Thanks for your reply. What you're describing looks like it could work,
however it looks like a wrapper to the visual component, rather than the
field itself. (And I'm trying to trap it at the actual field).

I'll keep it for reference, just incase I'm unable to find anything that
works for me.

Thanks & Regards

Adam.

>  I found a useful unit somewhere a while ago, with lots of helpful
> functions to simplify using RTTI - Run-time type information.
>
> Here's the unit's first few lines:
> ---------------------------------8<--------------------------
> unit clRTTI;
> {
> Author: Chris Lichti
> Email:  chlichti@mindspring.com
> February 2, 2001
>
> clRTTI is a utility unit that wraps Delphi's Run-Time Type Information in
> a set of easy-to-use classes:
<snip>

Page 1 of 2Next Page »
Jump to Page:  1 2
Image