Author: Andries Heylen

  • Extension de la classe Javascript FileMaker.PerformScript

    Extension de la classe Javascript FileMaker.PerformScript

    [vc_row bg_color=””][vc_column][vc_column_text]Avec la sortie de FileMaker 19, il devient plus aisé que jamais (c’était déjà très largement possible avant – j’ai eu l’occasion de montrer le “#hash trick” dans quelques conférences 😉 ) de faire communiquer FileMaker et Javascript. Notamment en exécutant du code Javascript dans un Web Viewer grâce au pas de script Exécuter Javascript dans un Web Viewer (FileMaker demande au Web Viewer d’exécuter un Javascript), et à la classe Javascript FileMaker.PerformScript( “Nom du script FileMaker”, “Paramètre facultatif” );

    Toutefois, il manque à nos yeux quelques possibilités à cette dernière. Nous avons évoqué ici l’impossibilité de reprendre un éventuel script FileMaker qui serait en pause, mais il y a aussi l’absence de possibilité de différencier le script appelé (callback) en fonction du succès ou de l’échec. Cet article développe ce dernier point et apporte une solution.

    La programmation asynchrone

    Aucune bibliothèque (library) n’est nécessaire, mais j’ai dû écrire ma propre classe qui étend un peu FileMaker.PerformScript à FileMaker.PerformScript ( scriptName, parameter, successCallback, errorCallback ).

    Un petit exemple pour faire une interaction bidirectionnelle entre FileMaker et Web Viewer. Il s’agit d’un système de callback et/ou de promesse, une façon dont le Javascript appelle souvent quelque chose de l’extérieur et selon que tout s’est bien passé (succès) ou mal (erreur), vous laissez quelque chose se produire dans votre application Javascript.

    En fait, tout se résume donc à cela : “FileMaker, appelle ce script. Si tout s’est bien passé fais ceci, si tout s’est mal passé fais cela”.

    Un exemple concret avec une intégration de calendrier : si l’utilisateur change le lieu d’un événement, il doit appeler FileMaker et l’enregistrer dans la base de données. Si cela n’a PAS réussi (par exemple, erreur d’écriture dans l’enregistrement), il faut annuler la transaction et remettre l’événement à son emplacement d’origine pour que l’utilisateur voie qu’il n’a pas été enregistré. C’est ce qu’on appelle la programmation asynchrone, et c’est quelque chose qu’il faut absolument comprendre si vous voulez continuer avec Javascript.

    Donc, en dans le calendrier, voici ce qui se passe réellement :

    1. L’action en Javascript est appelée, avec immédiatement les actions : que faire si ça va bien, que faire si ça va mal.
    2. En interne, ces actions sont enregistrées, et Javascript appelle FileMaker.
    3. Le code Javascript ne “tourne” plus, il n’y a plus de pause, nous avons effectivement atteint la fin du code.
    4. FileMaker fait son travail et décide s’il veut dire au Web Viewer si cela s’est bien ou mal passé.
    5. Le Web Viewer exécute les morceaux de code (enregistrés à l’étape 1).

    En code :[/vc_column_text][vc_column_text]

    #BUSINESS LOGIC
    #add as much logic as you want, for instance try to write to a folder
    
    #DEMO: a custom dialog
    Show Custom Dialog [ Title: "Choice"; Message: "Was the record saved?"; Default Button: “Yes”, Commit: “No”; Button 2: “No”, Commit: “No” ]
    
    If [ Get ( LastMessageChoice ) = 1 ]
        #we pass success to the callback
        Set Variable [ $result; Value:JSONSetElement ( "" ;
    [ "id" ; JSONGetElement ( Get ( ScriptParameter ) ; "id" ) ; JSONString ]; [ "success" ; Get ( LastMessageChoice ) = 1 ; JSONString ]
    )]
    Else If [ Get ( LastMessageChoice ) = 2 ]
        #we pass error to the callback
        Set Variable [ $result; Value:JSONSetElement ( "" ;
    [ "id" ; JSONGetElement ( Get ( ScriptParameter ) ; "id" ) ; JSONString ]; [ "error" ; Get ( LastMessageChoice ) = 2 ; JSONString ]
    )]
    End If
    
    #RETURN TO WEB VIEWER
    Perform JavaScript in Web Viewer [ Object Name: "wv"; Function Name: "fmcallback"; Parameter 1: $result ]

    [/vc_column_text][vc_column_text]Comme vous le verrez dans l’exemple, j’y ai mis une bibliothèque. Il m’a fallu beaucoup de sueur et de larmes pour que tout cela fonctionne. J’aimerais vous expliquer comment tout cela fonctionne, mais cela se résume à cela :

    J’ai un peu élargi le FileMaker.performScript de sorte que vous pouvez maintenant inclure un callback de réussite et un callback d’erreur. Je l’enregistre, puis j’appelle le script FileMaker. J’ajuste un peu le paramètre, parce que j’ajoute un autre “id” et ensuite le paramètre tel que passé.
    Voyez cela comme une sorte de “ligne téléphonique sur laquelle le FileMaker peut se rappeler”. Lorsque FileMaker appelle à nouveau le Web Viewer avec cette identification, le Web Viewer sait de quelle action il s’agit.

    En fait, le Web Viewer dit à FileMaker : “Bonjour, je suis l’action 23 et je voudrais que tu conserve cet enregistrement”. Après, FileMaker dit au Web Viewer que l’action 23 s’est très bien passée !

    Et voici un exemple, jouez avec et s’il y a des questions, n’hésitez pas à les poser ci-dessous ! C’est un concept assez difficile, mais une fois que vous avez maîtrisé la programmation asynchrone, vous désirerez en faire de même dans FileMaker 🙂

    Promesses (promise)

    Oh oui, pour les irréductibles : cela fonctionne aussi avec les promesses (sur Mac en tout cas, sur Windows pas sûr), donc vous pouvez faire ça aussi :[/vc_column_text][vc_column_text]

    fm.performScript ( "getData", "" )
        .then ( (data) => {
           //data is script result of getData
           data.sort();
           fm.performScript ( "storeData", data);
         })
        .then ( ( data ) => {
           //data is script result of storeData
           //do things here
        })
        .catch ( ( error ) => {
            //this is the error of getData or storeData, cool isn't it? :)
            alert(error);
     
        })
    

    [/vc_column_text][/vc_column][/vc_row][vc_row bg_color=””][vc_column width=”1/1″][ish_button el_text=”Télécharger l’exemple” url=”url:https%3A%2F%2Fwww.1-more-thing.com%2Fwp-content%2Fuploads%2F2020%2F06%2F1MT_javascriptCallBack.zip|title:T%C3%A9l%C3%A9charger%20l’exemple||” size=”big” align=”center” color=”color7″ text_color=”color4″][/vc_column][/vc_row]

  • FileMaker.PerformScript Javascript class extended

    FileMaker.PerformScript Javascript class extended

    [vc_row bg_color=””][vc_column][vc_column_text]With the release of FileMaker 19, it becomes easier than ever (it was already largely possible before – I had the opportunity to show the “#hash trick” in a few conferences 😉 ) to make FileMaker and Javascript communicate. Notably by executing Javascript code in a Web Viewer thanks to the script step Perform Javascript in Web Viewer (FileMaker asking the Web Viewer to execute a Javascript), and to the FileMaker.PerformScript Javascript class (“FileMaker script name”, “Optional parameter” ), Javascript calling a FileMaker script.

    However, in our opinion, the latter lacks some possibilities. We have mentioned here the impossibility to resume a FileMaker script that would be paused, but there is also the absence of possibility to differentiate the called script (callback) according to success or failure. This article develops this last point and provides a solution.

    Synchronous programming

    No library is necessary, but I had to write my own class that extends a bit FileMaker.PerformScript to FileMaker.PerformScript ( scriptName, parameter, successCallback, errorCallback ).

    A small example to make a bidirectional interaction between FileMaker and Web Viewer. It is a system of callback and/or promise, a way that Javascript often calls something from the outside and depending on whether everything went well (success) or badly (error), you let something happen in your Javascript application.

    In fact, it all boils down to this: “FileMaker, call this script. If it went well do this, if it went badly do that”.

    A concrete example with calendar integration: if the user changes the location of an event, he must call FileMaker and save it in the database. If this was NOT successful (for example, a commit error), the transaction must be canceled and the event returned to its original location so that the user sees that it was not saved. This is called asynchronous programming, and it is something that you must absolutely understand if you want to continue with Javascript.

    So in the calendar, here’s what really happens:

    1. The action in Javascript is called, with immediate actions: what to do if it goes well, what to do if it goes bad.
      Internally, these actions are recorded, and Javascript calls FileMaker.
      The Javascript code isn’t “running” anymore, there is no more pause, we have actually reached the end of the code.
      FileMaker does its job and decides if it wants to tell the Web Viewer if it went well or badly.
      The Web Viewer executes the pieces of code (saved in step 1).

    In code :[/vc_column_text][vc_column_text]

    #BUSINESS LOGIC
    #add as much logic as you want, for instance try to write to a folder
    
    #DEMO: a custom dialog
    Show Custom Dialog [ Title: "Choice"; Message: "Was the record saved?"; Default Button: “Yes”, Commit: “No”; Button 2: “No”, Commit: “No” ]
    
    If [ Get ( LastMessageChoice ) = 1 ]
        #we pass success to the callback
        Set Variable [ $result; Value:JSONSetElement ( "" ;
    [ "id" ; JSONGetElement ( Get ( ScriptParameter ) ; "id" ) ; JSONString ]; [ "success" ; Get ( LastMessageChoice ) = 1 ; JSONString ]
    )]
    Else If [ Get ( LastMessageChoice ) = 2 ]
        #we pass error to the callback
        Set Variable [ $result; Value:JSONSetElement ( "" ;
    [ "id" ; JSONGetElement ( Get ( ScriptParameter ) ; "id" ) ; JSONString ]; [ "error" ; Get ( LastMessageChoice ) = 2 ; JSONString ]
    )]
    End If
    
    #RETURN TO WEB VIEWER
    Perform JavaScript in Web Viewer [ Object Name: "wv"; Function Name: "fmcallback"; Parameter 1: $result ]

    [/vc_column_text][vc_column_text]As you’ll see in the example, I’ve put a library in there. It took a lot of sweat and tears to make it all work. I would like to explain how it all works, but it boils down to this:

    I’ve expanded the FileMaker.performScript a little bit so that you can now include a success callback and an error callback. I record it and then I call the FileMaker script. I adjust the parameter a bit, because I add another “id” and then the parameter as passed.
    Think of it as a kind of “phone line that FileMaker can remember”. When FileMaker calls the web viewer again with this id, the web viewer knows what action it is.

    In fact, the Web Viewer tells FileMaker, “Hello, I’m action 23 and I’d like you to save this record. Afterwards, FileMaker tells the Web Viewer that action 23 went very well!

    And here is an example, play with it and if there are any questions, feel free to ask them below! It’s a rather difficult concept, but once you’ve mastered asynchronous programming, you’ll want to do the same in FileMaker 🙂

    Promise

    Oh yeah, for the diehards: it also works with promise (on Mac anyway, on Windows not sure), so you can do that too :[/vc_column_text][vc_column_text]

    fm.performScript ( "getData", "" )
        .then ( (data) => {
           //data is script result of getData
           data.sort();
           fm.performScript ( "storeData", data);
         })
        .then ( ( data ) => {
           //data is script result of storeData
           //do things here
        })
        .catch ( ( error ) => {
            //this is the error of getData or storeData, cool isn't it? :)
            alert(error);
     
        })
    

    [/vc_column_text][/vc_column][/vc_row][vc_row bg_color=””][vc_column width=”1/1″][ish_button el_text=”Download demo” url=”url:https%3A%2F%2Fwww.1-more-thing.com%2Fwp-content%2Fuploads%2F2020%2F06%2F1MT_javascriptCallBack.zip|title:Download%20demo||” size=”big” align=”center” color=”color7″ text_color=”color4″][/vc_column][/vc_row]