Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

XFRX recognizes two types of hyperlinks:

  • “normal” hyperlinks (printed in blue), which navigate to other places in the report or to an external web address (using hyperlinks is described in detail in “Interactive features /Hyperlinks” chapter na stránce 19) and
  • “custom event” hyperlinks (printed in green), where XFRX allows for assigning a custom VFP code that will be called when users click the hyperlink.

This “custom event” hyperlink feature can be used for invoking application specific actions (information forms, custom processes, etc.) or for implementing drill-down functionality – invoking detailed report where the field user clicked on is taken as a parameter for the report (for example, clicking a customer name in the report listing all customers can run a report with detail information about this specific customer). The new report can be directed to a new page of a multipage previewer, which could provide a comfortable environment for “drilling down” specific information – with the ability to go back to the original report without closing the current one, side by side report comparison, exporting / printing selected reports, etc.

Table of Contents

The custom event hyperlinks are defined the same way as normal hyperlinks: you add #UR A HREF= to the label or field comment, followed by “vfpev” as a “protocol”, followed by a FoxPro expression to evaluate.

Example: Hello world

#UR A HREF="vfpev:\\messagebox('Hello world')"
If you add this to a field on your report a “Hello world” messagebox pops up whenever you click on that field. 

Please be aware that the text following after HREF= is evaluated during the report execution, at the time the field is about to be rendered. The result is then stored with that particular field and evaluated again when users click on the field. For example, if you need to call your function with a customer ID as a parameter (for example stored in customers.cusID as an integer value), you use something like this:

#UR A HREF="vfpev:\\myfunction("+trans(customers.cusID)+")"

During the report generation the customers.cusID expression is evaluated and the results (e.g. myfunction(1), myfunction(2), etc.) are stored with the individual fields. Myfunction function with the stored parameter is then called when users click on the field.

Accessing the calling previewer

In case the custom event should result in running a new report, the routine that processes the new report may want to previewer the resulting output in the original previewer, in which the click event occurred. In that case, you can use thisviewer variable as the previewer reference. For example, the following hyperlink definition would be sending the previewer reference as the second parameter of runreport method:

#UR A HREF="vfpev:\\runreport('"+allt(customerid_a)+"',thisviewer)" 

Drilldown solution example

(The following example is available in the DrilldownSample subdirectory of the evaluation as well as commercial package).

The sample solution consists of three reports:

  • A customer index page followed by a brief list of customers. For each customer there is a list of last three orders, total number of orders and the total turnover:
  • When you click on the customer name, a new report with customer details is generated, listing all customer’s orders:
  • By clicking on an order number, an order detail report is generated:


Whenever a new report is generated, it is added as a new page to the previewer container:

 

Here is the full source code:

Code Block
languagevb
linenumberstrue
LparametersLPARAMS m.tnReportType, m.tuPar1, m.toViewer
SetSET PathPATH ToTO src; xfrxlib; libs; drilldownsample
 
LocalLOCAL m.loSession, m.lnRetval, m.lcPageCaption, m.loPreview
 
IfIF EmptyEMPTY(m.tnReportType)
   *
   * no report type was sent - we need to initialize the previewer
   * and run the 1st report
   *
   SetSET ClasslibCLASSLIB ToTO xfrxlib
   m.loPreview = CreateobjectCREATEOBJECT("frmMPPreviewer")
   m.tnReportType = 1
   m.toViewer = m.loPreview
EndifENDIF
 
*
* initialize the XFRX listener
*
m.loSession=EvaluateEVALUATE([xfrx("XFRX#LISTENER")])
m.lnRetval = loSession.SetParams(,,,,,,"XFF")
IfIF m.lnRetval = 0
  *
  * now let’s see which report we want to run, select the data
  * and run the report
  *
  DO CASE
 Do Case   CaseCASE m.tnReportType = 1
    Select      SELECT companyname From customers Order By;
            FROM customers ;
            ORDER BY companyname IntoINTO CursorCURSOR custindex
 
          ReportREPORT FormFORM custindex ObjectOBJECT m.loSession Nopageeject

   Select       SELECT * ;
            FROM customers INNER JoinJOIN orders OnON customers.customerid = orders.customerid ;
                           INNER JOIN orderdetails OnON orders.orderid = orderdetails.orderid ;
      order By      ORDER BY customers.companyname, customers.customerid, orderDate Desc, orders.orderid ;
            INTO CursorCURSOR custlist

        Report  REPORT FormFORM custlist ObjectOBJECT m.loSession
          m.lcPageCaption = "Customers list"
 
   Case  CASE m.tnReportType = 2
         Select SELECT * ;
            FROM customers INNER JoinJOIN orders OnON customers.customerid = orders.customerid ;
                           INNER JOIN orderdetails OnON orders.orderid = orderdetails.orderid ;
            orderORDER ByBY customers.companyname, customers.customerid, orders.orderid ;
            WHERE customers.customerid = m.tuPar1 ;
            INTO CursorCURSOR custlist

   Report Form         REPORT FORM custDet ObjectOBJECT m.loSession
            m.lcPageCaption = "Customers detail ("+AlltrimALLTR(m.tuPar1)+")"
 
  Case    CASE m.tnReportType = 3
        Select  SELECT * ;
            FROM customers INNER JoinJOIN orders OnON customers.customerid = orders.customerid ;
                           INNER JOIN orderdetails OnON orders.orderid = orderdetails.orderid ;
                           INNER JOIN products OnON products.productid = orderdetails.productid ;
         order By   ORDER BY customers.companyname, customers.customerid, orders.orderid ;
            WHERE orders.orderid = m.tuPar1 ;
            INTO CursorCURSOR custlist

          ReportREPORT FormFORM OrdDet ObjectOBJECT m.loSession
          m.lcPageCaption = "Order detail ("+AlltrimALLTR(StrSTR(m.tuPar1))+")"
   EndcaseENDCASE
EndifENDIF
 
*
* now preview the report
*
m.toViewer.previewXFF(m.loSession.oxfdocument, m.lcPageCaption)
*
* show the preview if not yet visible
*
IF IfNOT loPreview.Visible
= .F.
  *
  * preview in modal Windows
  *
  m.loPreview.Show(1)
EndifEENDIF

As you can see, the code is first called without parameters, which automatically runs the first report (customer list). Then the same code is then called (recursively – as the previewer is in modal mode) from the previewer when users click on the custom event with parameters controlling which report should be run, which parameters should be used for the select statement and what should be the caption of the corresponding page in the previewer.

The report fields’ comments are defined as follows:

Report

Field

Comment

Customer list

Customer name

#UR A HREF="vfpev:\\runreport(2,'"+allt(customerid_a)+"',thisviewer)"

Customer detail

Order number

#UR A HREF="vfpev:\\runreport(3,"+allt(str(orderid_a))+",thisviewer)"