« MBS FileMaker Advent … | Home | ZUGFeRD Update »

MBS FileMaker Advent calendar - Door 3 - Drag & Drop

candy cane Monkeybread Monkey as an elf candy cane
Door 3 - Drag & Drop

Welcome to our third door in this advent calendar. Today we would like to start expanding our database. We want to have the possibility to store additional documents for the giftees. For this purpose, we will create a table with the name Files. This table should store the name of the file, the type and the file itself as a container value. In addition, we also need a field with the Foreigen Key here, because we want to establish a relationship so that the files can also be assigned to the giftee.

Now we have to think about how we want to bring these files into our database. We want to use drag and drop to do this. So we build an area where we can drag the desired file and the type and name are then automatically read out and the file and the remaining information are then stored in a record in the new table. This data record should be related to the giftee that is currently displayed.

We can create drag and drop areas with the MBS FileMaker Plugin. To avoid wasting useful space for a drag and drop field on our layout, we would like to place this drag and drop field as an overlay, i.e. a freely movable area on our layout that can be activated and deactivated by clicking a button. To do this, we first need to create an overlay and then assign drag and drop functionality to it.

So let's start with the overlay first. To do this, we have the functions from the Overlay section. First, we create a new overlay with the MBS function Overlay.Create. This function returns a reference. We also need to specify this reference in the other functions so that we know exactly which overlay in our project the functions should be applied to. Next, we want to determine the size and starting position of our overlay. To do this, we use the Overlay.SetFrame function and, as already mentioned, specify the overlay reference, the position with X and Y coordinates and the height and width of the overlay in pixels. So we want the top left corner of our overlay to be 30 pixels away from the right and top edge. In addition, our overlay should be square and 200 x 200 pixels in size. Our function call looks like this:

Set Variable [ $r ; Value: MBS("Overlay.SetFrame"; $overlay; 30; 30; 200; 200) ]

Now we want to create a background image for the overlay so that we can see it immediately. To do this, we use the Overlay.SetImage function. Here, too, we first need the reference and then the background image as a container. Of course, we can now place the image in a container on our layout, but we don't want to do that. For this reason, we create a table that is not related to the other tables and contains all the information we need to organize our database in a single data record. In our example, I will call this table Data. This table initially only gets the container field for the overlay from us and in the resulting layout we create the first data record and drag our desired background image into the container.

But now we have no access to this table from the Giftee table. The solution to this problem is, to write a script that stores the data from the Data table in global variables. Global variables are assigned a double $$ sign and are visible to the user in our entire FileMaker database. When we close FileMaker, these are released again. So we create a script WriteData. In order to have access to the data, we first go to the Data layout with the Go to Layout command. There we call up the first data record, which contains our data. Now we write the image stored there to the global variable $$Overlay_Image. Now we go back to the Giftee layout with Go to Layout.
This is what the complete script looks like:

Go to Layout [ “Data” (Data) ; Animation: None ]
Go to Record/Request/Page [ First ]
Set Variable [ $$Overlay_Image ; Value: Data::Image_Overlay ]
Go to Layout [ “giftee” (Giftee) ; Animation: None ]

This script for writing the data must be called once. It makes sense to do this automatically once when opening. Script triggers are available that automatically call a script when a certain action occurs in FileMaker. Here we would like to use the script trigger OnFirstWindowOpen. This calls a script as soon as the first window of our solution has been opened, i.e. we have started it. The settings for this script trigger can be found under File > File Options under the Script Trigger tab. Here you can select it and pass the script. As we have already opened FileMaker and therefore also the first window, we let the script run once.

Now, after this short excursion, we come back to our Overlay.SetImage function. We first specify the reference of our overlay in this function and then specify the background as the container value (our global variable). So that the overlay is now also displayed, we set the visibility to 1 in the Overlay.SetVisible function.

Now we can start our script once and see if it works. Our overlay is displayed, but cannot yet be moved on the screen and we are beginning to wonder how we can get it out of there again. Because even closing FileMaker has no effect. So we have to find another solution. And for that we need another script. On the one hand, we can simply hide the overlay by setting the visibility in the already known function Overlay.SetVisible to 0, but then our overlay is still present in the working memory and could also be displayed again by setting this function to 1 again, but if we want to remove it completely, we call one of the release functions. There are two available for this. One is the Overlay.Release function with which we can remove a specific overlay by specifying the reference and the other is Overlay.ReleaseAll with which all overlays are removed. In this example, we use the Overlay.ReleaseAll function.

Set Variable [ $r ; Value: MBS("Overlay.ReleaseAll") ]

Now we want to change our overlay script so that we can also move the overlay. To do this, we call the function Overlay.SetMovableByWindowBackground, pass the reference and set the value to 1. Now the overlay can also be moved. At the moment, it is not yet useful to us because it cannot yet receive files. For this we now need the functions for drag and drop from the plugin. We want to create a drop area now. To make the overlay our drop area, we use the DragDrop.AttachToOverlay function and enter the reference number of our overlay here. This function returns the reference number of the drag and drop area. We save this in a global variable (double $$ sign), as we need this reference in another script and local variables (single $ sign) are now visible in the script in which they were used for the first time. We now set up a script which is to be called when a file is dragged onto the drag and drop area. We assign this script to the area with DragDrop.SetDragActionHandler. In the parameters we pass the reference of the drag and drop area, as well as the FM file in which the script is defined (in our case the same file) and the name of the script we want to call. Our entire script overlay now looks like this:

Set Variable [ $overlay ; Value: MBS("Overlay.Create") ]
Set Variable [ $r ; Value: MBS("Overlay.SetFrame"; $overlay; 30; 30; 200; 200) ]
Set Variable [ $r ; Value: MBS("Overlay.SetImage"; $overlay; $$Overlay_Image) ]
Set Variable [ $r ; Value: MBS("Overlay.SetVisible"; $overlay; 1) ]
Set Variable [ $r ; Value: MBS("Overlay.SetMovableByWindowBackground"; $overlay; 1) ]
Set Variable [ $$DragDrop ; Value: MBS("DragDrop.AttachToOverlay"; $overlay) ]
Set Variable [ $r ; Value: MBS("DragDrop.SetDragActionHandler"; $$DragDrop; Get(FileName); "DragDrop") ]

Now we turn to the DragDrop script that is called when one or more files have been dragged onto the area. First we determine how many files arrive via the drag and drop area, here we also pass the reference of the DragDrop area which is in a global variable.

Nice to know:
A loop occurs quite often in programming. Here, a part of the program is executed repeatedly until a certain condition is met. In our case, we increment a variable. Once this has reached a certain value, we exit the loop again.

Then we create a loop that runs through the individual files. First we use DragDrop.GetPath to get the path to the file we are currently looking at. With Files.FileExists we check whether this file really exists. If this file exists, we use the functions Files.FileName, Files.FileExtension and Files.ReadFile to read the name, type and the file itself using the path. With Files.ReadFile, in addition to the path, we also specify the mode in which the file is read. For example, we can first decode a file Base64 in order to be able to read it. In this case, we simply specify auto so that the file is processed automatically. In the next step, we check whether there was an error with this function, as otherwise there would be no valid file in the container that we could add to the database. As the called function is an MBS function, we can query this with MBS("IsError"). This function returns true if there was an error in the last MBS call. Otherwise it returns false. If no error has occurred, we first save the primary key of our currently displayed Giftee in a variable. This is necessary because we want to open a new window in the next step and transfer the value from our original window to the new one. The new window is named "NewFile" and displays the layout files. We now create a new record in this window with the correct layout. Here we first transfer the saved Primary Key as Foreigen Key so that the data record in the Files table is related to the data record in Giftee. Now we also set the just determined values of name, type and the file itself in the record. After we have set everything, we want to close the window again. In the Close script step, you have several options for determining the window to be closed. Here I advise you to always close the window using the name of the window so that the wrong window is not closed by mistake, e.g. because there was an error in the script and the window that is closed is not the active window. This is what our script looks like now:

Set Variable [ $Count ; Value: MBS("DragDrop.GetPathCount"; $$DragDrop) ]
Set Variable [ $i ; Value: 0 ]
Loop [ Flush: Always ]
	Set Variable [ $FilePath ; Value: MBS("DragDrop.GetPath"; $$DragDrop; $i) ]
	If [ MBS("Files.FileExists"; $FilePath) ]
		Set Variable [ $Name ; Value: MBS("Files.FileName"; $FilePath) ]
		Set Variable [ $Typ ; Value: MBS("Files.FileExtension"; $FilePath) ]
		Set Variable [ $File ; Value: MBS("Files.ReadFile"; $FilePath; "auto") ]
		If [ MBS("IsError") ≠ True ]
			Set Variable [ $PK ; Value: Giftee::PrimaryKey ]
			New Window [ Style: Document ; Name: "NewFile" ; Using layout: “Files” (Files) ]
			New Record/Request
			Set Field [ Files::ForeignKey ; $PK ]
			Set Field [ Files::File_Name ; $Name ]
			Set Field [ Files::File_Typ ; $Typ ]
			Set Field [ Files::File ; $File ]
			Close Window [ Name: "NewFile" ; Current file ]
		End If
	End If
	Set Variable [ $i ; Value: $i+1 ]
	Exit Loop If [ $i ≥ $Count ]
End Loop

If you now start the script overlay, the overlay is displayed in FileMaker and we can drag files onto the overlay. I have added a portal to my layout as shown in door one which displays the data of files. Above the portal I added a button that executes the script overlay and a button that hides the overlay again.

If the files do not appear after you have dragged them onto the overlay, please do not panic right away. It may be that everything is OK in your programming, but you are still missing a relevant setting. The plugin calls a script as soon as we drag a file onto the overlay. However, we must first allow the plugin to do this in FileMaker. For this reason, we go to the security settings File>Manage>Security and select a profile here. We click on the gray pencil next to the profile name in the bar to edit the privacy sets.


In this list we select the Privilage Set fmplugin and activate it.

If you now exit the dialog and show the layout again, the files will be added to the database.

That's it for today and I hope to see you again tomorrow for the next door.


Monkeybread Software Logo with Monkey with Santa hat
2 👈 3 of 24 👉 4
Claris FileMaker Plugin
03 12 24 - 07:28