Platforms to show: All Mac Windows Linux Cross-Platform
/FMAPI/FileMaker Data API Test
Required plugins for this example: MBS FMAPI Plugin, MBS Main Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /FMAPI/FileMaker Data API Test
This example is the version from Fri, 25th Jan 2024.
Project "FileMaker Data API Test.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Open()
Dim l As New LoginWindow
l.show
End EventHandler
End Class
Class MainWindow Inherits Window
Control GetProductInfoButton Inherits PushButton
ControlInstance GetProductInfoButton Inherits PushButton
EventHandler Sub Action()
response = connection.ProductInfo
UpdateResponse
// {"response":{"productInfo":{"name":"FileMaker Data API Engine","buildDate":"07/28/2020","version":"19.1.1.54","dateFormat":"MM/dd/yyyy","timeFormat":"HH:mm:ss","timeStampFormat":"MM/dd/yyyy HH:mm:ss"}},"messages":[{"code":"0","message":"OK"}]}
If response.ErrorCode = 0 Then
// show version number in dialog box
Dim result As Dictionary = response.Result
Dim productInfo As Dictionary = result.value("productInfo")
If productInfo <> Nil Then
Dim version As String = productInfo.Value("version")
MsgBox version
End If
End If
End EventHandler
End Control
Control ResultTextArea Inherits TextArea
ControlInstance ResultTextArea Inherits TextArea
End Control
Control DebugTextArea Inherits TextArea
ControlInstance DebugTextArea Inherits TextArea
End Control
Control ResultField Inherits TextField
ControlInstance ResultField Inherits TextField
End Control
Control DatabaseNamesButton Inherits PushButton
ControlInstance DatabaseNamesButton Inherits PushButton
EventHandler Sub Action()
response = connection.DatabaseNames
UpdateResponse
// {"response":{"databases":[{"name":"Contacts"}]},"messages":[{"code":"0","message":"OK"}]}
If response.ErrorCode = 0 Then
// show names of databases in dialog box
Dim result As Dictionary = response.Result
dim Names() as string
Dim databases() As Variant = result.Value("databases")
For Each entry As Dictionary In databases
Dim name As String = entry.Value("name")
Names.Append name
Next
MsgBox "Database Names" + EndOfLine + EndOfLine + Join(names, EndOfLine)
End If
End EventHandler
End Control
Control LayoutNamesButton Inherits PushButton
ControlInstance LayoutNamesButton Inherits PushButton
EventHandler Sub Action()
response = connection.LayoutNames
UpdateResponse
// {"response":{"layouts":[{"name":"Contacts","table":""},{"name":"Contacts Details","table":""}]},"messages":[{"code":"0","message":"OK"}]}
If response.ErrorCode = 0 Then
LayoutMenu.DeleteAllRows
Dim result As Dictionary = response.Result
Dim layouts() As Variant = result.Value("layouts")
Dim Names() As String
WalkLayouts Layouts, Names
'MsgBox "Layout Names" + EndOfLine + EndOfLine + Join(names, EndOfLine)
End If
End EventHandler
End Control
Control ScriptNamesButton Inherits PushButton
ControlInstance ScriptNamesButton Inherits PushButton
EventHandler Sub Action()
response = connection.ScriptNames
UpdateResponse
If response.ErrorCode = 0 Then
ScriptMenu.DeleteAllRows
Dim result As Dictionary = response.Result
Dim scripts() As Variant = result.Value("scripts")
Dim Names() As String
WalkScripts scripts, Names, ""
'MsgBox "Script Names" + EndOfLine + EndOfLine + Join(names, EndOfLine)
End If
End EventHandler
End Control
Control LayoutMenu Inherits PopupMenu
ControlInstance LayoutMenu Inherits PopupMenu
EventHandler Sub Change()
UpdateButtons
End EventHandler
End Control
Control LayoutMetadataButton Inherits PushButton
ControlInstance LayoutMetadataButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
response = connection.LayoutMetadata("")
UpdateResponse
// {"response":{"fieldMetaData":[{"name":"SomeText","type":"normal","displayType":"editText","result":"text","global":false,"autoEnter":false,"fourDigitYear":false,"maxRepeat":1,"maxCharacters":0,"notEmpty":false,"numeric":false,"timeOfDay":false,"repetitionStart":1,"repetitionEnd":1},...
If response.ErrorCode = 0 Then
Dim result As Dictionary = response.Result
Dim fields() As Variant = result.value("fieldMetaData")
Dim Names() As String
For Each entry As Dictionary In fields
Dim name As String = entry.Value("name")
Names.Append name
Next
MsgBox "Field Names" + EndOfLine + EndOfLine + Join(names, EndOfLine)
End If
End EventHandler
End Control
Control GetRecordsButton Inherits PushButton
ControlInstance GetRecordsButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
// doesn't work?
'request.sort = "[{""fieldName"":""SomeNumber"",""sortOrder"":""descent""}]"
response = connection.GetRecords(request)
UpdateResponse
ShowRecords
End EventHandler
End Control
Control RecordIDField Inherits TextField
ControlInstance RecordIDField Inherits TextField
EventHandler Sub TextChange()
UpdateButtons
End EventHandler
End Control
Control GetRecordButton Inherits PushButton
ControlInstance GetRecordButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
request.sort = "SomeText"
response = connection.GetRecord(request, RecordIDField.Text.Trim)
UpdateResponse
ShowRecords
End EventHandler
End Control
Control ScriptMenu Inherits PopupMenu
ControlInstance ScriptMenu Inherits PopupMenu
EventHandler Sub Change()
UpdateButtons
End EventHandler
End Control
Control ExecuteScriptButton Inherits PushButton
ControlInstance ExecuteScriptButton Inherits PushButton
EventHandler Sub Action()
connection.Layout = LayoutMenu.text
Dim scriptName As String = ScriptMenu.Text
response = connection.ExecuteScript(scriptName, "TestParam")
UpdateResponse
End EventHandler
End Control
Control DuplicateRecordButton Inherits PushButton
ControlInstance DuplicateRecordButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
response = connection.DuplicateRecord(request, RecordIDField.Text.Trim)
UpdateResponse
End EventHandler
End Control
Control SetGlobalFieldsButton Inherits PushButton
ControlInstance SetGlobalFieldsButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
Dim dic As New Dictionary
dim now as new date
// you may need to create such a field!
dic.Value("Contacts::MyGlobalField") = "Hello World "+now.ShortTime
response = connection.SetGlobalFields(dic)
UpdateResponse
End EventHandler
End Control
Control CreateRecordButton Inherits PushButton
ControlInstance CreateRecordButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
dim fieldData as new Dictionary
fieldData.Value("First Name") = "Joe"
fieldData.Value("Last Name") = "Smith"
fieldData.Value("Title") = "Mr."
fieldData.Value("Company") = "Test Ltd."
fieldData.Value("Website") = "https://www.mbsplugins.de/filemaker"
request.fieldData = fieldData
response = connection.CreateRecord(request)
UpdateResponse
End EventHandler
End Control
Control EditRecordButton Inherits PushButton
ControlInstance EditRecordButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
dim fieldData as new Dictionary
fieldData.Value("First Name") = "Bob"
fieldData.Value("Last Name") = "Miller"
request.fieldData = fieldData
response = connection.EditRecord(request, RecordIDField.text.trim)
UpdateResponse
End EventHandler
End Control
Control UploadButton Inherits PushButton
ControlInstance UploadButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
Dim upload As New FMContainerUploadMBS
upload.ContainerFieldName = "SomeContainer"
upload.RecordId = RecordIDField.Text
upload.ModId = ModIDField.Text.trim
If Keyboard.AsyncShiftKey Then
upload.DataString = "Hello World"
upload.FileName = "Hello.txt"
Else
upload.SetPicture LogoMBS(500)
upload.FileName = "image.png"
End If
response = connection.UploadToContainerField(upload)
UpdateResponse
End EventHandler
End Control
Control ModIDField Inherits TextField
ControlInstance ModIDField Inherits TextField
EventHandler Sub TextChange()
UpdateButtons
End EventHandler
End Control
Control DeleteRecordButton Inherits PushButton
ControlInstance DeleteRecordButton Inherits PushButton
EventHandler Sub Action()
// which layout to use
connection.Layout = LayoutMenu.Text
Dim request As New FMRequestMBS
response = connection.DeleteRecord(request, RecordIDField.Text.Trim)
UpdateResponse
End EventHandler
End Control
Private Sub ShowRecords()
If response.ErrorCode = 0 Then
Dim w As New RecordsWindow
w.Setup response.Result
End If
End Sub
Sub UpdateButtons()
Dim HasLayout As Boolean = LayoutMenu.ListIndex >= 0
GetRecordsButton.Enabled = HasLayout
LayoutMetadataButton.Enabled = HasLayout
RecordIDField.Enabled = HasLayout
SetGlobalFieldsButton.Enabled = HasLayout
CreateRecordButton.Enabled = HasLayout
Dim HasRecordID As Boolean = RecordIDField.Text.Len > 0
GetRecordButton.Enabled = HasLayout And HasRecordID
DuplicateRecordButton.Enabled = HasLayout And HasRecordID
EditRecordButton.Enabled = HasLayout And HasRecordID
Dim HasScript As Boolean = ScriptMenu.ListIndex >= 0
ExecuteScriptButton.Enabled = HasScript And HasLayout
Dim HasModID As Boolean = ModIDField.Text.Len > 0
UploadButton.Enabled = HasLayout And HasRecordID And HasModID
DeleteRecordButton.Enabled = HasLayout And HasRecordID
End Sub
Sub UpdateResponse()
If response = Nil Then
ResultField.Text = "No response!"
DebugTextArea.Text = ""
ResultTextArea.Text = ""
Else
ResultField.Text = Str(response.ErrorCode)+" "+response.ErrorMessage
Dim Debug As String = response.DebugMessages
If response.ErrorCode <> 0 Then
Debug = Debug + EndOfLine + EndOfLine + response.RawResultJSON
End If
DebugTextArea.Text = ReplaceLineEndings(Debug, EndOfLine)
ResultTextArea.Text = ReplaceLineEndings(response.ResultJSON, EndOfLine)
End If
End Sub
Private Sub WalkLayouts(layouts() as Variant, names() as string)
For Each entry As Dictionary In layouts
Dim name As String = entry.Value("name")
Dim isFolder As Boolean = entry.Lookup("isFolder", False)
If isFolder Then
// look one level deep
Dim folderLayoutNames() As Variant = entry.Value("folderLayoutNames")
WalkLayouts folderLayoutNames, Names
Else
Names.Append name
LayoutMenu.AddRow name
End If
Next
End Sub
Private Sub WalkScripts(scripts() as Variant, Names() as string, Prefix as string)
For Each entry As Dictionary In scripts
Dim name As String = entry.Value("name")
Dim isFolder As Boolean = entry.Lookup("isFolder", False)
If isFolder Then
// look one level deep
Dim NewScripts() As Variant = entry.Value("folderScriptNames")
WalkScripts NewScripts, Names, Prefix + name + " > "
Else
Names.Append name
ScriptMenu.AddRow name
End If
Next
End Sub
Property connection As FMDataMBS
Property response As FMResponseMBS
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
Class LoginWindow Inherits Window
Control ServerField Inherits TextField
ControlInstance ServerField Inherits TextField
End Control
Control Label1 Inherits Label
ControlInstance Label1 Inherits Label
End Control
Control UserNameField Inherits TextField
ControlInstance UserNameField Inherits TextField
End Control
Control Label2 Inherits Label
ControlInstance Label2 Inherits Label
End Control
Control PasswordField Inherits TextField
ControlInstance PasswordField Inherits TextField
End Control
Control Label3 Inherits Label
ControlInstance Label3 Inherits Label
End Control
Control DatabaseNameField Inherits TextField
ControlInstance DatabaseNameField Inherits TextField
End Control
Control Label4 Inherits Label
ControlInstance Label4 Inherits Label
End Control
Control LoginButton Inherits PushButton
ControlInstance LoginButton Inherits PushButton
EventHandler Sub Action()
// new connection to FileMaker Server
Dim d As New FMDataMBS
'd.Version = "v2" // default is vLatest
d.Database = DatabaseNameField.Text.Trim
d.Password = PasswordField.Text.Trim
d.Username = UserNameField.Text.Trim
d.Server = ServerField.Text.trim
Dim r As FMResponseMBS = d.Login
If r = Nil Then
Break
Return
End If
// connection worked?
If r.CURLErrorCode <> 0 Then
ShowLog r
MsgBox r.CURLErrorMessage
Return
End If
Select Case r.ResponseCode
Case 200
Dim m As New MainWindow
m.connection = d
m.response = r
m.UpdateResponse
Self.close
Case 401
ShowLog r
MsgBox "Invalid credentials."
else
ShowLog r
MsgBox "ResponseCode: "+Str(r.ResponseCode)
End Select
End EventHandler
End Control
Control CancelButton Inherits PushButton
ControlInstance CancelButton Inherits PushButton
EventHandler Sub Action()
Quit
End EventHandler
End Control
Control TextLog Inherits TextArea
ControlInstance TextLog Inherits TextArea
End Control
EventHandler Sub Open()
self.Height = 200
End EventHandler
Sub ShowLog(r as FMResponseMBS)
Self.Height = 400
textlog.Text = ReplaceLineEndings(r.DebugMessages, EndOfLine)
TextLog.Visible = True
End Sub
Note "Contacts Database"
We use the english version of Contacts database in FileMaker Pro for testing.
So in FileMaker, create new database and select Contacts example.
End Class
Class RecordsWindow Inherits Window
Control List Inherits Listbox
ControlInstance List Inherits Listbox
End Control
Sub Setup(Result as Dictionary)
Dim dataInfo As Dictionary = Result.Lookup("dataInfo", Nil)
If dataInfo = Nil Then
Break
Return
End If
Dim databaseName As String = dataInfo.Value("database")
Dim layoutName As String = dataInfo.Value("layout")
Dim tableName As String = dataInfo.Value("table")
Dim totalRecordCount As Integer = dataInfo.Value("totalRecordCount")
Dim foundCount As Integer = dataInfo.Value("foundCount")
Dim returnedCount As Integer = dataInfo.Value("returnedCount")
Title = Str(returnedCount)+" of "+Str(foundCount)+" found of "+Str(totalRecordCount)+" records in "+tableName
Dim Data() As Variant = result.Lookup("data", Nil)
Dim fields() As String
For Each record As Dictionary In data
Dim recordID As String = record.Value("recordId")
Dim modId As Integer = record.Value("modId")
Dim fieldData As Dictionary = record.Value("fieldData")
Dim portalData As Dictionary = record.Value("portalData")
Dim c As Integer = fieldData.Count
If fields.Ubound < 0 Then
// first time
Dim keys() As Variant = fieldData.keys
For Each key As String In keys
fields.Append key
Next
// set listbox heading
List.ColumnCount = c
For i As Integer = 0 To c-1
List.Heading(i) = fields(i)
Next
End If
list.AddRow ""
For i As Integer = 0 To c-1
List.Cell(List.LastIndex, i) = fieldData.Value(fields(I))
Next
List.RowTag(list.LastIndex) = recordID
Next
End Sub
End Class
Sign
End Sign
End Project
See also:
The items on this page are in the following plugins: MBS FMAPI Plugin.