Best practices for intercepting events/having identical scripts in multiple fields?
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
-
- Posts: 234
- Joined: Thu Jul 01, 2010 11:50 am
Best practices for intercepting events/having identical scripts in multiple fields?
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?
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?
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.
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.
-
- Posts: 234
- Joined: Thu Jul 01, 2010 11:50 am
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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.
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?
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
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?
Although, once created, the button can be forgotten.MichaelBluejay wrote: ↑Wed Jan 06, 2021 2:18 amThanks! 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.
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.)
-
- VIP Livecode Opensource Backer
- Posts: 10048
- Joined: Sat Apr 08, 2006 7:05 am
- Contact:
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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:
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
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
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?
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.
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 -
Simple, eh?
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} -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.
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
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

Re: Best practices for intercepting events/having identical scripts in multiple fields?
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
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?
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...
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


Re: Best practices for intercepting events/having identical scripts in multiple fields?
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.
Finally, it's just more elegant and concise. The behavior acts like it's part of the control's script.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com
HyperActive Software | http://www.hyperactivesw.com
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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.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
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com
HyperActive Software | http://www.hyperactivesw.com
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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
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
-
- VIP Livecode Opensource Backer
- Posts: 10048
- Joined: Sat Apr 08, 2006 7:05 am
- Contact:
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
Re: Best practices for intercepting events/having identical scripts in multiple fields?
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.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com
HyperActive Software | http://www.hyperactivesw.com