From: John_Miller@mindlink.bc.ca (John Miller)
Newsgroups: comp.sys.mac.hypercard
Subject: Re: Validating Data Entry in a Field
Date: 26 Aug 92 23:06:31 GMT
Organization: MIND LINK! - British Columbia, Canada
Distribution: world

In article <1992Aug18.215256.1379@ncar.ucar.edu> hpoppe@ncar.ucar.edu
(Herb Poppe) writes:
>> If I'm not mistaken (I haven't tried this) the exitField handler
>> does what
>> you want. It is called every time the cursor leaves the field,
>> *even* if the the field data is unchanged.
>
> The problem is that there is no way (that I have found) to force
> the cursor back into the field using the closeField (or exitField)
> handler. It seems to me that I am going to have to trap every
> mouseUp sent to the card or button and every openField sent to
> other unlocked fields as a result of clicking outside of the
> field in error. That handler (in the card) will have to check
> if there is an error pending in a field. If there is, it will put
> the insertion point back in that field. If not, it will send a
> "myMouseUp" message back to the target of the mouse click.
> Similarly for openField.

Gadzooks!  You're right!

I've been using code something like this to check for errors:

on closeField
  if me is not a number then
     answer "Gimme numerics or gimme death!"
         select char 1 to 1000 of me
  end if
end closeField

This works great when the user moves around with the
Tab key.  (Notice I am *not* trapping tabKey directly.)
I never realized it didn't work when the user used the
mouse to exit the field.  I used to think that HyperCard
included "special case" code to handle this type of
error checking, but now I guess it is just a fluke
based on the way that the Tab key and select command
code is implemented.

Trapping openField is not going to work:  selecting
the other field in openField doesn't "stick"
either.  (Actually selecting field 1's text in
field 2's openField handler seems to stick if you
start with no field selected, but not if you start
with field 1 selected:  strange.)  You could try a
transparent button that covers everything that you
would show and hide/reclick, but then your cursor
would not change properly over fields without even more work.

You might try something like:

on closeField
  global errorRecovery

  if me is not a number then
    answer "I simply can't handle this junk."
    put "select char 1 to 1000 of" & the name of me into errorRecovery
  end if
end closeField

and then in the card/background/stack

on idle
  put hadError() into dummy
end idle

function hadError
  global errorRecovery

  if errorRecovery is not empty then
    do errorRecovery
        put empty into errorRecovery
        return true
  else
    return false
  end if
end hadError

You may still have to checks into some mouseUp handlers
that would check whether hadError() was true or false.

A 'go to card x"' could be added to the errorRecovery
commands to trap moves to other cards, if the idle
handler is high enough in the hierarchy.

It will be a lot of work to trap every event that
can cause the field to be deselected to ensure
that the data is always validated.  (For instance,
you would have to trap Command-Q to prevent the
user from quitting with invalid data. Or: a "start
using this stack" would also be necessary if you
are planning on trapping clicks on background
stacks as well. Very messy)  An approach
I favour is to check for errors at two times:
closeField and within whatever handler actually
has to use the data.  This allows detecting errors
immediately when the user makes a change while
allowing the user to then ignore the error
by exiting the field without further changes
(to go to a help stack or perhaps to quit and
try again later with the local expert who
understands this picky computer).  Your
data processing scripts then rechecks for
validity to protect itself.

______________________________________________________________________
John Miller                      (604) 433-1795
Symplex Systems                  internet:  john_miller@mindlink.bc.ca
Macintosh Consulting and Software Development
______________________________________________________________________