Using Carafe Bundles: Editing JSON in FileMaker

Implemented with Carafe Add-on


Introduction

JSON is an ideal standard for passing data back and forth in FileMaker, but it’s not the easiest format to read or interact with. Large amounts of data and very structured notation can lead to simple mistakes causing a multitude of problems. What if we could integrate a tool into FileMaker that can help solve these issues?

What is JSONEditor?

JSONEditor is a browser-based tool to view, edit, format, and validate JSON. It has various modes such as a tree editor, a code editor, and a plain text editor. Learn more.

JSONEditor broswer-based tool to view, edit, format, and validate JSON.
JSONEditor

What is Carafe?

In case you’re not familiar already, Carafe is a bundle format with a supporting toolchain that simplifies the process of integrating JavaScript in FileMaker. It’s completely free and open-source, and we encourage you to use and add to it! Learn more.

Carafe Add-on / Bundle Installation

To use the Carafe JSONEditor bundle, first install the bundle into your FileMaker solution using either Carafe Kitchen or the Carafe Add-on. Learn more.

If you’re already using Carafe Kitchen or Carafe Add-on, you can download the JSONEditor bundle and import it: https://carafe.fm/bundle/jsoneditor-soliant/

Alternatively, you can search for “JSONEditor” directly in the Carafe Add-on Configurator.

Search for JSONEditor directly in the Carafe Add-on Configurator
Search in the Carafe Add-on Configurator

Configuration

After installing the JSONEditor bundle, you should have sample data displaying in the web viewer. If not, please walk through the installation process again. Once you see sample data, we can begin the configuration process to bind the bundle to the specific fields and scripts in FileMaker required for our use case. To do so, we’ll need a script to marshal some JSON data from FileMaker and pass it to the bundle for display and/or editing. We can also configure other options in the bundle to change its behavior and/or call FileMaker scripts in order to get the JSON back to FileMaker to be persisted or used for anything a script needs JSON for.

Here are the JSONEditor bundle configuration options:

Option Description Default Value Type Optional
jsonValue Initial data loaded into the JSONEditor. WARNING - Omitting this value will display sample data in the editor. {} object false
options This object will be passed directly to the underlying JSONEditor package. See a couple of important options below and a link to the documentation which documents all of the possible options. {} object true
callback Name of the FileMaker script to call after a change is made and the debounce delay has passed without an additional change. The script will be called and passed a script parameter of the jsonValue as well as anything in additionalCallbackParameters. "" string true
additionalCallbackParameters Anything you want passed back to the script defined in the Callback option. {} object true
debounce Number of milliseconds to wait after a change is made and the debounce delay has passed without an additional change. 1000 int true
style Optional CSS that will be applied to the JSONEditor. "" string true

Base JSONEditor Package Options:

Package Description Default Value Type Optional
mode Set the editor mode. Available values: 'tree' (default), 'view', 'form', 'code', 'text', 'preview' "tree" string false
modes Create a box in the editor menu where the user can switch between the specified modes. Available values: see mode. Leaving this out will cause the drop-down menu not to be drawn, locking the JSONEditor in one mode. [] array false

Read more about the JSONEditor package complete documentation of all the available configuration options here. If you have any questions or would like to learn more, we encourage you to join the Carafe community here.

Example 1: Load and Save from a FileMaker field

Example Requirements:

  • OnRecordLoad script trigger, display the JSONEditor with the JSON value from a FileMaker field.
  • When the data in the web viewer is updated by the user, save the data back to the field in FileMaker.

Layout Setup:

Script Triggers tab in the Layout Setup window with
Layout Setup

Script Variables

$jsonValue: JSONEditorExample::jsonValue
$options: 
    JSONSetElement( "{}"; 
    	["mode"; "code"; JSONString];
    	["modes[0]"; "code"; JSONString];
    	["modes[1]"; "form"; JSONString];
    	["modes[2]"; "text"; JSONString];
    	["modes[3]"; "tree"; JSONString];
    	["modes[4]"; "view"; JSONString];
    	["modes[5]"; "preview"; JSONString]
    )
$callback: “Save”
$additionalCallbackParameters: 
JSONSetElement ( "" ; "id" JSONEditorExample::PrimaryKey ; JSONString )

Your script should look something like this:

Screenshot of the script variables
Script Variables

Save Script referenced in the callback option.

Screenshot of the Save Script reference in the callback option.
Save Script

Notice that line 7 goes to the web viewer by name. Be sure this matches the carafeWebViewerObjectName defined in the JSONEditor loader script.

Example 2: Adding schema validation

Additional Requirements:

  • Configure with schema to validate the JSON in the JSONEditor
  • Return a true/false flag when saving identifying the validity of the data

What is JSON Schema?

JSON schema allows you to validate the structure of your JSON data. Here’s some more info:

https://json-schema.org/understanding-json-schema/about.html#about
https://json-schema.org/understanding-json-schema/basics.html#basics

Layout Setup:

Update the OnRecordLoad trigger to call a copy of the Example 1 Loader script  that we’ll reconfigure with schema options.

Layout setup for adding schema validation
Update the OnRecordLoad trigger

Script Variables:

The only change from Example 1 is that we use the following definition for $options. Here we’re adding an additional “schema” property to the options array. This property is an object that defines the rules for schema validation. The schema shown here is taken directly from the JSONEditor examples (https://github.com/josdejong/jsoneditor/blob/develop/examples/07_json_schema_validation.html). It defines both employee and job level schema.

$options: 
JSONSetElement( "{}"; 
    ["mode"; "code"; JSONString]; // mode - initial mode of the JSONEditor
    ["modes[0]"; "code"; JSONString]; // modes - list of allowable modes
    ["modes[1]"; "form"; JSONString];
    ["modes[2]"; "text"; JSONString];
    ["modes[3]"; "tree"; JSONString];
    ["modes[4]"; "view"; JSONString];
    ["modes[5]"; "preview"; JSONString];
    ["schema.title"; "Employee"; JSONString]; // schema
    ["schema.description"; "Object containing employee details"; JSONString];
    ["schema.type"; "object"; JSONString];
    ["schema.properties.firstName.title"; "First Name"; JSONString];
    ["schema.properties.firstName.description"; "The given name."; JSONString];
    ["schema.properties.firstName.examples[0]"; "John"; JSONString];
    ["schema.properties.firstName.type"; "string"; JSONString];
    ["schema.properties.lastName.title"; "Last Name"; JSONString];
    ["schema.properties.lastName.description"; "The family name."; JSONString];
    ["schema.properties.lastName.examples[0]"; "Smith"; JSONString];
    ["schema.properties.lastName.type"; "string"; JSONString];
    ["schema.properties.gender.title"; "Gender"; JSONString];
    ["schema.properties.gender.enum[0]"; "male"; JSONString];
    ["schema.properties.gender.enum[1]"; "female"; JSONString];
    ["schema.properties.availableToHire.type"; "boolean"; JSONString];
    ["schema.properties.availableToHire.default"; False; JSONBoolean];
    ["schema.properties.age.description"; "Age in years"; JSONString];
    ["schema.properties.age.type"; "integer"; JSONString];
    ["schema.properties.age.minimum"; 0; JSONNumber];
    ["schema.properties.age.examples[0]"; 28; JSONNumber];
    ["schema.properties.age.examples[1]"; 32; JSONNumber];
    ["schema.properties.job.$ref"; "job"; JSONString];
    ["schema.required[0]"; "firstName"; JSONString];
    ["schema.required[1]"; "lastName"; JSONString];
    ["schemaRefs.job.title"; "Job description"; JSONString]; // schemaRefs - additional schema referenced from main schema
    ["schemaRefs.job.type"; "object"; JSONString];
    ["schemaRefs.job.required[0]"; "address"; JSONString];
    ["schemaRefs.job.properties.company.type"; "string"; JSONString];
    ["schemaRefs.job.properties.company.examples[0]"; "ACME"; JSONString];
    ["schemaRefs.job.properties.company.examples[1]"; "Dexter Industries"; JSONString];
    ["schemaRefs.job.properties.role.description"; "Job title."; JSONString];
    ["schemaRefs.job.properties.role.type"; "string"; JSONString];
    ["schemaRefs.job.properties.role.examples[0]"; "Human Resources Coordinator"; JSONString];
    ["schemaRefs.job.properties.role.examples[1]"; "Software Developer"; JSONString];
    ["schemaRefs.job.properties.role.default"; "Software Developer"; JSONString];
    ["schemaRefs.job.properties.address.type"; "string"; JSONString];
    ["schemaRefs.job.properties.salary.type"; "number"; JSONString];
    ["schemaRefs.job.properties.salary.minimum"; 120; JSONNumber];
    ["schemaRefs.job.properties.salary.examples[0]"; 100; JSONNumber];
    ["schemaRefs.job.properties.salary.examples[1]"; 110; JSONNumber];
    ["schemaRefs.job.properties.salary.examples[2]"; 120; JSONNumber]
)

Now that a schema is in place, you’ll notice that the JSONEditor will notify you in code mode when there are schema validation errors. When a schema is set, an additional “isValid” property will be populated in the callback parameter. This is a Boolean based on the validation of the current data with the supplied schema. If schema is not defined, isValid will be null.

Example 3: Remote schema validation

Additional Requirements:

  • Configure with remote schema to validate the JSON in the JSONEditor
  • Return isValid when saving the JSON data

JSON schemas can be shared for reuse. For example, JSON Schema Store (https://www.schemastore.org/json/) has 350 public JSON schemas available that you can use to validate your data.

One of the complications here is that schemas can reference other schemas, require multiple schemas, and can be nested. To overcome this, our Carafe bundle uses a special reference parser to gather all the dependencies from the passed schema before initializing the JSONEditor.

To point to url hosted JSON schema, simply replace the schema object with a string url to the schema definition.

Layout Setup:

Layout setup for remote schema validation
Layout setup for remove schema validation

Script Variables:

$options: 
JSONSetElement( "{}"; 
    ["mode"; "code"; JSONString]; // mode - initial mode of the JSONEditor
    ["modes[0]"; "code"; JSONString]; // modes - list of allowable modes
    ["modes[1]"; "form"; JSONString];
    ["modes[2]"; "text"; JSONString];
    ["modes[3]"; "tree"; JSONString];
    ["modes[4]"; "view"; JSONString];
    ["modes[5]"; "preview"; JSONString];
    ["schema"; "https://json.schemastore.org/geojson.json"; JSONString] // schema
)

In example three, I have changed the schema property in the Example 3 Loader script to https://json.schemastore.org/geojson.json, which is the schema definition for a geolocation. I’ve purposely created a typo on line 7. By removing the XXX, you should see the JSONEditor update in a valid state.

Screenshot of the JSONEditor
JSONEditor

Example File

Use in your own solution

The three examples we shared here should cover many of the use cases you may have for JSONEditor in your FileMaker solution. We’d love to hear what uses you have found for this new tool.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top