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.


The biggest plugin in space...