<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The FileMaker Collective &#187; S.F.R</title>
	<atom:link href="http://fmcollective.com/category/syndicated/sfr/feed/" rel="self" type="application/rss+xml" />
	<link>http://fmcollective.com</link>
	<description>Syndicating the best FileMaker blogs</description>
	<lastBuildDate>Tue, 27 Jul 2010 15:42:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.3</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Six Fried Rice Methodology Part 2 – Anchor Buoy and Data Structures</title>
		<link>http://sixfriedrice.com/wp/six-fried-rice-methodology-part-2-anchor-buoy-and-data-structures/</link>
		<comments>http://sixfriedrice.com/wp/six-fried-rice-methodology-part-2-anchor-buoy-and-data-structures/#comments</comments>
		<pubDate>Tue, 10 Mar 2009 21:59:42 +0000</pubDate>
		<dc:creator>Daniel Antunes</dc:creator>
				<category><![CDATA[FileMaker Basics]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/?p=229</guid>
		<description><![CDATA[In the last post about the Six Fried Rice methodology I went over the concept of data separation and why we use it.  That is essentially the starting point for how we structure the files of our system.  One file contains all of the UI components and scripts for the system while a second file [...]]]></description>
			<content:encoded><![CDATA[<p>In the last post about the Six Fried Rice methodology I went over the concept of data separation and why we use it.  That is essentially the starting point for how we structure the files of our system.  One file contains all of the UI components and scripts for the system while a second file contains all of the actual data.  Just doing that one basic separation provides several benefits that generally make life easier, but how we structure the data within the Base File itself is equally if not more important than the data separation.<span id="more-229"></span></p>

<p>To begin with I&#8217;m going to go over how we initially setup our tables.  The first thing we do after we create a table is add a number field named ID that is unmodifiable and set to auto-enter a serial number.  This may seem obvious to a lot of people, but as an absolute beginner I never even thought about this approach.  For simplicity&#8217;s sake we never call our primary ID field anything but ID.  If we ever need to store another table&#8217;s ID for relationship purposes, we use the convention <code>ID_ORDER</code> or <code>ID_PURCHASE_ORDER_LINE</code>.  Naming things according to a set standard of prefixes makes organizing and locating our fields a little bit easier and saves us from a lot of hunting through long lists of names.  Typically we apply this to all fields that can logically be grouped together.  For example, it we have two date fields and two purchase order fields in a table, here is what our field list would look like:</p>

<ul>
    <li>DATE_ESTIMATED_SHIP</li>
    <li>DATE_PROMISED</li>
    <li>ID</li>
    <li>ID_PO</li>
    <li>PO_VENDOR_NAME</li>
    <li>PO_CREATED_BY</li>
</ul>

<p>Standards like this help us keep our fields consistent, and should I ever need to work on a table that Jesse has created I will know exactly what I&#8217;m looking at.  Logically grouping your fields and giving them a standard naming convention will make navigating your data structures considerably easier.</p>

<p>Come to think of it, most of what our conventions are about is legibility.  The simpler and more standardized you can make your systems the easier it is to come back to them at a future date and work on them after the particulars of the system have left the forefront of you mind.   With that in mind here is how we approach the Anchor Buoy relationship graph setup.</p>

<p>Anchor Buoy is another of those concepts that like Data Separation require a little bit of additional setup in the beginning, but pays off big when you start using it in conjunction with context independent scripting and our layout design style. The basic idea is to create your Table Occurrences in several tree structures, with the root of the tree being the context that you are actually working in.  Here is an example of a relatively simple database relationship structure to help get the concept across.  I&#8217;ll break down the individual components and why they are setup the way they are after the image.</p>

<p><a title="Six Fried Rice Anchor Buoy Model for Relationships" href="http://sixfriedrice.com/wp/wp-content/uploads/2008/09/simple-relationship.jpg"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2008/09/simple-relationship.jpg" alt="Six Fried Rice Anchor Buoy Model for Relationships" /></a></p>

<p>First off, there are the root tables.  In this graph they would be <code>INV__INVOICES</code> and <code>CUS__CUSTOMERS</code>.  These table occurrences form the root of their respective contexts and give a clear starting point to the relationships that follow.  Let&#8217;s take a look at the Invoices tree to delve into how we setup these relationships and why we structure our data around them.</p>

<p>Any time anything happens to an invoice and any information needs to be pulled onto an invoice, the place we start is the <code>INV__INVOICES</code> table.  As you can see, all of the basic information we would need for this invoice is available through some relatively simple relationships.  If I need to get to the customers billing or shipping address, I can go directly through the customer table to the associated address.  This setup allows me to easily and clearly identify the relationships that my data relies upon.  For basic information, there is nothing more complicated than that.  I would recommend labeling any table occurrences that are based on anything but the basic ID relationship.  For example, when I am going to the customer&#8217;s billing and shipping addresses I have two separate occurrences of the address table using the same basic naming convention with the only difference being that I append the #shipping or #billing label to the end of the name.  And just as a note, because this was the first mistake I made when trying to use Anchor Buoy for the first time, never link a layout to anything but one of the root tables.  Using one of the buoy tables that is further down stream than the root can create all types of context issues when scripting and setting up calculations.  I can&#8217;t stress how many headaches you can avoid by having only one context to that you work in!</p>

<p>Now, calculations.  Let&#8217;s say I wanted to store the order total on the order record itself, and I wanted to pull the total directly from the order lines associated with the order.  Using the base table system, the context I would start in is <code>ORD__ORDERS</code>.  From there, I would pull the sum of the order lines from the <code>ord_ORDER_LINES</code> table occurrence.  This one calculation will now be the only place where the order gets it&#8217;s total price from.  So, when I want to display the order total on the invoice itself I would just grab that calculated total from the <code>inv_ORDERS</code> occurrence.  Basically the goal is to always set your data structure up so that your base tables do all the work of gathering information and creating contexts that will allow you to easily traverse your data when you are scripting and designing your layouts.</p>

<p>The end goal of using Anchor Buoy and Data Separation is to lay the ground work for a development environment that is simple to understand, powerful to work within and flexible enough to handle most any scenario that a customer can come up with.  Once you have this base in place, using our scripting methods and layout design has the potential to greatly reduce the complexity of development.  The next post will focus mainly on setting up the basic operating layouts we use and how we script around them to provide fully encapsulated and single point functionality.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/six-fried-rice-methodology-part-2-anchor-buoy-and-data-structures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Global Variables for List Selections</title>
		<link>http://sixfriedrice.com/wp/using-global-variables-for-list-selections/</link>
		<comments>http://sixfriedrice.com/wp/using-global-variables-for-list-selections/#comments</comments>
		<pubDate>Wed, 04 Mar 2009 20:36:54 +0000</pubDate>
		<dc:creator>Daniel Antunes</dc:creator>
				<category><![CDATA[Advanced Techniques]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/?p=233</guid>
		<description><![CDATA[A funny thing happened while I was stumped over the question of how to allow one of our clients to select and deselect multiple items in a list.  Multiple people would be using the list at the same time.  I was struck by the fact that I&#8217;ve been making something more complicated than it needs [...]]]></description>
			<content:encoded><![CDATA[<p>A funny thing happened while I was stumped over the question of how to allow one of our clients to select and deselect multiple items in a list.  Multiple people would be using the list at the same time.  I was struck by the fact that I&#8217;ve been making something more complicated than it needs to be for as long as I&#8217;ve been working with Filemaker.  After toying with various methods which included adding fields to the records in the list, join tables, global fields and horribly convoluted scripting it occurred to me that you can actually write a relatively simple custom function to handle it all.  It will add or subtract a value from a list that is stored in a global variable and then simply do some conditional formatting to highlight the selected items in the list.  No additional fields or scripting are needed, the global variable is session specific and once you are done you&#8217;ve got your list of data ready to go as is.</p>

<p><span id="more-233"></span>Here are all the components of this process and how they fit together:</p>

<p>AddOrRemoveFromList(list, value) &#8211; The custom function that will maintain the values in the list for you.</p>

<p>$$selectedItems &#8211; The global variable that stores the list I want to operate against.</p>

<p>Selected Item &#8211; The actual record that you are adding to the list.</p>

<p>First I&#8217;d like to explain the custom function.  Basically, that function checks a list that you the value you pass in.  If the function finds that value, it removes the value and returns the new list sans value.  If it doesn&#8217;t find the value, it returns to you the list with the value appended to the end of it.  Here is the what AddOrRemoveFromList(value, theList) contains:</p>

<p>let(</p>

<p>[newList = Substitute(¶ &amp; theList &amp; ¶, ¶ &amp; value &amp; ¶, ¶)];</p>

<p>if( PatternCount( ¶ &amp; theList &amp; ¶; ¶ &amp; value &amp; ¶) = 1 ; Middle(newList, 2, length(newList) &#8211; 2); theList &amp; if(not isempty(theList); ¶) &amp; value)</p>

<p>)</p>

<p>The reason for all those extra ¶&#8217;s is for encapsulation and searching.  When you think about what a list actually is, it turns into this:  apple¶orange¶pear¶applejuice.  If you want to search that list for apple right now you would be editing both the values apple and applejuice.  To get around that we put an extra ¶ before the first entry in the list and after the last entry so our list now looks like ¶apple¶orange¶pear¶applejuice¶.  So, if we now search for ¶apple¶ we would only be working with the actual apple value.  To get the correct list format returned after that you just need to use the middle function to strip the first and last ¶ from the list.</p>

<p>So, we now have a custom function that will handle adding and removing values from a list.  The only thing we have to do to make a selection is to say where we want to store the list.  Using a global variable has the advantage of being easily accessible and being completely separated from your data structure, so you don&#8217;t need any additional fields or records to keep track of what the user wants selected.  So, if you choose to use a global variable, the only step you need to take is to set the variable $$selectedItems using the custom function.  Here&#8217;s what that step looks like:</p>

<p><a title="Setting the Global Variable" href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/list-management-script.jpg"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/list-management-script.jpg" alt="Setting the Global Variable" /></a></p>

<p>If you are unformiliar with our parameter passing system, please take a look at this.  So, we now have the selected items being added to the desired list automatically.  So, let&#8217;s let the user see what they&#8217;ve selected.  Using conditional formatting we&#8217;ll just apply that same list checking we used in the custom function.  The formula should be:</p>

<p>PatternCount( ¶ &amp; $$selectedItems &amp; ¶; ¶ &amp; item &amp; ¶) = 1</p>

<p>&#8220;item&#8221; in the above example should be whatever you passed into the list.  No</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/using-global-variables-for-list-selections/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamic Finds in FileMaker 10</title>
		<link>http://sixfriedrice.com/wp/dynamic-finds-in-filemaker-10/</link>
		<comments>http://sixfriedrice.com/wp/dynamic-finds-in-filemaker-10/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 02:21:52 +0000</pubDate>
		<dc:creator>Daniel Antunes</dc:creator>
				<category><![CDATA[FileMaker 10 Tips]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/?p=322</guid>
		<description><![CDATA[In an earlier article we explored an isolation technique that was specifically designed to work on ID&#8217;s and that&#8217;s it.  There is a lot more that can be done with the new Set Field By Name step and in this article we&#8217;ll take a look at a slightly more complex but much more versatile [...]]]></description>
			<content:encoded><![CDATA[<p>In an earlier article we explored an <a href="http://sixfriedrice.com/wp/isolate-any-record-anywhere-anytime-and-any-context-with-one-script/">isolation technique</a> that was specifically designed to work on ID&#8217;s and that&#8217;s it.  There is a lot more that can be done with the new <code>Set Field By Name</code> step and in this article we&#8217;ll take a look at a slightly more complex but much more versatile search method.  This technique will rely on the use of our dictionary functions, so taking a look at this <a href="http://sixfriedrice.com/wp/filemaker-dictionary-functions/">article</a> is a definite prerequisite.</p>

<p><span id="more-322"></span></p>

<h3>The Basics</h3>

<p>First off lets go over the basic concept.  Essentially, the idea is that with <code>Set Field By Name</code> step, we can now pass in the field we want to search as well as the value to search for.  So, instead of having to script a bunch of hard coded <code>Set Fields</code> we can call one find script, pass in a bunch of find criteria and have that script set the fields we want dynamically.  With this new system, you can have one script perform just about any find you need.</p>

<p>Before our script will work, we need a system to pass the name of the search field as well as the value to search.  Using our parameter passing technique it&#8217;s actually pretty simple to send the information.  To pass in a specific field name we can use the <code>GetFieldName()</code> in conjunction with <code>#()</code>.  Here&#8217;s the example<code>#(getfieldname(yourfieldnamehere); criteria)</code>.  So, let&#8217;s say you have the NAME field in a table called CUSTOMER and you want to find <code>Sarah</code>.  Here&#8217;s what I need to pass into the script:</p>

<pre><code>#( GetFieldName( CUSTOMER::NAME ) ; "Sarah" )
</code></pre>

<p>At this point we&#8217;ve determined what we want to search for and where we want to search.  Now we need to write a script that will take this information and generate our search.  In concept it&#8217;s pretty simply.  Just loop through any parameters and simply set the specified fields to the value provided.  Now, since we are using the<code>Set Field By Name</code> script step, be sure that the field name you pass in is the fully qualified field name and that you have the right context before you call the find script.  So, if you are on a layout on the CUSTOMER table and you want to search the ID field be sure that the field name you pass in is CUSTOMER::ID.  If you pass in ORDERS::ID, you&#8217;ll never find anything!</p>

<p>Here&#8217;s the actual script:</p>

<p><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/02/flex-find-script.png" alt="A script that finds records using Set Field by Name" title="A script that finds records using Set Field by Name" width="600" height="324" class="alignnone size-full wp-image-330" /></p>

<p>The first order of business is to take all of the parameters that were passed into the script and stick them into a variable so we can operate on them more easily.  What you end up with in the <code>$dict</code> variable is the full dictionary of passed in parameters.  Now, we enter find mode, enter a loop and iterate through the dictionary values to create our individual criteria.  </p>

<p>The loop is a little complicated.  It uses a couple different of our custom functions in our previous article.  We use <code>DictFirst</code> to grab the name of the parameter on the top of the list, then <code>DictGet</code> to get the value that corresponds with the name we&#8217;ve found.  Those two values are then used to <code>Set Field By Name</code>.  Finally we need to remove that entry from the dictionary.  Once we&#8217;ve emptied all the entries out  of the dictionary, we exit the loop.</p>

<blockquote>
  <p>Note: If you pass in the same field multiple times the final value passed in will be the one ultimately used.  You&#8217;re basically just overriding the value every time you pass in the same field.</p>
</blockquote>

<p>To perform the find, we use our tried and true <code>Safe Find</code> script and then return the error to make sure the calling script knows what happened.</p>

<p>This system has the potential to save us a tremendous amount of time.  Basically, you can construct your finds on the fly by calculating the names of the search fields and the according search value.  This find script is relatively simple and we&#8217;ll be fleshing it out to allow for multiple requests and omits, but this is a good first step.</p>

<blockquote>
  <p>Note: The find script itself does not navigate to any layouts.  We&#8217;ve designed it around the context independent scripting principles that we here at Six Fried Rice love so much.  Before calling the find script, make sure you are in the correct context for the find you are trying to perform.</p>
</blockquote>

<p>find-database</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/dynamic-finds-in-filemaker-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Script Triggers: Monitoring and Restoring Tabs</title>
		<link>http://sixfriedrice.com/wp/script-triggers-monitoring-and-restoring-tabs/</link>
		<comments>http://sixfriedrice.com/wp/script-triggers-monitoring-and-restoring-tabs/#comments</comments>
		<pubDate>Tue, 20 Jan 2009 00:51:36 +0000</pubDate>
		<dc:creator>Geoff Coffey</dc:creator>
				<category><![CDATA[FileMaker 10 Tips]]></category>
		<category><![CDATA[FileMaker Basics]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/?p=295</guid>
		<description><![CDATA[FileMaker 10&#8217;s new Script Triggers feature just keeps delivering. You might, at first, think triggers are limited to layouts and fields, but it turns out your triggers can fire with all kinds of objects. In this article we&#8217;ll show you how to run scripts when users switch tabs on your tab controls. In the end, [...]]]></description>
			<content:encoded><![CDATA[<p>FileMaker 10&#8217;s new Script Triggers feature just keeps delivering. You might, at first, think triggers are limited to layouts and fields, but it turns out your triggers can fire with all kinds of objects. In this article we&#8217;ll show you how to run scripts when users switch tabs on your tab controls. In the end, we&#8217;ll also revisit a common FileMaker problem: tabs switch when you switch layouts. We&#8217;ll show you how to solve this problem quickly and easily using script triggers.</p>

<p><span id="more-295"></span></p>

<h2>Triggers with Tabs</h2>

<p>It is unfortunately not entirely obvious, but Script Triggers work with tab controls. Specifically:</p>

<ul>
<li><p>The <code>OnObjectModify</code> trigger fires whenever the user switches to a different tab. This is probably the most useful trigger for tab controls.</p></li>
<li><p>The <code>OnObjectEnter</code> trigger fires when the tab control gets keyboard focus. This happens when it is in the tab order and you tab to it (so a tab gets the thick black border). You can see a tab control with keyboard focus here:</p></li>
</ul>

<p><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/tab-with-keyboard-focus.png" alt="A tab control with keyboard focus, showing the thick black border around the active tab." title="tab-with-keyboard-focus" /></p>

<ul>
<li><p>The <code>OnObjectExit</code> trigger fires when the tab control <em>loses</em> focus. In other words, when you tab <em>away</em> from it.</p></li>
<li><p>The <code>OnObjectKeystroke</code> trigger fires when the tab control has focus and you press any key on the keyboard. </p></li>
<li><p>The <code>OnObjectSave</code> trigger never fires for a tab control.</p></li>
</ul>

<h2>Watching the Tab Change</h2>

<p>Once you know all that, keeping tabs on your tabs (sorry) is easy. For example, suppose you want to show a special message under some circumstances when someone switches to a particular tab. Setting this up couldn&#8217;t be easier:</p>

<ol>
<li><strong>Write a script that does what you want.</strong><br />For example, it might show a dialog box, calculate a total, set a global, or clear a selection.<br /><br /></li>

<li><strong>In Layout mode, select your tab control, then choose Format -> Set Script Triggers…</strong><br />The Set Script Triggers dialog box appears.<br /><br /></li>

<li><strong>Turn on the <code>OnObjectModify</code> checkbox.</strong><br />You&#8217;ve just told FileMaker you want to run a script, so it asks you which script to run.<br /><br /></li>

<li><strong>Select the script you created in step 1.</strong><br />When you&#8217;re done here, click OK, then switch to Browse mode. You&#8217;re ready to test.<br /><br /></li>
</ol>

<p>As this video attests, your script now runs as soon as the user switches to <em>any</em> tab:</p>

<p align="center"><script language="JavaScript" type="text/javascript">
QT_WriteOBJECT_XHTML (
  "http://sixfriedrice.com/wp/wp-content/uploads/2009/01/trigger-script-on-tab-change.mov", "514", "332", "", "autoplay", "false"
);
</script></p>

<h2>Which Tab</h2>

<p>If you watched the video closely, you may have noticed that the scripted dialog box showed <em>which tab</em> was selected. With only one trigger script, how do you manage this? You just have to ask. </p>

<p>FileMaker&#8217;s esoteric <code>GetLayoutObjectAttribute</code> function can tell you all kinds of information about objects on your layout. Of particular interest, it can tell you if a tab panel is <em>front most</em>. To use it, though, you first need to give your tabs <em>object names</em>. We&#8217;ve <a href="http://sixfriedrice.com/wp/tab-controls-without-the-tabs/#names">showed you how to do this before</a> but here&#8217;s a quick refresher. If you&#8217;re already an object names expert, you can <a href="http://sixfriedrice.com/wp/script-triggers-monitoring-and-restoring-tabs/#moving-on">skip ahead</a>.</p>

<ol>
<li><strong>In Layout mode, click on your tab control to select it.</strong><br />When you click, the first tab gets a thick black border. This tells you that specific <em>tab panel</em> is selected. (You can have an entire tab control selected, without selecting any of its individual panels. You&#8217;ll see this in a moment.)<br /><br /></li>

<li><strong>Choose View -> Object Info to show the Object Info palette.</strong><br />This is where you go to set object names (among other things). Since its a palette, you can simply leave it open while you work through all your tabs.<br /><br /></li>

<li><strong>In the Object Name box in the Object Info palette, type a unique and identifying name for your tab.</strong><br />You might call it &#8220;tab1&#8243; or &#8220;customer tab&#8221; or whatever you feel is appropriate.<br /><br /></li>

<li><strong>Click the second tab in your tab control.</strong><br />The second tab comes to the front but <em>it is not selected</em>. Notice it doesn&#8217;t have a thick border.<br /><br /></li>

<li><strong>Click once again on the second tab.</strong><br />This time it gets its thick border. This is important. You can only name a tab panel once you have it properly selected.<br /><br /></li>

<li><strong>Give this tab a unique name, then repeat these steps to name every tab in your tab control.</strong><br />If you want to find out if a particular tab panel is in the front, it must have a name, so you&#8217;re best of naming them all.<br /><br /></li>
</ol>

<p><a name="moving-on"></a>
Once you&#8217;ve given every tab panel a name, you&#8217;re ready to start asking FileMaker who&#8217;s in front. This part is easy. Here&#8217;s the long-but-simple formula to see if a tab is in front:</p>

<pre><code>GetLayoutObjectAttribute ( "myTab", "isFrontTabPanel" )
</code></pre>

<p>Notice that this formula only looks at one particular tab panel (in this case it is looking at the panel called <code>myTab</code> so be sure to put one of your tab panel object names there instead). It will return a <code>True</code> result if the tab panel is in front, and a <code>False</code> result otherwise. To determine which of all the tabs is in front, you can check them one by one:</p>

<pre><code>Case(
   GetLayoutObjectAttribute ( "myFirstTab", "isFrontTabPanel" ); "First tab is in front";
   GetLayoutObjectAttribute ( "mySecondTab", "isFrontTabPanel" ); "Second tab is in front";
   GetLayoutObjectAttribute ( "myThirdtTab", "isFrontTabPanel" ); "Third tab is in front"
)
</code></pre>

<p>Or, in a script:</p>

<pre><code>If [ GetLayoutObjectAttribute ( "myFirstTab", "isFrontTabPanel" ) ]
   # do stuff for the first tab
Else If [ GetLayoutObjectAttribute ( "mySecondTab", "isFrontTabPanel" ) ]
   # do stuff for the second tab
Else If [ GetLayoutObjectAttribute ( "myThirdtTab", "isFrontTabPanel" ) ]
   # do stuff for the third tab
End If
</code></pre>

<h2>Restoring Tab State</h2>

<p>Now that you know how to watch for tab changes, and figure out which tab is in front, you can take it one step further, and solve an age-old FileMaker problem in the process. Last year, we wrote up <a href="http://sixfriedrice.com/wp/restoring-active-tab-state/">a laborious technique</a> to remember which tab is in front before you leave a layout, then bring it back to the front when you come back. This way, if your scripts have to quickly zip to another layout to get some work done, your users don&#8217;t get distracted by tab controls that keep switching back to the first tab.</p>

<p>That technique worked, but it was tedious. You had to write two long and complicated scripts. Then you had to call one every time you <em>leave</em> the layout, and the other every time you <em>come back</em>. What a nuisance.</p>

<p>Using Script Triggers, you can save all the hassle. Now two very simple scripts can get the job done, and they can do it automatically every time you return to the layout.</p>

<blockquote>
  <p>Note: In fact, this new, simpler version is even better than the old way. The tab will restore itself even if you manually leave the layout and come back later, making things a touch more stable for your users.</p>
</blockquote>

<p>First, you need a simple script to remember the front most tab:</p>

<pre><code>Set Variable [ $$FRONT_TAB;
   Case(
      GetLayoutObjectAttribute ( "myFirstTab", "isFrontTabPanel" ); "First tab is in front";
      GetLayoutObjectAttribute ( "mySecondTab", "isFrontTabPanel" ); "Second tab is in front";
      GetLayoutObjectAttribute ( "myThirdtTab", "isFrontTabPanel" ); "Third tab is in front"
   )
]
</code></pre>

<p>That&#8217;s it (and its really a one line script, although we put it on a few lines here so it would be easier to read. Just set a global variable to the name of the font most tab.</p>

<blockquote>
  <p>Note: If you have multiple tab controls to keep track of, make sure you use a unique variable name (or repetition) for each one. Otherwise, changes to one set of tabs will impact the others.</p>
</blockquote>

<p>Now attach an <code>OnObjectModify</code> trigger to your tab control and set it to run the script. With these two steps complete, a new global variable will always remember which tab you last visited.</p>

<p>Next, you need to make FileMaker restore the front most tab whenever you come to this layout. This part is equally easy. Start with a simple script:</p>

<pre><code>If [ Not IsEmpty($$FRONT_TAB) ]
   Go to Object [ $$FRONT_TAB ]
End If
</code></pre>

<p>This script first checks to see if the <code>$$FRONT_TAB</code> variable has a value. If it does, it uses the <code>Go to Object</code> step to bring that tab to the front.</p>

<p>Finally, tell FileMaker to run <em>this</em> script whenever the layout loads. You do this with (shocker) a script trigger. Choose Layout -> Layout Setup, then switch to the Script Triggers tab. Turn on the <code>OnLayoutLoad</code> trigger and point it to your script.</p>

<p>Here&#8217;s a video showing the tab behavior with and without the triggers:</p>

<p align="center"><script language="JavaScript" type="text/javascript">
QT_WriteOBJECT_XHTML (
  "http://sixfriedrice.com/wp/wp-content/uploads/2009/01/automatic-tab-restore.mov", "462", "426", "", "autoplay", "false"
);
</script></p>

<p>In the first version (before the fade-to-black) FileMaker switches back to the firs tab every time you leave the layout and come back. In the second, it seamlessly keeps things in order. This magic works whether your user leaves the layout manually, or you do it with script. Easy as pie.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/script-triggers-monitoring-and-restoring-tabs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="" length="" type="" />
<enclosure url="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/trigger-script-on-tab-change.mov" length="443174" type="video/quicktime" />
		</item>
		<item>
		<title>Make the Status Toolbar Work for You</title>
		<link>http://sixfriedrice.com/wp/make-the-status-toolbar-work-for-you/</link>
		<comments>http://sixfriedrice.com/wp/make-the-status-toolbar-work-for-you/#comments</comments>
		<pubDate>Fri, 16 Jan 2009 02:17:29 +0000</pubDate>
		<dc:creator>Geoff Coffey</dc:creator>
				<category><![CDATA[FileMaker 10 Tips]]></category>
		<category><![CDATA[FileMaker Basics]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/make-the-status-toolbar-work-for-you/</guid>
		<description><![CDATA[FileMaker 10&#8217;s most visible new feature is the completely redesigned Status toolbar (formerly called the Status area). Perhaps because of its prominent position, or because it is such a striking departure from a 20-year FileMaker mainstay, this change has been met with its fair share of controversy. In this article we&#8217;ll show you why you [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sixfriedrice.com/wp/introducing-filemaker-10/" title="Our complete coverage of FileMaker Pro 10">FileMaker 10</a>&#8217;s most visible new feature is the completely redesigned Status toolbar (formerly called the Status <em>area</em>). Perhaps because of its prominent position, or because it is such a striking departure from a 20-year FileMaker mainstay, this change has been met with its fair share of controversy. In this article we&#8217;ll show you why you don&#8217;t need to worry, and how you can make the new Status toolbar <em>work for you</em>.</p>

<p><span id="more-283"></span></p>

<p>In FileMaker 10, the standard Status toolbar looks something like this:</p>

<p><img src='http://sixfriedrice.com/wp/wp-content/uploads/2009/01/standard-toolbar.png' alt='The standard Status toolbar in FileMaker Pro 10' /></p>

<p>If you leave the Status toolbar open, your user will see prominent New Record and Delete Record buttons (among others). At first this might seem <em>nuts</em>. After all, many of you have special buttons on your layouts specifically for record creation and deletion, and you certainly don&#8217;t want people willy-nilly switching layouts to the wrong view, confusing themselves in the process. But it turns out you have more control over these buttons than most people realize. You cannot add your own buttons or custom icons, but <em>you can</em>:</p>

<ul>
<li>Disable buttons you don&#8217;t want your users to click</li>
<li>Reconnect most buttons to scripts of your own</li>
<li>Rename buttons to better reflect the terminology in your database</li>
</ul>

<blockquote>
  <p>Note: If you have the equivalent menu commands disabled in your database, then the buttons are already disabled too. A database with locked-down user interface in 9 is just as locked down in 10.</p>
</blockquote>

<h2>Disabling Buttons</h2>

<p>There are three ways to disable buttons in the Status toolbar (not all apply to all buttons). You can set up custom record privileges to control who can create and delete records. You can restrict access to menu commands using a privilege set; and finally, you can use custom menus to remove troublesome menu commands. Which you use is a matter of your security and user interface needs.</p>

<h3>Custom Record Privileges</h3>

<p>Using custom record privileges you can remove the ability for a user to create or delete records for any particular table. When you do, the associated status toolbar button will disable as appropriate. This even works for so called &#8220;record level access&#8221; privileges. For instance, you can remove the ability to delete a record only once its Status field has been set to &#8220;shipped.&#8221; When you do, the Delete Record button will disable when you view shipped records.</p>

<p>Setting this up is easy:</p>

<ol>
<li><p><strong>In your database, choose File -> Manage -> Accounts and Privileges.</strong><br />The Accounts &amp; Privileges dialog box appears.</p></li>
<li><p><strong>Open one of your existing privilege sets, or create a new privilege set.</strong><br />You&#8217;ll probably need to switch to the Privilege Sets tab. If you&#8217;re doing this for the first time, it is probably easiest if you duplicate the [Data Entry Only] privilege set so you start off with some reasonable privileges.</p></li>
<li><p><strong>From the Records pop-up menu, make a reasonable choice.</strong><br />For example, if you want to remove the ability to delete records of any kind, choose &#8220;Create and edit in all tables.&#8221; For the ultimate in control, choose &#8220;Custom privileges.&#8221; This window shows a privilege set configured so users can create records in any table, but can only <em>delete</em> Vendor records:</p></li>
</ol>

<p><img src='http://sixfriedrice.com/wp/wp-content/uploads/2009/01/custom-record-privileges.png' alt='The Custom Record Privileges dialog box with Delete permission removed for one table.' /></p>

<p>Once you assign an account to this privilege set, when that user logs in, she&#8217;ll see the Delete Record button disabled when she looks at Customer records:</p>

<p align="center"><script language="JavaScript" type="text/javascript">
QT_WriteOBJECT_XHTML (
  "http://sixfriedrice.com/wp/wp-content/uploads/2009/01/disabled-buttons.mov", "600", "466", "", "autoplay", "false"
);
</script></p>

<h3>Restricted Menu Access</h3>

<p>The record privileges don&#8217;t effect the <em>other</em> toolbar buttons (since they have nothing to do with creating or deleting records). Also, for databases where security isn&#8217;t terribly important, and preventing <em>casual</em> or <em>accidental</em> unwanted actions is all you need, restricting record privileges can be heavy handed and hard to script around.</p>

<p>For cases like this, the easiest solution is to restrict menu access. If you revisit the Privilege Sets tab of the Manage -> Account &amp; Privileges dialog box, you&#8217;ll discover that you can make gross restrictions to the menu commands your users get:</p>

<p><img src='http://sixfriedrice.com/wp/wp-content/uploads/2009/01/limited-menus-with-privilege-sets.png' alt='You can limit menu access for a privilege set.' /></p>

<p>If you switch to Editing Only or Minimal, FileMaker takes away all the powerful commands (like Import and Export, New Record, Delete Record, Find, and so forth). All the associated Status toolbar buttons will disable as well.</p>

<h3>Custom Menus</h3>

<p>For the utmost in control, you can turn to Custom Menus. This power feature is only available in FileMaker Pro Advanced, and gives you almost complete control of the menus, sub-menus, and commands your users see when they use your database. You&#8217;ll see some step-by-step instructions for using custom menus at the end of this article. For now, it will suffice to say that if you <em>remove</em> a menu command from a menu set, then when that menu set is active, the associated button in the Status toolbar will be disabled. In this way you can selectively disable any button you choose.</p>

<h2>Renaming and Redefining Buttons</h2>

<p>Disabling buttons is all well and good, if you&#8217;re a fan of taunting your users with permanently-out-of-reach temptation. But why not take it a step further. <em>Embrace those buttons</em> and make them do your dirty work. Taking control of the toolbar buttons requires use of custom menus (and, by extension, FileMaker Pro Advanced).</p>

<p>Imagine you have a database of <em>customers</em> and <em>vendors</em>. Your business rules require that you carefully control the process of creating and deleting records. For instance, you may need to set up web site access for any new customers, which requires running your fancy SQL scripts. Here&#8217;s how to express your authority <em>and</em> keep the Status toolbar buttons:</p>

<ol>
<li><strong>From the File Menu, choose Manage -> Custom Menus</strong>.<br />
The (quite complex) Manage Custom Menus dialog box appears. This is grand central station for every menu command FileMaker can muster.</li>
</ol>

<blockquote>
  <p>Note: In this example, you&#8217;ll use the &#8220;Custom Menu Set 1&#8243; menu set FileMaker creates for you. Adjust the steps as necessary if you have your own custom menu sets already.</p>
</blockquote>

<ol start="2">
<li><strong>In the Custom Menus tab, select the Records Copy menu.</strong><br />FileMaker ships with a customizable copy of all the standard menus to make it easy to squeeze small changes into otherwise-normal menus. This is the copy of the usual Records menu, where the New Record and Delete Record commands live.<br /><br /></li>

<li><strong>With the menu selected, click Edit.</strong><br />The Edit Custom Menu dialog box appears. On the left side, you see all the <em>menu items</em> in this menu.<br /><br /></li>

<li><strong>Select the New Record menu item.</strong><br />When you select a menu item, the right side of the dialog box fills in with options for the item. There&#8217;s lots of power here, so feel free to explore. You can see the options here:</li>
</ol>

<p><img src='http://sixfriedrice.com/wp/wp-content/uploads/2009/01/menu-item-configuration.png' alt='The configuration options for a custom menu item.' /></p>

<ol start="5">
<li><strong>Look next to &#8220;Command&#8221; and make sure it says &#8220;New Record.&#8221;</strong><br />This is the key to this entire technique. This menu item is associated with the <em>New Record</em> command, which is a core command in FileMaker. When you adjust the behavior of the menu item associated with the New Record command, you also modify the behavior of the New Record <em>button.</em><br /><br /></li>

<li><strong>Turn on the Action checkbox and select the script you use to create new records.</strong><br />When you add an action to the menu item, you get to pick either a single step or a script. In most cases you&#8217;re best off using a script (even if it is a one-liner) because it makes it easy to change later, even if several different menu sets include items that do the same thing.<br /><br /></li>

<li><strong>If you want, turn on the Title checkbox, click its associated Specify button, and enter a calculation to determine the menu title.</strong><br />For instance, you might decide you want your menu called &#8220;New Customer,&#8221; &#8220;Create Record,&#8221; or <code>Pi * Random</code>. Ok, probably not the last one, but the point is, you can use all the power of calculations to generate a dynamic and interesting title for your menu. Anything you do here will also influence the label under the New Record button in the Status toolbar.<br /><br /></li>

<li><strong>Select the Delete Record menu item and configure as you wish.</strong><br />Just make sure you keep Command set to &#8220;Delete Record…&#8221; so FileMaker knows you&#8217;re adjusting behavior for the delete action.<br /><br /></li>

<li><strong>Click OK to close the Edit Custom Menu dialog box.</strong><br />You&#8217;re now back in the Manage Custom Menus dialog box.<br /><br /></li>

<li><strong>From the &#8220;Default menu set for this file&#8221; pop-up menu, choose &#8220;Custom Menu Set 1.&#8221;</strong><br />When you make this change, you&#8217;re telling FileMaker you want the customized menu set to be used automatically for this database. You can also configure custom menu sets on a per-layout basis (See the Layouts -> Layout Setup dialog box in Layout Mode) or switch menu sets via scripts (using the <code>Install Menu Set</code> script step).<br /><br /></li>

<li><strong>Click OK once more to close this dialog box.</strong><br />Now you&#8217;re ready to test your changes. If all went well, the New Record and Delete Record buttons in the Status toolbar now bend to your will.</li>
</ol>

<h2>Dealing With the View As Buttons</h2>

<p>The steps above show you how to attach your own actions to the New Record and Delete Record toolbar buttons. But at the outset, we also mentioned the potential confusion your users might get by accidentally clicking the View As toolbar buttons. Once again, you have two options here.</p>

<p><strong>To disable any of these buttons</strong> you can disable a particular view on a per-layout basis. For instance, your Customer List layout only makes sense in List view, so turn off Form and Table views. This is super easy. In Layout mode, choose Layouts -> Layout Setup, switch to the Views tab, and uncheck the views you don&#8217;t want your users to use. When you do, the associated buttons in the Status toolbar will be disabled.</p>

<blockquote>
  <p>Note: You might take this opportunity to disable Table view in many of your layouts, since it has some potentially unwanted power. We discuss this in more detail <a href="http://sixfriedrice.com/wp/introducing-filemaker-10/#table" title="An explanation of the new Table view features in FileMaker 10.">here</a>.</p>
</blockquote>

<p><strong>To get these buttons to run your own script</strong>, just override the View as Form, View as List, and View as Table commands using custom menus. You&#8217;ll find them in the View Copy menu if you use the built in custom menu set.</p>

<h2>To Infinity and Beyond</h2>

<p>Combining the various custom menu techniques, plus some clever naming conventions and scripts, you can get the Status toolbar really working for you. In this video demo, you can see a simple database that customizes the behavior of several toolbar buttons so this standard FileMaker user interface integrates seamlessly with your carefully controlled database.</p>

<p align="center"><script language="JavaScript" type="text/javascript">
QT_WriteOBJECT_XHTML (
  "http://sixfriedrice.com/wp/wp-content/uploads/2009/01/fully-customized-toolbar.mov", "600", "466", "", "autoplay", "false"
);
</script></p>

<blockquote>
  <p>Note: You can download the database in this video right here: <a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/my-databasefp7.zip" title="A sample database showing customized toolbar buttons for New Record, Delete Record, View as Form, and View as List.">My Database.fp7</a></p>
</blockquote>

<p>In this example (which is anything but fully baked) we use the <code>Get(LayoutName)</code> function and some custom scripting to get the &#8220;View as Form&#8221; and &#8220;View as List&#8221; buttons to switch to appropriate layouts. We&#8217;ve also added a custom script to the New Record and Delete Record buttons, and renamed them so it is more obvious what they will do.</p>

<p>This kind of integration has several powerful advantages:</p>

<ul>
<li><p>FileMaker takes care of a lot of nice user interface work that we would otherwise have to create (and duplicate on every layout) ourselves. That means less time fiddling and more time making databases meet the needs of our customers.</p></li>
<li><p>This database has more powerful interface elements than it would if we had to handle the UI ourselves. For instance, our end users can show and hide the toolbar at will, and customize it to their needs.</p></li>
<li><p>If we build multiple databases for the same customer, they all <em>work the same way</em>. If a user customizes the toolbar in one database, his changes will apply in all of them. He only has to learn one set of interactions. This means we get more consistency with less work.</p></li>
</ul>

<p>A lot of people have expressed frustration about the new Status area, complaining that FileMaker has taken away control they need. I hope this article makes it clear that we have <em>more control than ever before</em>.</p>

<blockquote>
  <p>Opinionated Note: A lot of the frustration about the Status toolbar seems to stem from the fact that it is now <em>more obvious</em> that you can, for example, delete a record. These commands used to be squirreled away in menus, and now they&#8217;re front-and-center. But of course a less visible menu command is just as dangerous in the wrong hands. So the new toolbar, perhaps, has simply made it more obvious to developers that they need to be careful.</p>
  
  <p>The reaction to the new prominence of these commands illustrates another interesting reality. Menus have become no-man&#8217;s land. More and more in modern, popular applications, the commands you need are readily available in an explorable, friendly <a href="http://www.google.com/products?client=safari&amp;rls=en-us&amp;q=busy+box&amp;oe=UTF-8&amp;um=1&amp;ie=UTF-8&amp;sa=X&amp;oi=product_result_group&amp;resnum=1&amp;ct=title">busy-box</a> of interface goodness. People expect to <em>see</em> what they can <em>do</em>. I think this phenomenon really underscores the wisdom in the new Status toolbar. To keep current, FileMaker has to get a more modern user interface. It did, and suddenly people notice what FileMaker can do. That is, in my opinion, A Good Thing&trade;. Editorializing over.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/make-the-status-toolbar-work-for-you/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/disabled-buttons.mov" length="796818" type="video/quicktime" />
<enclosure url="" length="" type="" />
		</item>
		<item>
		<title>Script Triggers: Filter as You Type</title>
		<link>http://sixfriedrice.com/wp/script-triggers-filter-as-you-type/</link>
		<comments>http://sixfriedrice.com/wp/script-triggers-filter-as-you-type/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 18:33:33 +0000</pubDate>
		<dc:creator>Geoff Coffey</dc:creator>
				<category><![CDATA[Advanced Techniques]]></category>
		<category><![CDATA[FileMaker 10 Tips]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/script-triggers-filter-as-you-type/</guid>
		<description><![CDATA[For years, FileMaker developers have been devising various filter techniques. The idea is that you type all or part of a name, part number, description, etc… and a list of results filters down to show relevant matches. As handy as these techniques are, they always stop just short of perfect because, before FileMaker 10, you [...]]]></description>
			<content:encoded><![CDATA[<p>For years, FileMaker developers have been devising various <em>filter</em> techniques. The idea is that you type all or part of a name, part number, description, etc… and a list of results filters down to show relevant matches. As handy as these techniques are, they always stop just short of perfect because, before FileMaker 10, you had to <em>exit the field</em> before the filter would take effect. Using FileMaker 10&#8217;s powerful Script Triggers, you can make the impact of your filtering more immediate.</p>

<p><span id="more-279"></span></p>

<blockquote>
  <p>Note: We&#8217;ve never done this before, but the idea, scripts, and sample file for this technique come directly from FileMaker luminary and Six Fried Rice reader David Graham of <a href="http://bittailor.com" title="Bit Tailor: Software with a Perfect Fit">Bit Tailor</a>. We&#8217;re publishing it here (with David&#8217;s permission) because it is an excellent example of Script Triggers solving an age-old problem in an elegant way.</p>
</blockquote>

<p>There are as many ways to filter lists in FileMaker as there are developers implementing it. The beauty of this technique is that it doesn&#8217;t matter if you prefer exploded keys and filtered portals, aggregate text fields and a find, or (my personal favorite) scripted multi-request finds. Whatever you want, when it is fast, clean filtering you&#8217;re after, it is <em>always</em> better if the results appear as you type. This sort of thing was essentially impossible with FileMaker 9. Once a user started entering data in a field, you were hands-off until they finished.</p>

<p>Some people dreamed up horrifying solutions with looping scripts and all manner of wackiness. These techniques, in my opinion, <em>never</em> worked well. Consequently, we were always resigned to the &#8220;press Enter when you&#8217;re done&#8221; model. But when the results appear as you type, the user gets immediate feedback, only needs to go as far as necessary to get the result she wants, and doesn&#8217;t have to click back into the field to correct or make a change. So it is clearly a better model. See for yourself:</p>

<p align="center"><script language="JavaScript" type="text/javascript">
QT_WriteOBJECT_XHTML (
  "http://sixfriedrice.com/wp/wp-content/uploads/2009/01/modify-filter.mov", "456", "385", "", "autoplay", "false"
);
</script></p>

<p>David&#8217;s technique relies on the handy <code>OnObjectModify</code> trigger on the filter field to kick off a script every time the field changes. This includes:</p>

<ul>
<li>When you add a single letter to the field by typing a key.</li>
<li>When you remove something by pressing Delete or Backspace.</li>
<li>When you cut text form the field or paste it in.</li>
</ul>

<p>You may be tempted to use the <code>OnObjectKeystroke</code> trigger for something like this, but <code>OnObjectModify</code> gets you more bang for the buck: It handles cut and paste, and doesn&#8217;t require <a href="http://sixfriedrice.com/wp/script-triggers-using-the-keystroke-trigger/" title="An article about keystroke triggers">all the complexity</a> of keystroke triggers.</p>

<h2>The Code</h2>

<p>I&#8217;ll let you explore David&#8217;s sample file for the full scoop, but the core of his technique can be found in two places. First, he uses an exploded key filtering technique, which I won&#8217;t cover her, except to say that the idea is to process some text data and produce a multi-line key that includes partial match values. In other words, if the value is &#8220;Test&#8221; then the key would match &#8220;T&#8221;, &#8220;Te&#8221;, &#8220;Tes&#8221; and &#8220;Test.&#8221; In this way, you can type all-or-part of the value and see the results. Look at David&#8217;s <code>ExplodeToMultikey</code> custom function to see how he accomplishes this.</p>

<p>If you prefer, you can use scripted finds and a list view layout to do your filtering instead.</p>

<p>But the interesting part is this very simple trigger script:</p>

<pre><code>Set Variable [$currentObject; Get ( ActiveLayoutObjectName )]
Commit Records/Requests []
Go to Object [ $currentObject ]
Set Selection [ Start: Length (Get(ActiveFieldContents)) + 1]
</code></pre>

<p>That&#8217;s it. This script really just does two things:</p>

<ol>
<li>It commits the record, causing anything you&#8217;ve typed in the filter field to take effect.</li>
<li>It returns you to the field, so if you type again, your keystrokes will go right on the end of the field.</li>
</ol>

<p>In this way, as you type, your changes reflect immediately. Very cool.</p>

<blockquote>
  <p>Note: If you were using finds instead of exploded keys, you would add a a few more steps to your script to switch to Find mode, build a find request or two, and then perform the find.</p>
</blockquote>

<p>You can <a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/spotlight-filter.zip" title="David Graham’s filter example file.">download the working file right here</a>.</p>

<p>Thanks to David for the great technique!</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/script-triggers-filter-as-you-type/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/modify-filter.mov" length="570965" type="video/quicktime" />
		</item>
		<item>
		<title>Using OnModeEnter Script Triggers to Display Custom Find Layouts</title>
		<link>http://sixfriedrice.com/wp/using-onmodeenter-script-triggers-to-display-custom-find-layouts/</link>
		<comments>http://sixfriedrice.com/wp/using-onmodeenter-script-triggers-to-display-custom-find-layouts/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 15:47:40 +0000</pubDate>
		<dc:creator>Daniel Antunes</dc:creator>
				<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/using-onmodeenter-script-triggers-to-display-custom-find-layouts/</guid>
		<description><![CDATA[Script triggers have in many ways completely changed the game when it comes to Filemaker development.  The fact that I can launch script triggers on mode changes opens up a whole slew of possibilities, one of which is being able to have a huge amount of control over where my users end up and what [...]]]></description>
			<content:encoded><![CDATA[<p>Script triggers have in many ways completely changed the game when it comes to Filemaker development.  The fact that I can launch script triggers on mode changes opens up a whole slew of possibilities, one of which is being able to have a huge amount of control over where my users end up and what information they see while they are navigating my system.  If I want to make sure that my users always have fields X, Y and Z regardless of how they get to find mode, I now have a way to make that happen.<span id="more-276"></span></p>

<h2>The Old Way</h2>

<p>Pre-10, it was a little bit of a hassle to try to give users a customized find layout.  For starters, it required scripting a method that would take the user to the correct find layout for their current context, making that process available on the main layout itself via a button and then locking down the permissions and changing the menu commands so that the users could only get to find mode via said button.  It was doable, but kind of a headache.  Now with script triggers, I can simply set a script to run when the user enters find mode that navigates them directly to the custom find layout I&#8217;ve built for them, and no matter how they get to find mode they will always end up looking at what I want them too.</p>

<h2>How It Works</h2>

<p>The process of setting this up is pretty simple in and of itself.  Let&#8217;s take a look at our starting point:</p>

<p><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/browse1.jpg" alt="A busy browse layout." /></p>

<p>There is a pretty good amount of information being laid out for my users on this particular screen.  Really they only ever search in about eight of these fields.  The rest is just clutter when it comes to finds.  So, I want to give them only what they need to see when they run a find.</p>

<p>To do that, I need to take three steps.  The first step is to design my find layout, including only the fields that are essential for my users to find the data they need.  Once I&#8217;ve got that done, I need to write a script to navigate to that layout.  This can be a complex navigation script that tracks a history of visited layouts or a simple go to layout script step.  Once I&#8217;ve got my script ready, I need to set the correct script trigger to make it run.  The script trigger I&#8217;m interested in for this is called OnModeEnter, and you set it on the main detail layout that the users see (the one in the picture above for me).  You can get to the layout script triggers on the last tab on the right in the Layout Setup dialog box.  The OnModeEnter trigger runs whenever the modes you have selected are entered.  So, to make sure that the user ends up on my find layout only when they are entering find mode and not at any other point, I deselect the &#8220;Browse&#8221; and &#8220;Preview&#8221; options.  Now, this trigger will only run when the layout I&#8217;m on enters find mode, no matter how find mode is entered.  So at this point, when my users try to search for an order they start at the screen above and are immidiately shuttled to the much more find friendly screen below:</p>

<p><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/find.jpg" title="Find Mode"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/find.jpg" alt="Find Mode" /></a></p>

<p>Now my users are happy that they have a simple find screen to look at without all the exta clutter, and I no longer have to try to lock down my system of all it&#8217;s innate functionality to keep my users where I want them.</p>

<blockquote>
  <p>Note: There is actually one final note to make all of this work seemlessly.  Since you&#8217;ve taken your users away from the main detail page to set the find criteria, you should probably take them back once they actually preform the find.  To do this, you&#8217;ll need to write one more script to navigate them back to the main detail page and set it with the OnModeEnter script trigger on the find layout to run when browse mode is entered.  This will make sure that your users are taken back to the details page to view their results.</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/using-onmodeenter-script-triggers-to-display-custom-find-layouts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Phoenix FMPug: Presenting FileMaker 10</title>
		<link>http://sixfriedrice.com/wp/phoenix-fmpug-presenting-filemaker-10/</link>
		<comments>http://sixfriedrice.com/wp/phoenix-fmpug-presenting-filemaker-10/#comments</comments>
		<pubDate>Fri, 09 Jan 2009 22:18:51 +0000</pubDate>
		<dc:creator>Geoff Coffey</dc:creator>
				<category><![CDATA[Announcements]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/phoenix-fmpug-presenting-filemaker-10/</guid>
		<description><![CDATA[Just a quick announcement for those of you in the Phoenix area. I&#8217;ll be presenting FileMaker Pro 10 with a focus on practical uses for Script Triggers at the next Phoenix FMPug meeting. We&#8217;d love to see you there.




  Update 10-Jan-2009: I added a link to the RSVP form.



When: January 20th, 2009 at 6:30 [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick announcement for those of you in the Phoenix area. I&#8217;ll be presenting FileMaker Pro 10 with a focus on practical uses for Script Triggers at the next Phoenix FMPug meeting. We&#8217;d love to see you there.</p>

<p><span id="more-275"></span></p>

<blockquote>
  <p>Update 10-Jan-2009: I added a <a href="http://www.fmpug.com/rsvp.php?eventID=855" title="RSVP for the FMPug Meeting">link to the RSVP form</a>.</p>
</blockquote>

<ul>
<li>When: January 20th, 2009 at 6:30 PM to 8:30 PM</li>
<li>Where: The Burton Barr Central Library, 1221 N. Central Ave (just South of McDowell on Central)</li>
<li>Who: Anybody interested in learning, sharing, and meeting about FileMaker Pro</li>
</ul>

<p>If you plan on attending, please <a href="http://www.fmpug.com/rsvp.php?eventID=855" title="RSVP for the FMPug Meeting">rsvp here</a> so they organizers can get a proper count.</p>

<p>The Phoenix branch of <a href="http://fmpug.org/" title="FMPug: The FileMaker Pro Users Group">FMPug</a>, the FileMaker Pro Users Group, is young and growing. This meeting promises to be a hit, with all the FileMaker 10 excitement. We&#8217;d especially like to thank Audrey Akhavan from <a href="http://www.filemakermagic.com/" title="FM Magic Web Site">FM Magic, Inc,</a> for starting the group and inviting us to present. Thanks, Audrey!</p>

<p>We can&#8217;t wait to see you all there.</p>

<p>Now back to regularly scheduled programming.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/phoenix-fmpug-presenting-filemaker-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Script Triggers: Using Layout Triggers for a Dynamic Tab Orders</title>
		<link>http://sixfriedrice.com/wp/script-triggers-using-layout-triggers-for-a-dynamic-tab-orders/</link>
		<comments>http://sixfriedrice.com/wp/script-triggers-using-layout-triggers-for-a-dynamic-tab-orders/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 19:24:20 +0000</pubDate>
		<dc:creator>Jesse Antunes</dc:creator>
				<category><![CDATA[FileMaker 10 Tips]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/script-triggers-using-layout-triggers-for-a-dynamic-tab-orders/</guid>
		<description><![CDATA[If you&#8217;re a male, do you really need to be asked you if you&#8217;re pregnant when you are at a clinic?  If your female, do you need a prostate exam?  Probably not.  There are little nuances to data entry that occur with just about every solution that make it just slightly more [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a male, do you really need to be asked you if you&#8217;re pregnant when you are at a clinic?  If your female, do you need a prostate exam?  Probably not.  There are little nuances to data entry that occur with just about every solution that make it just slightly more tedious to collect information with just a standard tab order.  We&#8217;re going to remedy that with using a simple layout keystroke trigger.</p>

<p><span id="more-272"></span></p>

<h2>Dynamic Tab Order for FileMaker 10</h2>

<p>In FileMaker there is only one way to navigate the tab order.  This can be annoying to an end user who has to tab through a bunch of useless fields to get to the good stuff.  The gender question above is a perfect problem to solve using a dynamic tab order in FileMaker 10.</p>

<blockquote>
  <p>Note: As Mikhail Edoshin points out, this process could be accomplished by attaching a script trigger directly to the field in question.  The reason I chose to attach the trigger to the layout is so all tab order changes are centralized in one script. For instance if you had 4 or 5 different modifications to the tab order, you would still only have one script when using the layout trigger.  If you were to place a trigger on each individual field you would need 4 or 5 scripts.  That was really the main idea of this whole post but I left it out for some stupid reason.</p>
  
  <p>Thanks for the heads up Mikhail.</p>
</blockquote>

<p>A better way for our tab order to progress in our example is to just skip fields depending on which gender is choosen.  Here is the psuedocode for what I think the tab order should look like:</p>

<pre><code>IF the active field is Gender THEN
  IF Gender = Male THEN go to the prostate question END
  IF Gender = Female THEN go to the pregnancy question END
END
</code></pre>

<h2>Finding our Key</h2>

<p>The <code>TAB</code>, <code>ENTER</code> and <code>RETURN</code> as they are the three keys that filemaker uses to move to the next field.</p>

<pre><code>Note:  You can specify one, two, three of these keys to progress to the 
next field in the Format &gt;&gt; Field/Control &gt;&gt; Behavior...
</code></pre>

<p>So using our knowledge from the previous article about <a href="http://sixfriedrice.com/wp/?p=253">keystroke triggers</a> and consulting our ascii tables we know the following will return true if any one of those keys is pressed:</p>

<pre><code>Let(
  keyCode = Code( Get ( TriggerKeystroke ) );

  keyCode = 9 or //Tab Key
  keyCode = 10 or // Enter
  keyCode = 13 // Retun
)
</code></pre>

<h2>Overriding the tab order</h2>

<p>Assuming that my table name is <code>TEST</code> and my field names are <code>GENDER</code>, <code>PROSTATE_EXAM?</code> and <code>PREGNANT</code>, we can write our script.</p>

<pre><code>If[ Let( keyCode = Code( Get ( TriggerKeystroke ) ); keyCode = 9 or keyCode = 10 or keyCode = 13) ]
  If[Get( ActiveFieldTableName ) &amp; "::" &amp; Get( ActiveFieldName ) = getFieldName( TEST::GENDER )]
    If[ TEST::GENDER = "F"]
      Go to Field [ TEST::PREGNANT? ]
      Exit Script [Result: False]
    Else If [ TEST::GENDER = "M" ]
      Go to Field [ TEST::PROSTATE_EXAM? ]
      Exit Script [Result: False]
    End
  End
End
</code></pre>

<p>Notice on the second line of the script we combined two get functions to determine the table and name of the field and then compared that to the result of  <code>getFieldName( TEST::GENDER )</code>:</p>

<pre><code>Get( ActiveFieldTableName ) &amp; "::" &amp; Get( ActiveFieldName ) = 
getFieldName( TEST::GENDER )
</code></pre>

<p>The reason we do this is to make sure that if for some reason you ever decide to change the name of either the table or field the script won&#8217;t break.</p>

<p>You&#8217;ll also noticed that I use the step <code>Exit Script [Result: False]</code> after I navigate to each field.  The purpose of this step is to reject the <code>TAB</code>, <code>ENTER</code> or <code>RETURN</code> key press.  If we were to leave the <code>Exit Script</code> step out, FileMaker would process the keystroke and therefore go the the next field in the tab order after the field I just told it to go to.  This would drive everyone crazy!</p>

<p>Once I&#8217;ve played with this technique a little more I&#8217;m sure it will prove quite useful.  It definitely makes data entry a little more user friendly.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/script-triggers-using-layout-triggers-for-a-dynamic-tab-orders/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Isolate Any Record, Anywhere, Anytime and Any Context With One Script</title>
		<link>http://sixfriedrice.com/wp/isolate-any-record-anywhere-anytime-and-any-context-with-one-script/</link>
		<comments>http://sixfriedrice.com/wp/isolate-any-record-anywhere-anytime-and-any-context-with-one-script/#comments</comments>
		<pubDate>Tue, 06 Jan 2009 18:00:02 +0000</pubDate>
		<dc:creator>Daniel Antunes</dc:creator>
				<category><![CDATA[FileMaker 10 Tips]]></category>
		<category><![CDATA[FileMaker Basics]]></category>
		<category><![CDATA[S.F.R]]></category>
		<category><![CDATA[Syndicated]]></category>

		<guid isPermaLink="false">http://sixfriedrice.com/wp/isolate-any-record-anywhere-anytime-and-any-context-with-one-script/</guid>
		<description><![CDATA[There are some things that are easier to explain through examples.  Putting the Set Field By Name script step to work is definitely one of them.  It&#8217;s not a complicated process, but seeing the new Indirection capabilities that Filemaker 10 has to offer makes a much stronger impression than trying to talk through it.  Also, [...]]]></description>
			<content:encoded><![CDATA[<p>There are some things that are easier to explain through examples.  Putting the Set Field By Name script step to work is definitely one of them.  It&#8217;s not a complicated process, but seeing the new <a href="http://sixfriedrice.com/wp/set-field-by-name-exposed/" title="Indirection SFR Style">Indirection</a> capabilities that Filemaker 10 has to offer makes a much stronger impression than trying to talk through it.  Also, all my introductory quips for &#8220;isolating&#8221; and &#8220;isolation&#8221; were turning out quite depressing.  So, here is how we used to find a specific record, and how we can do it now.</p>

<p><span id="more-259"></span></p>

<h2>The Old Way</h2>

<p>For this article I&#8217;m going to assume you are using two methods that are a part of our development process.  The first is <a href="http://sixfriedrice.com/wp/passing-multiple-parameters-to-scripts-advanced/" title="Multiple Parameter Passing">multiple parameter passing</a> (feel free to check this out if you&#8217;ve never run into it before) and the second is Safe Find.  Safe Find is a script we use to safely run a find and capture any errors that occur and return them without throwing an error dialog.  Here is a copy of the actual script:</p>

<p><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/safe-find.jpg" title="Performing a Safe Find"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/safe-find.jpg" alt="Performing a Safe Find" /></a><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/safe-find.jpg" title="Performing a Safe Find"> </a></p>

<p>So, now on to the concept of Indirection.  Here is how we used to find customers using our standard naming conventions, parameter passing and error handling:</p>

<p><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/customer.jpg" title="Finding a Customer"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/customer.jpg" alt="Finding a Customer" /></a><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/customer.jpg" title="Find a Customer"> </a></p>

<p>Now, here is how we find orders:</p>

<p><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/order.jpg" title="Finding an Order"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/order.jpg" alt="Finding an Order" /></a><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/order.jpg" title="Find an Order"> </a></p>

<p>And now for something completely different.  Here is how we find vendors:</p>

<p><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/vendor.jpg" title="Finding a Vendor"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/vendor.jpg" alt="Finding a Vendor" /></a><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/vendor.jpg" title="Find a Vendor"> </a></p>

<p>By now you&#8217;re probably seeing a trend in our scripting that has driven me nuts since day one.  In Filemaker 9, we had to maintain a separate set of scripts for each context that we wanted to operate in.  If we want to find a Vendor, that&#8217;s one script.  Find an Order?  That&#8217;s a second script.  Customer?  A Third script.</p>

<h2>The New Way</h2>

<p>Here is how we can find a Customer, Order or Vendor now:</p>

<p><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/isolate.jpg" title="One is the Lonliest Number"><img src="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/isolate.jpg" alt="One is the Lonliest Number" /></a><a href="http://sixfriedrice.com/wp/wp-content/uploads/2009/01/isolate.jpg" title="Isolation, it’s so lonely."> </a></p>

<p>This little beauty does something that makes us here at Six Fried Rice absolutely giddy.  I can call it from any layout, pass it an ID and it will isolate the record with the corresponding ID without any further hassle!  It is completely context independent.  Essentially we now have a single script to replace every find by ID script we have ever created.  A huge part of development model revolves around using structures, systems and conventions to centralize and simplify the development process.  This particular script is a perfect example of a very simple application of a very useful feature to cut out a huge amount of redundancy in a systems.</p>

<p>Note: This script does require that a few things are in place before hand.  For one,
you&#8217;ll notice that we use the Set Field By Name to set &#8220;ID&#8221; to the parameter that is
passed in.  This only works if you strictly follow the naming convention that dictates
having a primary key field called &#8220;ID&#8221; in every table.  I&#8217;ll be posting an article going much
deeper into our own conventions, but for now remember that to use a script like this, you
<em>must</em> have consistent naming conventions throughout your system or the script will not
execute correctly.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixfriedrice.com/wp/isolate-any-record-anywhere-anytime-and-any-context-with-one-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
