1 2 Previous Next 25 Replies Latest reply on May 6, 2011 12:30 PM by shudder

    Record Navigation Using Book - Script Trigger Possibility?

    shudder

      Title

      Record Navigation Using Book - Script Trigger Possibility?

      Post

      Hey Folks --

      I need to kick off a script to do some clean-up on the current record before going to a different record.  I can do this nicely programmatically, and all works well with that.  How can I do this if the user uses the Book (rolodex in the Status Area) to switch between records?  I don't see any way to attach a pre-run script to the Book, and I need something to happen on the current record before the user leaves it.

      I was thinking maybe I could use an OnRecordLoad trigger when the user clicks the Book to go to a different record (or perhaps drags the slider!!!), but not sure if I can get back to the old record to perform the clean-up I need to do and then get back to the new record correctly.  I say 'old' and 'new' because depending on which way one clicks on the book, the record choice might be Previous or it might be Next.  Or if they use the slider, I am really screwed!  See my dilemma?

      Anyone know a way I can solve this?

      I've searched a lot in here and found nothing relating to the Book and record navigation that is related.

      Thanks for your time.

      - shud

      PROJECTSgrn.jpg

        • 1. Re: Record Navigation Using Book - Script Trigger Possibility?
          philmodjunk

          I think this may work, but please read the notes belows because it doesn't solve all your problems here. It may not be possible to do what you want unless you also have FileMaker Advanced and use it to set up some custom menus.

          IF [Not IsEmpty ( $$PrevRec ) And Not $$TriggersOff ]
              Freeze Window
              Set Variable [$Here ; value: Get ( RecordNumber ) ]
              Set Variable [$$TriggersOff ; Value: True ] //keep your change in records from triggering this same script infinitely
              Go To Record/Request/Page [ $$PrevRec ]
              /// put your clean up script steps here
              Go To Record/Request/Page [$Here ]
              Set Variable [$$TriggersOff ; Value: False ]
          End If
          Set Variable [$$PrevRec ; get ( RecordNumber ) ]

          Note: There are other ways that you can jump from record to record besides using the book control and slider. This script, as written, will jump to the wrong record if you use omit record or duplicate record from the records menu. You may want to use custom menus to either disable those options or too run a script step that sets $$TriggersOff to True before doing the selected option.

          Performing finds will also cause this script to try to jump to the wrong record. You might want to use a script trigger that sets $$TriggersOff to True when you exit find mode or perhaps to perform your clean up script on the current record just before entering find mode.

          OnRecordLeave and OnDeleteRecord are two events I'd like to see in a future release of FileMaker. http://www.filemaker.com/company/feature_request.html

          • 2. Re: Record Navigation Using Book - Script Trigger Possibility?
            shudder

            Hey Phil --

            Thanks for the notes. I think your text "It may not be possible to do what you want" combined with "OnRecordLeave and OnDeleteRecord are two events I'd like to see in a future release of FileMaker" pretty much nails it.  [[You've linked in the Feature Request page -- would you like me to do that, or does your request suffice?]]

            Whereas the If/Then w/gVars you suggest could work to capture and manage the navigation in a way that would work for me, there would then possibly be trouble with omits and dupes, and perhaps other stuff by association (there is already some complex scripting that is triggered when folks leave a layout... can't fuss with that stuff).  The system has been up and running for over a year now, and to mangle their interface and/or make changes to menus would just be wrong.  Perhaps if they'd started off that way... (I do have Advanced, so could make the changes to exlcude, as you've pointed out).

            ===========

            Perhaps (if you will allow me) I can play out for you what I am trying to do, so that maybe it will kindle other ideas on how to proceed woith what I need.  To that end...

            Here's my script and notes on the process I am following to create highlighted rows in my onscreen portal.

            NOTE: I have named my target portal an object called ProjPortal.  It is a Selfjoin portal, so it shows all project records common to the current show (SHOW layout not shown here).  The main PROJECTS UI (non-portal) displays the entire current Project record.  Clicking a portal row brings up that project record.

            SCRIPT: Go to Related Record (from ProjPortal on PROJECTS LO)

            #
            #This is a BUTTON DRIVEN script -- inactivate the button when the user is in Find mode
            If [Get (WindowMode)=1]
                Exit Script []
            End If
            #
            #Keep window from flashing as changes are made
            Freeze Window
            #
            #Set a temporary lVar for the current portal row now (will change it to a gVar below)
            Set Variable [$PortalRowNumTEMP; Value:Get ( ActivePortalRowNumber )]
            #
            #Clear previous portal RowMarker field (~if~ one has been set previously -- this will be established by the success or failure of the following If/Then)
            If[not IsEmpty($$PortalRowNum)]
                Go to Object [Object Name: "ProjPortal"]
                Go to Portal Row [Select; No dialog; $$PortalRowNum]
                Set Field [PROJECTS_Selfjoin::RowMarker;""]
            End If
            #
            #Set the gVar $$PortalRowNum to the lVar set above
            Set Vairiable [$$PortalRowNum; Value:$PortalRowNumTEMP]
            #
            # Go to the new portal row number so that the follow-on GTRR knows where to go
            Go to Object [Object Name: "ProjPortal"]
            Go to Portal Row [Select; No dialog; $$PortalRowNum]
            #
            #Set the main UI to the record related to the Selfjoin portal row clicked on
            Go to Related Record [From table" "PROJECTS_Selfjoin"; Using layout: "PROJECTS" (PROJECTS)]
            #
            # Go back to the portal and...
            Go to Object [Object Name: "ProjPortal"]
            Go to Portal Row [Select; No dialog; $$PortalRowNum]
            #
            #...Set the RowMarker field to a bullet
            Set Field [PROJECTS_Selfjoin::RowMarker; "•"]
            #
            ==========

            I then created some Conditional Formatting calls to display the clicked on portal row in colors that match their respective color values (green, red, blue).  The formatting is based on two things: the Status of a project (denoting the color of the text) and then on the RowMarker field populated by the script above with a bullet.  The text values always appear in various colors, but the highlight of the row ONLY appears when the one and only RowMarker value is in place on a record.  It is this RowMarker value I need to clear out before leaving the record!

            Thanks again.

            - shud

            P.S.  I wanted to include a couple of screenshots, but don't see a way to u/l multiple screenshots.  I went ahead and put one of them up in the OP up top.  Hoppe that helps visualize things.

            • 3. Re: Record Navigation Using Book - Script Trigger Possibility?
              philmodjunk

              You've linked in the Feature Request page

              That's so that anyone that agrees with me can click the link and make the same suggestion, thereby increasing it's visibility when the FileMaker powers that be go through the suggestion box while attempting to prioritize which features to add/change in upcoming versions.

              I think you can do this with much less intrusive modification of the menus than you think. You don't have to remove any of these menu option, just replace them with scripts of your own design that perform the same option, but also secretly do the needed "housekeeping" so that a script like what I posted doesn't mess up after one of them have been selected.

              I'm not sure you need any such scripting though...

              If I read the script correctly, you are keeping the currently active portal row "marked" by setting a field in that record to the bullet character.

              What is the purpose of that marker? Why not update this marker when the user interacts with the portal instead of when the user switches from one record to another?

              (ou can, BTW, use conditional formatting to "mark" a record without changing any value in the portal's record. You can set a variable or global field with the portal record's serial ID number (assuming you have such a field defined) and your portal can highlight (or a calculation can display a bullet character) if the current record = the serial id stored in the global. Among other things, that keeps one user's interaction with this record separate from another user's interaction.

               

              • 4. Re: Record Navigation Using Book - Script Trigger Possibility?
                shudder

                Taking cues from Phil's post above, I was able to figure out a way to do everything I need to do with this issue, and it all works out pretty nicely (I think...)! 

                I'll post the solution up on Monday May 2 (I've left work today and have all the notes and script fixes up on my computer there).  Time for the weekend…

                - shud

                • 5. Re: Record Navigation Using Book - Script Trigger Possibility?
                  shudder

                  With Phil's help last Friday, I cobbled together what I think may be a 1.0 rev of making this portal navigation scripting work.  

                   

                  Here's the final script steps for the first of two scripts that make this all work: 

                  SCRIPT: Go to Related Record (from ProjPortal on PROJECTS LO)
                  #
                  #This is a BUTTON DRIVEN script -- inactivate the button when the user is in Find mode
                  If [Get (WindowMode)=1]
                      Exit Script []
                  End If
                  #
                  #Keep window from flashing as changes are made
                  Freeze Window
                  #
                  #Set a lVar for the ProjPortal row clicked on 
                  Set Variable [$PortalRowNum; Value:Get ( ActivePortalRowNumber )]
                  #
                  #Set the main UI to the record related to the ProjPortal row clicked on
                  Go to Related Record [From table" "PROJECTS_Selfjoin"; Using layout: "PROJECTS" (PROJECTS)]
                  #
                  # Go back to ProjPortal
                  Go to Object [Object Name: "ProjPortal"]
                  #
                  #Scroll down and select the row that was clicked on, based on the lVar set above
                  Go to Portal Row [Select; No dialog; $PortalRowNum]
                  #
                  #Set the gField gRowMarker with the value of the lVar (so that I can do Conditional Formatting of the fields)
                  Set Field [PROJECTS_SelfJoin::gRowMarker; $PortalRowNum]
                  #
                  #A final commit to get 'off' the portal record (no reason to be 'on' it since it is now highlighted properly)
                  Commit Records/Requests []

                  ==========

                  The script works when you click on a row of the ProjPortal.  You click a populated row and it then becomes the Project shown on the same LO.  The row in ProjPortal is selected and highlighted in color (as a result of utilizing Conditional Formatting on the fields displayed in the portal -- more on that below).  As mentioned earlier (I think), ProjPortal is a SelfJoin portal to the PROJECTS table, and it is shown on the same LO so that the user can see all Project records for a Show as they are viewing any particular Project record in full.

                  I then created a second script to run as any Project record loads (utilizing an OnRecordLoad trigger), even when you use the Book to scroll between records (either clicking ahead or backwards, or even grabbing the slider!).  The script is similar to the above, but has a few important differences.  First off, we do not want this script run unless the user is on the PROJECTS layout, so I have accounted for that.  Secondly, I do make use of that standard text field I called RowMarker, but I am thinking that it should be fine to utilize this field temporarily because the only use of it takes place entirely within the confines of the script and so will only be used for the short time the script is running.  Please let me know if this is potential trouble (and perhaps, why), and if there is perhaps a better way to do what I am doing -- that is, 'marking' a field on the main UI and then 'looking' for a value in that field in the SelfJoin portal.  Finally, I added a Summary field doing a count on the primary key of the SelfJoin table (for wont of anything better to count -- all records have a p key, so thought this would suffice nicely enough).  I called this field sRowCount, and it simply counts the populated rows, 1 thru whatever (as many rows are populated), displaying the iterative number on each successive row.  Thus, when I match sRowCount to the value in gRowMarker being populated via the script, there will be exactly one match in any display of records.  I use this match to do Conditional Formatting on the fields in the portal.

                  Here are the steps of the second script: 

                  SCRIPT: ON_RECORD_LOAD --> Set RowMarker in main UI, then go to that record in ProjPortal
                  #
                  #This is a BUTTON DRIVEN script -- inactivate the button when the user is in Find mode
                  If [Get (WindowMode)=1]
                      Exit Script []
                  End If
                  #
                  #EXIT the script if we are NOT on the PROJECTS LO
                  If [Get ( LayoutName ) ≠ "PROJECTS"]
                      Exit Script []
                  End If
                  #
                  #Keep window from flashing as changes are made
                  Freeze Window
                  #
                  #Set the RowMarker field on the project record in the main UI to a bullet
                  #Set Field [PROJECTS::RowMarker; "•"]
                  #
                  # Go to ProjPortal
                  Go to Object [Object Name: "ProjPortal"]
                  #
                  #Go to the first row and loop through them, looking for the bullet in the RowMarker field in the Selfjoin table
                  Go to Portal Row [Select; First]
                  Loop
                      #
                      #When you hit the record with the bullet, exit the loop
                      Exit Loop If [PROJECTS_SelfJoin::RowMarker="•"]
                      Go to Portal Row [Select; Next; Exit after last]
                  End Loop
                  #
                  #Blank out the RowMarker field (we do not want it ever populated with anything in the acutal UI)
                  Set Field [PROJECTS_SelfJoin::RowMarker; ""]
                  #
                  #Set the gField gRowMarker with the value of sRow_Count (so that I can do Conditional Formatting of the fields)
                  Set Field [PROJECTS_SelfJoin::gRowMarker; PROJECTS_SelfJoin::sRowCount]
                  #
                  #A final commit to get 'off' the portal record (no reason to be 'on' it since it is now highlighted properly)
                  Commit Records/Requests []
                  ==========

                  Works like a charm.  Please do let me know if thee is a better way to get from the record showing on the main UI to that same record in the portal.  This thing of marking the one field works, but I definitely see why it might not work occasionally.

                  Thanks everyone (especially if you've read this far!).

                  - shud

                  P.S.  I posted up to the Feature Request page.

                  • 6. Re: Record Navigation Using Book - Script Trigger Possibility?
                    philmodjunk

                    A couple of observations:

                    You have $PortalRowNumTEMP and PROJECTS_SelfJoin::gRowMarker that are both used to record the same thing, the number of the current portal row. Why not just use the global field for both or use a global variable in place of both of them?

                    Did you realize that you don't have to scroll through a portal to find a record and modify a field in the row to clear the "mark" such as a bullet? You can perform a find for this record on a layout based on the same table, change the value and switch back.

                    You can use the following strategy to "mark" a portal record when the portal row is clickec:

                    #This is just to "mark" a record not the other operations you have in your script
                    Set Variable [$$SelectedRecord ; value: Projects_SelfJoin::ProjectID ]

                    If you like using the bullet character to mark the row, put the bullet character inside the portal row as layout text and use this conditional format expression to hide the character by changing its text size to 500 pts when true:

                    Projects_SelfJoin::ProjectID ≠ $$SelectedRecord

                    Now you can "clear the bullet" with this script step:

                    Set Variable [$$SelectedRecord ; value: "" ]

                    • 7. Re: Record Navigation Using Book - Script Trigger Possibility?
                      shudder

                      >> You have $PortalRowNumTEMP and PROJECTS_SelfJoin::gRowMarker that are both used to record the same thing, the number of the current portal row. Why not just use the global field for both or use a global variable in place of both of them?

                      I'm attempting to wrap my head around this.  Though they do track the same thing, one event may occur without the other -- they do not necessarily happen consecutively.  This is the case if a user simply grabs the slider on the Book and moves to a different record.  In that case, no $PortalRowNum variable has been set by the first script, so you have to generate the same sort of value somehow without that having happened.  My first thought was to mark a field on the current record (in the main UI) and then search for that value in the list of SelfJoin-related records in ProjPortal (of which the current record is always one).

                      >> Did you realize that you don't have to scroll through a portal to find a record and modify a field in the row to clear the "mark" such as a bullet? You can perform a find for this record on a layout based on the same table, change the value and switch back.

                      I believe I tried this, and ran into problems when switching back to the main PROJECTS layout as that led to the script running itself again when the record loads there, ad infinitum.  In fact, that got me stuck in an endless loop at one point, and my only out was to Force Quit out of FMP altogether (I hate doing that!).

                      >> You can use the following strategy to "mark" a portal record when the portal row is clickec

                      I've already got a way to mark the record using the lVar in my first script (and yes, if needed I could change that over into a gVar).  I've no real need to use the bullet.  That was just a holdover when I had thoughts of using the actual bullet character to make the record standout visually in the portal.  As it is now, the bullet is just what I search for when the record in the main UI has been 'marked' (by using the Book to move to a different record), and then the rest of the script moves over to ProjPortal and locates that same record there in the SelfJoin table.

                      Sorry if I am not tracking with you entirely.  Is there a way I can have a record showing in the main UI and then to go to that record in the ProjPortal without utilizing the idea of 'marking' the current record in the main UI?

                      • 8. Re: Record Navigation Using Book - Script Trigger Possibility?
                        philmodjunk

                        I think you should get FileMaker Advanced as soon as possible. The Script Debugger can be a major frustration ender when wrestling with scripts such as this.

                        You can use global variables to temporarily disable layout based script triggers to that you can come and go without tripping the triggeers:

                        If [not $$TriggersOff ]
                          Set Variable [ $$TriggersOff ; value; True ]
                          // put your current script here
                          Set Variable [$$TriggersOff ;Value ; False ]
                        End IF

                        I realize changing a field in the portal row works for you, but it seems to add a lot of complexity to your script and in a multi-user environment, you'll see the marked records for all users at the same time--which would be very confusing to your users. using the single global variable eliminates going to a portal row just so that you can clear this field. Your loop is replaced by the single script step and the record marked by one user is not shown as marked for any other users.

                         

                        • 9. Re: Record Navigation Using Book - Script Trigger Possibility?
                          shudder

                          >> I think you should get FileMaker Advanced as soon as possible. The Script Debugger can be a major frustration ender when wrestling with scripts such as this.

                          Ha!  Yeah, well, as it would happen, I do use FMA.  Of course, I watch these scripts run in Script Debugger all the time as I troubleshoot them (this script I've written about in here is hardly the most complex, just the most vexing, currently), and I could not survive without it.

                          >> You can use global variables to temporarily disable layout based script triggers...

                          I did not know this!  Do I need to do anything else with the $$TriggersOff gVar you set up above?  Or is simply having it in place with a value of True make it somehow work universally to disable triggers?  I'm not clear on that.

                          >> I realize changing a field in the portal row works for you ... you'll see the marked records for all users at the same time--which would be very confusing to your users.

                          I don't think that is the case since the script should run almost instantaneously, and the RowMarker field is ONLY populated during the run of the script, not afterwards, so there is no bullet detritus left over after a run of the script to get to the proper row of ProjPortal.

                          >> You can use the following strategy to "mark" a portal record when the portal row is clickec:

                          #This is just to "mark" a record not the other operations you have in your script
                          Set Variable [$$SelectedRecord ; value: Projects_SelfJoin::ProjectID ]

                          Again, I have a way to get to the row of the portal when it is clicked upon (using the current lVar and gRowMarker fields from the first script that runs when a row of ProjPortal is clicked upon), just not the other way around (which is what I need when a user uses the Book instead to move between records).

                          So, following your line of thought... can I set the gVar like this when a user switches records using the Book?

                          #This is just to "mark" a record
                          SetVariable [$$SelectedRecord ; value: PROJECT::ProjectID ]

                          ... and then:

                          #Go to ProjPortal
                          Go to Object [Object Name: "ProjPortal"]

                          ... and then somehow use the value of $$Selected Record -- which is specific to one of the rows in ProjPortal! -- to get to its matching record in the PROJECTS_SelfJoin table showing in ProjPortal?

                          Am I over-complicating things (wouldn't be the first time...).

                          - shud

                          • 10. Re: Record Navigation Using Book - Script Trigger Possibility?
                            philmodjunk

                            $$TriggersOff or any global variable you use for this purpose only disables triggered scripts if the scripts themselves check for this variable and test it like I posted in my last post. Note how you enclose your entire trigger script inside an If statement that performs this check.

                            When I look back over this thread, I get increasingly confused here. I really have no idea why you need to mark the current portal row in the first place. What problem does that solve for you?

                            • 11. Re: Record Navigation Using Book - Script Trigger Possibility?
                              shudder

                              >> $$TriggersOff or any global variable you use for this purpose only disables triggered scripts if the scripts themselves check for this variable and test it like I posted in my last post. Note how you enclose your entire trigger script inside an If statement that performs this check.

                              Right, so embedding my scripts within one big If/Then that makes this $$TriggersOff call will render script triggers not work.  That's really interesting.  I didn't know you could do that.  Thanks.

                              >> When I look back over this thread, I get increasingly confused here. I really have no idea why you need to mark the current portal row in the first place. What problem does that solve for you?

                              Sorry, Phil.  Let's see if I can clear it up.  Please bear with me.

                              ======

                              1. The UI shows a main PROJECTS record and the ProjPortal shows that same record (name and ID only), along with all other records for the SHOW in the rows of the portal -- I need to do some Conditional Formatting on that record's row in ProjPortal;

                              2. My first script sets the lVar $PortalRowNum when that row of ProjPortal is clicked upon (thus 'marking' that record/row, if you will), then GTRR in the main UI to go to that record, then finally back to the ProjPortal row based on $PortalRowNum where the gField gRowMarker is then set to the value of $PortalRowNum.  My Conditional Formatting for that row (changing it to red, orange, green or blue) is based on comparing gRowMarker to sRowCount (which is a numbered count of the rows in ProjPortal).*  When they match, that row lights up in color; 

                              3. However, if a user uses the Book to scrub between records, I need a way to have the record hit in the main PROJECTS UI when they light upon their new record to then somehow go to that same record/row in ProjPortal where I do the same Conditional Formatting.

                              ======

                              Moving to a new record via ProjPortal -- clicking the row and setting that row number -- is handled, but setting the record into the main UI first, and then going to that record/row in ProjPortal is where I was marking that new record with the bullet, then locating that bullet in ProjPortal (and immediately deleting the bullet so it will not show to other users!) and then set that row as my match field to compare to sRowCount.  In the end, I need to have gRowMarker and sRowCount match up in order to kick off the proper Conditional Formatting for the row of ProjPortal, and the marking of the parent record and then moving over to ProjPortal and locating that 'marked' record was the only way I could figure out a way to do that.

                              * - In writing this up right now I see now that I don't really need to go to the exact row in the portal since I can just Set Field gRowMarker to $PortalRowNum on any record in the list and since it's value will only match ONE of the values anywhere in sRowCount, then only that one row will light up based on the match.  That might simplify my first script a step or two, but has no bearing really on the second script.

                              Thanks,

                              - shud

                              • 12. Re: Record Navigation Using Book - Script Trigger Possibility?
                                philmodjunk

                                I just don't see any need to loop through the portal records in order to do this. You might also consider what could happen if two users run this script at the same time. If they have the misfortune of kicking them off at exactly the same time, one or the other user could easily find the other user's marked record instead of their own. The more users doing this at the same time, the more likely this mischance becomes. It's fully avoidable if you don't actually edit the record in the portal row in order to mark it.

                                I think you have the same list of records showing in the portal no matter which record the user navigates to, correct?

                                Any user action that makes a specific portal row the active row can also trigger a script that records the ID of the record in a global variable that is used in your conditional formats. Since this is a global variable, this conditional formatting will not change when they use the slider to change records. The same script can also store the row number of the current portal row, but the only reason I can conceive for doing that is if you want to scroll the portal to make this row visible when they change reocrds--which still does not require a loop nor does it require setting a field in the record with a bullet character to "mark" it.

                                • 13. Re: Record Navigation Using Book - Script Trigger Possibility?
                                  shudder

                                  >> If they have the misfortune of kicking them off at exactly the same time, one or the other user could easily find the other user's marked record instead of their own.

                                  That's very true, and so while my marking the records does work (in a fashion) I am doing due diligence to suss out a better way.

                                  >> I think you have the same list of records showing in the portal no matter which record the user navigates to, correct?

                                  No.  Since we are not performing a Find to see the records in the portal (they are there as a result of being related to the over-arching SHOW record), then ALL records in the PROJECTS list are in the Book -- ones related to the current SHOWS record as well as all other records in the system that are attached to various other SHOW records.  So, when a user scrubs to a record and ends up on a PROJECT record for a different SHOW, then the entire ProjPortal changes to that list of records.  That makes it markedly more difficult to deal with the Book, but there ya go.  It's what I have to deal with.

                                  >> Any user action that makes a specific portal row the active row...

                                  In the second scenario, the user never touches the row, just the Book.  But, I want the row for that record that the user selected via the Book and is now showing in the main PROJECTS UI to be highlighted.  How do I get there if the user doesn't touch the ProjPortal?

                                  Please see numbers "3" and "4" in the pic I attached above for more clarity (hopefully).

                                  - shud

                                  • 14. Re: Record Navigation Using Book - Script Trigger Possibility?
                                    philmodjunk

                                    An active portal row won't be "active" unless the user interacts with the portal. Until the user does so, there won't be an active portal row. This interaction is completely separate from when you change records via controls in the status area, yet it is those scripts that are using get active portal row to determine which row is active. If any action by the user that might make the portal row active results in that portal row being captured in a global variable, you can then access that number in the global variable to determine the active portal row no matter what user action takes you to a different record.

                                    1 2 Previous Next