Working examples and basic function descriptions are available at the fmxj example page.
A Javascript based approach to FileMaker Custom Web PublishingWith fmxj.js and simple JavaScript Objects you can
fmxj.js does not have any dependencies, but does use prism.js for the demo page code blocks and moment.js for the postQueryFMS() demo page resultClass example.
fmxj.js is designed to do the data interchange work with FileMaker Server in JavaScript. Query strings are created from JavaScript Objects and then sent as a POST to FileMaker's XML Web Publishing Engine. An XML FMPXMLRESULT is returned and converted into JavaScript Objects/JSON by fmxj. The core idea is to do as little as possible on the FileMaker server and shift what we can to the client and JavaScript processes. Supporting FileMaker's Web Publishing can be challenging so removing as many variabes as possible is one of our goals with this project.
POSTS can be done directly to the FileMaker Server's XML WPE or a simple PHP relay can be used to get around cross-domain issues and provide more secure authentication options. With the goal of doing as little as possible on the Server, we were a little disappointed to need to rely on PHP at all, but there are some limitations to interacting with the FMS XML API directly, and a PHP relay is the simplest way to get around them. Specifically it's much easier to add access headers to a PHP page than it is to Apache! See more on the PHP relay below in the postQueryFMS() function.
Functions for working with FileMaker Server
The postQueryFMS() is the primary function used for POSTing queries to FileMaker Server via httpXMLRequest and then converting the FMPXMLRESULT xml results into JavaScript objects for callback. Queries can be created easily from JavaScript objects using the fmxj URL functions below.
postQueryFMS(query, callBackOnReady[, callBackOnDownload, phpRelay, classResult, max, nestPortals])
An optional handler function can be passed as well to report the download progress from FileMaker Server. Note that FileMaker server does not pass the e.total property in it's progres reporting, only the bytes downloded e.loaded.
Example of formatted results (stringified JSON) returned by the postQueryFMS function for a find query:
Example of formatted results (stringified JSON) returned by the postQueryFMS function for a find query with a Portal on the target layout.nestPortals must be set to true for this nesting to take place, otherwise just the first portal row will be returned at the top level. (We recommend using this sparingly as it can put a significantly higher load on the server, and we'll be exploring some client side alternitives to this.)
Deployment and the phpRelay
You can use fmxj without any PHP providing all the JavaScript is hosted on the FileMaker Server. In this case, the JavaScript will do the httpXMLRequest POST directly to FileMaker Server's XML API. If the Guest account is not enabled then you will be prompted for FileMaker authentication from the browser. This is simple Basic Authentication, so may not be suitable for your deployment. If you're using this deployment, you can simply not pass the optional phpRelay argument or pass null to it.
You will need to use the php Relay if your web server and Filemaker server are located remotely from each other. FileMaker server does not allow cross domain httpXMLRequests directly to the XML API, and changing this involves modifying the Web Server settings. This is actually pretty easy in Windows/IIS, but not so in Mac/FileMaker Server/Apache. In either case, dropping a single PHP relay file into the FileMaker Server's root directory is much easier.
fmxj comes with a simple PHP file (fmxjRelay.PHP) that you can use for this. You'll then do your POST to the PHP file which will then do the identical POST locally to the FileMaker server using cURL and then relay the XML results back. When doing this you'll need to have the fmxjRelay.php file in your FileMaker WPE's root directory. You'll then need to define an object in JavaScript and pass it as the phpRelay argument.
Supported Object Properties Are:
User name and password can be passed as part of the object. They are sent via POST, so can potentially be secured if both the web server and Filemaker Server are using SSL, otherwise passing the credentials like this is equivalent to Basic Authentication. You also have the option of hardcoding the FileMaker credentials in the PHP file so they're not passed via JavaScript at all.
Relay Examples
POSTING FileMaker credentials to a secure server would use an object like this:
Remember! Both the Web Server and the FileMaker Server need to be runnning SSL for this transaction to be secure. There's a good article on this here.
classResult Example
Specify an object 'class' for the results using the below syntax and pass it as the resultClass argument. This example uses moment.js. FileMaker Times are 'floating' so we need to specify a time zone to solidify the events in the continuum.
results in objects like this:
Data Functions
These three functions are used to build the specific query type strings for the postQueryFMS function to POST. The idea being that you can use existing objects or simple JSON to create complex query strings.
findRecordsURL(fileName, layoutName, requests[, sort, max, skip])
Can't Edit Single Portal Row Filemaker 1
Example
..returns:
-db=Events&-lay=Events&-query=(q1);(q2)&-q1=Resources&-q1.value=Example A&-q2=Resources&-q2.value=Example B&-sortfield.1=DateStart&-sortorder.1=descend&-sortfield.2=Resource&-sortorder.2=ascend&-findquery
..which can now be passed to postQueryFMS().
To specify a request as an Omit request, simply specify an -omit property in the object as 1, e.g.
..returns a query string for omiting all the records where the Resource is equal to Example A:
-db=Events&-lay=Events&-query=!(q1)&-q1=Resources&-q1.value=Example A&-findquery
editRecordURL(fileName, layoutName, editObj)
This function will create a -edit query for a FileMaker record if the -recid property is specified. This represents the FileMaker Record ID of the record to edit. Optionally a -modid property can be specified. See the FileMaker CWP XML guide for more info in using the -modid.
Filemaker Pro Portal
If the -recid property is not specified, then this function will create a -new query for generating a new record.
-edit Example
..returns:
-db=Events&-lay=Events&-recid=6198&Resources=Example A&-edit
-new Example
..returns:
-db=Events&-lay=Events&Resources=Example A&StartDate=1/11/2015&-new
..these queries can now be passed to postQueryFMS().
![]()
deleteRecordURL(fileName, layoutName, recid)
This function will create a -delete query for a FileMaker record with the specified -recid property.
Example
..returns:
-db=Events&-lay=Events&-recid=6198&-delete
..which can now be passed to postQueryFMS().
Design Functions
These three functions are used to build the specific query type strings for the postQueryFMS function to POST. These three are for getting facts about the files on the server. The layouts in a file, and the fields on a layout.
fileNamesURL()
This function will create a -dbnames query that we'll use to get a list of the available files on the server. Typing history on computer. Files will need to have at least one account with XML extended privileges to show up here. This query is slower than the rest.
Example
..returns:
-dbnames
..which can now be passed to postQueryFMS().
layoutNamesURL(fileName)
This function will create a -layoutnames query that we'll use to get a list of layout names for the specified file.
Example
..returns:
-db=Events&-layoutnames
..which can now be passed to postQueryFMS().
layoutFieldsURL(fileName, layoutName)
This function will create a -findany query that we'll use to get a one record result, but just return the layout fields and their data types. We use -findany, because FMPXMLLAYOUT does not give us the actual field types, but just the field control style on the layout. The postQueryFMS() recognizes the -findany and uses that as a flag to return the fields/types instead of actual data.
Example
..returns:
-db=Events&-lay=Events&-findany
..which can now be passed to postQueryFMS().
Functions for working with JavaScript Objects
Functions for handling your objects in JavaScript. One of the ideas of fmxj is to have the FileMaker server do as little work as possible. We want to get our data with small Ajax calls and any kind of necessary scripting in JavaScript.
We do have a php deployment option, but the php page is set up to do as little as possible. It takes our POST then relays it via cURL to the FileMaker Server. It then returns the raw FMPXMLRESULT for fmxj to convert to objects. We don't anticipate needing to (or wanting to) enhance this server side processing. Script running arguments were intentionally left off the findRecordsURL() function for the same reason. We weren't even sure about including the sort argument and supporting Portals as nested arrays, but they are in there now.
These functions are for that client side processing, and we anticipate (hope) that this is the part library that grows!
filterObjects(filters, searchTypes, source)
This function creates a new array of objects from a source array based on filters. Each filters object represents a FileMaker type find request where each set of name value pairs within the object are AND clauses and each object represents an OR clause. searchTypes alloes you to choose from one of the pre-configured regex searches set up in the function. You can add your own types by adding them to the generatRegEx() function that lives inside filteObjects.
Example
sortObjects(sortOrder, source)
This function sorts the specified array of objects by 1-n properties, specifying the data type for the property.
Example
nestObjects(parentArray, childArray, childName, predicates)
Nest one array of objects into another as a property a SQL like Join.
Example
I have two tables (Locations and LocationsStatus). The first is a list of all locations and the second lists the status of that location. The status is constantly updated and I want to keep a record of status updates over time, so it is necessary to keep a second table.
Now, on a 'dashboard' layout I display all locations in a portal (showing table Locations) and I want to display the status from (LocationStatus). However, if I put the field for status in the portal, it shows only the first record in the LocationStatus table related to that particular location. How do I get it to display the LAST related record in the LocationStatus table?
Can I make a portal (using LocationStatus) on top of the portal (for Locations) and sort by date and only display one record only? Or is there a more efficient way to do this? I have tried putting a portal on top of a portal, and it doesn't seem to work. It also doesn't seem very efficient. Any thoughts?
mattbowlbymattbowlby
2 Answers
The traditional solution to this is to create a dedicated relationship for this purpose, giving that relationship the sort order desired, in this case, a reverse date sort. Once this is done, simply place a portal using your new reverse-sorted relationship on the page and ensure that the fields within the portal also use this same relationship. The desired record will now be displayed first.
Notes: You cannot stack portals in FileMaker, as you've discovered. If you only want to display a single record, you can omit the portal and simply include the fields you want, again wired to the reverse-sorted relationship.
brian_schickbrian_schick
It sounds like you're on the right track for displaying the last LocationStatus in your dashboard portal. The element that you are most likely missing is assigning a sort order to the relationship between the
Location Table Occurrence and the LocationStatus Table Occurrence.
To do that, go you your relationship graph in the Define Database dialog and click on the relationship link. On the
LocationStatus Table Occurrence side, you'll see a sort order. There you can select a date field on the LocationStatus table, such as a Creation Date, and set it to descending order.
Once you have done that, when you pull the
Status field from that LocationStatus Table Occurrence, you will get the last one first.
Of note: FileMaker allows for multiple Table Occurrences for each Table. If you sometimes want the pft221pft221
LocationStatus in ascending order and sometimes want the LocationStatus in descending order, you would create two Table Occurrences of the LocationStatus table, each one with a different sort order.
1,67411 gold badge1313 silver badges1919 bronze badges
Not the answer you're looking for? Browse other questions tagged database-designfilemaker or ask your own question.
Posted by2 years ago
Archived
With Filemaker 16, I think I have finally figured out an easy way to display subsummaries in a portal using the new UniqueValues text function. In other words, summary groups and totals of a child table displayed on the parent table Body part. But I could use a sanity check. (Disclaimer: I'm not a developer and I support one Filemaker database for my wife's small business.)
The techniques I've found on the web involve complicated scripts, developer tables, Global variables, 'custom lists' and other hackery that I can't seem to wrap my brain around. My technique involves just using fields with simple unstored calculations and Summary fields, and ultimately UniqueValues to grab the unique lines from a List for display in a single row portal. There are no complicated relationships or scripts required. Screenshots are here and a copy of the demo db here.
Can't Edit Single Portal Row Filemaker Server
Have I stumbled into something that will scale? This works great in my tiny demo, but I'm wondering if it might hit the wall with a lot of records. Constructive feedback is appreciated.
edit..There's a mistake in the screenshots. The keys are text fields, not numbers, as autoenter serial was giving me problems and I switched to UUIDS
3 comments
I have two tables which both include a date field. Currently I have two portals, one for each table (occurrence).
Is it was possible to display the results of both of these in one portal, and sort by the date?
Andy Hayden
Andy HaydenAndy Hayden
203k5656 gold badges454454 silver badges449449 bronze badges
1 Answer
Technically a portal can only display records from one table. If you need to join two tables then you have to do this manually or change the design and use one table instead of two (since you want them in the same portal, then the tables are similar to some degree; maybe this similarity can go into its own table).
Sometimes developers use the so-called virtual table technique: they create a table with, say, a field with the record number and a bunch of calculated fields that pick their values from elsewhere, for example, from prefilled global variables. They create a portal to this table, set up the relationship to display the required number of records, and write the code to fill these variables. This way they can show data that isn't stored in any table, combine tables, etc. But it's an arcane technique, I would recommend it only as the last resort.
Mikhail EdoshinMikhail Edoshin
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Not the answer you're looking for? Browse other questions tagged portalfilemaker or ask your own question.Comments are closed.
|
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |