Secure reporting through the web viewer and Javascript

You might have already known that you can program data to the web viewer on the fly using the “data:,” prefix in your web viewer location. So for example, if you wanted a web viewer on your layout to always display the data in the field SampleTable::HTMLText field, you could have the web viewer display that as if it were a hosted webpage by making your web viewer’s location “data:,” & SampleTable::HTMLText. You might even have used global variables to store highly variable HTML on the fly.

Now let’s take it a step further. Let’s say you need to build a report in your system. This report will be highly complex. The requirements are also a bit tricky:

  1. The report will contain multiple table-occurrences with highly variable data in a single view that flows, or may even be a columnar report with completely different data in the two columns, or have a variable number of columns in the output depending on the data for the found set. FileMaker’s layout tools unfortunately cannot deliver the level of drill-down that the report requires, and might result in too much white-space in your portal rows.
  2. The report is sensitive, and access to the file must be tightly-controlled to prevent editing.
  3. Users should be able to preview the report before printing

As you begin to review your options for constructing such a report, you might realize that the format requires something a little more fluid than FileMaker’s layout objects can reasonably provide, and even if the two-column format was negotiable (it’s not, according to the manager), it can be difficult to append to a PDF in order to create your next volume of data while also maintaining the desired security settings. Besides, if you generate the file down to the Pro Client’s desktop, that becomes a potential point of failure for the report if you have to store it back up again.

Let’s say for an inventory request, you need to generate a table that contains sizable rows that list all of the required parts for a given order, and that those parts will change from order to order. For example, let’s say your report needs to look something like this:

This report contains two columns showing different data, using tables that have variable row sizes and variable row counts.

Now, this report wouldn’t be impossible to develop in FileMaker, but it might be a bit inelegant in places, particularly if your row heights on those tables were variable. Whereas, with a little scripting, you could spit this exact report out in HTML format with fairly little effort, especially if your company logo was available on an intranet or in another readable network location. And now assuming that the management at Sci-Fi Outfitters Ltd. wanted inventory reports to be Matters of Record at their generation, the HTML generated by the report would remain constant even in the face of evolving data, like if someone went in and changed a part # later on, or added another flux capacitor to the day’s order after the report was run.

Obviously, HTML has its drawbacks: If your report uses container field pictures, for example. But in this case, with a bit of scripting and basic knowledge of HTML and css, you could generate this report fairly easily from FileMaker data and store that in a field without the data ever leaving the server or generating a file on the client’s computer.

Now let’s talk security.

Since HTML is a text file that could be manipulated fairly easily if it is allowed to be exported, it’s not exactly the first thing that pops to mind when you think “secure report.” And obviously, anyone with enough time and effort could create a reasonable counterfeit of your report in a word processor for the purposes of sending to the printer (which, frankly, they could do with any report). But if the HTML itself is stored in a FileMaker field, and in fact is never exported as a file that can be tampered with, it becomes a pretty reliable means of storing your report data in a snapshot way, plus you have the added bonus of having a “report preview” function simply by virtue of loading up the HTML. Furthermore, in this example, we want people to be able to SEE the webpage, and to PRINT the webpage, but not otherwise INTERACT with it–no “view source” option in the context menu that will allow them to copy the data to a text editor, change the 10 to an 11, and then save the file someplace or print it outside of FileMaker. With some creative scripting, you could put hidden fields with serial numbers in them to further thumbprint the file. If you script your report generation so that the HTML is generated and stuck in a field, but once the report is generated that field is now locked and un-editable, you can basically have your document digitally signed by FileMaker and protected by the file’s security layer, indicating the timestamp and account name of the person who generated the report and then the report is read-only from there on out.

There is a problem, however, in turning off user interaction on a web viewer to prevent a person from right-clicking and selecting “view source” to potentially copy and manipulate–that right-click context menu is how we tell the web viewer to print, after all!

We can get around this using simple Javascript. And this is where the system can really shine. Even if you don’t need to strictly lock out the user from interacting with the web viewer, having a button to Print Report clearly visible is just better design than expecting them to right-click in the web viewer to select Print. By embedding a little javascript in our <head> element of the HTML, we can trigger calling that code when we apply the HTML to the report.

<script type="text/javascript">
 function printrpt()
 {
 window.print();
 }
 </script>

We can trigger this bit of script with an onLoad() element in our body tag:

<body onLoad="printrpt()">

Rather than hard-code that line into our HTML when we generate it, we want the body tag for the scripted HTML generation to simply be <body>. This way, when we set the web viewer’s location to data:,[HTML], the user isn’t prompted to print when they just want to look at the report. However, what we can do is create a Print button on the layout that’s uses a Substitute function to force the print dialog:

Substitute([HTML]; “<body>”; “<body onLoad=\”printrpt()\”>”)

By doing this, you have created a Report Preview window that allows the user to view the report in a tamper-proof environment, while still allowing them to print the window’s contents.

Sample File!

Here is a sample file — this is in FMP12 format. Login YourNameHere, no password. It’s full access… have fun!

On the Report Manager layout, a list of reports appears on the left. Select a report (there should be 1) and it will appear in the preview window. Note that you cannot right-click or otherwise interact with the web-viewer. Clicking “Print Report” will cause the global variable to swap out the body tag with a body tag that contains the onLoad call to print.

Go to Inventory Activity and add a few line items, obviously QtyOrdered will put the line in the left column, QtyRcd will put the line in the right column, then Go back to Reporting and Generate the report. Once a report is generated, it cannot be re-generated for that day (fortunately you have full access and can go into the Reporting table and delete the record and try again). As you can see from the data, I tried entering an order for 2 light cycles after I generated the report — they will not appear, which is a completely arbitrary rule depending on the requirements of your reporting module, as the HTML generation is controlled through scripting, there’s no reason the report couldn’t be re-generated if you want to allow people the ability based on your own business’s rules.

 

2 Responses to “Secure reporting through the web viewer and Javascript”


  • I note that you can preview the report; but you can never actually print it, even after doing the full access delete thing and regenerating the report. I’m not sure what your expectations are.

    ALSO: the prefix needs to be data:text/html, not just data:,

    If you change the prefix and then:

    1. Copy the value from $$reporthtml
    2. Go to Safari and paste it into the URL field
    3. You will see a copy of the report AND finally
    4. You will be presented with the print dialog that is called by your javascript

    But the print dialog called in the javascript does not ever display when using FileMaker and the web viewer.

  • Hey Bruce!

    Yeah, apparently it works on Windows. We’re checking out why it doesn’t fire on Macs. Perhaps Safari simply suppresses it outright.

    As for the Data:, thing, it was copied from the FileMaker help files apparently:

    http://help.filemaker.com/app/answers/detail/a_id/6455/~/web-viewer-enhancements-in-filemaker-pro-9

    Go figure. Interesting that modern browsers could figure out what to do with it anyway.

Leave a Reply