Writing JavaScript in FileMaker is hard. Sure, the path is easy to see and clear to follow, but the actual writing of the code is hard. I have tried to find a way to write JS code that makes it fairly easy. And by “easy,” I mean “make it so that FileMaker developers don’t have to learn a hundred skills to get JS to work in FM – other than the JS itself.” I’m striving for a better JavaScript Development Environment.

An Okay JS Development Environment

My first attempt was writing or placing code in FileMaker fields. That worked…and it didn’t. There’s a lot of advantages to this method, but there are as many disadvantages (a fact I was reminded of in session feedback comments and emails about the demos I’ve released). We’re just writing in a text field – there’s no automatic formatting of the code, and there’s not any helpful type-ahead or auto complete features. There’s a lot wrong with this. Even my attempts to use a code editor JavaScript library to render the code from a text field proved only marginally better.

I continued doing this method many times (here, here, and here) always knowing that this isn’t ideal.

But recently, Kevin Frank approached me about a JS project. Working with him on this JSON-parsing library, I took it as an opportunity to finally come up with a better way of developing JavaScript in FileMaker. Kevin has written about it in his post FileMaker 19 + JSONata. Check out the details of the origin and use. We also recorded a podcast episode about it – check that out.

Towards a Better JS Development Environment

After all of our work with JavaScript in FileMaker, we’ve come to our current definition of a better JS development environment. To be effective with our coding time, here’s what a ‘better development method’ must include:

  1. Using a proper HTML/JS code editor.
  2. Immediate rendering or performing of the code in the FileMaker web viewer object.
  3. Using data from the FileMaker app.
  4. Using the result of the JavaScript processing in FileMaker.

Let’s tackle each one of these and use my work with Kevin as illustration.

A Proper Editor

Writing JavaScript is a piece of cake when one has an integrated development environment (IDE) that catches all the mistakes and properly formats the code immediately. And my previous methods (e.g., typing into a text field) failed on both those fronts. Sure, I could use a JS code-editing library (I’ve done that). It works decently, but there’s always a catch or two that frustrated users (including me).

So this trend toward the better includes using a proper IDE to write the JS outside of a FileMaker field.

Working with a proper editor brings up a whole host of challenges; one has to actually pick a platform to use and then learn to use that platform. That takes time. I use VSCode for all my JS work now (and from that app will come screenshots). It’s complex and I don’t know all of it. But what I do know is that it makes writing JS so much easier. 

With this project, I set up a small web-based file structure inside a project folder. There are two simple files in which I do all my writing: index.html and index.js. That’s manageable. I can write my simple JavaScript code here and (eventually) get it into FileMaker.

index.html
index.html
index.js
index.js

I can’t get into all that VSCode does here in this post, but if you’re going to explore writing JavaScript, VSCode is a great choice to use. I’ll share more about how to use VSCode in the near future.

See the Fruits of My Coding

The FileMaker developer is used to seeing what she is developing appear or work before her eyes – if not in scripts, at least in what’s on the layout. So too must she be able to see the code work (or not) in the web viewer right away. Additionally, since we’re using the web viewer inside FIleMaker, it’s essential to get the JS code inside FileMaker as soon as possible.

Todd figured out a way to see the JavaScript work immediately in a FileMaker file’s web viewer object. We use it in our projects here at Proof+Geist, we used the technique in the add-ons, and I’m using it for this demonstration file.

Essentially, when I am developing the JavaScript code, I can run a development server that serves the code I’m writing. This development server is picked up by the web viewer and shows the results of my JavaScript coding. Whether the code works or doesn’t, I see how my code is turning out immediately.

By starting up a development server in VSCode, whatever I write in the code will be picked up by the web viewer.
The Development Server in Action

The mechanics behind this are a bit complex. It involves Node.js and some JavaScript libraries to run a development server. Hopefully, very soon, we will have a template project you can use that has all this already set up.  So be on the lookout for that.

Using the web viewer inside of FileMaker to render the code is one part of a better JavaScript development environment.

Using FileMaker Data

A hallmark of a better JavaScript development environment is to use real data inside FileMaker. Since we’re working inside a FileMaker app, it follows that we could use the data already in there. I don’t want to develop with fake data that may not have the same performance considerations as the real data. If my goal is to show 1000 records in a data table, then I want to make sure the whole process works with 1000 real records. 

In our development, we use data from FileMaker, and we do this using the Perform JavaScript in a Web Viewer step.

For this JSONata example, I’m using this script step to load data into the web viewer. The web viewer already contains the JS code, and the work will happen when it receives the JSON data and the query. Here’s my code.

This pattern is pretty standard:

  1. The web viewer on the layout is named. I write the name into a variable (line 1).
  2. I give the name to the global function inside the JavaScript in a variable (line 2).
  3. I pick up the query data in a variable (line 3).
  4. I pick up the JSON data in a variable (line 4).
  5. I then call the script step with the above pieces (line 8).

Notice that I’m pausing in line 7. In all of our work with the web viewer, we’ve found this to be essential. Since I’m using a new window (line 5) where the web viewer is located, I need to wait a small amount of time for the web viewer to load. And this has to happen so that the JS function “simpleQuery” is loaded and ready. Between Kevin and myself, we’ve tested it to be around ½ to 2 seconds. 

Getting the Data into the Web Viewer

The JavaScript function itself is pretty simple, but it has one part that is vital: it has to parse the incoming JSON data into something JavaScript can read. Line 4 here shows that I’m taking the JSON that comes in and parsing it.

The simple function called from FileMaker

We have template scripts written to help us remember the pattern. I use those all the time. 

Returning Results

Many times the point of a JavaScript library is to return results to FileMaker. This is the case in the work Kevin Frank and I did together. He found this cool library called JSONata that parsed JSON using a query language (one designed for this library). The idea is to pass the web viewer some JSON and a query and then get the result of the query back. So we have to work with FileMaker’s ability to get the result out.

In this example, we’re getting the results back in two ways: 1) we’re setting the data into a field, and 2) we’re getting the data back to use inside the script itself.

You can examine each script to see what they’re doing. They’re pretty simple:

Get Result Into the Field

This script simply shows what happens in the normal use case: One script calls the JavaScript. The JavaScript does the work and calls a FileMaker script – in this case, “Get Result” to return the result back to FileMaker. The original calling script finishes its run before the “Get Result” function runs. And that’s a fine progress of steps. The callback script gets the result and places the result into a field. End scene.

Get Result Into the Script

This script is built differently and uses the newer FileMaker.PerformScriptWithOption() function (documented here). In this case, I want to use the result in the original script. So I call this the function simpleQueryInScript(). The function processes the JSon using the query and calls back to FileMaker a script called “Get Result In Script”. This script interrupts the original script, gets the result from the JS and, in this case, sends it back to the original script.

I know this is a lot to take in, so study the scripting and examine the JS code provided here and see how it all works together.

This is a better environment for JavaScript in FileMaker development. It’s pretty close to all we can do to make it easy enough to write JS and see it render out in the web viewer while developing.

One more thing

We’ve been talking here about writing JavaScript. But there’s one more step: actually using the code you’ve written in an actual production. Don’t worry. We’ve got that covered. After I’ve finished with the code, I can run a small command and the JavaScript is put into the correct field inside of the app for the web viewer to pick up.

Uploading new code to FileMaker

Onward

Finding a better JavaScript development environment for FileMaker has been something we’ve explored for many years. We’re interested in making using JavaScript even more accessible by providing easy tools to get the job done. This FileMaker 19 + JSONATA exercise gave me the opportunity to flesh out what is really necessary to easily develop the code. Thank you to Kevin Frank of FileMaker Hacks for his proposal, his collaboration, and his support.

We’re not done; in future posts, we can point out how we work with VSCode and other tools to make this work.

If you are interested in working more with JavaScript in this better environment, let me know (jeremy.brown@proofgeist.com). If there’s enough interest, we can provide some training around this environment set-up and use.

The demo file is found here and at Kevin’s site.

The Claris FileMaker Add-ons, released just a few updates ago, are one of the components that make up the Open Platform release. They’re useful in solving problems for FileMaker developers. Calendars and Kanban boards are popping up all over the community. They’re not without their issues, however, but most of what’s there we can control. We have written lots about how to work with these add-ons, and I offer another explanation to edit add-ons: allowing them to display more or less records than the default found set. It’s rather easy, and I’ve included here a file in which you can copy a few script lines into your add-on (any add-on) scripting. So let’s look at the FileMaker add-on found set changes we can make.

Found-Set Based Add-ons

There are five add-ons that we think of as “found-set” based. They display a found set of records (the number of which is the subject of this post) in the web viewer in some form, whether through an event grid, columns or rows, in lanes, or as colored dots or cards. These add-ons find a set of records using the new Execute FileMaker Data API (EF DAPI) script step and display them in some form.

By default each add-on has a limit to the number of records it returns:

  • The Calendar: 3000
  • The Heatmap: 500
  • The Kanban: 500
  • The Timeline: 500
  • The Heatmap add-on: 100

NOTE: The limit is the maximum number of records returned. If there’s only 34 records in the target table, only 34 records will be returned.

The Limit

The query used in the EF DAPI script step, in most cases contains a property that defines the limit. The query itself is generated from the add-on and sent back to FileMaker as part of the “Find” script parameter. In there, at around line 17 or 18 or 19, the $data variable gets the query. You can see that if you debug the script. Here’s the Activity Timeline’s query:

{
    "layouts":"ActivityTimelineSampleData",
    "limit":500,
    "query":[
       {
          "ActivityTimelineSampleData::PrimaryKey":"*"
       }
    ],
    "sort":[
       {
          "fieldName":"DateStarted",
          "sortOrder":"descend"
       }
    ]
 }

That little ol’ limit property defines the limit. In this case, the Activity Timeline will only return the first 500 records in the found set. In this case, the records are sorted in descending order and THEN the first 500 records are returned. WIthout the sort property, a query would simply return the first 500 records in the table.

Almost every add-on contains this limit property. It seems the Photo Gallery one does not; its query is missing this property. In this case, the query uses the built-in default of 100 as the limit.

The Limit is Good

There are good reasons to have a limit to the number of records that are returned. For one, the larger the found set–say 10000 or 32999 records, the slower the FileMaker script step will be. The step is doing a find basically, and we know all about Finds! As with the Data API functionality, this query has a built in limit of 100 records if one isn’t defined, to speed up the return.

Also, limits are built into APIs for speed and server resource conservation.

So there’s a limit. Okay. But we can work around that. I can think of two ways to do so: change the limit, or play with the offset property. Let’s explore each one.

Change the Limit

The limit of each add-on is defined (or assumed, as in the Photo Gallery), but that’s not a problem for us. The query in the $data variable is simply JSON and we all can work with JSON nowadays. So the simplest course of action is to UPDATE (or add) the limit number in the Find script.

All we’d have to do is use the FileMaker JSON functions to update this query. Immediately after the step where the $data variable is set, include a step to either add this property or update the existing property in the query:

Set variable [ $data ; value : JSONSetElement ($data ; "limit" ; <<yourNumberHere>> ; JSONNumber)]

And that’s it. The query will return the number of records we place in the <<yourNumberHere>> part of the JSONSetElement() function.

This gets me thinking: since I’m using a script step to update the limit, I could easily make the limit value a user-facing choice. I could put on the layout a field with a value list of, say “10, 25, 50, 100, 500, All” and use whatever value a user selects. Obviously if the user selects “All” my script will have to replace all with some incredibly large number: 9999999999 (as long as that’s larger than the entire possible found set).

The Offset

As with other API responses, the Execute FileMaker Data API script step query (that’s a long phrase) has an offset property. This option tells the script step which block of records to return. Here’s an example:

{
    "layouts":"ActivityTimelineSampleData",
    "limit":500,
    "offset": 501
 }

This query is saying: I want you to return 500 records, but start at record 501. That is: I want the second block (or page) of numbers.

The offset property is used all over in APIs, and it is referred to as pagination. Because of possible issues with server load in returning records, there’s a limit, but the offset gives us the chance to eventually get all the records.

In Real Life

Using this in real life is very practical and helpful. In a Photo Gallery add-on, showing records in the Photos table, it is not useful to return all the photos. No one can reasonably see all of them at once. Instead, we can build a paging mechanism that allows the user to page back and forth through blocks of photos. Also, with the offset value in place, we can return fewer records at a time. Rather than returning even 100 photos, our scripting can return 20 at a time and update the offset.

Updating the Offset

We can update the offset in the same way as we updated the limit:

Set variable [ $data ; value : JSONSetElement ($data ; "offset" ; <<yourNumberHere>> ; JSONNumber)]

We can work with this scripted offset-update in many ways. If we’re building a paging workflow, for example, a “Next” and “Previous” button on the layout above the gallery can provide the number for the offset. This offset number can be tracked in some manner and increased or decreased as necessary.

Here’s the product of about 30 minutes of playing with the limit and offset property. You can see how I used this in combination to update the number of and page of records being returned. I’m sure there’s some bugs here and some optimization to do, but this is the first attempt.

And here’s the extent to which I hacked the “Find” script (which you can do to any found-set add-on):

Onward

Each of the Claris FileMaker add-ons work directly out of the box, but eventually we’ll all need to customize them in some way. What I’ve described above is just another way to make minor updates to the scripting to make it your own. In this case we’re looking at the FileMaker add-on found set, and you can replicate what I did here for the Photo Gallery for your own implementation of any of the “found-set” add-ons. Feel free to download this sample file to see how I’m working with the offset and limit parameters.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at the FileMaker add-on events.

Each FileMaker add-on comes with one or more events. A user triggers an event through their interaction of the web viewer. Events include clicking on a card, clicking on a button, double-clicking, navigating through records. Whatever the event, the scripting is built already for you, covering the normal use cases. And that is probably good enough for most folks. But, if you want to do something different with the event, then read on and let me explain.

Handling the Events

Each add-on comes with an Event script, named after the add-on. So the Calendar event script is titled FCCalendar Events. Explore that script and use this script to do something different. Let’s walk through each part of the event script.

The beginning of the script gets the script parameter from the JavaScript (triggered when a user does something in the web viewer), and various pieces are extracted into separate variables. The most relevant one to our needs right now is the $eventType, which collects the event from the JS parameter. The other information is less important but necessary, and you can see their descriptions in the comments at the top of the script.

It’s important to leave this script name alone as the JavaScript has this name in the FileMaker.PerformScript() function.

Event Logic

Once the variables are created, the remaining script lines handle the logic as determined by the $eventType. The conditional step there are easy to follow: if $eventType is a certain option, then execute certain script steps.

Many of the possible events for an add-on use the $data variable, the value of which was constructed in the JS for use in this particular event. Through the debugger you can see its value. For example, when I clicked on a day in the calendar to create an event, this is the value of the data:

{
   "AllDay":true,
   "EndDateStr":"2020+10+14",
   "EndTimeStr":"00:00:00",
   "StartDateStr":"2020+10+13",
   "StartTimeStr":"00:00:00"
}

Now constructed, the “NewEventFromSelected” event uses the $data to write fields in FileMaker.

Just a quick note: Almost every script, including this one, gets the $Config from the JavaScript. As we learned in the Config post, this holds all the information about this particular add-on, and is available for use in the event script. In a click event, for example, the script grabs the primary key’s field name from the $Config variable and uses it to do a find.

Once the data and event have been determined, the rest of the script runs just fine in its logic. We built these Event scripts to do something expected for each event, but you’re welcome to override it and do something else with the provided data.

FileMaker Add-on Events: You Decide

So take this information and do with it what you will. Use the FileMaker add-on events script to refine the add-on’s behavior as you see fit. Let us know what you come up with and how you’re using this script differently.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at how to use the FileMaker add-on refresh feature.

The Point of the Add-ons

In previous posts I’ve mentioned that the discussed feature is the point of the add-ons. I talked about how multiple instances is the point. Refetching the data, and other parts of the add-ons are the point. Maybe there’s too many points, but I’ll add one more. Being able to refresh the add-on’ without any flashing of the web viewer is a win for these add-ons. Let me explain how it works.

The Stale Data

The new Claris FileMaker add-ons are JavaScript based. They take data from your app and render the data into the add-on. That works perfectly. The data is in the browser of the web viewer object. It is displayed in the web viewer as cards, shades of a color, or a data point on a chart. The data grows stale in the web viewer over time. That’s a problem when someone–whether a user in another office or the user facing the Kanban board–changes the underlying data in some way. You’d expect to see the change in the web viewer. And that just didn’t happen ‘naturally’ in the past. In all the cool web viewer integrations I’ve done, that was one of the problems.

The Fresh Data

These add-ons, however, come with a refresh feature that solves the problem. Any user, including the one viewing the Calendar, can edit a record in various ways. Closing that record or even switching layouts or windows could force a refresh of just the data part of the add-on. The entire code doesn’t have to be reloaded (which is the thing that caused a web viewer flash). Now the newly-changed data can flow into the add-on with no jolt in what the user sees save for the new card to be added or the shade of the heatmap to go darker, whatever the case may be. This feature really turns the add-on into a ‘first-class’ feature of FileMaker; the add-on interacts with data just as a button bar calc or portal or hide calculation does.

The FileMaker Add-on Refresh

Here’s how the refresh works. Each add-on comes with a Refresh script, named after the add-on. The Timer’s script is “Timer Refresh”. Its job is to update the add-on with data from the source table (declared in the config and procured through the find script, if applicable). It takes as a parameter the Addon UUID as a string, collects the data and sends the data to the add-on through a function that begins, often, with the word “update”. You can see it in the script.

That’s how it works. It’s simple.

Tips on Refreshing

The refresh script is there for you, the savvy FileMaker developer, to use wherever you see fit to refresh the data. This script can be called as a trigger, as a subscript, as a parent script on a button. It can be part of updating routines that happen. Let me give you some specific suggestions on using this.

  • All you need to do to refresh the data is to run the Refresh script, passing in the add-on’s UUID as a string parameter. Don’t worry about the find mechanism or filter mechanism. This refresh script, or more specifically the JS function that it calls, will do all that finding/filtering for you.
  • A sample layout is included for the dashboard-type add-ons. This layout is used as a card window when the user clicks on a card or event or circle in the heat map. The button on this layout that closes the window also runs the Refresh script. Use that model in your work.
  • For those record-type add-ons (Timer, Editor, Simple Chart), your refresh should go on a field in which a user types data. Without this, it would take a layout enter to get it to refresh (since the add-on is self booting and gets the initial data).
  • Be sure to include as a parameter the add-on UUID, which is found in the add-on itself.

The Difference Between the Refresh and Refetch

We’ve talked about the simple Refetch mechanism found in most add-ons. When thinking about that and the refresh, you might wonder: what’s the difference?

Well certainly they both get the latest data from the source table and push it into the add-on. In that way, they’re the same. But the refetch happens on some add-ons (Heatmap, Kanban, Activity Timeline), and it happens at an uncontrolled interval. To force the refresh of data, you, well, refresh the data. You control the refresh.

The FileMaker Add-on Refresh

This simple feature, something you hook up where ever you want, is one of the most powerful parts of each add-on. You have control over when the add-on is refreshed with new data. So do that: add the refresh and watch data flow at your command to the add-on.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we will examine the FileMaker add-on refetch process.

Many of the add-ons are sort of ‘dashboard’ add-ons. They are meant to be visible for extended periods of time with some interaction. A user, for example, can bring up the activity timeline, scroll through it, and click on a card to open it up. The timeline could be on the user’s screen for some time, and it would benefit her to see the latest records in the events table.

Refetch

In these cases, the add-ons are built with a refetching mechanism. At a certain time interval, one unspecified and un configurable, the add-on will use its JavaScript power to perform the find again (that is, the JS will call a FileMaker script) and re-render the data in the display. This process happens during those times when the user is not running a script (by a click of a card). A developer could be sitting there, staring blankly at the screen, and suddenly see a new event, or the color of a card change from red to blue.

A Couple of Notes

Since it happens automatically, and sort of behind the scenes, there’s really nothing for you to do with this except know about it. Here’s a few additional details about the FileMaker add-on refetch mechanism:

  • The timing of it is unconfigurable. There’s no way to change the interval at the moment.
  • The refresh happens not that often in a given time period. While it’s a bit different in length for each add-on, the refresh will not get in your or your users’ way.
  • The refresh process uses the Find script for the add-on.
  • The refresh will only affect one instance at a time.
  • If you do have multiple add-ons (multiple instances or different types) on the current layout, each one will run its own refresh (as applicable).
  • If another script is running when the refresh happens, the Find script will be added to the script call stack.

FileMaker Add-on Refetch

That’s really about it. The latest data is shown because of the Refetching mechanism. Users will get to see all that’s fresh and new in the data source table.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at how to use multiple instances of the FileMaker add-ons.

The Point of the Add-ons

One of the biggest reasons to use an add-on is that it can be used many times throughout your file. Just like a portal or a button bar, the calendar add-on or the photo gallery add-on is flexible enough to use all over.

As a FileMaker developer you don’t have to know how this works; just know that it works. Your use of an add-on multiple times in the file will not disrupt any of the other add-ons. Here’s a silly example.

Two Timers To Track Times

These two timers are separate instances of the same Timer add-on.

They work with two sets of the timer’s required fields. They have their own configurations (one has a blue button/gray background, and the other has a red button/white background).

Each add-on runs independently of each other; indeed, you can kind of see it here (in the button text), the first timer is running and the second timer has stopped.

Each Timer is Unique

The magic behind this idea is that each timer is given a unique Addon UUID when you drag/drop the add-on to a layout. You can see this unique ID in a few places:

  1. The add-on’s FileMaker buttons (such as the configurator button or the back/forward arrows) script parameter
  2. The name of the web viewer object in the Inspector
  3. The web viewer’s calculation

Of course all of these match, and have a specific purpose.

Multiple Instances of FileMaker Add-ons: The Deets

Let’s make sure we have something clear in our heads:

  • When we install the add-on, all the scripting, layouts, etc comes in as a complete package. The scripts come in once.
  • When we drag/drop the add-on onto a layout, we’re creating a new and unique instance of it. The UUID gets generated and attached to the places you see above.
  • If you were to copy an add-on, you’re copying the UUID as well, so there will be two add-on groups with the same UUID. Can’t have that.

Now that we have that clear (if not, go back and read it again), all add-ons of the same type use the same scripts, so the UUID is passed to scripts to let the script know which one to work with in some manner. The “Show Config” script gets the UUID attached to the button and grabs the config from the ConfigStore field using that UUID. Because the web viewer is named with the UUID, the script knows which web viewer on a layout to activate and manipulate.

This idea of the UUID is incredibly important. You don’t want to change it, unless you want to go to the trouble of updating it all over.

The Only Other Thing

I believe the only other thing you really need to know about multiple instances and the UUID is the script containing the words “WebViewer Object Name”. This script generates the web viewer’s name at runtime, and is used in almost every add-on script. Just FYI.

Oh yeah: if you really want to know how the UUID is generated, I explain that in the post on creating add-ons. Check that out.

Go Forth and Multiply

So use add-ons all over the place. Use a timer ten times in your custom app. Build a dashboard using charting add-ons. Create a layout with two Kanban boards that show different tasks. You got it! It’s easy and the add-ons are built with this in mind.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at the FileMaker add-on configurator

The add-ons are meant to be working with little effort. Even at the moment of install they work using sample data and some default settings. At install, you see exactly how they work.

Make it Your Own

There’s no one here, however, that wants the sample data settings to be part of the add-on in their app. Some of the settings too may not fit every customer solution. Both of these issues are easily solved with the add-on Configurator.

So let’s take a look at how to configure the add-ons. We’ll look at the configurator generally, and then in a follow-up post, we’ll address specific add-on configuration settings.

Configuration, Generally Speaking

The configurator dialog is a window installed as part of the add-on package. The layout contains only a blank web viewer, and this layout is used as a card window. And finally, every instance of an add-on–whether used multiple times on a layout or multiple times in a file–will use this one configuration layout.

As part of the layout object that you drag over, a button with a gear icon is included. This activates the “Show Configurator” script. This button is set to be invisible on iPhone or if a user is logged in with a non-full access account. The script uses the UUID of the add-on (generated on drag/drop), and opens the configurator.

Once the configurator is open, you’re presented with some mini pages that contain drop downs or text fields or checkboxes to enter your configuration for this particular add-on instance (remember, you can have multiple instances of the same add-on throughout your file).

In many add-ons there are the same pages: Required, Settings (or options), and Filter. The required fields are required, and the add-on will not save until those fields are filled in.

Required & Optional

I’ve discussed already the required fields for each add-on, but I need to point out one more thing: Most add-ons require a layout in the first drop-down.

This choice is vital: you have to select a layout on which contains all the fields you wish to use in the add-on. All the required fields as well as the optional fields you want to use in the display. For example, the Kanban add-on requires some fields and gives you optional fields. Each of these fields need to be on the layout you choose.

The layout you choose should be one you’d like to use to show the record when it is clicked on in the add-on. Here’s a couple of tips when picking a layout:

  1. Be sure and put all the fields on the layout: either visible and part of the design or off to the right of the visible area.
  2. You can use fields from a related context, but you might run into some slow-down of gathering data.
  3. Before you actually set up the add-on, create all the required and any optional fields in the data table.

Settings

Many add-ons give the developer some ways to customize the add-on. It could be as simple as button color. Whatever the settings, each add-on has default settings that you can change.

Filter

We’ve discussed before the filter mechanism. It is part of the configurator, so you can read up on that. There’s not a whole lot more to talk about there.

Scripting

The button that opens the configurator runs a script partially named “Show Configurator”. This button contains the AddonUUID as a parameter. Here’s an example:

JSONSetElement ( ""; 

  ["AddonUUID" ; "701F0F8B-BED4-48D0-948D-B7E5F2D1171B" ; JSONString]

)

As we’ve talked before about add-ons generally, this UUID is generated when you drag the add-on to your layout. Further, this UUID in the parameter is the same as the UUID for the web viewer object. The UUID attached to the button allows for you to use multiple instances of the add-on all through your file or on the same layout. Each button will have the UUID of its web viewer package, thus be tuned only for that instance.

The Config

It’s important to know where this FileMaker add-on configurator gets the options. For each instance of an add-on, the configuration–that is, the field choices and settings–is stored as a JSON object inside the add-on’s table in the ConfigStore field with the add-on’s UUID as the key.

{
   "701F0F8B-BED4-48D0-948D-B7E5F2D1171B":{
      "AdditionalInfoField":{
         "required":false,
         "type":"select",
         "value":""
      },
      "AssignedTo":{
         "required":false,
         "type":"select",
         "value":""
      },
      "CardDraggable":{
         "required":false,
         "type":"checkbox",
         "value":true
      },
      "CardStyle":{
         "required":false,
         "type":"select",
         "value":"Tasks::BackgroundColor"
      },
      "DataSourceLayout":{
         "reScanOnChange":true,
         "required":true,
         "type":"select",
         "value":"Tasks"
      },
      "DescriptionField":{
         "required":false,
         "type":"select",
         "value":"Tasks::Description"
      },
      "FilterField":{
         "required":false,
         "type":"select",
         "value":""
      },
      "LabelField":{
         "required":false,
         "type":"select",
         "value":"Tasks::Label"
      },
      "LaneSortOrder":{
         "value":[
            "To Do",
            "In Progress",
            "Done"
         ]
      },
      "PrimaryKeyField":{
         "required":true,
         "type":"select",
         "value":"Tasks::PrimaryKey"
      },
      "QueryField":{
         "required":false,
         "type":"select",
         "value":""
      },
      "SortField":{
         "required":true,
         "type":"select",
         "value":"Tasks::SortOrder"
      },
      "StatusField":{
         "required":true,
         "type":"select",
         "value":"Tasks::Status"
      },
      "StatusSort":{
         "required":true,
         "type":"select",
         "value":"KanbanSampleStatus"
      },
      "Style":{
         "required":false,
         "type":"select",
         "value":"Red"
      },
      "TitleField":{
         "required":true,
         "type":"select",
         "value":"Tasks::Title"
      }
   },
   "DEV_UUID":{
      "AdditionalInfoField":{
         "required":false,
         "type":"select",
         "value":"KanbanSampleData::AssignedTo"
      },
      "AssignedTo":{
         "required":false,
         "type":"select",
         "value":"KanbanSampleData::AssignedTo"
      },
      "CardDraggable":{
         "required":false,
         "type":"checkbox",
         "value":true
      },
      "CardStyle":{
         "required":false,
         "type":"select",
         "value":"KanbanSampleData::Style"
      },
      "DataSourceLayout":{
         "reScanOnChange":true,
         "required":true,
         "type":"select",
         "value":"KanbanSampleData"
      },
      "DescriptionField":{
         "required":false,
         "type":"select",
         "value":"KanbanSampleData::Description"
      },
      "FilterField":{
         "required":false,
         "type":"select",
         "value":""
      },
      "LabelField":{
         "required":false,
         "type":"select",
         "value":"KanbanSampleData::Start Date"
      },
      "LaneSortOrder":{
         "value":[
            "To Do",
            "In Progress",
            "Done"
         ]
      },
      "PrimaryKeyField":{
         "required":true,
         "type":"select",
         "value":"KanbanSampleData::PrimaryKey"
      },
      "QueryField":{
         "required":false,
         "type":"select",
         "value":""
      },
      "SortField":{
         "required":true,
         "type":"select",
         "value":"KanbanSampleData::Sort"
      },
      "StatusField":{
         "required":true,
         "type":"select",
         "value":"KanbanSampleData::Status"
      },
      "StatusSort":{
         "required":true,
         "type":"select",
         "value":"KanbanSampleStatus"
      },
      "Style":{
         "required":false,
         "type":"select",
         "value":"Blue"
      },
      "TitleField":{
         "required":true,
         "type":"select",
         "value":"KanbanSampleData::Name"
      }
   }
}

Notice that in the above Config, I have two properties, one for the add-on with the UUID beginning with “701F0F8B” and is tuned to the settings I want: the Tasks table fields, the Red style, and so forth. The other with the key of “DEV_UUID”, which contains the settings for the default (on-install) set up. If I end up with ten instances of this add-on throughout my file, there will be ten objects here, each identified with the add-on’s UUID.

If you really, really, really, ever, ever, ever want to wipe this field out there’s a Developer-only script called “Clear Config” that will clear this field. If you do that, all of your configs for all your add-ons will be wiped out. So maybe don’t do this??

Using the Configurator

And finally, as each instance of the add-on is used throughout your file, the add-on setup, the custom functions, and the “Show Config” script work together to get the config out of that field and pass it to the JavaScript code, where it is used all over, telling the JS such things as what colors to use, what layout to pop up to display the data, what fields to use. There’s a lot in this config, and it’s best to leave it alone. Other scripts use the config as well, so

If you want: If you’re really interested you can, at any time, hijack this config and overwrite it with something temporarily. It’s just JSON, and you can target and change anything in here. What you change will update the web viewer.

The FileMaker Add-on Configurator

So that’s the skinny on the FileMaker add-on configurator. It’s an important part of the set up, but really only needs to be touched once during development. After that you’re free to move the button off the layout to the side and use it only when necessary. Heck you don’t even need the button. You can use the same parameter in the button set up in a parent script to call the Show Config script. As long as you pass in the Addon UUID as a JSON object, you can call the configurator via a Developer-only script.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at the required fields for the FileMaker Add-ons.

Add-ons Required Fields

Each add-on has one or more required fields for it to work. The dashboard-type add-ons (Kanban, Calendar, Activity Timeline, Photo Gallery) all require the Primary key field of the source data records. That’s a given. The Heatmap add-on doesn’t require a primary key field since it will return all the events of a clicked-on date.

But each add-on has other requirements, and you can see the FileMaker add-on required fields in the configurator. But the configurator is in one part of the add-on, and adding fields is elsewhere, so what follows is a list of all the required fields for each in-product add-on. You can use this list to create the fields in your data tables (or just copy from the SampleData table that comes with each add-on).

An Example Configurator

Remember, these fields do need to be on the target layout, whether on or off screen (off the layout to the right), in order for the add-on configurator to get the data you need.

For fun, I’ll list the non-required fields as well, just so you can make them all at once. These fields provide additional functionality if you choose to add them to your data table.

Calendar

Required Fields

  • Primary Key
  • Title: that which you’ll see on the calendar.
  • Start Date
  • End Date
  • Start Time
  • End Time

Non-Required fields

  • Tooltip
  • AllDay – a number field (1 or 0(empty)) representing the full-day indication
  • Editable: a number field (1 or 0/empty) to indicate if the event can be clicked on and edited.
  • EventStyle: a text field describing the color style the event should be. The FCCalendarStyles value list provides the pre-determined choices.

Kanban

Required Fields

  • Primary Key
  • Name or Title: that which you’ll see on the board.
  • Sort: a number field determining the sort of the cards in each lane. Note: this field get constantly updated as users drag/drop to rearrange the cars on the board. But you can do an initial set of the sort.

Non-Required fields

  • Description: a field holding a description of the task. This is one paragraph with no returns in the text.
  • Label: the label will appear on the top-right of each card. You may want to put a priority level or a date field here.
  • Additional Info: the value in this field will be included in the card if there’s data in the field. It just provides more information about the task.
  • Assigned to: pick a field that holds the assignee name.
  • Card Style: a text field describing the color style the event should be. The KanbanSampleStyles value list provides the pre-determined choices.

Activity Timeline

Required Fields

  • Primary Key
  • Start Date: A timestamp or date field.

Non-Required fields

  • Title
  • Description: a field holding a description of the task. This is one paragraph with no returns in the text.
  • Assigned: pick a field that holds the assignee name.
  • Background: a text field describing the color style the event should be. The ActivityTimeline Styles value list provides the pre-determined choices.

Required Fields

  • Primary Key
  • Photo: This field points to either a container field or a base64-encoded field (see the sample data table). If the file with the add-on is hosted, you can use the container field. Local files require the base64-encoded field.
  • Scale Width: A number field given the relative width of the image. You can calculate this from the original width of the photo. See the SampleData table for examples.
  • Scale Height: A number field given the relative height of the image. You can calculate this from the original height of the photo. See the SampleData table for examples.

Calendar Heatmap

Required Fields

  • Start Date: A timestamp or date field.

Barcode Creator

Required Fields

  • Barcode Source: The data you want to turn into a barcode.
  • Image: Where to place the barcode image.


Timer

Required Fields

  • Time Logged: A field where the time from the timer will be placed when a user stops the timer.
  • Total Time: A field which holds the total time.
  • Time last Started: This field will be given a UTC timestamp when the timer starts, which is used to determine the state of the timer: on or off as users navigate to other records.

Text Editor

Required Fields

  • Rich Text HTML: This is the field where the rich text will be placed and read from when the editor loads.

Simple Chart

Required Fields

  • Field One: A number field with a value that will be graphed on the chart.

Non-Required fields

These non-required fields are additional data points you can plot on the chart.

  • Field Two
  • Field Three
  • Field Four

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at the FileMaker Add-ons Filter mechanism.

The Default Behavior

By default, the add-ons work with all the data in the target table. If you select the “Events” table as the data source, you’ll get all the records. The Heatmap and the Calendar actually search for a range of records by default (as we can demonstrate below) but for the most part, add-ons use display all the records in the target table. This happens automatically using the add-ons Find functionality

We can, however, filter the data set to return only some of the records in the table (or in the range of returned records). The Add-on contains a specific piece of functionality to add a filter without revising any scripts. Let’s take a look at this.

FileMaker Add-ons Filtering: Return Some Records

The heatmap add-on returns records within the three month range as shown in the add-on. It returns all the records in this range and plots them on the widget.

If I click on September 10, 2020, I get three events, one for projects 3, 4, and 5.

Let’s say, however, users would want to only see their projects. When User A logs in, she is assigned only to project 3, so she should only see project 3. Well, with the add-on Configuration, we can apply a filter to a field in the target table so that User A only see’s project 3.

In the configurator there are two settings for the filter: the query field and the filter field.

The filter field is the field in which the search criteria will be applied. In the example above I’ve set the filter field to be the HeatmapSampleData::ID_Project. Does that make sense?

On the layout where the Heatmap is located, for the sake of simplicity, I placed the global query field and entered “==3”. In our world, this means “find all records with an exact match of 3 in the field”.

What the add-on will do is, when it does the next refresh of data, it will apply this filter “==3” to the data set in the find mechanism, and return just those records where 3 is in the ID_project field.

After I applied it to my data set, 9/10/2020 shows only 1 event, and that event is for Project 3.

That’s pretty nifty.

Oh, the Possibilities

I can hear your little gray cells activating and thinking of possibilities for this FileMaker add-on filter. Maybe some of what you’re forming in your head is listed below:

  • The field doesn’t have to be visible on the layout. It can be offscreen, or it can be removed once the Configuration has been set.
  • The field can be set via a script. For example, your onOpen script can set this field to the user’s projects.
  • The text inside the Query field can be any string we use to perform FileMaker finds: “<=1/1/2020”, “!”, “==4”, “*” , “=”, etc.
  • The field can be displayed as a pop-up control with a value list.
  • If you do use a value list, you might have to go further under the hood to add the FileMaker operator symbols via the Find script.

Deeper Under the Hood

I’m giving you the details about how to use the filter mechanism. That’s good. If you want to know how this actually works, read on. Otherwise skip to the next section.

When a Filter Field is designated in the configurator, the filter value is applied to the target field in the AddonFind script. The filter field and value is added to the query that is used in the Execute FileMaker Data API script step. See here:

Inside the Config of this add-on, there’s an “EventsFilterField.value” property. This holds the NAME of the field in the target table in which to search. If there is a here, then lines 27-32 run and we grab the name of the filter Field and get its contents and then finally (line 32) add it to the query section of the $data (the request).

Read more about the Find script in that blog post. There we talk about how to adjust the find to fit whatever scenario you’d like.

Actually Applying the FileMaker Add-on Filter

As we will discuss in other posts (they’re coming soon), the add-on periodically does a refetch of the data and refreshes the add-on with any new or changed data. But you can force a refresh of the data, thus applying the FileMaker add-on filter, at any time. In each add-on there’s a script called “Refresh” that does this work. Apply this to a button or to a field as a script trigger and this will cause the data to refresh with the given filter you’ve set up.

Refer to that blog post about Refreshing (coming soon).

Filtering in the Add-on

So there you have it. A complete and hopefully clear guide to how add-ons provide filtering functionality. Play with this and give it a try. Let us know what ways you were able to apply this filter idea to your use of these add-ons.

We’re continuing our discussion of the new FileMaker 19 add-ons. Claris has released a great video on these add-ons, but, in this series of posts, we’re taking a deep dive into how the add-ons work. In this post we look at the FileMaker Add-ons Find mechanism.

FileMaker Add-ons Find Mechanism

By default, each ‘dashboard’ add-on returns all or most of the data in the target table. For the Kanban, the add-on will display all the tasks in that table. The Calendar add-on will return a found set of events: those events in a three-month time period where today is the center of that. And for most uses and users, that is fine.

You can certainly adjust the filter of an add-on to return a different found set. However, there are folks (you know who you are!) who want to dive deep into all parts, including the find. So let us help you understand what’s happening in the find.

This find script is rather simple in its purpose. It does three things:

  1. Gets the important information (config, data, addonUUID, etc) from the add-on.
  2. Constructs the search query, adding in any filters;.
  3. Performs the query and returns the result.

After these three steps, the find script sends the found set back to the add-on where the add-on renders the new data.

This script is called automatically by other scripts (the Refresh Script, for example), and it is called, in some cases, by the add-on itself at regular intervals. Additionally when the add-on self-boots, this script is run to get the initial set of data.

You can finagle with this script to perform a tighter find for you. We’ll explore possibilities at the end of this discussion.

Setting the Stage

In the information-gathering set of steps, the script gathers the important information it needs to process the find. It starts with the $json, a script parameter sent from the add-on to FileMaker. Here’s a description of each of the variables:

The $data is the basic query that will be used in the Execute FileMaker Data API script step. It was constructed by the JavaScript code and includes the target layout, primary key field, and any other fields used in the query. All of the fields are set in the configurator. Here’s what the Activity Timeline’s query looks like.

{
   "layouts":"ActivityTimelineSampleData",
   "limit":500,
   "query":[
      {
         "ActivityTimelineSampleData::PrimaryKey":"*"
      }
   ],
   "sort":[
      {
         "fieldName":"DateStarted",
         "sortOrder":"descend"
      }
   ]
}

Since this value in $data is just JSON, you can easily update it on the fly via the script. If you want to return more than the limit of 500 records, adjust that. If you want to add more filters to the query, you can do so.

$Callback contains the name of the JS Callback function that will run. There’s no need to update or change this.

$FetchId contains a UUID for the JS code and this fetch. There’s nothing to see (or do) here.

$AddonUUID is the unique identifier of the add-on that is triggered.

$Config contains the config for this add-on. Though it is stored in a FileMaker field, this config object is also part of the add-on and is used all over.

Adding the Filters

In the next set of steps, the Config-set filter is added to the query. This, of course, happens only if there’s a filter value.

Performing, Getting, Sending

In the last section of this script, the query is performed using the Execute FileMaker Data API script step. The response is checked for errors, and, if no error, the response is sent to the add-on.

Here’s where the $Callback variable gets used. This JS Function replaces the data in the add-on with the new found set.

Possibilities

This Find process works just fine as it is, but there are possibilities to refine it. As a FileMaker developer you know what you’d need to do, but the basic idea is that you update the find query. The filter mechanism is a user-facing possibility, as you have a field that contains a find criteria. But you could easily update this script to include hardcode something into the find, whether it’s to return user-based or security-based or any other kinds of constraint.

Most of the script shouldn’t really be altered, but here are the few places:

  • Update the $data query on the fly, adding or updating JSON elements.
  • Add to the Query filter if you want, or change it.

That’s really it. This find script is there to gather data, and really it should be left alone as much as possible. The script name shouldn’t be changed, and of course, don’t delete it.