1 2 Previous Next 22 Replies Latest reply on May 10, 2016 6:03 AM by TSGal

    get(activefieldcontents) produces inconsistent result

    JonJ

      Summary

      get(activefieldcontents) produces inconsistent result

      Product

      FileMaker Pro

      Version

      14 (and 12 and 13)

      Operating system version

      OSX Yosemite and Win8

      Description of the issue

      the documentation for get(activefieldcontents) says that it "Returns the contents of the field that has the focus."

      When you set up a script trigger for a field, onObjectModify, using get(activefieldcontents) as a script parameter, the value delivered is the *unmodifed* value, even though the script trigger is supposed to fire *after* the object is modified.

      If the target script includes get(activefieldcontents), with no intervening records commits or reverts, the value delivered is the *modifed* value.

      This is inconsistent, as there should not have been any changes in record state between the script trigger firing and the script starting. It is clear from the documentation, that the script parameter should be delivering the *modified* (but so-far unsaved and uncommitted value), not the *unmodified* value.

      FileMaker has been doing this since v12, and I've usually had a workaround, but in a current solution, I need the function to work as expected.

      Steps to reproduce the problem

      Set up a field with a script trigger as above, with  get(activefieldcontents) as a script parameter, and targeting a script which also sets a variable using get(activefieldcontents)

      Expected result

      The results of both instances of get(activefieldcontents) should deliver the same result, namely the current, unsaved contents of the modified field.

      Actual result

      The two instances of get(activefieldcontents) deliver different results; the script parameter delivers the field's original (unmodified) value.

      Exact text of any error message(s) that appear

      N/A

      Configuration information

      Same on PC or Mac, any FM version from 12-14.

      Workaround

      usually I opt to use one or the other, with an understanding of the inconsistency. In my current project this isn't possible.

        • 1. Re: get(activefieldcontents) produces inconsistent result
          philmodjunk

          This issue isn't unique to this get function. Any expression in the script parameter evaluates the same way. I frequently put Table::Fieldname into a script parameter specifically as a way to capture the "before" value--particularly with OnObjectEnter as a way to capture the value on a field formatted with a popup menu.

          In my current project this isn't possible.

          I confess to being curious here. I can't quite imagine how this isn't possible.

          Why can't you use Get ( ActiveFieldContents ) as part of the first script step executed in your script?

          • 2. Re: get(activefieldcontents) produces inconsistent result
            JonJ

            I'm using a generic library script that works on the script parameter, if one is provided. Or, if nothing is provided, it works on the result of  get(currentfieldcontents).

            In this instance, I want to process the data slightly before the script works on it (modifying the data in the light of some other values). Ideally, I'd do the processing on the script parameter, leaving the library script untouched (which, of course is used elsewhere) — if only I could access the correct field value!

            So, it might be stretching a point to say that it "isn't possible" in my current solution, but it's certainly very inconvenient — to fork my library script, just to accommodate this bug!

            • 3. Re: get(activefieldcontents) produces inconsistent result
              TSGal

              JonJ:

              Thank you for your posts.

              This happens because the OnObjectModify is triggered before the modification occurs (when the script parameter is generated), and the script runs after the modification.  This was intentionally designed because we believed it would be important to get information at the time of the event instead of later.  You can always get the modified data during the script.

              I have requested that this be made clearer in future documentation.

              TSGal
              FileMaker, Inc.

               

              • 4. Re: get(activefieldcontents) produces inconsistent result
                philmodjunk

                Still scratching my head over what you are trying to do here

                Ideally, I'd do the processing on the script parameter,

                Couldn't you set a variable to the result in the script parameter, manipulate the variable value and then set the field to this new value?

                • 5. Re: get(activefieldcontents) produces inconsistent result
                  JonJ

                  TSGal,

                  > his happens because the OnObjectModify is triggered before the modification occurs (when the script parameter is generated)

                  The documentation says that it's triggered after the modification ( http://www.filemaker.com/help/html/script_trigg.38.4.html ) -- however, perhaps the script parameter is stored beforehand. 

                  In any case, it would be useful to be able to access both before and after states by a function -- get(ActiveFieldContents) and get(ActiveFieldSavedContents)?

                  Thanks,

                  J.

                   

                   

                  • 6. Re: get(activefieldcontents) produces inconsistent result
                    JonJ

                    PhilModJunk,

                    > Couldn't you set a variable to the result in the script parameter, manipulate the variable value and then set the field to this new value?

                    No, I don't want to modify the field content, just apply a function to the content before passing it on to a script.

                    Sorry you're scratching your head. Let me give you an example:

                    Say you have a library script that performs a fuzzy search based on the submitted script parameter. Say I have a field for the user to enter a phone number (which I don't want to override or alter), but I want to search automatically for similar numbers. 

                    I might want to standardise any spacing characters (dashes and dots, etc.) and standardise country codes (0044 to the recommended +44, for example) before the search.

                    Now, I don't want to rewrite the library script for this one example, it's used in its of other places, on lots of different data types. It works well, and is very efficient.

                    It would seem reasonable to use the get(activefieldcontents) function to take the active field contents, so that I can manipulate the the string as I need, before passing it on to the library script. This shouldn't be a problem, as get(activefieldcontents) is supposed to get the active field contents, regardless of its committed state.

                    There are, of course, ways around the issue, but they all involve extra work, which shouldn't have been necessary.

                    I take on board TSGal's explanation of the issue but I think that, in this case, FileMaker has got it wrong — the function should behave as advertised, and always grab the data in the active field (indeed, as displayed on the layout). If I needed to grab the data as it was, I could use other existing methods (for example addressing the fully qualified field path, which would retrieve the last committed value, or using the onObjectEnter trigger, rather than the onObjectModify trigger).

                    J.

                     

                    • 7. Re: get(activefieldcontents) produces inconsistent result
                      philmodjunk

                      TSGal has it wrong. OnObjectModify trips after the object is modified not before.

                      But script parameters passed to trigger performed scripts always evaluate before the triggering event--I know of no place in the documentation that tells you this. This is something that I've worked out by experimenting with triggers and their parameters.

                      But I still don't see the work-arounds now available as being all that painful.

                      If you want to work with the value of the field "pre-modify", put the value of the field into your script parameter. If you want to work with the data "post modify", you should be able to access the value via get (activeFieldContents) as the first executable line of your script. Whether you modify the data directly in the field or use set variable to set field to copy the value of that field somewhere else and modify it there doesn't make any difference that I can see.

                      And your example sounds like something that might work more smoothly as a script performed by the OnObjectValidate trigger instead of OnObjectModify--especially since each individual keystroke in the field will separately trip OnObjectModify.

                      • 8. Re: get(activefieldcontents) produces inconsistent result
                        JonJ

                        > And your example sounds like something that might work more smoothly as a script performed by the 
                        > OnObjectValidate trigger instead of OnObjectModify--especially since each individual keystroke in the 
                        > field will separately trip OnObjectModify.

                        The actual instance is to do an executeSQL search for filtering records. As it's a script for filtering, I'd like it to trigger on each keystroke. Processing the data by copying it elsewhere interrupts the typing enough for it to feel 'laggy', and in any case, I do not want to write a special script just for this instance — what sort of developer environment is that? I want to use my library script, that is quick, efficient, and can be used in any solution only by tweaking some simple script parameters.

                        In the end I've updated the library script to allow you to pass a string for evaluation, so I can pass the required calculation as a string in the script parameter -- the script then uses the evaluate() function, and if the string includes get(activefieldcontents), it will be evaluated as the actual active field contents.  At least this has added some functionality to the library script that might prove useful in the future.

                        • 9. Re: get(activefieldcontents) produces inconsistent result
                          philmodjunk

                          ExecuteSQL can be slow to evaluate all by itself so that may be a major contributing factor here.

                          • 10. Re: get(activefieldcontents) produces inconsistent result
                            JonJ

                            No, as I said my library script is very efficient. It returns results much faster than the user can type. 

                            • 11. Re: get(activefieldcontents) produces inconsistent result
                              Fred(CH)

                              No, as I said my library script is very efficient. It returns results much faster than the user can type. 

                              JonJ,

                              Several factors could confirm Phil's warning here depending how many records are filtered (a number that could increase in the future), also the time access to the database, in particularly when the file hosted, maybe accessed via a LAN WAN, and why not, thru a VPN. All these can alter your impression that a call is "very efficient".

                              I also agree with Phil that the actual behavior, even not documented, is clearly consistent on all instances. In this specific instance you are pointing out, it is veeeery useful to get access to old value that way (the parameter) : it would be a "Hell" if it wasn't the case !

                              Dont' know if it could help, but i adopted the policy to have only one script for each trigger event. As yours, there are generics. However, it is true that these general scripts call others subscript, more specifics depending of contexts. Maybe it could be the solution here.

                              • 12. Re: get(activefieldcontents) produces inconsistent result
                                JonJ
                                 In this specific instance you are pointing out, it is veeeery useful to get access to old value that way (the parameter) : it would be a "Hell" if it wasn't the case !Several factors could confirm Phil's warning here depending how many records are filtered (a number that could increase in the future), also the time access to the database, in particularly when the file hosted, maybe accessed via a LAN WAN, and why not, thru a VPN. All these can alter your impression that a call is "very efficient".

                                Not really. Efficiency is producing a result in the quickest way possible -- it will still be slower over a WAN, etc., but will still as quick as any such operation can be.

                                In terms of practical experience, it's been used via WebD over the internet, on various LANs (including VPNs) and WANs, with different client databases, including searching across 100,000s of records -- it's still fast! On occasions where I've discovered something that makes a significant improvement in speed, it's been easy to retrofit it into previous clients, as it's only a single script.

                                I also agree with Phil that the actual behavior, even not documented, is clearly consistent on all instances.

                                It's consistent with respect to script triggers, but inconsistent with respect to the function, which now delivers two different results depending on where it's used. 

                                In this specific instance you are pointing out, it is veeeery useful to get access to old value that way (the parameter) : it would be a "Hell" if it wasn't the case !

                                I quite agree, but it would be nice to be able to choose which value you want to access where and when. The different values are all in Filemaker somewhere, and I'm sure we can all think of circumstances where we've found it awkward not to be able to get ahold of the one we want.

                                Dont' know if it could help, but i adopted the policy to have only one script for each trigger event. As yours, there are generics. However, it is true that these general scripts call others subscript, more specifics depending of contexts. Maybe it could be the solution here.

                                That's also possible — I'll see how the 'evaluate' route works out.

                                 

                                • 13. Re: get(activefieldcontents) produces inconsistent result
                                  Fred(CH)

                                  In terms of practical experience, it's been used via WebD over the internet, on various LANs (including VPNs) and WANs, with different client databases, including searching across 100,000s of records -- it's still fast! On occasions where I've discovered something that makes a significant improvement in speed, it's been easy to retrofit it into previous clients, as it's only a single script.

                                   

                                  Very interesting to me ! i was not aware WebDirect could trig a script during typing. Thanks for the hints.

                                  • 14. Re: get(activefieldcontents) produces inconsistent result
                                    philmodjunk

                                    You missed my point. ExecuteSQL can be slow. It's not the quickest thing in the tool box to evaluate. We've actually had to remove eSQL and replace it with other methods in a few cases due to noticable delays.

                                    By itself, it may or may not work acceptably fast or be unacceptably slow. What I was trying to state is that the "lags" you reported may well be due to the combination of eSQL and the additional data processing done in the same script.

                                    Either task in isolation might be just fine. So I was just trying to point out that a faster eSQL query--either due to a design change in your DB or an upgrade by FMP inc in a future version that no longer "interprets" the SQL code might provide more freedom for a calculation to evaluate. You also have to watch out for a set up that works acceptably at the start and then gradually becomes unacceptable as the number of records in the queried table increase. Many database operations, such as the sorts and searches typical of an SQL query fit the(O)NLogN category of execution time "curves" where N is the number of entities searched or sorted.

                                    Just to be clear, while it took a few turns around the bush, I get what you are trying to do here and using a text expression with evaluate seems an excellent way to get the job done by keeping your script flexible yet still doing the necessary "post modify" processing.

                                    1 2 Previous Next