Proper Printing in WebDirect [Updated]

By Daniel Wood, 15 August 2014

[Update 26/9/14]

Thank you to some readers who pointed out a few bugs in the example file affecting windows users. The issue was in the "RoboPrint - Process Print Jobs" script. Interestingly, this script runs in the context of a popup window, and we were using a third off-screen window to carry out individual print jobs. When this off-screen window closed, the script focus was actually returned to the main window, not the popup which launched the off-screen window, a bug if ever I saw one! We have modified the example file to explicitly change context back to the RoboPrint popup once processing of print-jobs has been completed. You can download the revised example file at the bottom of this article.

 

Introduction

For those not familiar with WebDirect think of it as Instant Web Publishing enhanced. Whereas IWP was fairly static, the goal for WebDirect is to be more dynamic and responsive to user interaction. Most FileMaker Pro functionality is there in WebDirect and the overall experience can be made to feel very similar to FileMaker Pro. One of the key features it lacks though is the ability to print reports and this is quite an important feature if WebDirect is to be used as a substitute for FileMaker Pro as a deployment platform.

  

The implications of no printing in WebDirect

Because the Print script step is unsupported in WebDirect, the only other way to print is through the browsers print function. This however is a very poor substitute as the browser will only print the visible window contents. Any lists of records or any layout that cannot fit entirely in the visible window will not print. Without Preview mode we also have no ability for producing complex sub-summary reports or sliding of records. Basically, it just dun work!

Side note: when we say printing in this article what we really mean is preview mode and all that goes along with that (such as printing).

  

Okay so it doesn't print, so what can it do?

One thing WebDirect does do quite well is displaying interactive container data. What has that got to do with anything you ask? Well, it means displaying a PDF within WebDirect is pretty nice, so if we could generate a report as a PDF and display that to the WebDirect user instead, then this should allow them to scroll through it, preview it, and subsequently print it via printing of the PDF.

  

How will we generate a PDF for the WebDirect user?

This is at the heart of the entire framework. Unfortunately FileMaker Server is unable to natively generate a PDF. The only two FileMaker platforms capable of generating a PDF is FileMaker Pro and FileMaker Go. Go is obviously not an option so lets use FileMaker Pro! What we need to do is have a copy of FileMaker Pro responsible for the PDF generation of WebDirect user initiated reports.

This is not an uncommon technique and is something that sometimes is used when reports need to be e-mailed to users on a nightly basis. Because FileMaker Server cannot produce the PDF, we instead call on the help of a Robot copy of FileMaker Pro to do the effort of PDF generation. FileMaker Server can then attach and send the reports via a scheduled script or the copy of FileMaker Pro could just do this itself.

We shall call this copy of FileMaker Pro from this point on RoboPrint !

RoboPrint

  

What is the basic framework outline?

In the framework we refer to the WebDirect user as RoboUser and the robot copy of FileMaker Pro tasked with producing report PDFs as RoboPrint. The basic process of events is as such:

  1. RoboUser initiates a print job
  2. RoboPrint is polling for new print jobs and detects the request from RoboUser
  3. RoboPrint then runs the report on behalf of RoboUser.
  4. The resulting report is saved as a PDF document onto the print job and marked as done.
  5. RoboUser now sees their report has been generated and is able to view the PDF.

That is it in a nutshell. Now how this all actually works is a little more in-depth so we'll cover the process in a little more detail below and how this relates to the example framework file.

  

... For those who just want to get stuck in and see how it works...

Technical jargon and explanations of how it all works are below, but if you want to just fire up the example file and see what it's all about then you will need to do a few things first:

  • Example file needs to be hosted on FileMaker Server (because WebDirect is FMS only).
  • A copy of FileMaker Pro must be running the database logged in with username RoboPrint (no password), and the RoboPrint procedure must be running by clicking the launch button.
  • In WebDirect open the hosted database with username RoboUser. You can then click on any of the 3 report buttons to test.

If all goes well you should see the WebDirect RoboUser wait for the PDF to be generated. In FileMaker Pro you should see RoboPrint retrieve the print job, process it and mark it as done. Then back in WebDirect you'll see the resulting PDF displayed in an interactive container.

You can also test as RoboUser in either FileMaker Pro or FileMaker Go - this does not require WebDirect to test with. If you do not have access to WebDirect then so long as you can access the database (shared) in 2 copies of FileMaker Pro you will be able to test the demo.

  

Still a work in progress

This framework at this stage is by no means perfect. It was built out of necessity for a large WebDirect deployment and has so far stood up to the test and been a reliable means of generating reports in WebDirect which is why we have turned it into an article :) 

There will always be improvements that can be made to the framework and the intention is that others in the community will take the general method and build upon it for others.

  

Example File

Please find attached an example file. This file is provided to help you fully understand what is going on in the rest of the article below. Note that FileMaker 13 is required to view this example file.

The example file is intended to be a demonstration of a framework. This is not a modular style implementation currently so to use in your own solution you would recreate the functionality found within the file.

Click here to Download the Example File

  

  

The geeky stuff on how it works

   

Still with us?

Good. You have made it through the first part of the article - congratulations! If you are still here then perhaps you have downloaded the example file and had a look and are curious as to the technicalities behind how it works. It's not that complicated really! Below we'll just cover the basics of the framework so you can feel confident if you need to implement into your own solutions or to make any adjustments or improvements. 

  

The idea of a print job

In the framework is the idea of a print job. Because RoboPrint runs in FileMaker Pro, and RoboUser can be on any platform, there needs to be a method of communication between them in order to convey the type of report RoboUser wants to run, and any criteria around running it. We do this by way of a table funnily enough also called RoboPrint (just to confuse you!).

Each record in this table is an individual print job that is generated by a user for example lets say in WebDirect. The record contains a number of fields that will tell RoboPrint all the information it needs to generate the correct report. Most fields are self explanatory (you can check the comments on the fields for more info).

When a WebDirect user runs a report the script that is run will generate one of these records, populate it with the required information, and sit back and wait until the record is marked as either complete or in the event something went wrong marked with an error.

  

The request initiation script

When the WebDirect user wishes to run a report the generic script they run is called "Robouser - Initiate Print Job".

We pass 3 key parameters:

  • Type is a keyword that will tell RoboPrint what type of report the user wishes to run
  • Parameters is a text string of parameters that may be required to produce the correct report output.
  • Timeout - this is a period - in seconds - which will be used for how long the WebDirect user will wait for the report output to be delivered. Default is 30 seconds.

The rest of the script will launch a new virtual web window and go to the RoboUser PDF layout. It creates a print job and then simply sits and waits until the process if finished, or expires.

The nice thing about using a new window is that on WebDirect this acts as a 'virtual' window which from the users perspective looks like they have gone to a different page entirely.  We can just use an onTimer at this point for the timeout.  The user can also click a "Done" button on this screen which will delete their print request and close the window - taking them back to their original layout.

  

Custom Functions for parameters

The framework makes use of 4 custom functions for managing multiple script parameters and results. It's not terribly important you know how they work, but it is important to know how to use them for script parameters.  

To pass multiple parameters to a script we use the SetProperty function.  If you look at the initialisation script above it is taking three named parameters. We would pass these to the script in the following format:

The SetProperty function can be strung together with & to pass multiple named parameters.

In the property called "Parameters" , we can nest further multiple parameters here if need be.

The script uses the GetScriptProperty function to parse out this data. This function is basically a helper function that calls the GetProperty function, but will automatically pass through the Get(ScriptParameter) function, saving us having to do this bit.

Finally, GetResultProperty is exactly the same as GetScriptProperty with the difference that it will automatically pass through Get(ScriptResult), so is useful for parsing multiple script results.

  

RoboUser has sent a print request, what happens now?

RoboPrint should be initiated and running in a copy of FileMaker Pro. This is where print jobs are dealt with.  RoboPrint is launched using the script RoboPrint - Initiate Process.

Again a fairly simple script. It takes one optional parameter called Duration. This tells RoboPrint how many seconds it should wait between checking for new print jobs. The default is 2 seconds.

RoboPrint operates in a popup modal window which is completely locked down. We use a loop where processing occurs after the duration pause.  The loop carries on forever until the process is stopped.

At each check, the script RoboPrint - Process Print Jobs is run.

  

Processing print jobs

This script is responsible for checking for new print jobs, and for any found making sure the correct report is run. It is also responsible for generation of the resulting PDF, and any tidyup after that.

I won't go and post a big screenshot of the script here, you can check it out for yourself. The following are key points in the process flow of the script:

  • It will immediately exit if it finds no new print jobs
  • Two windows are utilised in processing of print jobs.  First is the main RoboPrint window which controls print job processing. The second is a helper window created off-screen. This special window is where the report itself is generated and the PDF is produced. The reason we use a second off-screen window is one of niceness. It ensures that the main RoboPrint window never changes context, and the dirty work of producing the report never gets seen.  The helper window is created and used for all print jobs being processed in this batch.
  • RoboPrint must ensure it can get a record lock on a print job record before it will process it. The reason is that it ensures a user may not be in the act of creating or deleting their print job.
  • The script will branch off and run a report-specific subscript whose responsibility is to correctly find the report records, set sort order, page setup etc.  At this point in the script the $Type variable passed as a parameter is utilised. This is the only part of this script that a developer will need to modify when new reports are added.
  • At any point in the process if any errors occur, these are marked on the print job record and that job is then considered processed. The user will see that an error has occurred and the reason for the error.  Errors can be at the FileMaker level (eg could not produce PDF) or at the report level (user tried to run an invoice report but no invoices matched their criteria...)

 

Branching to run report specific subroutines

As mentioned above, there has to come a time in this process where a script is run for the specific reports, as each report is different.

You can see this part of the script pictured below.  Each print job is tagged with a type keyword that is set into the local variable at the start of the script. Here is where you check the type and run your appropriate subroutine script, passing through the parameters that script will require.

 

Drinks Break!

  

How you should configure your report specific scripts

Okay back to it. There are a few rules that need to be followed when you setup your specific report scripts for use with RoboPrint.

  • Make sure there are no script steps that will pause the script, such as custom dialogs.
  • Make sure error capture is on - we cannot have any FileMaker dialogs appearing here as RoboPrint ain't gonna dismiss them!
  • In the event of an error, or a reason why the user can't run the report (e.g. no records, or no access) you should return a script result using the Setproperty function with the property name "Error". This will be set back onto the print job as an error that the user will be informed of.

Once done, your script just needs to exit without error. You needn't do anything regarding PDF generation, that is handled elsewhere, just finish!

  

Production of the PDF

The Process Print Jobs script is responsible for calling another sub-script to produce the PDF once the users custom report script has been executed.  This script is called "RoboPrint - Produce PDF"

The script again is pretty straightforward. We pass it the type of report simply for the purpose of the PDF filename.  By default the PDF filename is a combination of the current timestamp as a number, and the report type. This ensures a good chance of a unique PDF filename for the report.  You could change this here to whatever you wish the format to be for your solution.

The script will either return an error if for some reason the PDF could not be saved or the path to that PDF on disk.

  

Finally...

The process print jobs scripts final task is to take that PDF path and insert the PDF into an interactive container on the print job.  Once it does this, the print job is marked as completed, and the script will go onto the next print job if there is one, otherwise it is done.

  

The user has been waiting a while, what are they up to...

As soon as that PDF is inserted onto the print job, the user will see it magically appear in front of them

They will be able to scroll through the PDF and depending upon the browser they are using they will se some PDF controls that will let them print, save, zoom etc..

  

Print job statuses

We show the print jobs status both on the users screen, and in RoboPrint so that at all points of the process the user is kept notified of the status of their request. Statuses include 

  • Waiting: Print job not yet picked up for processing by RoboPrint.
  • In-Progress: RoboPrint has got the lock on the job and is now processing.
  • Completed: RoboPrint has finished and put the PDF onto the print job.
  • Error: Something went wrong. RoboPrint has put the error message onto the print job.

  

Some important information on SSL

Certain browsers such as Google Chrome and Firefox have security features that will mean you may notice some unusual behaviour when it comes to the PDF in the interactive content container. These browsers cannot display the content when secure connections to FileMaker Server (SSL) has been turned on within FileMaker Server. The reason is WebDirect will in this case use HTTPS protocol, however external container data will still use HTTP. In the event a secure site has insecure content within it, these browsers will flag it as such and prevent the content from displaying.

What you will see instead is either the icon/filename for the file (which you can actually still right click and export to view) or you will see a link in some cases which you can click to view the PDF.

While not ideal, there are possible ways around this but may involve accepting security dialogs when used first time.

This FileMaker knowledgebase article better documents the issue

 

Example File

Please find attached an example file. This file is provided to help you fully understand what is going on in the rest of the article above. Note that FileMaker 13 is required to view this example file.

The example file is intended to be a demonstration of a framework. This is not a modular style implementation currently so to use in your own solution you would recreate the functionality found within the file.

Click here to Download the Example File

 

Something to say? Post a comment...

Comments

  • Daniel Wood 24/02/2017 7:57am (7 years ago)

    hi Jenky, thank you for the comment.

    If you wanted to instead print a single record as opposed to all the records, then (based on the demo file) it requires simply modifying the parameters you pass to the print job script for that given report.

    Taking the demo as an example, the "Customers by State" report runs the initiate print job script, telling it what type of report to run, and what parameters are required.

    Limiting it to a specific record in this instance is somewhat tricky because as a webdirect user you don't actually know what the resulting found set will be until after the report is produced.

    However if you do know a very specific customer who you wish to print it for, then you can simply pass their primary key ID value through in the script parameter.

    In the demo file we use custom functions 'SetProperty' to pass parameters, and the script uses functions 'getscriptproperty' to then obtain them.

    the parameters passed in this case are:

    "SetProperty ( "Type" ; "Customers" ) &
    SetProperty ( "Parameters" ; SetProperty ( "Version" ; "State" ) )"

    You'd simply modify this for example and add a third parameter "SetProperty ( "CustomerID" ; $ID ) where $ID would be the value of the specific customer you'd want to print for.

    Then, it's a case of modifying the actual report script responsible for doing the search for customers. In this case the "Report - Customer Report" script, would obtain the customer ID from the $Parameters variable, in the same way that if you look in the script you can see it obtaining the $Version parameter.

    Then you just modify the search to include searching the customer ID for the value passed - if no customer ID was passed then no worry because it not search that field and you end up with the current version of the report finding all customers. but include an ID and it will restrict it down to one only.

    That's how you'd do it if you knew the customer you wanted to print for. If you simply want to just print the first result from the report, then you can do so in the "Roboprint - Print PDF" script, this script is responsbile for turning the output into a PDF. If you look at the "Save records as PDF" step and click on the 'specify options' setting, you'll note there is an option to Save Records being browsed. You can change this to 'Current Record'. In this case it will be the first record, as the webdirect user actually has no control over changing the record they're looking at - something normally done in preview mode when on desktop.

    Hope this helps!

  • JENKY 24/02/2017 5:47am (7 years ago)

    Love this article. Kinda late getting on the train. I like how this prints reports, but how can I make it print just one record? I've been able to set this up to print all the records in a specific form, but how about limiting to one record?

    I'm sure it's an easy answer, having difficulty figuring it out.

  • Eligio Ospina 08/11/2016 5:09pm (7 years ago)

    How do I go to a particular record in the Customers table if what I need is to print a form with the fields in that record?
    In which script do you search for that particular record?

  • JESSICA 26/10/2016 9:02am (7 years ago)

    Gracias por el post.
    Pero cual es el user y contraseña del archivo ejemplo?

  • Daniel Wood 15/07/2015 9:21am (9 years ago)

    Hi Stephen,
    Do you have any ability to run FileMaker Pro Advanced on their server (or do you have FMPA yourself) ? The script debugger would be my first port of call for checking what is happening - I don't have any real clues myself sorry. If you could get a copy of their system and run it locally in FMPA that would also help, but if it can be run on there server under their conditions it would be better.

    I might try a test here and see if I can replicate it to see if it is anything obvious.

  • Stephen Clough 14/07/2015 10:38pm (9 years ago)

    Daniel,
    We have just upgraded from FM13 to FM14 and our (3rd party) IT Support have installed FM14 Server and FM14 Pro successfully on their server. They have successfully started the Roboprint process, but it is not processing the RobuUser requests. We now get the message: "Roboprint could not complete the print job"
    Any ideas??

    Thanks,

    Stephen

  • Julia 10/02/2015 10:27am (9 years ago)

    Thanks Daniel. Appreciate the help. All is working great now!

  • Daniel Wood 02/02/2015 8:36am (9 years ago)

    hi Julia. So when RoboPrint runs and processes a print job, it first determines what type of print-job it is, and then calls the relevant sub-script to actually produce the report. It will be this script that is failing in your implementation. If your script that is responsible for correctly setting up your report is failing - here in this case in a Go to Layout (or go to related record) script step, then you will be ending up on the wrong layout, and when the PDF is saved, it is saving the main roboprint layout instead of your actual report.

    I would check your script that sets up the report as it seems you may be missing a go to layout script step, or are incorrectly getting to your layout & found set. If you use FileMaker Pro Advanced then use the script debugger and this should tell you exactly where its going wrong.

  • Julia 30/01/2015 3:47pm (9 years ago)

    Hello everyone,

    Many thanks for the directions here Daniel. I thought I had everything set up correctly but I'm having trouble getting the correct PDF generated. Currently a PDF is being created and is being inserted in the container file, the trouble is that the PDF appears to be a screenshot of the RoboPrint layout with the Processing Glayven message. Any thoughts?

    Appreciate it,

    Julia

  • Jesper 22/01/2015 3:51am (9 years ago)

    Hey guys,

    First of all. Thanks Daniel for showing us this technique. I just hope FileMaker is up to something regarding native functionality for printing.

    I want to point out an error I got while implementing this technique in a Windows Server environment. Apparently the error code 3 occurs while trying to insert the PDF if Quicktime isn't installed on the machine. Don't know if this is a no brainer for everybody else, but I didn't know that Quicktime was required for PDF functionality.

    Have a good one,

    Jesper

  • Daniel Wood 18/11/2014 3:55pm (9 years ago)

    Hi Nelson, I fielded a similar question not long ago about multi-file deployments. One possibility is to have a file dedicated to processing print jobs across multiple solutions. This file is connected to all databases on your server that need to use roboprint. The main file polls for print-jobs in its roboprint table. In much the same way as it currently runs, when jobs come in they get processed by a sub-script that runs the report and spits out a path to the PDF. However in this modified version, that script exists in other files. The roboprint file calls other files to give it back the PDF which it puts into its roboprint record and marks as done.

    The other separate database solutions would also have to have an external reference to the roboprint file such that it can display the print record, PDF etc. Basically we are taking components out of the single-file and placing some (the roboprint stuff) within the roboprint file, and other stuff (robouser related things) into separate databases. There is obviously going to be some replication here of functionality in individual separate database solutions, but I see no reason why this design would not work.

    Actually in thinking about it, you could make it a bit simpler in just having everything roboprint related in the one file, and having external files have a link back to roboprint. The only thing that would need to exist in each separate database would be scripts to be passed parameters such that it could run a report and return the PDF path. You could manage viewing the PDF by having separate databases simply go to a layout in roboprint file. On WebDirect switching to a different file could appear quite seamless.

  • Nelson 18/11/2014 12:34pm (9 years ago)

    Daniel, I set up the printing process on a different computer and it worked fine so I will chalk it up to a directory permissions thing on the computer that failed. I have another question. How would you suggest using this operation on more than one database. Meaning if robo print is running one database, a second can not be opened and print process launched.

  • Cristopher Crowder 18/11/2014 6:15am (9 years ago)

    I love the solution. I have not been able to get it to open the PDF. I have changed the path to where it saves. The container field does not open the pdf it just has a link. If i click the link it is a totally different filename than the name in the container field. The folder with the name is /Streaming/MainDB/ this is where the link points to. Is there a way to change where the link points to? I have looked through the scripts and am unable to find where to change it. I may be overlooking something.

  • Daniel Wood 17/11/2014 3:44pm (9 years ago)

    Hi Nelson. The saving of the PDF happens in the "RoboPrint - Produce PDF" script. I have noticed similar issues in the past (normally on windows), however for me these tended to happen when the filewin or imagewin (similarly on mac using filemac or imagemac) prefix for saving to disk. When these were replaced with simply file/image it resolved the issue.

    I have checked the demo file however and it is using "image" as its path which is what I would expect. You could try modifying the save path in the script to be documents/desktop (just for testing purposes) to see whether the temporary folder path is an issue. I've also seem sometimes that simply restarting the computer or FileMaker will resolve the issue.

    Cheers

  • Nelson 14/11/2014 4:45am (9 years ago)

    I came across and weird problem. I had roboprint set up and working fine by opening the database in filemaker on one computer, but when I open the database and start the roboprint process on another computer and a web direct user tries to create a print job the message received on the filemaker machine says it can't save the PDF because there is no space on the computer. Obviously this is a path problem, but I don't see how, when roboprint gets a temporary path. Any ideas? thank you

  • Cris 14/10/2014 10:50am (9 years ago)

    I love the solution. I have not been able to get it to open the PDF. I have changed the path to where it saves but when the link is created it goes to a different folder. It creates one in both folders. Is there a way to change where the link points to that I am overlooking? The folder with the name is /Streaming/MainDB/ this is where the link points to.

  • Garrett 24/09/2014 12:36am (10 years ago)

    Weird - my email address disappeared. Here it is again garrett.lafrance@gofixxit.com

  • Garrett 24/09/2014 12:32am (10 years ago)

    Daniel, It is Windows (Windows 7 Pro)

    I can definitely relate to confusion caused by Windows. I usually wind up on the wrong context myself as my 2 estimators currently have iPads but they want to upgrade to Android tablets :-/

    The missing link is of course printing. That's why it was great to see your detailed solution.

    Thanks again -garrett <garrett.lafrance@gofixxit.com>

  • Daniel Wood 23/09/2014 10:17am (10 years ago)

    Hi Garret, can you let me know if you are using windows? We did find the issue with windows where roboprint would get confused as to which window it was operating in and end up on the wrong context, giving errors. There is a fix which I hope to put into the demo file soon. Flick me your e-mail address and I can send you the fix for now (sorry I can't exactly remember the specific changes to detail here right now).

  • Garrett 23/09/2014 4:07am (10 years ago)

    Daniel,

    Such an excellently writ tutorial.

    I have been trying to get the example file to run and I've run into the same issue described by Stephen Clough. Trying using Chrome & Explorer I initiate a print job and see the FMP RoboPrint on the Sever process the job and mark it as complete. At this point the FMP Application stops working and I have to force quit it through the Task Manager.

    I have the latest server update 13.0.4.400. I am also using HTTPS and have approved my browsers to allow popup windows.

    Was there a solution to Stephen's problem?

    Thanks -garrett

  • Nelson 20/09/2014 6:19am (10 years ago)

    Adding image fixed it. Who would have thought. Thank you

  • Daniel Wood 19/09/2014 8:20am (10 years ago)

    Hi Nelson, have a look at this link as it seems to give the answer (using image instead of file for the path prefix) - http://fmforums.com/forum/topic/93592-insert-pdf-script-command-error/ (maybe this is you??)

  • Nelson 18/09/2014 12:37am (10 years ago)

    I'm using a Mac and I can run the insert PDF manually, just won't work through the script. I'll run debugger and see what error I get. Thanks for the quick response.

  • Daniel Wood 17/09/2014 2:50pm (10 years ago)

    Hi Nelson. First thing to make sure is that you haven't mistakenly deleted the "output file" container that is sitting off the right edge of the roboprint layout. For insert the field is required on the layout.

    Next, make sure your file is definitely read/write access for fmsadmin when it was put up on your server. If the file is still non-modifiable then actions such as inserting PDF would likely fail.

    Also, if you are using windows then I've found through another reader a bug that affects the roboprint scripts. After the first loop the scripts context changes to the main database window instead of the roboprint processing window which ends up breaking the scripts context. To resolve, in the "Roboprint - Process Print Jobs" scroll to the bottom and toward the end of the script you see a section that selects $ProcessWindow and then closes it. After the close window, add another "Select Window" script step and tell it to select the window $RoboWindow (the window name is stored in this variable). This seems to only be a windows issue.

    You could also try debugger on and check the error code your insert PDF step is giving, this could give an indication of why it is failing.

  • Nelson 17/09/2014 2:41pm (10 years ago)

    Great scripts. I have one problem and that is the PDF doesn't insert into the container field. If I change the path of the PDF to be saved on my desktop I can see the PDF being created and then when I change the path where the insert command should grab the file from it fails and doesn't insert the PDF. Can the insert command work when the script is looping? It gets through the produce PDF and then fails on the insert and the path variable is being set to the same path as the PDF gets saved. Any suggestions?

RSS feed for comments on this page | RSS feed for all comments

Categories(show all)

Subscribe

Tags