I've pretty much completely re-written this from what I wrote here about 4 days ago. The way I wrote it before was unclear and raised a bunch of issues that really aren't relative to the core matter. That created some controversial (perhaps) comments and discussion, and some down votes that may have been the result of it not being clear as opposed to it being a bad idea. So here's a new version. And it includes screen shots!
The TL:DR or short version is: Essentially give us a UI and mechanism that provides and documents multiple script parameters very similar to how FM already does this with custom functions... but... better!
And the long version...
- Native Multiple Parameter Passing asked for the feature in principle, and has now been marked by FMI as delivered, because (as I understand it - could be wrong) FMI believe the JSON functions provide the desired functionality. My opinion, and the opinion of many in that thread (it currently has over 85 comments) is that that is not the answer, and many of those comments reflect that.
- So then ChristianSchmitz - creator of the MBS plugin - posted (on behalf of many of us) this: Native Multiple Parameter Passing without JSON which has gained some traction.
- mrwatson-gbs - a very active member of this community - pulled from those this issue: Method needed to Define & Document Multiple Script Parameters & free up Script Name.
This post addresses all those and then some.
Quite a few people, including myself, have noted that FM already has a system and UI for passing multiple parameters to something. The Custom Function UI. It's not the greatest, but in principle, script Parameters should work the same way - for consistency with something already in FM (Custom Functions). It can be better, and I believe what Im proposing below addresses provides a UI consistent with Custom Functions, while also addressing the issues with Custom Functions. See some comments about all that: here, here, here, here, and here for a few starters from jbante, toddgeist, and myself, among others.
So, for most of my points, let's consider this custom function:
And let's consider how we call this function. You're typing out a calculation and when you want to use this function you use it like this:
Middle2 ( "some text" ; 3 ; 8 )
...and of course, that example evaluates in your calculation as "me tex".
I think for consistency, as well as because what I'm proposing here solves a bunch of problems, I think we should adopt something like this. But better...
JSON offers two options.
1. Pass in an object. Essentially key-value pairs. Great because you can always see the parameter names when reading code later. You don't have to remember the order. You don't have to pass in optional parameters (just leave them out). Bad because you have to remember the parameter names exactly (one small typo and your script is hosed). And you have to pass in the names along with the values. EVERY . SINGLE . TIME . YOU . CALL.
2. Pass in an array. Order matters (but no big deal really). Option parameters still have to be included. When reading code later, if you don't already know, you can't tell what parameter is what unless you look up the called script (its code or documentation) on the side. But, you don't have to pass in the names with the values every time you call. The names are defined in the called script and it's responsible for figuring them out.
JSON in FM is great, but for passing parameters to scripts, regardless of which option you choose, JSON kinda sucks because:
1. Lots of data type issues. You have to specify that 1 is a number and "a" is a string, otherwise things don't work.
2. *Relatively* complex (not necessarily complex, but more complex than passing parameters to scripts needs to be) syntax to type, and read, especially for new users. JSON (code, requiring careful syntax, logic and understanding) should be considered a more advanced function whereas passing multiple script parameters should be a basic function.
3. Those two might not be a big deal, but this one is: If any of the parameters are:
- styled text it DESTROYS the styling.
- data for or from a container field/variable: not possible without various workarounds such as Base64Encode-ing and -Decode-ing, which are kludgy (for this usage), cumbersome and performance hogs.
4. Inside the called script, we have to explode the JSON out into multiple parameters one by one, or we have to refer to each parameter with another function (JSONGetElement) with very specific syntax that you have to get right (again, fine for experts, lousy for what should be a basic function).
One other issue: Without a native way to include the parameter names in the script itself somewhere, we have to resort to naming conventions that include the parameters in the name. A pain in and of itself, but with a 100 character limit for script names sometimes it's not long enough.
1. Defining a script to include parameters, and using them inside the script.
Inside a custom function definition, when we want to refer to one of the parameters, we don't have to JSONGetElement it, or GetParameter ( $n ) or GetParameter ( $name ) or anything else like that. We just use the parameter name on its own. In the example function above, text, start, and end are just typed into part of the calculation without having to explode them out or assign them anything first.
So a script should work the same way:
Note the parameter names are defined in the script (just like they are with custom functions). You don't have to remember them. You don't have to assign them to variables. They're just there because they're part of the script definition (same as how they work in a custom function definition).
To use them in the script, just type them out like constants, functions, fields, or whatever else. Auto-type-ahead would include them in the list of what comes up so you only have to type a few characters to get at them.
Much better than typing JSONGetElement ( Get ( ScriptParameter ) ; "ProductName" ) ... right?
2. Calling it.
Defenders of JSON object notation or key-value pairs (including in some of the comments below referring to the earlier version of this post) prefer that because of the ability to see the names and the values together when reading the code later. So this provides that while still making it so that you don't have to type them in every time you call.
Here, New Script (yeah I forgot to give it a sensible name before taking the screen shot, sorry lol) is a parent script calling the Add New Product subscript from above.
Note the names of the parameters are visible. No guessing what they are 2 months later when re-reding your code, or immediately when reading someone else's code.
They're part of the script definition, so they always show, with their values, if any.
Note again you don't have to remember the names. They're defined in the script you're calling, and so they automatically show up at the bottom of this window - as many or as few as are defined. Again, they're just there.
That area (under "Script Parameters:") could dynamically resize to hold as many as needed, with an upper limit of say 5 at which point that area becomes scrollable.
If you want any of them to be optional, just leave the corresponding text box blank!
(Also note, that if for any reason you just don't want to do it this way, you can still do it the old way. I think to accommodate that, FM could by default always include one parameter for every script created, and until you label it otherwise it's just called Parameter. or even leave it as the existing "Optional Script Parameter:". In that way the existing functionality still remains entirely and if you really want to do it all with JSON or #Assign functions or whatever else you like, you still can.
That's it! Can it be any easier or better? If it can, please let me know in the comments.
Addendum: Script Results.
Two schools of thought here. Currently, functions return only one result. Scripts should be consistent with that and do the same? I'd prefer not. Why can't a script, or a function for that matter, return multiple results, natively. The syntax for functions returning multiple results could get awfully complicated and perhaps that's not ideal. If a function needs to return two separate results, then maybe it needs to be two functions. And that's how it works now. So should scripts be the same, for consistency? Perhaps. Although there's an argument for scripts being more flexible than functions and adopting multiple results. I can think of a number of ways it might work, but that might be for another post.
If you like this approach and agree it's the right way to do this (most FileMaker-y, easiest for new users to learn, consistent with custom and built-in functions (but better), no unnecessary steps in using it, etc), please, of course, vote it up. At the same time, please also vote up the Native Multiple Parameter Passing without JSON idea/request that inspired this.
And of course, I welcome comments and feedback.