Category Archives: Blog

  • 0

FileMaker 17: Data API Multi-File Upload

Tags : 

The FileMaker 17 Data API, also known as fmrest, includes a new capability to upload data to a container field. Prior to 17 the Data API only allowed container data to be downloaded. Uploading data from a website to FileMaker had to be done using plugins, Base64 encoding, or by saving a temporary copy of the file in a spot where a FileMaker script could find it. Now we can upload to FileMaker container fields using only the Data API. This blog post describes how to use the new upload capability with HTML and JavaScript.

Before uploading to FileMaker, we need to obtain an access token. We’ll use this token to authenticate our requests to FileMaker. The 17 Data API allows you to obtain an access token using either a basic authentication header or an OAuth identity provider like Google. In this blog I’ll use basic authentication.

To simplify the code I’m using jQuery. Google makes jQuery easily available through their content delivery network. Load the library by including the following script tag at the top of your HTML:

<html>
   <head>
       <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
   </head>

 

To configure basic authentication we prompt the web user for a username and password. The user needs to enter credentials for an account that has been assigned the “fmrest” extended privilege. Once the user submits this form, we concatenate their username and password, separated by a colon. Then we Base64 encode this concatenated string, which can be done in a web browser using the JavaScript method btoa. Here’s what this looks like:

   <form id="login">
       <label for="username">Username</label>
       <input name="username" type="text" />
       <label for="password">Password</label>
       <input name="password" type="password" />

       <input type="submit" value="Login" />
   </form>
  
   <script>
   let request;

   $("#login").submit(function(event){
       event.preventDefault();
       if(request) {
           request.abort();
       }

       let $form = $(this);

       let $inputs = $form.find("input");

       const auth = btoa($form.find('input[name="username"]').val() + ':' +  
$form.find('input[name="password"]').val());

       $inputs.prop('disabled', true);

 

With our newly encoded string, we’re ready to make our login request. If you used the Data API in FileMaker 16, the format of 17 API calls will be familiar to you. Note however that many of the URIs have changed. The URI for logging in has changed to “/fmi/data/v1/databases/filename/sessions”, for example.

Our login request looks like this:

       request = $.ajax({
           url: 'https://17.app.works/fmi/data/v1/databases/MultiUpload/sessions',
           type: 'post',
           headers: {
               'Content-Type': 'application/json',
               'Authorization': 'Basic ' + auth
           },
           data: {}
       });

 

If our login request is successful we store the access token in localStorage so we can use it in subsequent requests, then load the upload page. Otherwise we log an error message.

       request.done((response) => {
           localStorage.setItem('fmrest_token', response.response.token)
           $inputs.prop('disabled', false);
           location = 'blog-demo-upload.html'
       });

       request.fail((jqXHR, textStatus, errorThrown) => {
           console.log(errorThrown)
           $inputs.prop('disabled', false);
       })
   });
   </script>
</html>

 

Now that we have an access token saved in localStorage, we can begin making other requests to FileMaker, including uploading files to container fields.

My FileMaker demo file contains a simple table and layout called “Image”. The Image table contains 17’s default fields and two fields of my own: a container field named File and a text field named Name. We’ll upload a file by creating a new record in the Image table, obtaining the recordId in the response, then using the recordId in a call to insert the file into the container field.

To get started, let’s load jQuery and set up our form:

<html>
   <head>
       <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
   </head>

   <form id="uploadForm">
       <label for="upload">Upload</label>
       <input name="upload" type="file" />

       <label for="name">Name</label>
       <input name="name" type="text" />

       <input type="submit" value="Upload" />
   </form>

 

Next let’s get our access token from localStorage. If we find that the token does not exist, we redirect the user back to the login page.

   <script>
       const token = localStorage.getItem('fmrest_token');
       if (token === null) {
           location = 'blog-demo-login.html'
       }

 

When the user submits the form, we need to create a new record in the Image table and obtain it’s recordId from FileMaker’s response. First let’s grab what the user typed in the “Name” field:

       let request;
       $("#uploadForm").submit(function(event) {
           event.preventDefault();
           if(request) {
               request.abort();
           }

           let $form = $(this);

           let $inputs = $form.find("input");

           $inputs.prop('disabled', true);

           let name = $('#name').prop('value');

 

To create a record using the 17 Data API, we need to send a JSON object containing the fields and values we want to set. Let’s create our JSON object:

            const fieldData = {"fieldData": {"Name": name } }
            const data = JSON.stringify(fieldData)

 

With our JSON object created, we’re ready to make our request. The URI for creating records is in the format “/fmi/data/v1/databases/database-name/layouts/layout-name/records”. Notice that in our request, we include an Authorization header set to our token, with the prefix Bearer:

           request = $.ajax({
               url: 'https://17.app.works/fmi/data/v1/databases/MultiUpload/layouts/Image/records',
               type: 'post',
               headers: {
                   'Content-Type': 'application/json',
                   'Authorization': 'Bearer ' + token
               },
               data: data
           });

 

If our request succeeded, we obtain the recordId from FileMaker’s response and pass it to our insertFile function (see below). Otherwise, we display an error.

           request.done((response) => {
               insertFile(response.response.recordId)
               $inputs.prop('disabled', false);
           });

           request.fail((jqXHR, textStatus, errorThrown) => {
               console.log(errorThrown)
               $inputs.prop('disabled', false);
           })
       })

 

Our insertFile function builds a FormData object from the file upload input box:

        const insertFile = (recordId) => {
           let formData = new FormData();
           formData.append('upload', ($("#upload"))[0].files[0]);
           console.log(formData)
           event.preventDefault();
           if(request) {
               request.abort();
           }

 

Then it sends the object to FileMaker and uses recordId to identify which record it’s trying to modify:

           request = $.ajax({
               url: 'https://17.app.works/fmi/data/v1/databases/MultiUpload/layouts/Image/records/9/containers/File/1',
               type: 'post',
               headers: {
                   'Authorization': 'Bearer ' + token
               },
               data: formData,
               cache : false,
               contentType: false,
               processData: false
           });

       }

 

Knowing what we know now about uploading a single file to FileMaker, how can we change our code to allow us to upload multiple files at once? The answer lies in the HTML Drag and Drop API. This API is built into modern browsers and allows us to assign drag and drop event listeners to our DOM elements. A property of these events is dataTransfer, which is an object containing whatever files the user dropped on our DOM element.

The following chunk of code is borrowed from Mozilla’s documentation.

First let’s set up a div on the page where users can drop their files:

<div id="dropbox" style="height:200px; width:200px; background:rgba(0,0,0,0.2)">Drop files here.</div>

 

When “dropbox” hears a “drop” event, it assigns a dataTransfer object to dt. Then we select the files from dt and pass them to a handler function, handleFiles. Our handler function simply needs to iterate through our list of files and pass them off one by one to functions that call the Data API:

       const handleFiles = (files) => {
           for(i = 0; i < files.length; i++){
               createRecord(files[i], multiInsert)
           }
       }

 

Like our process when uploading a single file, we first create a record in the Image table using createRecord then call multiInsert to upload the file:

       const createRecord = (file, callback) => {

           const fieldData = {"fieldData": {"Name": file.name } }
           const data = JSON.stringify(fieldData)

           request = $.ajax({
               url: 'https://17.app.works/fmi/data/v1/databases/MultiUpload/layouts/Image/records',
               type: 'post',
               headers: {
                   'Content-Type': 'application/json',
                   'Authorization': 'Bearer ' + token
               },
               data: data
           });

           request.done((response) => {
               callback(file, response.response.recordId)
           });

           request.fail((jqXHR, textStatus, errorThrown) => {
               console.log(errorThrown)
           });

       }


       const multiInsert = (file, recordId) => {
           const formData = new FormData();
           formData.append('upload', file);
           event.preventDefault();

           request = $.ajax({
               url: 'https://17.app.works/fmi/data/v1/databases/MultiUpload/layouts/Image/records/' + recordId + '/containers/File/1',
               type: 'post',
               headers: {
                   'Authorization': 'Bearer ' + token
               },
               data: formData,
               cache : false,
               contentType: false,
               processData: false
           });
       }

 

These code snippets should hopefully get you started working with the Data API’s container features. They can be refined and built upon to do things like validation (only accept certain file types), relate an uploaded file to a record in another table, and even traverse a folder structure. If you’re interested in learning more about 17’s features, check out our other recent blog posts.


  • 1

FileMaker 17: Default Field Customization

Tags : 

With the release of FileMaker 17 comes Default Fields, and thankfully they are customizable! This will be a time saver for all of us who copy and paste the same five (or more) fields into every table in every file, all the time. It may seem like a small savings at first, but will quickly amount to a lot of time and clicks. So let’s get started!

The 5 Default Fields from FileMaker

You just created your first new table in FileMaker 17 and (bam!) there are five new fields in the table already. “That’s awesome!” you thought, which was probably followed by “But how do I customize them?”  Don’t worry we’ll cover that next, but first let’s take a look at the fields that FileMaker has already provided:

  1. PrimaryKey – Unique identifier of each record in this table
  2. CreationTimestamp – Date and time each record was created
  3. CreatedBy – Account name of the user who created each record
  4. ModificationTimestamp – Date and time each record was last modified
  5. ModifiedBy – Account name of the user who last modified each record

Although naming conventions for them vary, the fields above are standard to most developers and should be for you too. They are incredibly valuable in maintaining the integrity of your data. If you are new to FileMaker or are unsure of their use, I recommend you keep them as they will come in handy in the future.

Customization

The fields that FileMaker have included by default are a great starting point, but this new feature becomes truly powerful when we customize them. Modifying the field names to conform to your specific naming conventions, and adding your additional ‘standard’ utility fields are just a couple reasons you should take the time to customize them.

Step 1:

Download the template file called DefaultFields.xml included in this article. You can also dig into the FileMaker Advanced 17 package folder to find it. If you choose the latter, be sure to exit the application before doing so and make a separate copy of the file in a different location where you can then modify it.

Mac:
In Finder, navigate to the FileMaker Advanced 17 folder and right-click on the application, then click ‘Show Package Contents’. From there you can navigate to the following file:
Contents/Resources/en.lproj/DefaultFields.xml

Windows:
C:\Program Files\FileMaker\FileMaker Pro 17 Advanced\Extensions\English

Step 2:

Open the XML file in a text editor and start customizing!
Side note: although I couldn’t find documentation from FileMaker on the grammar required, it’s fairly easy to gauge what options are available for each field and how to modify them.

Step 3:

Move your customized file into the following directory:
Mac: Users/Shared/FileMaker/Shared/
Windows: C:\ProgramData\FileMaker\Shared\

Step 4:

Open your FileMaker solution and go to File>Manage>Database to create a new table. Your new default fields should be created automatically. That’s it!

Turn Default Fields Off

If for some reason having FileMaker’s default fields added to every new table just doesn’t work for you, you can easily turn this functionality off (and back on again when you realize how valuable they really are!).

Step 1:

Create and save a blank file called DefaultFields.xml. Any basic text editor such as TextEdit on Mac or Notepad on Windows will work fine for this task.

Step 2:

Move this file into the following directory:
Mac: Users/Shared/FileMaker/Shared/
Windows: C:\ProgramData\FileMaker\Shared\   

 

What default fields are you excited to create?

 


  • 0

FileMaker 17: Portal Excitement

Yeah, I know. How can you really be excited about something like FileMaker portals? And what is a portal anyways? Well, maybe YOU can’t get excited about them, but we at AppWorks can, and I’ll tell you why: Because portals are used all the time in FileMaker development, and there are two huge new time-saving options in the FileMaker 17 portal creation dialog box — “Show records from Current Table” and “Show records from New Add-on Table”. Each of these options on its own can save us an hour or more of development time, up front, which makes the initial setup of a new file much, much quicker, especially considering how frequently portals are used in FileMaker projects. Which means we can spend more time on the fun stuff, like improving the UI, adding features, and refining the user experience, and all for the same end cost.

For those of you not familiar with the concept of a FileMaker portal, it’s essentially a “window” into data that’s related to the screen you’re currently on. So, for example, if you’re looking at a person, you might have a portal with a list of that person’s addresses, and another portal with a list of that person’s phone numbers. The person record is in one table, and the related address and phone numbers are stored in different tables. You look through the portal “window” at the related phone and address records.
The steps to make portals work involve creating all the tables from scratch, adding all the fields to store the data, connecting them in the relationship graph, and then manually creating those portals on a screen layout. There are also scripts that have to be written to interact with the related data (add, delete, edit, etc), and UI widgets that need to be created. None of these tasks is particularly complex in and of itself, but taken together, they can add up significantly to the amount of time spent building basic functionality.

In FileMaker 17, when you go to add a portal, the first choice you are presented with is which table the portal will display. In prior versions of FileMaker you had to choose from pre-existing related tables that you had already set up. In FileMaker 17, you can choose New Add-on Table. Version 17 provides the user with a number of common table types that can be “bolted on”, like Addresses, Phones, Action Items, Attachments, Notes, etc. FileMaker 17 will then automatically create the table (with all the required fields), create a relationship to that table, and create all the basic UI widgets, field layouts, and scripting to interact with that table in a portal. This is something we FileMaker developers do on every project, multiple times, by hand. And now it takes a matter of seconds.

That. Is. Huge.

The other new portal option that makes a huge difference for us is the option to “Show records from Current Table”. This, in effect, gives us easy access to a very common UI pattern that everyone is familiar with, called “Master Detail”. It’s the “List-on-the-left, Detail-on-the-right” user interface for much of the software you use every day — Gmail, Slack, iTunes, Spotify, Photos, even websites use it. You click on an item in a list, and the details about that item show up on the right. While we could build this UI pattern from scratch in FileMaker (and frequently do), it required some special tricks to work elegantly, and still had some limitations. But with FileMaker 17, it’s trivial to create a basic setup that works just like that. And by trivial, I mean a matter of seconds again.

Easy, time-saving implementation of the most common UI patterns in custom software means we can spend more time improving our software, which is exciting for us!


  • 0

FileMaker 17: Admin API

Tags : 

If you manage multiple instances of FileMaker Server, maintenance would typically be performed by logging in to each via a web browser or running fmsadmin CLI commands. These methods become unwieldy when you need to make the same change or gather the same bit of information across several servers. A seemingly simple task now takes 30 minutes or more with multiple servers. For example, ensuring that servers have enabled the security setting “Host password-protected databases only” is a quick task for the first few servers, but surprisingly time-consuming when checking twenty.

The time-saving solution to administering a fleet of Filemaker Server instances is the Admin API. Prior to 17, the Admin API was only available in FileMaker Cloud. Now, FileMaker Server 17 running on Windows or Mac OS can be administered from any tool capable of generating HTTP requests, including curl, PHP, and Filemaker Pro Advanced. Given a list of server addresses, we can programmatically log in to each server to gather configuration information, close database files, run schedules, and more.

To start off, here is the sequence of curl commands necessary to enable the “Host password-protected databases only” setting on a single server:

Obtain a JWT token:

curl -X POST \
 https://example.com/fmi/admin/api/v1/user/login \
 -H ‘Content-Type: application/json’ \
 -d ‘{
“username”: “admin”,
“password”: “admin-password”
}’

Use the JWT token (“a-very-long-string”) to authenticate subsequent requests.

Change the security setting:

curl -X PATCH \
 https://example.com/fmi/admin/api/v1/server/config/security \
 -H ‘Authorization: Bearer a-very-long-string’ \
 -H ‘Content-Type: application/json’ \
 -d ‘{
        “requireSecureDB”: true
}’

Confirm the new security setting (optional):

curl -X GET \
 https://example.com/fmi/admin/api/v1/server/config/security \
 -H ‘Authorization: Bearer a-very-long-string’

Logout (also optional, but generally a good idea as only a few admin connections can be open at once):

curl -X POST \
 https://example.com/fmi/admin/api/v1/user/logout \
 -H ‘Authorization: Bearer a-very-long-string’ \
 -H ‘Content-Type: application/json’

To make these requests against a list of servers, you just need to programmatically set the host address (e.g. https://example.com), username, and password within each curl command. The screencap below illustrates how to achieve this using a FileMaker script. For the purposes of this blog post, I’ve hard-coded and stored these in plain text. In production you’ll want to store and retrieve credentials in a secure manner using a service like AWS Secrets Manager.

The Admin API will be a trial feature until September 2019. You can provide feedback to FileMaker here.


  • 0

FileMaker 17: Edit Grouped Objects

Tags : 

How many times have I been annoyed and delayed by having to ungroup something just to make a simple edit? Too many to count.

I often group many things together to aid in layout setup and positioning. Say you have a set of fields and objects that together make up a ‘widget’ or function (e.g. a custom calendar picker, or custom labeling for a radio button set, a set of fields for an address, etc), and you want to keep them all together in a particular arrangement. But then you might have to make a change to a font, or a hide condition, or a small tweak to the position of one item within the group. Now you can do all those adjustments without having to break the group and then re-group the objects when you are done!

There is a double whammy when there is a Hide Condition applied to a group, or a button action has been applied to non-button objects, e.g. a Text object. (To make it a button FileMaker makes it into a group, first. It’s a group of 1 object, but still a group.) In FileMaker Pro Advanced 16 you could apply a hide condition to a group, but then if you needed to edit one of the objects in the group, you had to un-group those items in order to make those edits. Breaking the group apart causes you to lose the hide condition or button definition on the group – at least FM was nice enough about it and would warn you that you were going to lose something when breaking the group. These types of groups will cause you to lose your calculation definitions as well as being slower to work with the sub-objects.

Even simple groups that don’t have an additional button or hide definitions will incur delays just because you’ll have to un-group and then re-group the items. (Minor, yes, but still delays – the keyboard shortcuts here help a lot, but even then it’s a delay.) Now in FileMaker Pro Advanced 17 you don’t have to break the group in order to edit items in that group, thus you won’t lose the hide condition. To be clear, in 17 if you break the group you WILL still lose the hide condition, you just won’t have to break the group nearly as often.

The user experience for this new feature is pretty darn intuitive and straightforward. In FileMaker Pro Advanced 17 when you first click on a group, it will highlight the group in the normal blue outline with drag handles – the same as it does now in FileMaker Pro Advanced 16.

When you click a second time on an object in that same group a dashed box shows up around the group as a whole, and the individual object you clicked on will have the typical blue highlight border with the drag handles:

This combination of borders gives you clear indication that you are still working in a group, but that you are editing a single object of that group. Once you have a single object of the group as your in-focus object, you can edit any of the definitions about that object – font, padding, size, position, etc. This can be done by dragging an object handle, using arrow keys (for movements), or making changes in the Inspector.

Another nice touch is that the dynamic guides are specific to whichever level of editing you are doing. If you drag an entire group the dynamic guides will display relative to the entire group.

With this new feature when you move a single object within a group with the mouse or arrow keys, the dynamic guides will show up with respect to that single object you are editing.

Here I moved the “Country” field down to create empty space and moved “Postal Code” over into the empty space. Notice that the group-bounding box increased in size – handily, the outer/group dashed-box dynamically changes size if you happen to move an object that defines one of the outer bounds of the group (the “Country” field in this case).

It’s really just like you are normally editing the single object on the layout, with the addition of the dashed box around the group. And FileMaker has made this single-object editing very simple to access – it doesn’t get in the way of attempting to edit that single object: If you double click an item that’s part of a group, you will still immediately start editing that item – the same as if it hadn’t been a part of a group. Thus, you can double click a text object and it will insert the cursor into that text object and allow you to start editing, or if you double click a field it will display the field picker dialog. You don’t have an extra click just because it’s in the group.

So make your work more efficient and less copy/paste happy by utilizing the new edit-within-group feature of FileMaker Pro Advanced 17. It will save you time and aggravation.


  • 0

FileMaker 17: New and Improved Licensing Programs

Tags : 

As a certified FileMaker license reseller, AppWorks is jumping for joy with the new and improved FileMaker License programs! After years of competing acronyms such as AFLT, FLT, AVLA, VLA, ASLA, SBA, etc., FileMaker Inc. has simplified the programs to: User Licensing, Concurrent Connection Licensing and Site Licensing. *phew*

Additionally, each program is available for annual contracts or perpetual use, and all of them come with a robust list of features.

Even better news (yes, it’s possible), the new licensing contracts will have one license key to manage the installation of all new products. Plus, it won’t change from release to release!

What does all products mean? With the release of FileMaker 17, each of the license contract types includes the entire platform of products. Let’s break down the programs and what products come with each:

User Licensing

According to FileMaker, Inc., “A user is a unique person who will need any type of access to the FileMaker Platform. A user can create or use apps to view, enter or modify data with iPad, iPhone, Mac, Windows or the web.” Under this new contract, each of your users will have access to all of the following:

  • FileMaker Pro Advanced
  • FileMaker Go
  • FileMaker WebDirect
  • FileMaker Data API
  • 3 FileMaker Server installations (one for dev, one for production and one for FM Cloud)

Perhaps the best news of all, with the release of FileMaker 17, purchases are based on the number of users after the initial minimum of 5 users. You can add new users as needed in increments of one!

For example, if your company had 8 FileMaker users, you’ve likely purchased AFLT or AVLA for 10 users for FileMaker Pro. But now your company has grown to 11. Rather than purchasing another bundle of 5 users for just one more person, you can renew under the User Licensing for 11 users.

Concurrent Connection Licensing

This is the right choice for you if the majority of your users are anonymous or occasional users who typically connect via the web. Again, under this new contract, each of your users will have access to all of the following:

  • FileMaker Pro Advanced
  • FileMaker Go
  • FileMaker WebDirect
  • FileMaker Data API
  • 1 FileMaker Server installation

For example, if your company had 12 employees in the office who logged into FileMaker Pro, 7 of whom would also need to log into FileMaker WebDirect, you’ve likely purchased a concurrent license for 5 connections. Now, you can renew under the Concurrent Connection Licensing for 7 connections and take advantage of all of the above. If you’re an existing customer with a concurrent connection contract, you’ll transition to the New Concurrent Connections licensing with the equivalent number of connections as you obtained in FileMaker 16, plus one FileMaker Server.

Site Licensing

This program is based on headcount in the organization, rather than users, starting at 25 employees. This is the right choice for you if you have an integrated WebDirect component into your solution for anonymous users that don’t install or use FileMaker Pro Advanced, but need access to read-only data, or entering data for a singular use.

Under this new contract, this program bundles:

  • FileMaker Servers*
  • FileMaker Pro Advanced
  • FileMaker Go
  • FileMaker WebDirect
  • FileMaker Data API

*The number of server installations matches the headcount of your company.

For example, if your company had 27 employees, but had an integrated WebDirect component into your solution, you’ve likely purchased a site license for 30 users and possibly had to purchase at least one FileMaker Pro Advanced license. Now, you can purchase a Site Licensing contract for exactly 27 users, and all users get to take advantage of the above. Reminder: anonymous users may access FileMaker WebDirect, but may not install or use FileMaker Pro Advanced.

Here’s what to expect with your new and improved products:

FileMaker Pro Advanced is the only option for desktop, and this means everyone now has access to the advanced features. POWER TO THE PEOPLE!  No need to worry about a FileMaker development takeover, you have the ability to turn the advanced features off for specific users.

FileMaker Data API

The release of FileMaker 16 provided the ability to connect with various APIs. Now with FileMaker 17, The server receives unlimited data transfers with inbound API Calls. Outbound API Calls use gigabytes from the shared annual data transfer cache. These gigabytes are metered at the server level. Below is the math behind the total mount of shared annual data transfers you have for your yearly contract.

 

Number of

users/concurrencies/seats

x

2 GB

per month

x 12

months

=

Shared annual

data transfer

For example, your company has a 5 user licenses your API data transfer total would be:
5 x 2 x 2 = 120GB for the year. If you need more than this, you can purchase additional API connections.

Still confused? Don’t worry – it’s a lot to take in all at once. AppWorks is here to answer any and all of your FileMaker licensing questions. Our staff are trained to help navigate you and your team through this transition and as always, we’re here for any of your training and development needs as well. Please call Shawn at 503.616.9422 x4 to learn more, or send her an email: shawn@app.works.


  • 0

Women of Pause on Error

Tags : 

Street Jazz in New Orleans

This weekend the women of AppWorks will make their way to the Women of FileMaker-hosted Pause on Error in New Orleans. Our very own Kimberly Carlson has been chosen to speak this year. Be sure to check out her Tuesday afternoon session “Employee and Subcontractor Management.” Bring any “real-life” scenarios you’d like to throw her way.

What sessions are you excited about? See the full schedule.

Not able to make it to New Orleans? Join our Pause on Error summary and discussion FMPDX Meetup on May 16 during your lunch hour!


  • 2

Render WebDirect in an Iframe

Tags : 

Is there a feature you want to add to your website that you could quickly implement using FileMaker but not using the language your site’s programmed in? You could send users to a WebDirect app, but replicating all of your website’s design elements in FileMaker can be time consuming. Plus, if your site’s style is not carefully carried over to WebDirect, you risk weakening your brand’s cohesiveness in the eyes of users. What if you could create the feature in FileMaker and drop it into a page of your website as a component, letting your website’s theme take care of unrelated components like headers, navigation bars, and footers?

The HTML Iframe element loads another website or web resource as a child element of the surrounding page. They’re useful in cases when there’s an external resource you’d like to serve to visitors of your website, but you do not want to send visitors to a whole new site. Most if not all modern browsers support Iframes, and you can even include multiple Iframe elements on a single page. This post describes how to embed a FileMaker WebDirect solution within a website using an Iframe element.

Before we get started it may be helpful to see an example of a framed WebDirect app in production. If you’ve visited our Downloads page recently, you already have. That page uses a framed WebDirect app to collect contact details before providing access to file downloads. The parent elements (header, navigation bar, footer, etc.) are the exact same as other sections of our website. Changes we make to the WebDirect app via FileMaker Pro get pushed to the framed element, and changes we make to our website’s template get pushed to the parent elements.

To accomplish this we had to make a few server-side configuration changes. By default, FileMaker Server’s HTTP response headers only allow pages to load WebDirect content within an Iframe if those pages have the same origin. According to Mozilla, “pages have the same origin if the protocol, port (if one is specified), and host are the same for both pages.” For example https://app.works/downloads/ and https://app.works/project-give2017/ have the same origin, but https://app.works/blog and https://differenthost.app.works do not. This is the default configuration because it prevents other sites from surreptitiously framing your FileMaker WebDirect solution. Without the right response headers in place, your app would be vulnerable to attacks like Cross-Frame Scripting.

Luckily, you can maintain your site’s security and take advantage of Iframes by using Content-Security-Policy (CSP) and X-Frame-Options response headers. These headers tell web browsers whether or not to load a page within an Iframe. CSP, the newer and more robust of the two headers, lets you specify which sources to trust for specific resource types using what are called directives. For example, you can use the “font-src” directive to define https://fonts.google.com/ as the only valid source of fonts for your page. In the case of framing WebDirect, the CSP directive we care about is “frame-ancestors”, which lets us define who can frame our app.

X-Frame-Options has been deprecated in favor of CSP, however it still needs to be included in order to support certain browsers including Internet Explorer. If your web server’s response headers include CSP but not X-Frame-Options, browsers that do not support CSP will assume you have not set any restrictions on who can frame your site. Unfortunately, X-Frame-Options only provides three options: do not allow framing at all, allow same origin framing, or allow from one specific origin (single frame ancestor).

Now that the details are out the way, here’s how you implement these response headers. In the following steps I’ll assume you’re running FileMaker Server on Windows.

  1. Open File Explorer and go to this folder: C:\Program Files\FileMaker\FileMaker Server\HTTPServer\conf 
  2. Copy a backup of the file C:\Program Files\FileMaker\FileMaker Server\HTTPServer\conf\web.config to another folder like the Desktop. If you make an irreversible edit to the web.config file, you can simply restore your backup copy.
  3. Run your preferred text editor as administrator and open the web.config file.
  4. Scroll to the bottom of the file. Add or edit the <customHeaders> element to include the Content-Security-Policy and and X-Frame-Options headers.
  5. Save and exit the web.config file.

One last change is needed to ensure your WebDirect app renders within an Iframe. In Safari 11, Apple enables the “Prevent cross-site tracking” privacy preference by default. This preference prevents cookies from being set across domains if the user has not already visited the domain setting the cookie. In other words, if https://your-parent-site.com frames https://your-webdirect-app.com and a user at https://your-parent-site.com has never visited https://your-webdirect-app.com, Safari will not allow https://your-webdirect-app.com to set cookies as a frame element.

To workaround this setting, a few lines of JavaScript code (courtesy of Github user vitr) at both the parent site and the framed site are necessary. First, add this code to the parent site’s html within a script tag:

// Safari 11.0 cross-site tracking support.
// If the user is browsing in a Safari Private Window,
// browse to the framed site. The framed site should then
// set a cookie and navigate back to the original site.
// Reference: https://github.com/vitr/safari-cookie-in-iframe
var is_safari = navigator.userAgent.indexOf("Safari") > -1;
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}
if (is_safari) {
if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
// JavaScript at https://your-webdirect-app.com/cookie.html sets a cookie and
// navigates back to https://your-parent-site.com.
window.location.replace("https://your-webdirect-app.com/cookie.html");
}
}

Second, create a file called “cookie.html” and save it within the C:\Program Files\FileMaker\FileMaker Server\HTTPServer directory. Then add these lines to cookie.html within a script tag:

// Reference: https://github.com/vitr/safari-cookie-in-iframe
var is_safari = navigator.userAgent.indexOf("Safari") > -1;
// Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
if ((is_chrome) && (is_safari)) {is_safari = false;}
if (is_safari) {
// See if cookie exists (https://stackoverflow.com/a/25617724/1502448)
if (!document.cookie.match(/^(.*;)?\s*fixed\s*=\s*[^;]+(.*)?$/)) {
// Set cookie to maximum (https://stackoverflow.com/a/33106316/1502448)
document.cookie = 'fixed=fixed; expires=Tue, 19 Jan 2038 03:14:07 UTC; path=/';
window.location.replace("https://your-parent-site.com");
}
}

With these changes applied, your framed WebDirect app should render correctly in all modern browsers while still being secured against unwanted framing.


  • 0

DevCon 2018 Details Revealed

Tags : 

FileMaker Developer Conference 2018 (DevCon 2018) has been officially announced! See below for a snippet of the press release from FileMaker. More information is available on FileMaker’s website, including a schedule of events, session topics, and recommended tracks. We’ll see you in Texas!

August 6-9, 2018 | Gaylord Texan Resort | Dallas, Texas

Join 1500 developers, just like you, at the FileMaker Developer Conference 2018.

DevCon 2018 is the must-attend event to learn everything and anything about FileMaker custom app development:

Expand
Broaden your development skill set with more than 80 sessions to choose from. Attend beginner, intermediate, advanced, business, and special focus sessions.

Innovate
Discover how to build more innovative FileMaker apps using technologies such as REST, JSON, cURL, SSL, JavaScript, SQL,OAuth, AI, iOS, and more.

Explore
See how to plan and develop FileMaker projects that will differentiate your business from the competition and maximize ROI.


  • 0

Women of FileMaker DevCon Scholarships

Tags : 

Are you interested in an in-depth look at FileMaker 17’s features? How about bolstering your understanding of cryptography and its uses in FileMaker? Do you want to adopt an Agile approach to your next project but don’t know where to start? These topics plus many more will be covered this August 6 through August 9 at FileMaker Developer Conference (DevCon) 2018 in Dallas, Texas.

If you’re a woman considering attending for the first time, you may be able to have the conference registration fee covered thanks to the Women of FileMaker community group.

The Women of FileMaker community has been providing scholarships to first-time attendees of DevCon since 2016. This year, scholarship recipients will have DevCon’s pre-paid registration cost covered and be assigned a conference mentor. They’ll also be introduced at the twelfth official Women of FileMaker luncheon.

Scholarship hopefuls can apply now by completing a short form and submitting an essay. The application deadline is Friday, March 16.

Funding for the scholarship and conference mentors are provided by the FileMaker community. If you’d like to contribute to the scholarship fund, make a donation via the GoFundMe page. If you’re interested in becoming a mentor, visit the Women of FileMaker website. Our very own Kimberly Carlson has been a mentor since its inception and would be happy to answer any questions you may have about the program.

And don’t forget to say hi to those of us attending this summer from AppWorks!