We’re also using Selector-Connector as the data model for the new SeedCode Complete and it is one of the primary reasons we feel Complete is working so well; seeing how Selector-Connector is letting folks extend and modify Complete also tells us this approach is being validated.
The most important thing to me about the Selector-Connector model is that the techniques themselves are not new new at all. It uses powerful, native techniques that have been around since FileMaker 7–like global keys and cross-joins–but it organizes them as a pattern that we can describe, much like we can describe the Anchor-Buoy pattern.
FileMaker Data Models: Extending Anchor-Buoy
The Selector-Connector should be seen as an extension of the currently predominant data model, Anchor-Buoy. Anchor-Buoy is arguably the most widely adopted FileMaker standard in the development community, and there are two very good reasons for that.
- It organizes the graph very clearly with a small set of rules
- It has a great name that is very visually descriptive.
We want to make sure we don’t lose either of those things if we’re going to tinker with the model. In general terms, Selector-Connector keeps the current Anchor-Buoy model but builds “on top of it.” We’re just going to “bend” its rules a little bit.
A very basic interpretation of the Anchor-Buoy rules would be:
- All layouts must reference Anchor Table Occurrences
- Interacting with Buoys is only done from the context of their Anchor
- Anchor Table Occurrences cannot be related to each other.
By sticking to these rules, the Anchor-Buoy model forces us to be aware of context and it also limits the chance of us doing an operation out of context, like picking the wrong table occurrence for a portal; very important things in FileMaker and generally these benefits have outweighed the draw-backs of Anchor-Buoy, and that’s why it’s the standard.
The Pop-Over Cometh
As I mentioned above, there’s nothing technically new to the Selector-Connector model. So what changed to start us down this road? For me, it was the introduction of the Pop-Over in FileMaker 13. Here was a great new object that would be a light weight alternative to pop-up windows and dialogs.
It would be great for picking records from a portal, and for editing and creating records. And, using the new slide panels, selecting, creating, and editing, could be done all in one place! FileMaker Inc. seemed to have a similar thing in mind as the demo files that came with 13 had a nice example of this “all in one place” behavior: bring up a pop-over with a portal and filter for the record you’re looking for. If you can’t find it, then hit new and “slide” to a new record form right in the same pop-over…very slick! We were starting to work on the new SeedCode Complete and I saw a great design pattern taking shape.
However, when I started exploring this, I realized (obviously) that these pop-overs would have to be done as single purpose objects: even though both Projects and Invoices would need to pick Contacts, I wouldn’t be able to use the same pop-over as it would be bound to the context of the Project or Invoice layout. Even if I was using a virtual list for my Contact Picker, the portals would each still need their own buoys attached to Projects and Invoices. This suddenly seemed like madness, and I was determined to find a way to copy and paste my pop-overs from Anchor to Anchor and have them work with very little modification.
If we wanted the pop-overs to work universally, then there was no way around it, we would need to have a context for them to work in, and the idea of Universal Context was born. For a long time, Todd and I were both using this description of the model as the Selector itself hadn’t taken form. Here’s a representation of our first pass.
We decided to “compromise” on the Anchor-Buoy rule of Anchors being related to each other. We still don’t want them directly related to each other, or even interacting directly with each other. However, we do want them all to be able to access the Universal Context table occurrences of Home and Virtual List Rows. This way, any Anchor layout can all use the same portal on our Pop-Over Selector. Not only can they use the same portal, but the scripts that reference the portal can also be generic: and we’re a little closer to having the portable pop-over we’re after!
What about Record Locking?
The idea of the above graph is that I can set the RowsToShowGlob global field in Home and control the contents of my virtual list (setting a list of contacts to select from, for example). But what if another user is trying to do the same thing? This isn’t a Session Model, and we don’t want to have to manage multiple records in Home to prevent record locking, so how can we get around that? It turns out that if the Home table only has global fields in it, you’ve, in essence, made it a global table that multiple people can interact with without locking. This was really a critical milestone in the process. By having a central/single TO that we could connect through, we could enforce a similar, although slightly looser, model as Anchor-Buoy.
Create From Anywhere
The model above solved my problem of being able to use a Contact Picker Pop-Over from any of my layouts, but I also wanted to be able to create new contacts right from my pop-over. Since we’ve already extended the Anchor-Buoy model for our Virtual List, we’ll extend it a little bit further and create a dedicated TO for contact creation. So now you’ll see a table occcurence called CreateContacts hanging off our Home table occurrence below.
We can create new Contacts through this relationship. If the relationship between Home and CreateContacts is a creation relationship and the ContactIdGlob in home is empty, we can create a new Contact simply by typing into a field in the CreateContacts table occurrence. The Contact id is an auto-generate field and this value for the new record will be pushed back into the global. This behavior may seem a little strange, but has existed for as long as I can remember in FileMaker and is referred to as the “pop-back” or “magic key.” For us it allows us to create a new Contact from anywhere by creating a temporary “parent” in Home, and we no longer need to go to a Contact layout to do this. We can use our Pop-Over Contact Picker on any layout to both pick and create contacts! Problem Solved and our graph is not a mess.
Soon after we got this part working, we began to realize that there was more we could do with this model. If we’re using this Universal Context to create records from anywhere, then we can also very easily use this same model to view and edit records from anywhere. Master Detail or Selection Portals are very common in FileMaker, and we soon realized that the Universal Context would work great for them.
Typically an Anchor would need two Buoys to a related table to do a proper Master Detail view. Normally we’d click on a portal row of our first Buoy to get the id of the record we clicked. We would then set that id to a global to set up a relationship to the second Buoy where we would see additional data about the selected record. With Selector-Connector we can now set that global in our central Home Table Occurrence and use the relationship to CreateContact for our detail view. This means we can get rid of that second Buoy for the detail, and more importantly, any Anchor that wants to see Contact details can use that same Table Occurrence.
This is really the birth of the Selector. The central table is now no longer called Home, but the “Selector”. The table occurrences to its right are the “Selected”, and they’re also the relationships that let us create new records. We’ve now consolidated, pickers, creation and master-detail into a single “component” of the graph instead of a bunch of similar Buoys attached to each of your Anchors.
As we started working with this new model, there was this great sense of relief that we weren’t “fighting” with FileMaker like we have in the past. Context and Layouts were still tied to the Anchors, and it was living up to the promise of being the best of both worlds! In addition, we started to see some residual benefits. For one, since most of the global keys were being moved to the Selector, we didn’t need them in actual data tables anymore. In SeedCode Complete, we were able to remove virtually all global fields from our the data tables. This keeps them much easier to work with, particularly if integrating with another data source or doing imports as you don’t need to wade through all the globals. This led to the idea of the Connector.
For me, the Connector is about modeling the graph to not just symbolize what’s a layout and what isn’t, but the different logical components of the graph. Initially we were thinking we had just two components, the Anchor-Buoy component and the Selector component, but once you adopt that model, it can be taken a little further. Really, the Selector is different than the Virtual List, so we decided to make our graph represent that. We also now have a place where we can keep indexed values available to all Anchors as well. Things like settings or graphics can also be cross-joined to our central Connector and accessed from anywhere. These things working together is the full Selector-Connector model.
In conclusion, I’d like to remind you of this great Picasso quote my mother recited to me for as long as I can remember, and how I think it applies here.
“Learn the rules like a pro, so you can break them like an artist.”
After going through this exercise, I believe that Anchor Buoy was not necessarily what the developers of the graph had in mind, but it was an absolutely critical step in our collective development. The idea of approaching something like the Selector-Connector without a complete and thorough understanding of FileMaker Context would be daunting and probably fruitless. The only reason we can use, or even talk about, a model like this is because of what Anchor-Buoy has taught us, and I want to re-emphasize the idea that the Selector-Connector (as I see it) is an extension and/or continuation of Anchor-Buoy. We’ve worked hard to learn and honor its rules, so we might be ready for a little artistry.