By Daniel Wood, 9 January 2011
Using Popup windows is common FileMaker technique for showing more information, managing dialogs, and running wizards to name a few. However, all to often little care is given to the aesthetics of creating and positioning a popup, leading to an unpolished and half-finished feel. This article gives some pointers on how you can create popups that are clean, efficient, and correctly positioned.
Why would you want tidy popups?
Consider any standard application on your computer, such as iTunes, Mail, Safari etc. When you open new windows in these applications, such as entering the preferences, what do you see? Typically, you will see the popup windows appear centered in front of your current window. They appear right away, and they appear all setup and ready to go.
Now, if an application can do it, then why shouldn't your database? Databases are just as critical as applications, if not more, so why skimp on the detail?
Having tidy popups makes your entire database feel tidy and polished, and can be achieved very easily.
All too often I see popup windows created in FileMaker with no care. How many popups have you seen in databases that appear in seemingly random positions, with the incorrect size, showing scrollbars or status area. Then, how many do their setup on-screen, so you see the hiding of the status area, the resizing of the popup, layout changes and so on? I don't know about you, but I see it all the time and it is one of my biggest bug-bears about database design - the lack of care taken on the user interface and design side of a system.
If you are building any kind of commercial database, then how it looks and behaves should be one of your top priorities, no one wants to buy a database that looks half-finished !
Setting up a popup without the user seeing
The creation of new popup windows that are not visible to the user has already been covered in one of my previous articles - "Using an Offscreen Window to do a Scripts Work".
The idea is that new windows are created with a large negative left coordinate value, this ensures the new window appears at a coordinate not visible by monitors, and so is not on-screen.
The article above concerns using these windows as temporary workspaces which can be closed when done, but the same idea can apply to creation of popups the user will eventually see. The popups can be created with it's width, height, and top coordinate set correct for the popup, but with the large negative left coordinate. When the popup is ready to be displayed, it can be shifted back on-screen in a single step using the "Move/Resize Window script step.
In the images above, you can see how the new popup window can be created. Local variables have been used to store the default top/left coordinates, and the popups default width and height.
Positioning the popup where you want
Depending on the purpose of the popup window you are creating, there may be many different initial locations on screen where you want the popup to appear. If you know the actual coordinates, such as wanting the popup to always appear in the top left corner of screen, you can obviously enter 0/0 as your coordinates.
However, more often than not the position of a new popup will be dependent upon the location of your current window. For example, if you wish to have the popup appear directly centered in front of your current window, then the initial coordinates of the popup are dependent upon the current coordinates of your main window.
Similarly, you may wish to position the popup in a location relative to an object on your layout. Small popup windows may be used to carry out an action specific to a location such as a particular button, or field. In this case, your popups initial coordinates are dependent upon the coordinates of the layout object.
Center-Aligning a popup window
To create a center-aligned popup window, I have created a couple of helpful custom functions that perform the necessary calculations to derive a top and left coordinate for your new window:
The popup_CenterLeft function takes your popups initial width as its parameter. This is required to position the popup correctly horizontally. Similarly, popup_CenterTop requires the popup height to center vertically.
I won't go into great detail as far as dissecting the functions, suffice to say they produce the coordinates using the popups dimensions, compared to the current windows dimensions and location on screen.
The image above shows how you can establish your popups coordinates in variables. Here, $Width and $Height have been previously set to the popups initial dimensions.
Establishing the popups initial dimensions
This is the most crucial part of the process in my opinion. In order to prevent visible scrollbars when you popup is displayed, you should set your width and height exactly correct for the popup. This is going to involve determining the exact dimensions. Some may think that this "hard-coding" of dimensions into your script is a bad thing, but I say that if you are creating a popup window, it is highly unlikely its dimensions will change unless you manually make changes to the layout, in which case your script should change accordingly. It is also important to get correct dimensions so you see no window resizing toward the end of the process.
In the image above I have set my width and height into variables. You'll notice the use of two more custom functions popup_GetWidth and popup_GetHeight. These functions help correctly determine your windows dimensions.
The reason for using these functions is because there is a difference in window dimensions depending on whether you are on a PC or a mac. On a PC, scrollbars are thicker and so the window will be larger. These functions take as their parameter the raw layout-mode width/height of your layout, and produce the resulting windows dimensions based upon what platform is being used.
To determine your layout height, you will need to obtain the pixel heights of your layout parts. If your layout has a header of height 50 pixels, and body part of 100 pixels, then your parameter to popup_GetHeight is going to be 150. Of course, if your popup is using list/table view, this becomes less important, and your popup dimensions should just be determined by what you wish the size of the popup to be initially.
To determine your layout width, select every object on the layout using cmd+A (ctrl+A) and in the inspector/object info panel, look for the right coordinate.
If you only ever use one platform, you can skip using the custom function and directly set your window width & height. To do this, open the popup window in browse mode & resize to fit, using your data viewer, obtain the values of Get(WindowLeft) and Get(WindowTop) functions respectively.
Putting it all together
All the required components are now known, and we can create the window, set it up, and move it back on-screen when ready.
The script above sets the required coordinates and dimensions of the new window. The window is created off-screen. Then follows the setup of the window, in this case switching to the desired layout. Finally, the window is moved back into its exact correct location using Move/Resize window.
Aligning popups relative to a layout object
The last type of popup I will be dealing with is those that are to be initially positioned relative to a layout object. Whereas the center-aligned method uses the dimensions of the current window, this will use the dimensions and coordinates of a layout object.
Again, two custom functions have been produced to assist in the correct positioning of the window, popup_ObjectLeft and popup_ObjectTop.
These functions take 3 parameters respectively:
-ObjectName - The object name of layout object to position relative to.
-Orientation - a keyword "top", "left", "bottom", or "right" to position popup.
-PopupWidth/Height - dimensions of popup depending on function used.
Again, not going into much detail about the functions, but just to say the functions make use of the GetLayoutObjectAttribute function to obtain coordinates & dimensions of the layout object, all information required to correctly determine the popups initial coordinates.
From here, once the coordinates are known, it's just a case of creating the window, setting it up, and then moving it back on screen as shown earlier.
A note about dock positioning on OS X
While writing this article I noticed a peculiar bug in FileMaker concerning obtaining a windows coordinates versus a layout objects coordinates. This is most apparent when your os x dock is positioned on the left edge of your screen.
In the picture above, my dock is on the left edge of my screen. You can see the left coordinate of the window when positioned right beside the dock is 0 pixels. This would suggest that when the dock is on the left of screen, window coordinates begin from the edge of the dock, rather than the screen itself.
However this is not the case for left coordinates of layout objects. As you can see, the gap between the edge of the window and the object is 126 px. You would think that this would mean the left edge of the button would be 126 px, you would be wrong! The left edge is in fact 176 px, a full 50 pixels more. So it turns out that when obtaining object coordinates, they do in fact begin from the left edge of your screen, and not from the edge of the dock as a window coordinate will.
This causes some problems in determining a correct popup window position because you cannot determine in FileMaker whether your dock is on the bottom of screen, or on left of screen. The functions mentioned in this article are assuming that the dock is at the bottom of screen, and thus the window coordinates and the object coordinates use the same 0 pixel coordinate location.
If your dock is on left of screen, you will find that the left coordinate of the popup window is slightly offset to the right of the object when using the object-aligning technique. This can be modified in the functions themselves, but is not a good solution, as users can always change their dock location whenever they want.
Note that the coordinate bug is not a factor when center-aligning a popup in front of the parent window.
Final Thoughts:
If any database is to be taken seriously as a professional looking, polished solution, then care needs to be taken in how you create your popup windows. Unnecessary window flashing, resizing, or visual setup of a popup should be avoided, as it makes a database feel unpolished and even unfinished. Correct positioning of popups is not a difficult thing to do given the proper tools, and can go a long way to improving the usability of your solution.
Example File
Please find attached an example file. This file was used for all the screenshots in this article, and is provided to help you fully understand what is going on in this article, and to let you experiment in FileMaker with this solution.
Something to say? Post a comment...
Comments
Bob 04/01/2020 11:27am (5 years ago)
Thank you for your tips and sample file. I was able to make this work for one of my projects and it works flawlessly. Appreciated. FMP.12 using FM version 16. Copied the functions over. Fantastic! January 3 2020.
Greg 15/02/2014 2:05pm (11 years ago)
Two added steps to insure the window remain within desktop bounds. (Has not been tested on dual screen desktops.)
# Insure that entire New Window appears within bounds of desktop.
Set Variable [ $Left; Value:Case (?( $Width ) + $Left > Get ( WindowDesktopWidth ) ; Get ( WindowDesktopWidth ) - $Width ; popup_CenterLeft ( $Width )
)]
Set Variable [ $Top; Value:Case (?( $Height ) + $Top > Get ( WindowDesktopHeight ) ; Get ( WindowDesktopHeight ) - $Height ; popup_CenterTop ( $Height )
)]
Tony 05/02/2013 1:06pm (12 years ago)
Hey Daniel -
Regarding your center pop-up solution -- how would you modify it so that it works when users have a DUAL SCREEN set up? All the values on the left monitor (for example), are negative numbers... so the math gets a little tricky (a negative - negative = positive thing).
rob 23/12/2012 2:04am (12 years ago)
Daniel,
want to THANK YOU !! For that, hide the portal !
Being a disabled war vet with ringing the ears leaves me unfocused sometimes towards the most simpliest routines !!
So while i have you on the phone like to ask another question? , _i_ be darn if _i_ can find, HOW TO, "remove the last carriage return and all text right of it"?
_i_ simply have a text field with a list of 'names' followed with a carriage return.
Well, to explain briefly .. _i_ sometimes need to remove the last carriage return along with last name.
rob
Wawak, Indiana
Daniel Wood 19/12/2012 1:30pm (12 years ago)
Hi Rob, it has been done before :) To get something basic up and running, create a global field somewhere, doesn't matter which table, lets call it "Toggle". Write a script that will set "Toggle" field to 1, or if clicked again and toggle already has the value 1 in it, it sets it to 0. The script step will be "Set Field" and you'll be using a calc something like "if ( global = 1 ; "" ; 1 ) to set it. Add a second script step after that called "Refresh Window" and tick the "flush cache to disk" option.
Next, go to the portals setup and choose the filter tickbox and specify a calcualtion for it. Just set the calculation to be the global field.
Now when you run the script, it should set global 1 to which will reveal the portal rows. Running the script again sets the global to blank which will hide the portal rows.
rob 19/12/2012 1:27pm (12 years ago)
DANIEL,
ok.... sorry it IS simple .... just simply show my portal records if a variable is present however my graphic button does not hide.
Of course _i_ have it placed on the first portal row so that it shows across all portal records but in this first row it not disappears with the data. _i_ suppose _i_ can hide it by having a container field over it and insert a picture ? HEY THANKS A LOT !!!
rob 19/12/2012 1:16pm (12 years ago)
Daniel, ok .. so you ARE, a Professional Biker who knows how to, "Bike With The Elements of Filemaker Pro" !! This DOES sound like the answer !! :-) _i_ve never used portal filter conditioning ? Soooooo-ooo _i_am kindna not knowing where to begin for setting up a condition and a script .. "wanting the portal data Buttons to be invisible only when i click a activation button" which makes it pop up / visible. Then after i select / click one of the portal row data buttons it will disappear. you got time to bike on over here ???
surprised nobody has ever done this ? Neat way to hide a Button Control Panel !!!
thanks alot
rob
Daniel Wood 19/12/2012 8:41am (12 years ago)
Hi Rob, maybe I don't understand you correctly, but if you set the portal filter condition to false, then if no portal rows draw because of that, then nothing within the portal row will render either, buttons and folder names included, when in browse mode it will be as if the portal isn't there at all (of course it will still be visible in layout mode however).
There is no way to reposition objects on a layout by script. The only way a layout object can move is by using the anchoring property and having it move upon the window resizing.
r o b 'jesus Land Tidd' lewis 18/12/2012 6:14pm (12 years ago)
Daniel THANKS !!
However my portal contains Folder Names and every portal row has a button !!
20 Buttons on screen !
This IS the way _i_ want it. but not want my portal always visible.
_i_ thought Filemaker had script code for repositioning objects ? Well .. they do repositioning windows ?
Great !! _i_ not want my portal on a floating window !! _i_ wanted my portal buttons !
think about how useful this would be in many solutions !
In any case with what i discribed more for what _i am_ doing it appears your idea won't work ??? if it will work ?? whats a few of its code for getting me going ?
THANKS FOR YOUR TIME,
rob
HARDWARE SOFTWARE VISIONARY
Daniel Wood 18/12/2012 5:53pm (12 years ago)
Hi Rob,
While you cannot script the movement of a layout given it is simply a layout object, you can somewhat hide it by applying a filter calculation to the portal. In the portals setup, use the filter portal records option. You can define a calculation that if evaluating to false means no records will be shown in the portal (thus basically hiding it and its contents). To show the portal with contents, set the result of the calculation back to true and refresh. Hope this helps.
r o b 'jesus Land Tidd' lewis 18/12/2012 5:44pm (12 years ago)
this gives valuable infromation however
WHAT SCRIPT WILL TOGGLE A PORTALS POSITION ? hide it by repositioning it off screen ?
_i am_ looking for script code that will reposition my portal ? hide it, by repositioning it. off to the right of the screen on the extended part f the browse mode layout, that is not visible.
THUS HIDING MY PORTAL. when not needing it.
i know you can use tabsto do this, but _i am_ wanting my Portal to disappear and to reappear in its origional position over on top of ANY of my selected tabs.
A nd the script needs to return my portal back on screen in its origional location.
THANK YOU
FOR YOUR ATTENTION
CWright 31/05/2012 5:05am (13 years ago)
Lyle...I'm sure you've found a fix by now, but I came across something new today and thought I'd share. I too was going crazy with Windows resizing my main window. My mentor, recommended keeping every window maximized, but sometimes the user needs to be able to reference the main window. Previously I would always maximize the main window when the popup closed. This didn't work cleanly, because then you get a flicker and a refresh.
So what I found today comes from an old 10/2009 post by Chad Sager (IT Solutions) at http://www.topitproviders.net/index.php/2009/09/17/78/ . He basically is calling it a "Fake Maximized Window". You set your main window on login to the size that takes up all the real estate. His method is to set your window size using "Get ( WindowDesktopHeight ) and Get ( WindowDesktopWidth ) functions. This will tell you how big to make the window. I?ve found that subtracting 4 pixels on each dimension will make the window size just right."
This is working great for me so far. A little worried it may not be the best solution if you have users with both high and low resolution displays. Guess it depends on which user you base your layout design. ;) I'm sure there are other drawbacks, but I'm going to try if for awhile and get some user feedback.
jGalt 31/12/2011 5:05am (13 years ago)
Thanks Daniel, the refresh fixed it...on OSX anyways. ;)
Daniel Wood 30/12/2011 9:41pm (13 years ago)
hi J,
After some testing I've found that you can remove this scrollbar flicker by inserting a "refresh window" script step after the script step that sets the layout of the new window. If I had to guess why this works I would say that when the layout is offscreen, FileMaker sees no need to render the window, and it is only when it is moved on-screen does FileMaker render the layout. Before it renders however it does not know the layout dimensions and so the window initially starts out with the scrollbar, and once it renders it realises there is no need for the scrolls so they disappear.
The refresh window step in the script before it goes onscreen must force FileMaker to re-draw the layout in the off-screen window which must then tell it the window does not require scrollbar, so when it moves on-screen it doesn't have them.
Anyways that's all assumption, but the refresh seems to do the trick :)
jGalt 30/12/2011 8:55pm (13 years ago)
I mean to say I am running FM11 on OSX 10.6.8
jGalt 30/12/2011 8:53pm (13 years ago)
Thanks for sharing your technique. I am running FM11 on OSX 10.8. I have downloaded your demo file and I am seeing a very brief but noticeable flicker in the scroll bars. The flicker is being caused by the (not sure what they are called, "the elevator sliders?") appearing and then disappearing. Is everyone seeing this? Is there a way to get rid of the flicker?
Graham Parkhurst 19/11/2011 1:29am (13 years ago)
Hi,
Nice idea to create the popup off screen.
I use something similar but store the windows position and size within a table in case the end user wishes to move a window. Some windows I allow the end user to move and others will always popup within the centre of the viewing area. Within my table I have various presets for locking the status area, hiding toolbars etc which are scripted into a general window creation script, including the window name and every time a window is closed there is another general script that writes any required position changes to the table.
Lyle Chamney 25/10/2011 4:02pm (13 years ago)
Thanks for the speedy reply, Daniel :)
However, from what I gather from your reply, you may have misunderstood my issue. The popup on both platforms is perfect, the correct size and in the correct location, no scroll bars :)
The problem I am having is with the layout where the button resides that calls this popup. As mentioned, the layout that has this button is maximized and of course, take up the full screen width. On the Mac, when this button is clicked, the popup displays where it should, at the size it should, and the underlying layout does not change. But on Windows, the same holds true for the popup - where it should be and the size it should be - BUT - the underlying layout SHRINKS to the "best fit" size (roughly 3/4 of the full size). The issue is not with the popup but with the underlying layout :)
Cheers!
Lyle
Daniel Wood 25/10/2011 3:42pm (13 years ago)
hi Lyle,
One way to get around this is when determining the initial width/height of the popup, to accommodate depending on the platform you are using. I know that there are defined pixel dimensions for the differences between mac and pc scrollbars and so on, so you can take a dimension from the mac and convert it to the windows dimension and vice versa. The best place to start looking might be briandunning.com for custom functions to do this - I can't remember the dimensions off the top of my head sorry. Another place they may be is in FileMakers knowledge base.
Cheers.
Lyle Chamney 25/10/2011 3:36pm (13 years ago)
Howdy Daniel,
Thank you for the great tip on the centred popup! Just what I was looking for to "polish" an app I am working on.
However, while it works "out of the box" on the Mac exactly as you describe, on Windows, the calling layout is "reduced to fit" just before the popup is displayed, and the popup is then centred to the original size of the calling layout. It should be noted that my startup script maximizes the initial window ("Home" screen).
I tried a number of "things" and used the script debugger, but alas, my noggin is not yet completely wrapped around such matters :) Any light that you may be able to shine on this matter will be tremendously appreciated as this app is for a Windows-only "crowd" (I'm trying! ... have "converted" three people so far, but many more to go :) It took me over a year, but I was finally able to convince the airline I am contracted to, to get on the FM bandwagon ... FMSA plus 11 FMP licences ... to start, for 3 apps that I am putting together for them :)
Cheers!
Lyle
Daniel Wood 25/08/2011 2:13pm (13 years ago)
My work e-mail, the link is on my name, and I'm sure it's on the site somewhere, cheers.
Alan 25/08/2011 2:08pm (13 years ago)
Daniel,
Great thought on the transparent rectangle!
What email address should I use?
Thanks
Alan
Daniel Wood 25/08/2011 2:02pm (13 years ago)
Hi Alan, could you please e-mail the example file to me, as I no longer frequent the site you linked to, cheers.
Alan 25/08/2011 1:58pm (13 years ago)
Hi Daniel,
Thanks for the reply. That's what I attempted to do in the modification to your example file, and have set up several script parameters to pass along. Works fine, but that darn small flash from the resize step. I realize that was your reason for manually setting the dimensions.
On another note...In the example file I posted, I attempted to modify your functions (renamed popup_ObjectLeft_Offset and popup_ObjectRight_Offset) and for positioning the pop up by adding parameter for pixel offset. Your original functions appeared to offset by 10 pixels.
In the example I am not able to use the "Top" or "Bottom" parameter successfully with an offset of of say 5 pixels with the changes I made. Any light on that would be appreciated.
Thanks again...Alan
Daniel Wood 25/08/2011 1:52pm (13 years ago)
Actually just had a thought. How about if you put a transparent rectangle on the layout behind everything which was placed at 0,0 on the layout and which was sized to the default size of the layout. Give the rectangle an object name. Then in your script you can use GetLayoutObjectAttribute using the Width and Height keywords for that function to obtain the dimensions of the rectangle, and thus the default dimensions of the layout. If you used that convention on all your layouts then you could easily determine the initial size your layouts had to be.... Just a thought
1 2 next »
No one has commented on this page yet.
RSS feed for comments on this page | RSS feed for all comments