Goya Blog

Conditional Formatting in BaseElements

This is the first of a series of posts where I'm going to be highlighting new features and functionality in the upcoming BaseElements 3. Where possible I'll also reveal how we've done various things to hopefully give you some ideas of how to use these things in your own solutions.

---

One of the issues in reporting on all of the detail of any FileMaker solution is how to show all of the detail in a way that makes it clear and easy to find the information you need. A field or a layout object has so much meta data available about it and showing that level of detail for every item takes some work. Recent versions of FileMaker have added conditional formatting, so we've taken advantage of that to make some of our layouts cleaner and clearer.

For example, the fields layout has lots of details to cover all of the various permutations of field types and settings. This is a screenshot from version 2 :

Screen shot 2010-07-02 at 1.37.57 PM.png

The Setup and Detail tabs contain information about the field itself, with the Auto Enter and Validation on the Details tab. Plus you have the "Items Used" and then another tab for every place this field is used. In a perfect world ( or maybe in FileMaker Pro 15 ) we'd have dynamic layout objects, so the tabs would hide if they're not in use. Seeing as we don't have that, I've instead reverted to having tabs and objects appear to fade out when not in use. See this screenshot of a different field in BE 3 :

Screen shot 2010-07-02 at 1.42.53 PM.png

You can easily and quickly tell which tabs are required and which aren't. So this field doesn't have a calculation or use Auto Enter or Validation options. Plus it's not using any items, nor is it used in any menus or FileReferences. Just a simple change ( and lots of time consuming adjustments to objects), but it makes for a much simpler view.

Plus this meant it no longer made sense to show the counts of each number of related objects. They were in place as a sort of quick reference to the actual items. Removing them makes the layouts much clearer. We've also made errors more visible using the same technique :

Screen shot 2010-07-02 at 1.49.19 PM.png

So in that example, not only is there Auto Enter details for this field, but there's something broken there. A quick look at the tab will reveal what exactly.

Normal tabs don't allow this sort of customisation, every tab is the same colour and text, and changing one alters all of them. What we've done instead is use fixed width tabs and put global fields over the top. We were using global fields anyway so that we can have multiple languages so we already have the fields there to be able to customise them. To make it easier we position the fields just slightly above the top of the tab, as you can see in this screenshot :

Screen shot 2010-07-02 at 1.50.44 PM.png

This means that the fields are actually outside the tabs, so we only need one text object for each tab, not one whole set for every tab.

This isn't difficult to do, but in BE there are lots of tabs, and each one has one or more conditional formatting options, each with a different calculation, so it was a time consuming change.

BaseElements 3 Beta

I've uploaded a beta version of BaseElements 3. This first release is Mac only while I sort out some issues with the plugin on windows. Hopefully that should only be a day or two.

Some new features :

  • FMP 11 compatible.
  • FMPA 11v2 Runtime.
  • Faster imports than BE 2, even with importing more data!
  • New Smart Find.
  • Lots of new layout styling with Condition Formatting.
  • Lots of cleanups.
  • Lots more...

There are also some other points that are works in progress and will be fixed before the beta goes final :

  • Plugins still need to be setup with the new import.
  • Indirection will also need to be adjusted.
  • We want to add some more features before the final too.

Generally, we've spent a lot of time on the import engine, so although we believe it's completely accurate, I'd like some more public testing. The public beta period is more for getting the new v11 import option in front of those who are waiting for it while we add in new features.

The links you need are :

BaseElements_Mac.dmg - fp7 files.
BaseElements_Mac_MU.dmg - Sharing enabled version.
BaseElements_Mac_Runtime.dmg - Runtime.

There is lots of content on the site to update, but I wanted to get this out early to people can start to play with it. If you've got any questions or issues, please use the support pages, or contact us directly or even send us a note on twitter.

This beta will expire at the end of July, and for now will use any current v2 licence. The final version will be a paid upgrade from v2, although any purchases made since the 1st of March 2010 will get the new version for free.

Reducing Complexity in Software

Every time I'm working on BaseElements, there is an ongoing struggle between adding more features and making it easy to use. Recently I came across this article on Neven Mrgan’s Tumbl which is kind of related to the subject, but the final quote I think summed it up neatly :

"do less, and do the best less you can"

I think it explains a lot in that you're better off doing the main features well and not adding extras that you either can't or don't have the time to do well.

My goal with version 3 of BaseElements is to reduce the number of things that aren't part of the core of BE, while making the core tasks easier, clearer and faster.

FileMaker Pro 11 v2

FileMaker has released the first update for FileMaker Pro 11. The full details and downloads are available here. As with all updates, there is a lot there and I'd suggest that they're worth downloading for all users.

One curious inclusion in the fixes was this :

Addressed an issue with empty merge variables appearing on layouts in Browse, Find, and Preview modes.

This is a very good change from the previous behaviour where empty layout variables would show the variable name. When introduced, this was cited as a feature, so you could see what the layout name was and fix the display. I'm glad this one was changed as the first workaround people looked at was how to style an empty variable to not display when empty.

I'm now building the BaseElements 3 beta with the new v2 updates and will hopefully have it out later today.

BaseElements Blog and site updates

If you're already subscribed to this feed, you may have recently noticed everything old is new again :) Apologies for that. We've been working on our website lately, and amongst other things all of the blog content has been reshuffled. So you may get duplicates items in your feed.

But seeing as I have your attention, we are also working on a new site design, I'm looking to change our payment processor and we've got a new Goya logo. All of this is coming soon.

In the mean time, we've got a new BaseElements 3 beta to launch, so I'd better get back to it.

Thanks for listening and we hope you'll hang around.

BaseElements and FileMaker Pro 11

We've posted a long note updating the status of BaseElements in FileMaker Pro 11. You can read the whole thing in the FAQ section of our website. You can keep up to date with our progress on the blog or the subscription list or our twitter account.

BaseElements 2.6.0 Released ( at last )

We've finally completed work on BaseElements 2.6.0 and it's now available for download. This one has been a while in coming and many people have asked where it's at, so we'd like to thank everyone for being patient. More on the delays below, but firstly the good news : New Features.

BaseElements 2.6.0 contains the super-duper whiz-bang fmSearchResults so you can search anywhere within your solution analysis for generic text. It's fast and contains a great user interface for searching. If you like what you see in BaseElements, make sure you download their demo materials and consider putting it in your own solutions too. We'll have more on the implementation of fmSearchResults later.

Also this version is now completely multilingual. BaseElements now speaks Swedish and Japanese, and we'll have a bunch more languages available soon too.

There is more detail in the release notes as there are some more tweaks, fixes and features as well.

And for anyone interested in the delays, one of the issues we've had to overcome with the localisation is how do you translate the buttons in custom dialogs. We'd looked at not translating them (not a great option), or providing dialogs via a plugin. We decided to develop our own plugin so that we could have a single plugin to do the general file functions and the dialogs. After a lot of development and testing time, in the end the single plugin option didn't work out, and we've instead reverted to using Troi File and adding Troi Dialog, but making it optional for those wanting translated dialogs. The extra time and work involved in developing and testing the plugin is the reason for the delay. We may come back to the plugin later, but for now it's on hold.

We will also write something up about our experiences with translating BaseElements for those interested in the process.

For now, grab your copy of BaseElements and if you've got any questions or issues, jump over to the support website http://baseelements.tenderapp.com/ and let us know.

Goya on Twitter

BaseElements now has it's own twitter account :

http://twitter.com/baseelements

And we'll be posting more regularly there as we work through new features and additional content on the website and in the software itself.

Using name / value pairs for parameters and storing data.

One of the greatest features added to FileMaker since the change to the fp7 file format has been the ability to pass parameters to scripts and get script results back. This is using

Get ( ScriptParameter )
and
Get ( ScriptResult )

But anyone who's ever done any other coding will realise there is one glaring oversight. There is only one parameter or result. We can't define a script with multiple named parameters, and I don't think that given FileMaker's target market, that that will change any time soon. So if you're trying to modularise your code and have scripts that can do different things based on their parameters, then you need a way to have reliable variables in the single text of a script parameter.

If you're not sure why this is useful, you can use it, for example to send the name, address, and phone number to the "Create New User" script, and have those values put into the appropriate fields.

I've seen lots of ways that other people do this sort of thing, and I'm going to outline how we do this and why. First some options :

One value per line.

This might work for simple rules, but would quickly break for any values with returns in them, and gives you quite confusing code. For example to only send the seventh value, you need to use "¶¶¶¶¶¶Value", but it's not clear why that is, and it's not obvious from the code. GetValue ( Get ( ScriptParameter ) ; 7 ) suffers from the same problem, in that you're not sure what it is and why.

Using XML for parameters.

This is an interesting idea, in that XML is a known standard so it would help in that way. It's also built in as to how you encode and decode and what values you can use for the names of parameters.

But you also need to consider that these parameters are unlikely to be set or retrieved outside of FMP (less so these days in the case of web and esp Web Services) so the extra code makes the parameters less understandable to the average FMP coder.

Name Value pairs.

This is just a way of having a list of values like so :

name1=value1
name2=value2
etc.

This is what we use. It allows you to have an unlimited set of parameter variables, which you can get and set at will, and by escaping any return characters, you can handle any value at all. It has the advantage of being very human readable, as opposed to machine readable like XML.

Because you're getting and seting the values by name, you know exactly what you're getting. For example this code :

GetScriptProperty ( "Contact Name" )

makes it clear what is being retrieved. There are two main custom functions we use to get and set these name value pairs. We've called them "Properties". So you have :


SetProperty ( Name ; Value )
---
Trim ( Substitute ( Name ; [ ¶ ; "" ] ; [ "=" ; "" ] ) ) & "=" & Substitute ( Value ; [ "\\" ; "\\\\" ] ; [ "¶" ; "\r" ] ) & ¶

And another function to get the values :


GetProperty ( propertyList ; propertyName )
---
Case ( IsEmpty ( propertyList ) ; "" ;
Let ( [
first = GetValue ( propertyList ; 1 ) ;
eq = Position ( first ; "=" ; 1 ; 1 ) ;
firstName = Trim ( Left ( first ; eq - 1 ) ) ] ;
Case (
firstName = Trim ( Substitute ( propertyName ; [ ¶ ; "" ] ; [ "=" ; "" ] ) ) ;
Substitute ( Middle ( first ; eq + 1 ; Length( first ) - eq ) ; [ "\\\\" ; "\\" ] ; [ "\r" ; ¶ ] ) ;
GetProperty ( RightValues ( propertyList ; ValueCount ( propertyList ) - 1 ) ; propertyName )
) ) )

So you Set the properties in the parameter of the script you're calling, and then Get them back inside the script when you need to use them.

We've also added some extra shortcut custom functions to get script parameters and results :


GetScriptProperty ( propertyName )
---
GetProperty ( Get ( ScriptParameter ) ; propertyName )

and


GetResultProperty ( propertyName )
---
GetProperty ( Get ( ScriptResult ) ; propertyName )

which make it much easier to get a name script parameter via GetScriptProperty ( "Name" ).

Advantages

Some of the reasons we like this sort of way of coding is that you can have a script that takes in 10 different properties - for example the "Create New Contact" script might set 10 different fields. But you can pass it any number of those 10 properties in any order. So a basic script call might only use one named property, but when you're calling the same script from a different location it might set all 10 properties or only 5.

We put a comment into the first line of the script about which parameters the script takes, so when you want to call a script, you open it up and copy the parameters from the first comment line and then paste that into the parameters box. So, for example, the comment might say :


Parameters :
SetProperty ( "Name" ; Value ) &
SetProperty ( "ContactID" ; Value ) &
SetProperty ( "Status" ; Value )

You only need to copy those three lines and alter the "Value" part and you're up and running.

One other neat bonus if you're nesting scripts you can add to the values without altering the existing parameters, or even override the values very easily.

For example, you have a "Create New Invoice" script, which you call with some parameters such as the Contact ID to set, and that in turn calls the "Create New Invoice Item" script to put the first item in the invoice. Your parameters for the first script call might be :


SetProperty ( "ContactID" ; Value ) &
SetProperty ( "Item Description" ; Value )

So even though the "Create New Invoice" script will only ever use the "ContactID" parameter, it then only has to pass on the parameters by calling "Create New Invoice Item" with "Get ( ScriptParameter )" and the invoice item script has the "Item Description" it needs.

But it can be smarter than that too. You can add to the parameters, so the New Invoice script will call "Create New Invoice Item" with :


SetProperty ( "InvoiceID" ; Value ) &
Get ( ScriptParameter )

So you've passed on the values you received, and also added your own.

And you can override values, as the values are retrieved in the order they're in from first to last. So I could modify the description by using :


SetProperty ( "InvoiceID" ; Value ) &
SetProperty ( "Item Description" ; NewValue ) &
Get ( ScriptParameter )

And when the New Invoice Item script goes to Get the "Item Description" it will return "NewValue" instead.

But wait, there's more

One interesting way we've started to use this is in places where you have a "Create New Record" script, and that script needs to set a bunch of fields in the new record. One downside in this idea of named parameters is that you have to get the names right. If you're getting a different name than you set, then the value won't be found and you'll get an empty result.

But we have a special new function in FileMaker 10 now :

GetFieldName ( field )

So what you can do with this is code your names to be the actual name of the field itself. That way you don't need to type the name and if it changes in the table, your code will still work. So you can Set the property by using :

SetProperty ( GetFieldName ( table::field ) ; Value )

And this works regardless of the current context. Fortunately, the GetFieldName function doesn't require you to be using a field that you can access via the current context. So then the obvious way to Get the script parameter is via a Set Field step using :

GetScriptProperty ( GetFieldName ( field ) )

But there is an even easier way. You just define the field itself with an auto enter calculation of :

GetScriptProperty ( GetFieldName ( Self ) )

Which means you can call a script which sets 100 different fields with different values, without a single "Set Field" step in sight. And it's smart enough not to cause issues in user created records, or outside your record creation process.

Neat isn't it?

And note that you don't need to do this only in script parameters, this will work anywhere you're wanting to store multiple values. So in this example from David Head : Metadata for your FileMaker Pro records, you could use it to store all of the metadata about a single record in a single field and have it be very obvious what each piece of metadata was. So you wouldn't confuse the CreationDate with the ModificationDate, for example.

Performing a "Diff" comparison of 2 text fields in FileMaker.

There are lots of ways of doing comparisons of 2 lots of text. Although there isn't anything native in FileMaker to do anything like this. We wanted to do something that did a visual comparison of 2 scripts in BaseElements, so you could see changes before and after when a script was modified.

After some hunting around, we came across some javascript functions that can highlight differences in text within a website, and we've integrated one of them into the webviewer so you can do the same thing inside a FileMaker solution.

This example requires FileMaker Pro 8.5 for the webviewer, but doesn't require any plugins or internet access to work, so is quite a neat way of doing a visual comparison in FileMaker Pro.

The original code for this is from : http://code.google.com/p/google-diff-match-patch/

AttachmentSize
DiffCompare.fp7100 KB
Syndicate content