Page 1 of 2

Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Tue Jan 05, 2021 11:49 pm
by MichaelBluejay
I have sixteen fields that need to have the same scripts. They do things like validating input as keys are pressed, adding the values of all the fields to a total, and clicking another part of the screen if the tab key is pressed. I could have the same scripts in each field, but then if I edit the script on one field, I have to edit all of them (or else write a script to copy the script from one field to all the others).

I could have no scripts in the fields, and put all the handlers in the card (on keydown, on rawkeyup, on tabkey), but then they’re gonna run when anyone types anything anywhere in the app, which seems inefficient. Also, I don’t think there’s a built-in way to tell what field is active when running any of those handlers, so I’d have to have a script in each field to put the field name or ID into a global variable or custom property when the field was opened. (openField doesn’t bubble up to the card script) So that’s getting kind of convoluted.

How would you all handle this?

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Wed Jan 06, 2021 12:30 am
by SparkOut
In a word, "behaviors".

You can use the script of one object as an "instanced copy" for another object. Historically a button was used as the "template" script holder. (Although the list of object types that can be the master has been expanded, I gather there may be some reasons why it is preferable to have a button, but I am not clear on those reasons though.)

Anyway, in the Property Inspector you can find a section in the "advanced" settings to select the behavior.

When editing the "master" script, all objects with that behavior will have the same edits virtually applied. The other relevant factor is that all references to the message path and object are instanced so that non global variables are independent, and the resolution "of me" etc will be relative to the instance, and not the master script.

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Wed Jan 06, 2021 2:18 am
by MichaelBluejay
Thanks! Apparently I can't assign a behavior to the script of another field, I get an error "parentScript: bad object".

I don't want the clutter of having a separate button (even if it's hidden, which is in a way worse, because I'll forget about it), so I just wrote a command to copy the scripts when I type "cs" on the command line.

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Wed Jan 06, 2021 5:00 am
by dunbarx
Behaviors have to live in either a button or a stack script.

As for your concern about errant messages, you can always filter "the target", so that only those particular fields will invoke the card script. It is what I often do.

This takes a little more effort, of course, because those fields each need to share some unique identifying property. There are about a million ways to do that. Do you need (or want) help going down that path?

Craig

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Wed Jan 06, 2021 8:27 am
by SparkOut
MichaelBluejay wrote:
Wed Jan 06, 2021 2:18 am
Thanks! Apparently I can't assign a behavior to the script of another field, I get an error "parentScript: bad object".

I don't want the clutter of having a separate button (even if it's hidden, which is in a way worse, because I'll forget about it), so I just wrote a command to copy the scripts when I type "cs" on the command line.
Although, once created, the button can be forgotten.
If you inspect any field that has the behavior script applied, as well as setting up the behavior, you can edit it with a click. (You can by script as well, of course, but the Property Inspector makes it possible to ignore the button, which can be on another card or substack, as well as hidden.)

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Wed Jan 06, 2021 6:46 pm
by FourthWorld
Most of my projects include a substack for resources, which the user never sees, containing things like images used throughout the program. I often put my behavior objects there.

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Wed Jan 06, 2021 8:26 pm
by dunbarx
I have made behavior gadgets, but rarely use them. Old fashioned, you know.

In any case, one must distinguish certain controls from all the others. This allows one to set the behavior of those controls to a behavior script living somewhere else. The local behavior property has to be set explicitly in each control of interest.

Another method is to write a handler in, say, the stack script. It is similarly critical that only the controls of interest invoke it. Again, one has to set some sort of property so that "the target" in the stack script knows when to run. Either of, say:

Code: Select all

if the XYZ of the target then doSomething
if the name of the target contains "XYZ" then doSomething
All the behaviors, or all the "XYZ's" can be set at once by selecting all the pertinent fields and setting a property, or in any other convenient manner.

It is possible, of course, to put the overArching handler in a library stack, so it too is available everywhere, and is not limited to a particular stack script.

Aren't those two methods essentially identical in ease of setup, flexibility and power? If not, why? And if mostly so, then what is second greatest advantage of using behaviors over way downStream handlers? I have never heard of actual examples why behaviors are so newsworthy.

Craig

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 12:20 pm
by bogs
I was about to chime in with almost exactly what Craig posted. I haven't ever used behaviors, mostly because the (IDEs / engines) I work in don't support them, instead using the 2nd method he mentioned most often.
all the "XYZ's" can be set at once by selecting all the pertinent fields and setting a property, or in any other convenient manner.
The method I use is by assigning prefixes to control names, and, depending on where in the path I need to intercept the messages, placing the handling script at the card or stack or (as Richard mentions) a ilbrary stack. The handler is then no more complicated than something like {Psuedo code} -

Code: Select all

if character 1 to 3 of the short name of the target is {prefix for the fields in this case} then
	{either direct code for a single thing, or repeat loop for each additional thing or a set of things
	or an array of things}
end if
For instance, if I want a button being hovered over to turn a certain color, I would give my button name a prefix such as "cmdButtonName". For the above example, the code would look like -

Code: Select all

on mouseEnter
   if character 1 to 3 of the short name of the target is "cmd" then set the backgroundcolor of the target to "yellow"
end mouseEnter

on mouseLeave
   if character 1 to 3 of the short name of the target is "cmd" then set the backgroundcolor of the target to ""
end mouseLeave
aPic_buttonHighlighted.png
Standing out...
Simple, eh?

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 4:24 pm
by dunbarx
Bogs.

You are old fashioned as well, eh?

But I know that others will chime in soon, telling both of us why behaviors are more robust, modern and powerful, and why they bring LC closer to OOP.

Craig

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 5:46 pm
by bogs
dunbarx wrote:
Thu Jan 07, 2021 4:24 pm
Bogs.
You are old fashioned as well, eh?
Well, I wouldn't want to date myself too much, but just before Lc I was using Delphi 5, before THAT I was using stone tablets and chisels...
dunbarx wrote:
Thu Jan 07, 2021 4:24 pm
But I know that others will chime in soon, telling both of us why behaviors are more robust, modern and powerful, and why they bring LC closer to OOP.
LOL, no doubt heh, but Mc doesn't have them, and I haven't found a need as yet to look into them.

I'm just not sure how much more 'OOP' you could get than having (many) object(s) inherit the behavior of one script located in the path as needed. Heck, if all the objects were say, in a group, putting the script there would suffice, you wouldn't even have to have special names or anything, just 'childControls of me' would probably do :P

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 7:00 pm
by jacque
Not having to do all that target checking is a big advantage. There's no special naming or properties required. You can use "me" to refer to the current control regardless of how many other controls use the behavior. Also, the message doesn't have to work its way through the message path so it's faster. You also don't need to put common handlers like "openfield" in scripts that will probably trigger repeatedly for controls that don't need to use the handler. And you can frequently avoid "send".

Finally, it's just more elegant and concise. The behavior acts like it's part of the control's script.

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 7:10 pm
by jacque
Heck, if all the objects were say, in a group, putting the script there would suffice, you wouldn't even have to have special names or anything, just 'childControls of me' would probably do :P
That's what I do too. Behaviors are most useful when the controls are scattered around the card or stack separately. I have a behavior for scrolling groups that distinguishes between desktop and mobile use, for example. On desktop it responds to one set of messages and on mobile it responds to mobile-specific messages. This is not only cleaner, but it keeps a lot of cruft out of the main stack script.

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 10:56 pm
by dunbarx
Jacque.

I get what you are saying, that there is an explicit link to the behavior object. And since each control of interest has to have that property, about the same amount of work as to set a defining property the "old" way, that effort is a wash. I guess I was wondering if there was a mighty increase in functionality.

Then what is all this about mightily advancing the OOP model for LC? Simply that increase in elegance?

Craig

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Thu Jan 07, 2021 11:52 pm
by FourthWorld
dunbarx wrote:
Thu Jan 07, 2021 10:56 pm
Then what is all this about mightily advancing the OOP model for LC? Simply that increase in elegance?
The benefits of behaviors may be summarized as efficiency, flexibility, and portability.

Efficiency is achieved by not having to evaluate whether a message applies to an object, as a global script has to do. With behaviors, the only messages sent are the ones specific to the object in question.

Flexibility refers to chaining and overloading. Chaining is the ability to effectively create subclasses or superclasses by having chained behavior scripts. For example, I may want a class for handling input controls, a subclass for form fields, and subclasses of that for specific types of form fields. Overloading with "before" message handlers (eg "before MouseDown") opens up lots of possibilities that are less graceful through other means.

Portability comes from externalizing code. Whether as a button script in a library stack, or a script-only stack, I can maintain a single code base where fixes benefit everything I'm working on that uses it. With traditional copy-n-paste methods I'd need to go back to each copy and update, and hope I don't forget one.

There may be other benefits, but these hit the highlights of why behaviors are so empowering for larger projects.

Re: Best practices for intercepting events/having identical scripts in multiple fields?

Posted: Fri Jan 08, 2021 12:25 am
by jacque
Richard said it better than I did. I think of it as a private message path that I can reuse and move anywhere. And I forgot to mention the useful "before" and "after" handlers.