I call it "Marking". I use a button that runs a simple script to set/unset a global variable to the ID of the record you want to use. That global variable is used for both the conditional formatting and for later scripts.
The meat of the script is one Set Variable step. I pass the ID I want to grab as a script parameter and code the global so it's tied to a layout ( my layouts never have duplicate names and there's benefits to tying it to a TO too). You may want an onLayoutLoad trigger that clears the variable depending on your needs. I also use Bruce Robertson's custom function AntiFilterValues().
id = get ( ScriptParameter ) ;
code = Code ( Get ( LayoutName )) ;
marked = $$marked[code] ;
exists = not IsEmpty ( FilterValues ( marked ; id ) ) ;
result = If ( exists ; AntiFilterValues ( marked ; id ) ; List ( marked ; id ) )
REPETITION: Code ( Get ( LayoutName ) )
The conditional formatting calc is:
marked = $$marked[Code ( Get ( LayoutName ) ) ] ;
id = TABLE::_p ID ;
exists = not IsEmpty ( FilterValues ( marked ; id ) )
Whenever you want to use that list of IDs, you just need to use $$marked[ Code ( Get ( layoutName ) ) ] and you can, for example, loop through that list and create join records, or send e-mails, or whatever.
David Jondreau 9, 10, 11
Wing Forward Solutions, LLC
Santa Fe, NM
Yep, when I've done something like this have also used a global variable to store a list of id's, and then use that variable in later scripts, the conditional formatting etc...
However, have done this without custom functions or even the Let function, which for newbie's is a quite incomprehensible function....
Usually the on/off toggle I use in the portal is a script that if the selected portal row currently is 'off' then appends a string to the global variable in the format : current 'master' record id and a delimiter such as '*' and the portal row's related record id, e.g. 2*213, plus a carriage return character, to ensure that the most recent addition to the list ends with a carriage return character.
This way, the technique works across multiple records in the 'master' table of the layout currently being used, so that moving from one record to another using the current layout, then the 'selection list' is preserved for each record.
If the portal row is 'on', then the scripts removes the occurrence of, in this example, 2*213 & the carriage return, from the global variable.
To determine whether a portal row is 'on' or 'off', then a PatternSearch function is used to calculate whether or not the occurrence of, in my example '2*213' in the global variable is greater than 0. This is also used in the conditional formatting calculation.
To use the list of selected portal rows of a particular record of the layout currently being used for these selections in a script, for example, generating records in a join table, the script creates a new temporary/local variable using a sub-list of the global selection list generated by using a loop through that global variable that checks if the character to the left of the delimiter of each list value matches the current record id, and then adds it to this new variable.
Following so far? ... It does work well, and very fast, using nowadays hardware and FileMaker....
With this newly generated script local variable, then a second loop through its list items to perform whatever actions you require..., and then possibly removing its occurrence from the global variable using the Substitute function.
Again, very fast, retains 'selections' across multiple master records, multi-user friendly, and no global fields being needed or used - the 'old way'...
Sorry if this is long winded and maybe there are better ways that others use. Am typing this up from memory and experience, without actually using FMP right now to test and make sure what i say is correct... will try and post an example file when back in office tomorrow, uk time... On iPad just now.... :-)
Oops, PatternCount, ... Not PatternSearch.... Told ya I wasn't 'on desk'
My technique of using Code ( Get ( LayoutName ) ) is for storing Marked records from a list view, not a portal. For a portal, I do similar to Sky. I use Code ( table::primary Key ) instead. My keys are text UUIDs so there's no collisions.
Let() may be the best function for newbies to tackle. The concepts in understanding Let() help with scripting and the function makes your code a brazillion times easier to understand (for yourself and others).
So here is a sample file that demonstrates the techniques I detailed above.... Feel free to delve into it and see how the conditional formatting and scripts work etc....
All the best,
multiselect.fp7.zip 8.2 K
Thanks, very interesting and useful.
Thanks a lot for all of your help on this topic guys. Greatly appreciated.
I was able to do exactly what I needed after viewing that file.
How might this be possible with the standard user selecting experience of... one click for single selecting to select one line item at a time, but shift-click for selecting multiple line items at a time.. and if one lets go of the shift key and selects an item again it lets go of the previously multiple selection? Also... shift down/up arrow keys for keyboard users?
You can use Get ( ActiveModifierKeys ) to check to see if Shift is pressed.
forgot to say thanks. Thanks very much. Still new to this.
Very nice, I really like this, much smoother than whatever I made up.
One nitpick: You should remove the Flush Cached Join results and Flush Cached External data from your Refresh Window step. It seems to work without those checked.
Having those checked can be a performance hit, if the file gets hosted, and there are a lot of related records.
Please feel free to correct me if I have missed something.