+ All Categories
Home > Documents > Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side...

Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side...

Date post: 26-May-2018
Category:
Upload: lytram
View: 297 times
Download: 4 times
Share this document with a friend
42
Best Practice Web Client Scripting
Transcript
Page 1: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

Best Practice Web Client Scripting

Page 2: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

Copyright © 2016 Lexmark. All rights reserved.

Lexmark is a trademark of Lexmark International, Inc., registered in the U.S. and/or other countries. All other trademarksare the property of their respective owners. No part of this publication may be reproduced, stored, or transmitted in anyform without the prior written permission of Lexmark.

Page 3: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

Table of Contents

1 Introduction ......................................................................................................... 1

1.1 Scriptable Web Client Components ................................................................... 1

1.2 Scripting Prospects and Types ........................................................................... 1

1.2.1 Client-side Scripting ........................................................................................ 1

1.2.2 Server-side Scripting ....................................................................................... 2

1.2.3 ZUL Scripts ...................................................................................................... 2

2 Scripting API and Principles ............................................................................... 2

2.1 The $component$ Placeholder .......................................................................... 3

2.2 Full Qualified Class Names ................................................................................ 3

2.3 Mask Cache ......................................................................................................... 3

3 Web Client Scripting API .................................................................................... 3

3.1 Form API .............................................................................................................. 4

3.2 Element API ......................................................................................................... 4

3.3 Results List API ................................................................................................... 4

4 Events ................................................................................................................... 5

4.1 ZK Events ............................................................................................................. 5

4.2 ResultSet Events .................................................................................................. 5

4.3 Form Events ......................................................................................................... 5

5 How to Start Scripting ........................................................................................ 6

5.1 The Forms Designer ........................................................................................... 6

6 Script Examples ................................................................................................... 7

6.1 Field Validation .................................................................................................... 7

6.1.1 Scenario ........................................................................................................... 7

6.1.2 Example Code .................................................................................................. 8

6.1.3 Process Description ........................................................................................ 8

6.2 Default Values of Lookup Table .......................................................................... 8

6.2.1 Scenario ........................................................................................................... 8

6.2.2 Example Code .................................................................................................. 9

6.2.3 Process Description ........................................................................................ 9

6.3 Sending Selected Data to an External Application ............................................ 10

6.3.1 Scenario ........................................................................................................... 10

6.3.2 Example Code .................................................................................................. 10

Example Server-side Code ............................................................................ 10

Example Client-side Code ............................................................................. 10

6.3.3 Process Description ........................................................................................ 11

6.4 Restricting a Query ............................................................................................. 11

Page 4: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.4.1 Scenario ........................................................................................................... 11

6.4.2 Example Code .................................................................................................. 11

6.4.3 Process Description ........................................................................................ 13

6.5 Display "Select user..." Dialog ............................................................................ 13

6.5.1 Scenario ........................................................................................................... 13

6.5.2 Example Code .................................................................................................. 13

6.5.3 Process Description ........................................................................................ 15

6.6 Open Index Form of eFile Application in a Pop-up Window ............................. 15

6.6.1 Scenario ........................................................................................................... 15

6.6.2 Example Code .................................................................................................. 15

6.6.3 Process Description ........................................................................................ 17

6.7 Display of Differentiated Results ...................................................................... 18

6.7.1 Scenario ........................................................................................................... 18

6.7.2 Example Code .................................................................................................. 18

Listener of the first [Results] Button ("SHOW_MODE_ORDER") .............. 18

Listener of the second [Results] Button ("SHOW_MODE_RECEIPT") ....... 18

Listener of the Results List ........................................................................... 19

6.7.3 Process Description ........................................................................................ 20

6.8 Using Mash-Up with deduced Data ................................................................... 20

6.8.1 Scenario ........................................................................................................... 20

6.8.2 Example Code .................................................................................................. 20

Listener at Mash-Up (Server Script) ............................................................ 20

Mash-Up Script ............................................................................................. 22

6.8.3 Process Description ........................................................................................ 24

6.9 Deactivate Context Menu Entires in the Navigation/ Results List ................... 25

6.9.1 Scenario ........................................................................................................... 25

6.9.2 Example Code .................................................................................................. 25

6.9.3 Process Description ........................................................................................ 26

6.10 Embedding a Results List in an Index Form ..................................................... 27

6.10.1 Scenario ........................................................................................................... 27

6.10.2 Example Code .................................................................................................. 27

6.10.3 Process Description ........................................................................................ 28

6.11 Limitation of Lookup Fields with multiple Conditions ...................................... 28

6.11.1 Scenario ........................................................................................................... 28

6.11.2 Example Code .................................................................................................. 29

7 Practical Application: Downloading Documents via an External Applet ........... 30

7.1 Scenario ............................................................................................................... 30

7.2 Extending the Web Client by Own Classes ........................................................ 30

7.3 Create a Java Project ........................................................................................... 31

7.4 Implementing Logic and Behaviour ................................................................... 31

7.5 Code Examples .................................................................................................... 32

Page 5: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7.5.1 DocumentDownloader.java ............................................................................. 32

7.5.2 DownloadAppletCaller.jsp ............................................................................... 33

7.5.3 Applet Class ..................................................................................................... 34

7.6 Deploying the Extensions ................................................................................... 35

7.7 Creating Server-side Script ................................................................................. 36

7.8 Permissions ......................................................................................................... 37

Page 6: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

1.1 Scriptable Web Client Components

1

Best Practice Web Client Scripting

1 Introduction

This manual describes the fundamentals of Web Client scripting. Here you can learn more details, such

as

+ Which Web Client components can be adjusted by scripting?

+ Which scripting possibilities are available?

+ How do I start?

1.1 Scriptable Web Client Components

In the Web Client a set of components, that are the navigation panel, a query or index form, a results

list and a viewer can be opened.

While the navigation and the viewer component are not adjustable by scripting, scripts can be inserted

in forms and result lists. As a result, all input fields, buttons and result lists (including contained rows)

can be customized.

1.2 Scripting Prospects and Types

Generally, Web Client scripting can be divided in client-side scripting and server-side scripting.

1.2.1 Client-side Scripting

With client-side scripting it is possible to insert custom JavaScript Script code to a form. This enables

you to change or supervise the DOM Document Object Model) of the web page.

Client-side scripts are included by <script> tags in the HTML markup and are executed by the user agent.

As a result, all elements of a currently displayed web page are accessible. For example, the elements of

a form can be changed or a user’s form entry can be validated.

i The execution of client-side scripts take place when the browser is rendering the respective

page. Details of the syntax, possible functions and performance are therefore depending on the

JavaScript engine of your browser.

Summary

+ Scripting language: JavaScript

+ Execution via the browser

+ Enables the access to elements of the currently loaded page

Page 7: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

2 Scripting API and Principles

2

+ Fields of application: definition of own JavaScript methods which are called when required (e.g.,

as reaction to events)

+ Unsuitable for business logic

+ Pitfalls: In an AJAX application not all elements of a page are contained because the page content

may change dynamically.

1.2.2 Server-side Scripting

With server-side scripting it is possible to change the Web Client’s business logic. Thus, document

archiving, document revisioning or workflow functionalities can be customized by server-side scripting.

Additionally own logic and masks can be added to the Web Client.

Server-side scripts are implemented using the Java programming language and are executed at

server-side by a servlet-container, such as Tomcat. Server-side scripts can access both, client-side and

server-side components.

Summary

+ Scripting language: Java

+ Execution via application server (e.g., Tomcat)

+ enables access to server-side objects. ZK-API allows also access to client-side resources (e.g., client

script defined JavaScript functions)

+ Server scripts are executed by an interpreter within the ZK engine which runs on the application

server

+ Pitfalls: In cases the element is added to the page, possibly other elements are not available yet.

1.2.3 ZUL Scripts

A special form of server-side scripts are ZUL-files. “ZUL” stands for ZK User Interface Markup Language.

Via ZUL-files individual masks and its behaviour can be implemented. ZUL-files have an own XML syntax

and are interpreted and executed by the ZK-framework at server-side.

i ZK is the GUI framework by which the SAPERION Web Client is implemented.

For more information on the ZK-framework and ZUL-files, please refer to: http://www.zkoss.org/.

2 Scripting API and Principles

Before the first script is implemented, let’s take a look at the provided scripting API and some scripting

principles.

Page 8: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

2.1 The $component$ Placeholder

3

2.1 The $component$ Placeholder

Normally, you select the element in the mask to which you want to allocate your script. Element are for

example, a result list, input fields or buttons.

Since for server-side scripts the programming language is Java, references are needed to access objects.

Thus, a reference to the result list for example, is needed to access it from Java. This can be achieved

in using the provided $component$ construct.

i The $component$ construct always references the object the server-script is allocated to.

2.2 Full Qualified Class Names

Server script is interpreted and executed at runtime by the ZK-framework when the corresponding mask

is loaded by the Web Client. The dynamic code interpretation and execution requires the script to use only

full qualified Java class names, whenever non-ZK classes or classes from other packages than java.lang

are used

i To avoid failures in the source, we recommend to always use full qualified class names in

server-scripts when not using ZK or java.lang classes.

2.3 Mask Cache

After a mask definition has been changed in the Forms Designer (for example by adding a script) the

corresponding mask needs to be reloaded for the changes to take effect. A restart of the system or a new

registration by the user is not necessary.

The same applies for the Web Client as long as the mask cache is deactivated. Only when the mask cache

is deactivated the mask will be reloaded from the SAPERION core when the mask is reopened. The mask

cache is deactivated in the "web.xml". Set the following property:

<env-entry>

<description>Turns cache for masks on or off.</description>

<env-entry-name>masksCache</env-entry-name>

<env-entry-type>java.lang.Boolean</env-entry-type>

<env-entry-value>false</env-entry-value>

</env-entry>

i Please deactivate the mask cache in the "web.xml" when developing Web Client scripts.

3 Web Client Scripting API

This section provides an overview over important API calls needed to create valuable scripts.

Page 9: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

3 Web Client Scripting API

4

3.1 Form API

Since all components to which you can allocate scripts are embedded in a mask, usually the form API

is an appropriate entry point for all scripts. To get a reference to the form, the method getParentForm()

can be called on every $component$ instance. Following table shows the most important API calls.

Form API

Method Name Description

getFields () Returns a list of all fields contained in the form.

getButtons () Returns a list of all buttons contained in the form.

getResultSets () Returns a list of all result lists contained in the form.

doClearContent () Empties all fields of the form.

DoCreateSysMask (String) Loads the system query mask for the given DDC name.

DoCreateSysQueryMask (String) Loads the system index mask for the given DDC name.

3.2 Element API

The element API is valid for all form elements. Following table shows the most important API calls.

Element API

Method Name Description

getParentForm () Returns a reference to the surrounding form. This method can be called on every $component$ instance.

getFieldName () Returns the unique name of a form element.

setFieldInactive (TRUE/ FALSE) Activates/ deactivates a field.

setValueImplicity (SaPropertyVa-

lue)

Changes a field's value and notifies the surrounding form about the change.

3.3 Results List API

The resultSet API provides methods to manipulate a result list, get information about the currently

displayed results and performing queries. Following table shows the most important API calls.

Result List API

Method Name Description

clearResultSet () Empties the result list.

setSelectedIndex (int) Selects the row with the given index.

getSelectedIndex () Returns the index of the selected row.

getSelectedItems () Returns all selected rows.

getNumberOfIndexes () Returns the number of rows.

refresh () Reloads the result list.

selectNext () Selects the next row.

Page 10: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

4.1 ZK Events

5

Method Name Description

selectPrevious () Selects the previous row.

selectFirst () Selects the first row.

selectLast () Selects the last row.

performQury (SaQueryInfo) Performs the given query and displays the result.

i A complete API overview can be found in the Javadoc of the Web Client distribution package.

4 Events

The Web Client works event-based which means that every action triggers an event and thus this event

can be used to perform event-based actions. This section provides an overview of important events.

4.1 ZK Events

ZK-framework events can be captured on server and client side.

ZK Events

Event Name Description

onClick Is triggered on a mouse click.

onBlur Is triggered when an insert field loses its focus.

onFocus Is triggered when an insert field gets the focus.

onChange Is triggered when the value of an element changes.

onSelect Is triggered when the selection of a list element changes.

onCheck Is triggered when checkbox is selected.

onCreate Is triggered when an element and its child elements are created.

4.2 ResultSet Events

A result list basically has one essential event:

ResultSet Event

Event Name Description

onIndexChange Is triggered when the result list entries are changed.

4.3 Form Events

A Form has basically two important events:

Page 11: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

5 How to Start Scripting

6

Form Events

Event Name Description

onDisplayResultItem Is triggered when a document is shown in the form.

onSaveDoc Is triggered when a document was saved by the form.

5 How to Start Scripting

i The following chapters of this scripting guide will focus on server-side scripting, anyhow in section

#"Sending Selected Data to an External Application" you can find an example of a client-side

script.

This section describes the first scripting steps.

5.1 The Forms Designer

The starting point of all scripting actions is the SAPERION Forms Designer which can be opened via

the Rich Client. All masks are created by means of the Forms Designer, therefore you need to integrate

your own scripts here.

1. Open the Forms Designer in the Rich Client by clicking DESIGN ribbon > APPLICATIONS

group > CREATE SEARCH FORMS command. The Forms Designer opens.

2. Select the required element that you want to be scripted. In the "Properties" panel, on the

right, the two property entries "Server-script" and "Client-Script" can be found.

3. Select the kind of script by clicking the according [...] button. Depending on you selection,

the "Server-Script" resp. the "Client-Script" window opens.

Page 12: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.1 Field Validation

7

4. Enter the script code as needed.

6 Script Examples

This section provides some scripting examples along with description.

6.1 Field Validation

6.1.1 Scenario

This example demonstrates how to validate an user’s entry in a specific field (named "SupplierNo") of

an index form. Before the changes are saved in the archive, a validation should be executed for checking

whether all fields are completed. The validation is processed when the user submits his entry.

In cases the field "SupplierNo" has not been filled, the user receives a notification.

Page 13: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

8

For this purpose the script needs access to the field value and must have influence to the event editing.

Use a server-script and allocate it to the [OK] button of the index form.

6.1.2 Example Code

$component$.addEventListener("onClick", new EventListener(){

public void onEvent(Event event) {

com.saperion.ngc.iform.IntelligentFormView form = $component$.getParentForm();

List fields = form.getFields();

for (com.saperion.ngc.iform.field.IntelligentField field : fields) {

if (field.getFieldName().equalsIgnoreCase("SupplierNo")) {

if (field.getValue().length() == 0) {

Messagebox.show("SupplierNo muss angegeben werden.", "Fehler",

Messagebox.OK, Messagebox.EXCLAMATION);

event.stopPropagation();

}

}

}

}

});

6.1.3 Process Description

In order to perform the validation, when the user submits the form, the above mentioned script has been

allocated to the [OK] button of the form. A new event listener for the "onClick" event is registered. When

the event was triggered, the "onEvent" method of the registered event listener is called.

In this case "$component$" points to the [OK] button. Via "getParentForm" the surrounding form

reference is obtained. With the form reference at hand a list of all form fields is delivered by calling

"getFields". The FOR loop iterates over all form elements. But only for the "SupplierNo" field the length

of the current value is checked (methods used: "getFieldName" and "getValue").

In case the field is empty (value length is zero) a message box is shown to the user. Since the form is

not valid the event is stopped via "event.stopPropagation" in order to not save the form changes.

6.2 Default Values of Lookup Table

6.2.1 Scenario

In this example the user has to index various documents by filling the same fields for each document.

The values of the fields are interdependent so that some fields are filled automatically as soon as a

particular field is available. In our example the user enters a value into the field "SupplierNo" and the

corresponding fields "Name", "Address" and "Phone" are filled automatically. The values are loaded

from a lookup table.

Page 14: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.2 Default Values of Lookup Table

9

For this purpose the field "SuppplierNo" is necessary.

6.2.2 Example Code

$component$.addEventListener("onBlur", new EventListener() {

public void onEvent(Event event) {

String value = $component$.getValue();

if (value != null && value.length() > 0) {

com.saperion.ngc.model.ClassicConnectorProvider provider =

new com.saperion.ngc.model.ClassicConnectorProvider();

com.saperion.connector.SaClassicConnector connector = provider.get();

com.saperion.rmi.SaQueryInfo info = new com.saperion.rmi.SaQueryInfo(

"from suppliers s where s.SUPPLIERNR = " + value);

List result = connector.searchHQL(info);

if (result.size() > 0) {

com.saperion.intf.SaDocumentInfo supplier =

(com.saperion.intf.SaDocumentInfo) result.get(0);

for (com.saperion.ngc.iform.field.IntelligentField field :

$component$.getParentForm().getFields()) {

if (field.getFieldName().equalsIgnoreCase("SupplierName")) {

field.setValueImplicitly(supplier.getValue("Name"));

} else if (field.getFieldName().equalsIgnoreCase("SupplierAddress")) {

field.setValueImplicitly(supplier.getValue("Address"));

} else if (field.getFieldName().equalsIgnoreCase("SupplierPhone")) {

field.setValueImplicitly(supplier.getValue("Phone"));

}

}

}

}

}

});

6.2.3 Process Description

The code above is allocated to the field where the user enters the supplier number ($component$ refers

to the "Field" entry). Once this field has been filled and lost its focus the script is executed since an

"onBlur" event listener is used.

First, the entered value is checked to be not "null" and to have more than zero characters. If so, a database

query is performed. This is done by the means of the Classic Connector. An already logged in Classic

Connector instance is retrieved by the Classic Connector Provider. The method "searchHQL" is used to

perform the query.

After the query result is checked not to be empty, the first row is excluded by the call "result.get(0)".

Query result rows are represented by "SaDocumentInfo" objects which stand for the suppliers in this

Page 15: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

10

example. A FOR-loop is used to iterate through the form fields. Specific fields (identified by their name)

are manipulated with the values "Name", "Address" and "Phone" of the selected supplier.

6.3 Sending Selected Data to an External Application

6.3.1 Scenario

This example shows how to send selected result list data to an external application. The external program

is a simple web application and the data are transmitted as URL parameters.

For the purpose of sending data, a new context menu element is available for the user.

This example covers both, server-side and client-side scripts. The server-side code directly calls a

client-side JavaScript function.

6.3.2 Example Code

6.3.2.1 Example Server-side Code

Menuitem item = new Menuitem("External");

item.addEventListener("onClick", new EventListener() {

public void onEvent(Event event) {

List rows = $component$.getSelectedRows();

if (rows.size() == 1) {

com.saperion.ngc.model.resultset.ResultProperties row = rows.get(0);

String invoiceNo = row.getPropertyAsString("InvoiceNo")[0];

String amount = row.getPropertyAsString("Amount")[0];

String supplierNo = row.getPropertyAsString("SupplierNo")[0];

String jscript = "openExternal('" + invoiceNo + "', '" + amount +

"', '" + supplierNo +"');";

Clients.evalJavaScript(jscript);

}

}

});

$component$.addCustomMenuItem(item, false);

});

6.3.2.2 Example Client-side Code

function openExternal(invoiceNo, amount, supplierNo) {

window.open("http://localhost:8080/SimpleApp/index.jsp?InvoiceNo="

+ invoiceNo + "&Amount=" + amount + "&SupplierNo=" + supplierNo,

"_blank", "width=500, height=600, location=no, status=no,

Page 16: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.4 Restricting a Query

11

dependent=yes, resizable=yes");

}

6.3.3 Process Description

The server-side script is allocated to result list of forms. First, a custom menu item with the name

"External" is created. Then an event listener is registered to this menu item. This listener is invoked when

the user clicks on the menu item.

The "onEvent" method first gets the selected rows of the result list the script is allocated to. If only

a single result list row is selected, the scripts perform any further. Via "rows.get(0)" the first and

only selected row is retrieved which is represented by a "ResultProperties" object. Using the object’s

"getPropertyAsString" method the data by the name of "Invoice no.", "Amount" and "Supplier no." are

retrieved. Since SAPERION supports multivalue fields a call to "getPropertyAsString" returns an array.

By using [0], the first array entry is returned.

Having the requested data, the JavaScript function call is built as a String. Via the ZK call

"Clients.evalJavaScript" the JavaScript function call is executed at client side.

To ensure that the JavaScript function will be performed successfully the corresponding function must

also exist at client-side. As shown in the script example above, required data are taken as parameters.

The script opens a new browser tab/ window and calls a simple JSP-site passing in the data as URL

parameters.

6.4 Restricting a Query

6.4.1 Scenario

The current logged in user executes a query ans should only see the results list that is restricted to his

rights. Which documents are displayed to him is maintained in a special lookup-table (DDC named

"invoices_user").

In this example customer's invoice data in a DDC are pre-filtered. Customers are identified by the

customerID.

6.4.2 Example Code

$component$.addEventListener("onButtonQuery", new EventListener() {

public void onEvent(Event event) {

// get classic connector

com.saperion.ngc.model.ClassicConnectorProvider provider = new

com.saperion.ngc.model.ClassicConnectorProvider();

com.saperion.connector.SaClassicConnector conn = provider.get();

// get current user name

com.saperion.ngc.main.HttpSessionWrapper wrapper = new

com.saperion.ngc.main.HttpSessionWrapper();

com.saperion.ngc.model.authorization.User user =

Page 17: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

12

(com.saperion.ngc.model.authorization.User) wrapper

.getAttribute(com.saperion.ngc.main.HttpSessionWrapper.USER_ATTR);

String username = user.getName();

// check database for user enclosures

String sql = "select KDNR from invoices_user where USERNAME =

:user_name";

com.saperion.rmi.SaQueryInfo query = new

com.saperion.rmi.SaQueryInfo(sql);

query.setParameter("user_name", username);

try {

List enclosures = conn.searchHQL(query);

// return if no enclosure is available for the user

if (enclosures.isEmpty()) {

System.out.println("Empty list: No enclosure found for user: " +

username);

return;

}

com.saperion.intf.SaDocumentInfo data =

(com.saperion.intf.SaDocumentInfo) enclosures.get(0);

String[] numbers = data.getValue("KDNR").getStringValues();

String inStm = com.google.common.base.Joiner.on(",").join(numbers);

if (inStm.isEmpty()) {

System.out.println("No enclosure found for user: " + username);

return;

}

com.saperion.ngc.events.iform.ResultFieldEvent orig =

(com.saperion.ngc.events.iform.ResultFieldEvent) event;

if (null != orig) {

// create custom condition

String condition = " IN (" + inStm + ")";

com.saperion.ngc.iform.CustomConditionBean ccb = new

com.saperion.ngc.iform.CustomConditionBean("Kundennummer",

"KUNDENNUMMER", false, condition);

//append condition to form filter list

orig.getList().add(ccb);

}

} catch (Exception e) {

e.printStackTrace();

}

}

Page 18: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.5 Display "Select user..." Dialog

13

});

6.4.3 Process Description

The server-side script is allocated to the results list. An event listener is registered to the

"onButtonQuery" event which is fired as soon as the user clicks on the [Results]/ [Search] button.

First, the "onEvent" method creates an instance of the SaClassicConnector which is needed for the search

of the user-customerID correlation in the lookup-DDC. To perform the query, the user name of the current

user is also needed. The name can be retrieved from the Web Client session.

The user name can then be matched via the SaClassicConnector-method "searchHQL" against the

lookup-DDC. The matching results are listed in a comma-separated list.

In order to send this generated list of IDs along with the search criteria that is stated by the user, the

"CustomConditionBean" is used. This bean describes the additional search criteria and is attached to

the existing query conditions via the "orig.getList().add" call.

The user gets a results list where his search criteria are considered, but which is also restricted to his

rights.

6.5 Display "Select user..." Dialog

6.5.1 Scenario

In an index form of the Web Client the "Select user..." dialog should be opened at the push of a button.

The user can then select and assume the required user for the index field.

6.5.2 Example Code

package com.saperion.ngc.resultset;

import com.saperion.intf.wf.WorkflowMember;

import com.saperion.ngc.dialogs.userselect.UserSelectionDialog;

import com.saperion.ngc.dialogs.userselect.UserSelectionDialog.UserSelectionResult;

import com.saperion.ngc.exception.NgcUiException;

import com.saperion.ngc.iform.IntelligentFormView;

import com.saperion.ngc.iform.button.FormButton;

import com.saperion.ngc.iform.field.TextField;

import com.saperion.ngc.resultset.ResultSetPresenter;

import com.saperion.ngc.resultset.ResultSetView;

import com.saperion.ngc.resultset.ResultSetViewImpl;

import org.zkoss.zk.ui.event.Event;

import org.zkoss.zk.ui.event.EventListener;

Page 19: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

14

public class ChooseUser {

public static void method(final Object component){

final FormButton button = (FormButton) component;

button.addEventListener("onClick", new EventListener() {

public void onEvent(Event event) throws NgcUiException{

IntelligentFormView parentForm = button.getParentForm();

final TextField textField = (TextField) parentForm.

getFieldByFrameId(40);

ResultSetView resultSetView = parentForm.getResultSets().get(0);

ResultSetPresenter resultSetPresenter = ((ResultSetViewImpl)

resultSetView).getPresenter();

WorkflowMember userTree = resultSetPresenter.getUserTreeRoot("");

// event listener used by UserSelectionDialog

EventListener dlgEvtListener = new EventListener() {

@Override

public void onEvent(Event event) throws Exception {

UserSelectionResult userResult = (UserSelectionResult)

event.getData();

if (userResult.getButton() == UserSelectionDialog.

OK_BUTTON) {

if (userResult.getSelectedUsers().size() > 0){

textField.setText(userResult.

getSelectedUsers().get(0).

getName().toString());

textField.setChangedImplicitly();

}

}

}

};

UserSelectionDialog.show(resultSetView, resultSetPresenter, userTree,

false, dlgEvtListener);

}

});

}

Page 20: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.6 Open Index Form of eFile Application in a Pop-up Window

15

}

6.5.3 Process Description

In this example a class "ResultSetPresenter" that has the visibility "Package" from the Web Client has to

be used. In order to avoid a modification of the ResultSetPresenter code the above mentioned script is

set into the same package as the ResultSetPresenter itself - "com.saperion.ngc.resultset".

You have to create a JAR out of the script. By "package com.saperion.ngc.resultset;"

it is defined that this class belongs logically to the same package (although it is

physically in a different JAR) as the Web Client. Into the server script field only the call

"com.saperion.ngc.resultset.ChooseUser.method($component$);" is entered.

In the example code an onClick listener is assigned to the [Select user] button. When clicking, the text

field in which the selected user has to be filled is specified (in the sample code: field with ID 40).

The ResultSetView provides the mentioned ResultSetPresenter which represents the amount of users

("userTree").

A further listener ("dlgEvtListener") catches the click on the [OK] button in the user selection dialog and

fills the selection into the defined text field.

6.6 Open Index Form of eFile Application in a Pop-up

Window

6.6.1 Scenario

In an eFile application documents should be populated into a record. Due to the reason that documents

filed are not physically existing files but only meta data, the index form should be opened not via

documents but at a push of a button. This pop-up window should be opened until the user closes

it actively. In this way, multiple documents can be indexed successively. When there are no further

documents to be indexed the user clicks on the [Done] button in order to close the pop-up-window.

6.6.2 Example Code

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.zkoss.zk.ui.Component;

import org.zkoss.zk.ui.event.Event;

import org.zkoss.zk.ui.event.EventListener;

import org.zkoss.zk.ui.event.Events;

import com.saperion.connector.SaClassicConnector;

import com.saperion.intf.SaSaveInfo;

import com.saperion.ngc.events.navigation.FolderSearchInfos;

import com.saperion.ngc.events.resultset.NewItemEvent;

Page 21: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

16

import com.saperion.ngc.iform.FieldResultBean;

import com.saperion.ngc.iform.FormMode;

import com.saperion.ngc.iform.IFormPopupResult;

import com.saperion.ngc.iform.IntelligentFormPopupWindow;

import com.saperion.ngc.iform.IntelligentFormView;

import com.saperion.ngc.iform.button.FormButton;

import com.saperion.ngc.model.ClassicConnectorProvider;

import com.saperion.ngc.resultset.ResultSetView;

import com.saperion.structures.DocumentInfo;

public static final String MASK_NAME = "dokument_i";

public static final String DDC_NAME = "dokumente";

public static final String POPUP_LABEL = "Indexierung-["+MASK_NAME+"]";

final FormButton button = (FormButton)$component$;

final IntelligentFormView parentForm = button.getParentForm();

final FolderSearchInfos folderInfos = parentForm.getCurrentFolderSearchInfos();

public void onEvent(Event event) {

createPopup();

}

private void createPopup(){

final Component window = IntelligentFormPopupWindow.show(POPUP_LABEL, null, true,

false);

Events.sendEvent(window, new NewItemEvent(window, MASK_NAME, DDC_NAME,

FormMode.INDEX_POPUP));

window.addEventListener("onFBOk", new EventListener() {

@Override

public void onEvent(Event event) throws Exception {

IFormPopupResult popupResult = (IFormPopupResult) event.getData();

ClassicConnectorProvider provider = new ClassicConnectorProvider();

SaClassicConnector connector = provider.get();

Map<String, Object> beanMap = fieldResultsToMap(popupResult.

getFieldResultBeans());

DocumentInfo doc = new DocumentInfo(DDC_NAME, beanMap, null, "");

SaSaveInfo info = connector.createDocument(doc);

connector.addToFolder(folderInfos.getContainingFolder().getDdcName(),

info.getSysRowId(), DDC_NAME, folderInfos.

getContainingFolder().getObjectId());

Page 22: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.6 Open Index Form of eFile Application in a Pop-up Window

17

for (ResultSetView resultSet : parentForm.getResultSets()){

resultSet.refresh(true);

}

window.detach();

//do a loop as long as not chanceled ("Fertig")

createPopup();

}

private Map<String,Object> fieldResultsToMap (

List<FieldResultBean> fieldResultBeans){

Map<String,Object> map = new HashMap<String, Object>();

for (FieldResultBean bean : fieldResultBeans){

map.put(bean.getDatabaseFieldName().replace(

"[", "").replace("]", ""),

bean.getValue()[0].asString());

}

return map;

}

});

window.addEventListener("onChancel", new EventListener() {

@Override

public void onEvent(Event event) throws Exception {

window.detach();

}

});

}

});

6.6.3 Process Description

The [Index document] button has a listener that starts the method "createPopup" when clicking on. This

method uses internally IntelligentFormPopupWindow.show() and sends an event which defines which

form to be displayed in the created window and on which DDC it is based.

The form contains the two buttons [OK] and [Done] which send automatically events to the form when

clicking on. In order to equip the buttons with functionality two listeners are attached to the form which

listen to events. The "onFBOk"-listener collects the entered index data and creates a document in the

Page 23: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

18

appropriate data format via Classic Connector in the DDC. Because it is an eFile application here, the

document must be filed into the correct record. This is achieved by the "connector.addToFolder(…)"-call.

6.7 Display of Differentiated Results

6.7.1 Scenario

In the forms designer you have the facility of linking conditions to the the [Results] button, e.g., via SQL

code, which leads to a prefiltered display of results. But this linking has only effect to the Rich Client. For

the purpose of a prefiltered results list in the Web Client the following script is implemented.

6.7.2 Example Code

In the following you are provided the example scripts for the [Results] buttons that deliver the respective

results list.

6.7.2.1 Listener of the first [Results] Button ("SHOW_MODE_ORDER")

import org.zkoss.zk.ui.event.Event;

import org.zkoss.zk.ui.event.EventListener;

import com.saperion.ngc.iform.IntelligentFormView;

import com.saperion.ngc.iform.button.FormButton;

$component$.addEventListener("onClick", new EventListener() {

public void onEvent(Event event) {

IntelligentFormView parentForm = (IntelligentFormView) ((FormButton) $component$).

getParentForm();

parentForm.setAttribute(ScriptConstants.SHOW_MODE, ScriptConstants.SHOW_MODE_ORDER);

}

});

6.7.2.2 Listener of the second [Results] Button ("SHOW_MODE_RECEIPT")

import org.zkoss.zk.ui.event.Event;

import org.zkoss.zk.ui.event.EventListener;

import com.saperion.ngc.iform.IntelligentFormView;

import com.saperion.ngc.iform.button.FormButton;

$component$.addEventListener("onClick", new EventListener() {

public void onEvent(Event event) {

Page 24: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.7 Display of Differentiated Results

19

IntelligentFormView parentForm = (IntelligentFormView) ((FormButton) $component$).

getParentForm();

parentForm.setAttribute(ScriptConstants.SHOW_MODE, ScriptConstants.SHOW_MODE_RECEIPT);

}

});

6.7.2.3 Listener of the Results List

import org.zkoss.zk.ui.event.Event;

import org.zkoss.zk.ui.event.EventListener;

import com.saperion.ngc.events.iform.ResultFieldEvent;

import com.saperion.ngc.iform.CustomConditionBean;

import com.saperion.ngc.iform.IntelligentFormView;

import com.saperion.ngc.resultset.ResultSetView;

$component$.addEventListener("onButtonQuery", new EventListener() {

public final static String ATTRIBUTE = "ID";

@Override

public void onEvent(Event event) throws Exception {

IntelligentFormView parentForm = (($component$)ResultSetView).getParentForm();

ResultFieldEvent origEvent = (ResultFieldEvent) event;

if (null != origEvent) {

//delete evtl. former additional beans

CustomConditionBean ccbOrder = new CustomConditionBean(ATTRIBUTE,

ATTRIBUTE.toUpperCase(), false, " IS NULL ");

CustomConditionBean ccbReceipt = new CustomConditionBean(ATTRIBUTE,

ATTRIBUTE.toUpperCase(), false, " IS NOT NULL ");

origEvent.getList().remove(ccbOrder);

origEvent.getList().remove(ccbReceipt);

//create custom condition

if (ScriptConstants.SHOW_MODE_RECEIPT.equals(

parentForm.getAttribute(ScriptConstants.SHOW_MODE))){

origEvent.getList().add(ccbReceipt);

} else if (ScriptConstants.SHOW_MODE_ORDER.equals(

parentForm.getAttribute(ScriptConstants.SHOW_MODE))){origEvent.getList().add(ccbOrder);

}

}

}

Page 25: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

20

});

6.7.3 Process Description

The results list knows the event "onButtonQuery“ which is handed over when clicking on one of

the [Results] buttons. Because there is no differentiation which of the buttons has caused the event

both of the event listener obtain an appropriate attribute including value which is then attached to

the superordinated form when triggered (parentForm.setAttribute( ScriptConstants.SHOW_MODE,

ScriptConstants.SHOW_MODE_ORDER);).

Furthermore, at the event "onButtonQuery" the results list obtains additionally a listener that reads

the attribute and - depending the value - extends the event by the appropriate SQL condition

(origEvent.getList().add(ccbReceipt);).

6.8 Using Mash-Up with deduced Data

6.8.1 Scenario

In an eFile application metadata of documents are previewed in a table when clicking on the file cover.

For this purpose a so called mash-up is used. This is a form element which can be programmed by

JavaScript.

For this, the two methods "setValue(name,value)" and "execute()" are provided. A server-side script in

Java obtains the metadata of the documents and on the client side these data are presented in a table

by means of the above mentioned JavaScript methods.

6.8.2 Example Code

6.8.2.1 Listener at Mash-Up (Server Script)

Listener am Mash-Up (serverscript)

import java.util.HashMap;

import java.util.LinkedList;

import java.util.List;

import org.zkoss.json.JSONObject;

import org.zkoss.zk.ui.event.Event;

import org.zkoss.zk.ui.event.EventListener;

import com.saperion.connector.SaClassicConnector;

import com.saperion.constants.SaConstants.SaFieldType;

import com.saperion.intf.SaDocumentInfo;

import com.saperion.intf.SaPropertyValue;

import com.saperion.jni.SaJNIValue;

import com.saperion.ngc.events.resultset.IndexResultItemEvent;

import com.saperion.ngc.iform.IntelligentFormView;

Page 26: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.8 Using Mash-Up with deduced Data

21

import com.saperion.ngc.iform.field.IntField;

import com.saperion.ngc.iform.xml.EditFieldType;

import com.saperion.ngc.model.ClassicConnectorProvider;

import com.saperion.ngc.model.resultset.ResultProperties;

import com.saperion.ngc.model.resultset.ResultProperty;

import com.saperion.rmi.SaPropertyValueImpl;

import com.saperion.rmi.SaQueryInfo;

$component$.addEventListener("onCreate", new EventListener() {

public static final String DDC_NAME = "akte";

public static final String JSCRIPT_KEY = "mashup";

@Override

public void onEvent(Event arg0) throws Exception {

mask.getMashups().get(0).addEventListener("onIndexChange", new EventListener() {

@Override

public void onEvent(Event event) throws Exception {

ClassicConnectorProvider provider = new ClassicConnectorProvider();

SaClassicConnector connector = provider.get();

IndexResultItemEvent selectEvent = (IndexResultItemEvent) event;

ResultProperties props = selectEvent.getProperties();

if (props != null){

List<SaDocumentInfo> positions =

connector.searchFolderDocuments(

DDC_NAME, props.getProperty("SYSROWID").

getValue().getStringValue(),

new SaQueryInfo(""));

String jsonValue = "";

if (!positions.isEmpty()){

List<HashMap<String, String>> values = new

LinkedList<HashMap<String,String>>();

for (SaDocumentInfo pos : positions){

HashMap<String,String> position = new

HashMap<String,String>();

values.add(position);

for (SaPropertyValue val : pos.getValues()){

position.put(val.getName(),

val.getStringValue());

}

Page 27: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

22

}

jsonValue = listToJSONString(values);

}

EditFieldType eft = new EditFieldType();

eft.setDbFieldName(JSCRIPT_KEY);

eft.setFName(JSCRIPT_KEY);

SaPropertyValueImpl saVal = new SaPropertyValueImpl(DDC_NAME,

JSCRIPT_KEY, new SaJNIValue(jsonValue, SaFieldType.FT_STRING));

selectEvent.getProperties().setProperty(new

ResultProperty(saVal, eft));

}

}

private String listToJSONString(

List<HashMap<String, String>> list) {

String s = JSONObject.toString("",list);

//omit the "<key>:"

return s.substring(s.indexOf(":") + 1, s.length());

}

});

}

});

6.8.2.2 Mash-Up Script

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

<title>Insert title here</title>

<style type="text/css">

table#positiondata {

border: 1px dotted gray;

font-size: small;

max-width: 500px;

}

table#positiondata thead td {

padding-right: 10px;

font-weight: bold;

}

table#positiondata tbody td {

border-top: 1px solid gray;

}

</style>

<script type="text/javascript">

Page 28: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.8 Using Mash-Up with deduced Data

23

var valGlob = null;

function execute() {

var elTable;

var elRow;

var elCell;

var posData;

elTable = document.getElementById("data-body");

while (elTable.firstChild) {

elTable.removeChild(elTable.firstChild);

}

if (valGlob == null) {

return;

}

if (valGlob.length == 0) {

return;

}

posData = eval(valGlob);

for (i=0; i<posData.length; i++)

{

elRow = document.createElement("tr");

elCell = document.createElement("td");

elCell.innerHTML = posData[i].POS_MENGE;

elRow.appendChild(elCell);

elCell = document.createElement("td");

elCell.innerHTML = posData[i].POS_BESCHREIBUNG;

elRow.appendChild(elCell);

elCell = document.createElement("td");

elCell.innerHTML = posData[i].POS_GESAMTNETTO;

elRow.appendChild(elCell);

elCell = document.createElement("td");

elCell.innerHTML = posData[i].POS_KOSTENSTELLE;

elRow.appendChild(elCell);

elCell = document.createElement("td");

elCell.innerHTML = posData[i].POS_ARTIKELGRUPPE;

elRow.appendChild(elCell);

elTable.appendChild(elRow);

}

valGlob = null;

Page 29: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

24

}

function setValue(name, value) {

if (name.toLowerCase()=='mashup') {

valGlob = value;

}

}

</script>

</head>

<body>

<table id="data">

<thead>

<tr>

<td>Menge</td>

<td>Beschreibung</td>

<td>Netto Gesamt</td>

<td>Kostenträger</td>

<td>Artikelgruppe</td>

</tr>

</thead>

<tbody id="data-body">

</tbody>

</table>

</body>

</html>

6.8.3 Process Description

In the forms designer the linking from the lists of file covers to the mash-up has to be set. A click on the

file cover triggers the transfer of metadata to the mash-up. Data are then listed in a table by the mash-up.

A listener is set onto any field of the form. When creating this field the listener itself creates a

listener that is set onto the mash-up contained in the form. When clicking on the file cover the

"onIndexChange" event is treated first by the added listener. In the event the metadata of the file

cover are contained and can now be used for finding the according documents via Classic Connector

(connector.searchFolderDocuments(…)).

A JSON string (JavaScript Object Notation) is created out of the found metadata. This corresponds to

the string representation of the list of documents resp. their metadata ( [{key1:value1, key2:value2}, {

key1:value1, key2:value2}, { key1:value1, key2:value2}] ). This JSON string is added as new property to the

current event whereby a fix defined value ("mashup") is the key used in the JavaScript code.

The manipulated event is passed to the mash-up where its data are used to execute the

"setValue(name,value)" and "execute()" methods. In the JavaScript a table including table header is

defined by CSS. For each property of the event the "setValue(name,value)" method is called. In cases

a property which name corresponds to the defined value ("mashup") is found its JSON-String is saved

globally.

Page 30: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.9 Deactivate Context Menu Entires in the Navigation/ Results List

25

After the "setValue" method is called for all properties "execute()" will be carried out. The table that is

eventually filled by the last event will be emptied and prepared by means of DOM manipulation (e.g.,

elRow.appendChild(elCell);).

6.9 Deactivate Context Menu Entires in the Navigation/

Results List

6.9.1 Scenario

In all application folders the menu entries "Delete", "Rename" and "Create new folder" should be

deactivated. For this purpose, an own handler for menu entries can be allocated to the navigation that

determines dynamically the availability of context menu entries for certain folder types.

i Similar to other script samples, we recommend to create an own JAR-file and integrate it in the

Web Client for this purpose. In the interest of simplicity, the example below is not in a JAR-file.

The script is directly integrated in the "index.zul" file by adding a further attribute to the the navigation

element.

It is also possible to remove context menu entries of the results list. To this end, a list of menu entries

that should not be available can be handed over to the results list element of a form by means of a

server script.

6.9.2 Example Code

Deactivation of Menu Entries in the Navigation

<navigation id="navigation"

allowedMaxNrOfNodesPerLevel="20" fastAccessEnabled="true">

<attribute name="onCreate">

import com.saperion.ngc.navigation.NaviTreeNodeMenuHandler;

import com.saperion.ngc.model.navigation.intf.NavigationElement.TREE_ITEM_TYPE;

import com.saperion.ngc.navigation.NavigationView;

import com.saperion.ngc.navigation.NaviTreeNode;

import com.saperion.ngc.navigation.NaviMenuRights;

// the handler that will set the rights for each folder

class TestNaviTreeMenuHandler extends NaviTreeNodeMenuHandler {

public TestNaviTreeMenuHandler(NavigationView naviView) {

super(naviView);

}

public NaviMenuRights getMenuRights(NaviTreeNode node) {

NaviMenuRights rights = NaviMenuRights.getAllRights().disableDeleteFolder()

.disableRename().disableCreateFolder();

return rights;

Page 31: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

26

}

}

// Add the TestNaviTreeMenuHandler to the navigation tree

// Handler will be used for nodes of type FORM (Applications) only

navigation.addNodeMenuHandler(new TestNaviTreeMenuHandler(navigation), TREE_ITEM_TYPE.FORM);

</attribute>

</navigation>

Deactivation of Menu Entries in the Results List

import com.saperion.ngc.resultset.MenuItemKey;

// create the list of menu entries to remove

// entries are identified by a MenuItemKey

List itemsToRemove = new ArrayList();

itemsToRemove.add(MenuItemKey.DOC_DOWNLOAD);

// tell the result list to use the list for multi-selection menus

$component$.setRemoveMenuItemList(itemsToRemove, true);

// tell the result list to use the list for single selection menus

$component$.setRemoveMenuItemList(itemsToRemove, false);

6.9.3 Process Description

Deactivation of Menu Entries in the Navigation

In this sample, same rights are allocated to each folder. Due to the reason that the folder to be handled

is transferred as a parameter to the method getMenuRights, the rights for each folder can be determined

dynamically (e.g., by means of the folder name). It is also possible to make the rights subject to the

currently logged in user by accessing the current user:

User userAttribute = new HttpSessionWrapper().getUserAttribute();

Via the userAttribute information (like user type or user ID) are retrieved and can be used for the

allocation of rights.

Using the HttpSessionWrapper, the following additional import is necessary:

import com.saperion.ngc.resultset.MenuItemKey;

Page 32: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.10 Embedding a Results List in an Index Form

27

Deactivation of Menu Entries in the Results List

Similar to the deactivation of menu entries in the navigation the list of menu entries can also be

determined dynamically. In the above mentioned example code the menu entry "Download" of single

or multiple documents is removed.

6.10 Embedding a Results List in an Index Form

i This feature is available from SAPERION version 7.5 SP0 patch level 1 on.

6.10.1 Scenario

In order to display documents from another DDC or lookup table in an index form you can embed a

results list in the index form.

Example

In the implemented application the Web Client user is allowed to display a second DDC to an open

invoice in order to check invoice items or to edit according index data if required.

Fig. 6–1: Example: Embedded results list in the index form

The results list is triggered via the scripting interface of the Web Client. The below mentioned scripting

sample must be added directly to the index form as server script.

6.10.2 Example Code

In the following example the results list is used to display data of the document opened in the index

form loaded from a lookup table.

import com.saperion.ngc.events.resultset.IndexResultItemEvent;

import com.saperion.ngc.model.resultset.ResultProperties;

import com.saperion.intf.SaPropertyValue;

import com.saperion.ngc.resultset.ResultSetView;

import com.saperion.rmi.SaQueryInfo;

$component$.addEventListener("onIndexChange", new EventListener() {

public void onEvent(Event event) throws Exception {

// convert the received event

IndexResultItemEvent orig;

if (event instanceof ForwardEvent) {

orig = (IndexResultItemEvent) Events.getRealOrigin((ForwardEvent) event);

} else {

orig = (IndexResultItemEvent) event;

}

ResultSetView resultSetView = $component$.getResultSets().get(0);

// row contains the index data of the selected document

Page 33: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6 Script Examples

28

ResultProperties row = (orig).getProperties();

if (row != null) {

SaPropertyValue val = row.getPropertyValue("EX7_CUST");

String query = "select d from CUSTOMERS d where COMPANYNAME = :param1";

SaQueryInfo info = new SaQueryInfo(query);

info.setParameter("param1", val.getValues()[0].getStringValue());

resultSetView.performQuery(info);

} else {

// clear the result list when nothing was selected in the query mask

resultSetView.clearResultSet();

}

}

});

6.10.3 Process Description

In the used script an event listener which responds to the "Index change"-event is added to the index

form. This event is used by the results lists of query forms to inform other components when a new

element is selected from the list.

At the beginning of the "onEvent"-method the forwarded event is converted to the original event. After

that index data of the selected document are read out of the event. The linking of index table and lookup

table of this example is obtained by the "EX7_CUST" field in the index table and the "COMPANYNAME"

field of the lookup table. This index value is used to create and parametrize a HQL query.

The lookup table of this example is named "CUSTOMERS". In the HQL query all values of the lookup

table are requested. Finally, the results list in the index form is instructed to carry out the request.

After the query has been executed successfully the results list behaves the same way as a normal results

list. That way, index data of displayed documents can be edited or new elements could be added to to

the lookup table if the according permissions are existing. However, it is necessary that an index form is

defined in the results list. Also for the display of properties of former document revisions via the revision

history an index form must be defined.

i Please note that an embedded results list in an index form is not triggering an event when one

entry is selected. Furthermore the dispatch of selected documents is only allowed by means of

the MAILTO-function.

6.11 Limitation of Lookup Fields with multiple Conditions

6.11.1 Scenario

In addition to the limitations defined for the lookup field in the form, further conditions can be added.

These conditions are then used at every query in the linked lookup table. The function can be integrated

via the scripting interface of the Web Client.

For this purpose the class "com.saperion.ngc.iform.field.LookupTextField" has been enhanced by the

following two methods:

Page 34: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

6.11 Limitation of Lookup Fields with multiple Conditions

29

public void addCondition(String fieldName, Object value, SaFieldType fieldType)

public void removeCondition(String fieldName)

+ "addCondition" method

By means of the "addcondition" method own conditions can be added to the field. Here, the column

name of the lookup table, the value of the condition and the column type must be specified.

+ "removeCondition" method

By means of the "removeCondition" method already added conditions can be removed. For this,

the column name for which the condition has been added must be specified.

i All conditions at the query are linked by AND.

6.11.2 Example Code

In the following samples, two conditions are added to a lookup field first and are removed afterwards.

The first script has been assigned directly to the respective field in the query form as server script. The

second has also been assigned as server script to a button in the same form.

Example 1

import com.saperion.constants.SaConstants.SaFieldType;

// $component$ is the LookupTextField

$component$.addEventListener("onCreate", new EventListener() {

public void onEvent(Event event) {

$component$.addCondition("Country", "Germany", SaFieldType.FT_STRING);

$component$.addCondition("City", "Berlin", SaFieldType.FT_STRING);

}

});

Example 2

import com.saperion.ngc.iform.field.LookupTextField;

// $component$ is a button

$component$.addEventListener("onClick", new EventListener() {

public void onEvent(Event event) {

// get the LookupTextField from the mask

LookupTextField field = (LookupTextField) $component$.getParentForm().getFieldByFrameId(9);

field.removeCondition("City");

}

});

The supported data types are listed in Enum SaFieldType:

http://portal.saperion.com/docsxml/javadocs/75/javadoc_CC/com/saperion/constants/SaConstants.SaFieldType.html

Page 35: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7 Practical Application: Downloading Documents via an External Applet

30

i In order to optimize the the query (faster request) you can optionally set the following parameter

in the "webclient.properties": "ExactMatch=TRUE".

7 Practical Application: Downloading Documents

via an External Applet

In this section you will be offered a complete illustration of how to call an external applet which

downloads selected documents from SAPERION and stores them in the local file system.

The following steps within the process are demonstrated:

+ Extending the SAPERION Web Client by own classes

+ Calling own classes from server-side script as reaction to user triggered events

+ Calling an own applet to download SAPERION documents and store them on a local file system.

7.1 Scenario

A forms result list is extended by a custom context menu item. Once this item is clicked a JSP should

be opened containing an applet. This applet should download the selected document from SAPERION.

For the purpose of selecting the local storage location the "Open" dialog opens.

Fig. 7–1: Custom JSP File with Applet

7.2 Extending the Web Client by Own Classes

There are a number of benefits associated with the extension of the Web Client by own classes. First, the

server-side script can directly call your custom methods to execute your logic. Second, using own classes

or jars the server-side scripts itself are shortened considerably which decreases potential failures.

Page 36: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7.3 Create a Java Project

31

i We recommend to use own classes/ jars in server-side scripts to avoid scripting failures and

shorten up the script itself.

7.3 Create a Java Project

The easiest way to create custom Java classes/ jars is to create a Java project in an integrated

development environment (IDE). For this example the Eclipse IDE is used.

1. In Eclipse, click on FILE > NEW > JAVA PROJECT in order to create a new project.

2. Enter the project name and click [OK].

3. In this example the created classes use SAPERION and ZK logic. As a result, a number of

libraries need to be included to the project.

The following jars have been added to the class path of the project:

+ src-classicconnector.jar

+ scr-webclient.jar

+ zcommon.jar

+ zk.jar

+ zul.jar

All jars can be found in the SAPERION Web Client distribution.

i The created project (including all files) is a part of this guide. Please refer to the files directly to

see all implementation details. Important parts are explained in the following section.

7.4 Implementing Logic and Behaviour

The logic of this example is implemented in the following classes/ files:

Classes/ Files

Class Description

DocumentDownloader.java This class is instantiated and used in the server-side script. It takes the selected rows of the result set as an ar-

gument, creates download URLS, stores them in the session and calls the "DownloadAppletCaller.jsp" which is

then opened in a new browser window/ tab.

DownloadAppletCaller.jsp This JSP-file retrieves the download URLs from the session and loads our custom applet while passing the

URLs as applet parameters.

DownloadApplet.java This class represents our custom applet. It takes the given download URL parameter and downloads the corre-

sponding SAPERION documents with the help of the class "FileDownloader". Once the files are downloaded

they can be stored to the local file system, if the applet has the required permissions.

Page 37: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7 Practical Application: Downloading Documents via an External Applet

32

Class Description

FileDownloader.java This class takes the download URL as a parameter and downloads the files.

7.5 Code Examples

7.5.1 DocumentDownloader.java

The following listing shows the "DownloadDocument" method of the "DocumentDownloader.java" file.

It is called directly from the server script.

1public void downloadDocument(List<ResultProperties> documents) throws Exception {

2try {

3 // current request

4 HttpServletRequest request = (HttpServletRequest) Executions.getCurrent()

5 .getNativeRequest();

6 // get first document

7 ResultProperties document = documents.get(0);

8 // get unique document id

9 DocumentId docId = settingsService.fixRevId(document.getDocumentId(), false);

10 // get number of elements

11 List<ElementInfo> elements = docService.getDocumentPages(docId, true);

12 // Applet arguments

13 String documentIdent = docId.getRevisionId();

14 Set<String> downloadURLs = new LinkedHashSet<String>();

15 for (ElementInfo element : elements) {

16 String documentURL = ServletUrl.constructDocumentUrl(documentIdent, true,

17 element.getNumber(), element.getName(), true, request);

18 downloadURLs.add(documentURL);

19 }

20 if (downloadURLs.isEmpty()) {

21 Messagebox.show("There is no content to download.", "No content",

22 Messagebox.OK, Messagebox.ERROR);

23 } else {

24 // add download URLs to session

25 HttpSession session = request.getSession();

26 session.setAttribute("downloadURLS", downloadURLs);

27 // call download servlet

28 Executions.getCurrent().sendRedirect(

29 ServletUrl.getBaseUrl(request, "/downloadAppletCaller.jsp"), "_blank");

30 }

31} catch (Exception e) {

32 e.printStackTrace();

33 throw e;

34}

35}

Page 38: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7.5 Code Examples

33

In line 7 the first document from the result list is obtained. The ID of this document is fixed (completed)

in line 9. The "settingsService" is an instance of the class "SettingsClassicConnectorService".

In line 11 we get all elements of the document via an instance of the "DocClassicConnectorService" class.

i Fix document IDs via the "SettingsClassicConnector". By doing so, it is ensured that always valid

IDs are used.

For all document elements a download URL is built via the "ServletUrl" class (line 16). This class helps

you out when building URLs to SAPERION servlets.

i Use the "ServletUrl" class to obtain SAPERION servlet URLs easily.

In line 26 the list of download URLs are stored in the session and in line 28 our custom JSP file is called.

7.5.2 DownloadAppletCaller.jsp

1boolean showApplet = false;

2Object attribute = session.getAttribute("downloadURLS");

3StringBuilder sb = new StringBuilder("Download URLS: <br/>");

4StringBuilder urls = new StringBuilder();

5if (attribute != null) {

6 @SuppressWarnings("unchecked")

7 Set<String> downloadURLS = (Set<String>) attribute;

8 //show URLS

9 sb.append("<ul>");

10 int count = 0;

11 for (String url : downloadURLS) {

12 count++;

13 sb.append("<li>").append(url).append("</li>");

14 urls.append(url);

15 If(downloadURLS.size() > count) {

16 urls.append("$");

17 }

18 }

19 sb.append("</ul>");

20 showApplet = true;

21}

22[…]

23<% if(showApplet) { %>

24 <h1>Initializing download applet</h1>

25 <% out.write(sb.toString()); %>

26 <div style="text-align: center">

27 <applet CODEBASE="<%= ServletUrl.getBaseUrl(request) %>"

28 ARCHIVE="DownloadApplet.jar"

29 CODE="com.saperion.ngc.custom.applet.DownloadApplet"

30 WIDTH="95%"

31 HEIGHT="400px"

Page 39: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7 Practical Application: Downloading Documents via an External Applet

34

32 HSPACE="0"

33 VSPACE="0"

34 ALIGN="middle"

35 >

36 <param name="downloadURLS" value="<%= urls.toString()%>>"/>

37 </applet>

38 </div>

39<% } else {

40 out.write("<h1>There are no download URLs!</h1>");

41}

42%>

In line 2 the download URLs are retrieved from the session. The following lines build a concatenated

string of the URLs and show them as HTML lists.

In line 27 the applet is included to the JSP. Once again, the "ServletUrl" class is used to

get the base URL of the request. The applet works with the archive "DownloadApplet.jar"

and the "com.saperion.ngc.custom.applet.DownloadApplet" class. The jar which contains the

"DownloadApplet" needs to be accessible under the given base URL.

In line 36 the download URLs are passed as a parameter to the applet.

7.5.3 Applet Class

1// get URLS to download

2givenUrls = getParameter("downloadURLS");

3if (null != givenUrls && givenUrls.length() > 0) {

4 StringTokenizer st = new StringTokenizer(givenUrls, "$");

5 if (st.countTokens() > 0) {

6 urlSet = new HashSet<String>();

7 while (st.hasMoreTokens()) {

8 urlSet.add(st.nextToken());

9 }

10 }

11}

12[…]

13for (String url : urlSet) {

14 count++;

15 htmlTextArea.append("Started download of: " + url + "\n");

16 String fileName = "unknown";

17 String flag = "filename=";

18 if (url.indexOf(flag) > -1) {

19 fileName = url.substring(url.indexOf(flag) + flag.length());

20 fileName = fileName.substring(0, fileName.indexOf("&"));

21 fileName = URLDecoder.decode(fileName, "UTF-8");

22 } else {

23 fileName += count;

24 }

25 byte[] file = FileDownloader.downloadFile(url, htmlTextArea);

26 // store file in map

Page 40: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7.6 Deploying the Extensions

35

27 filesMap.put(fileName, file);

28 htmlTextArea.append("Downloaded file: " + fileName + " with size: "

29 + file.length / 1024 + " kb.\n\n");

30}

31button.setEnabled(true);

In line 1 the download URLs parameter is read and the concatenated URLs are separated in the following

lines.

In line 13 it is iterated over all URLs and the corresponding files are downloaded via the "FileDownloader".

The download URLs point to the SAPERION download servlet.

7.6 Deploying the Extensions

Now you need to deploy your custom extensions which are described in this section.

1. First, export the Java project as a jar file and place it in the SAPERION Web Client’s class

path.

2. Right click on the Eclipse project to open the context menu.

3. Select the "Export…" entry and choose "JAR-file". The "JAR Export" dialog opens.

4. Deselect the "lib" checkbox, because all libs are already present in the deployed Web Client.

5. Enter the path to the deployed SAPERION Web Client’s lib directory and click the [Finish]

button. After the export the classes are available for the Web Client's class path.

Now, the applet needs to be exported. Normally, the JAR-file that has been just exported can be used as

an applet as well because the required applet class "DownloadApplet.java" exists in that JAR-file. But the

applet needs to be stored to the Web Client’s root directory so that you need to export as follows:

1. Right click on the Eclipse project to open the context menu.

Page 41: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7 Practical Application: Downloading Documents via an External Applet

36

2. Select the "Export…" entry and choose "JAR-file". The "JAR Export" dialog opens.

3. Deselect the "lib" checkbox.

4. Change the export destination to the Web Client’s web root directory.

Example:

The Web Client runs under a Tomcat which is installed under ‘D:\develop\apache-

tomcat-6.0.29’. Then the Web Client's web root directory is ‘D:\develop\apache-tomcat-

6.0.29\webapps\ngclient\’.

5. Rename the JAR-file to "DownloadApplet.jar" and click the [Finish] button.

6. Finally, copy the JSP-file "DownloadAppletCaller.jsp " to the Web Client’s web root

directory.

7.7 Creating Server-side Script

For the purpose of using the extension some server-side scripts need to be created.

1. Open the correponding query mask in the SAPERION Forms Designer.

2. Select the mask element "Result list".

3. Open the Script Editor.

4. Enter the following script:

1//--------------------------------------------------------

2// Add own contextmenu submenu with item

3//--------------------------------------------------------

4Menu menu = new Menu("My custom menus");

5Menupopup popup = new Menupopup();

6menu.appendChild(popup);

7Menuitem open = new Menuitem("Open in applet");

8popup.appendChild(open);

9open.addEventListener("onClick", new EventListener() {

10 public void onEvent(Event event) {

11 com.saperion.ngc.custom.DocumentDownloader downloader = new

12 com.saperion.ngc.custom.DocumentDownloader();

13 downloader.downloadDocument($component$.getSelectedRows());

14 }

15});

16$component$.addCustomMenu(menu, false);

+ In line 4-8 a menu with a sub-menu item is created. This menu is added to the result

list in line 16.

Page 42: Best Practice Web Client Scripting - Kofax Web Client scripting can be divided in client-side scripting and server-side scripting. 1.2.1 Client-side Scripting With client-side scripting

7.8 Permissions

37

+ Line 11, 12 and 13 create the instance of our custom class using a full qualified name.

The method "DownloadDocument" is called passing in the selected result set rows.

7.8 Permissions

Since the applet tries to store the downloaded files to the local file system it needs the according

permissions. To grant the required permissions two steps need to be performed:

1. Sign the applet using Javas "jarsigner" tool.

For more information on the jarsigner, please refer to the official documentation: http://

download.oracle.com/javase/1.3/docs/tooldocs/win32/jarsigner.html

2. Adjust Javas security policy file in the Java installation directory.

If Java is installed under ‘C:\Program Files\Java\jre6\’ the security file can be found under

‘C:\Program Files\Java\jre6\lib\security\java.policy’.

3. To grant all permission to all code bases, enter to following lines:

grant {

//all permissions to all domains

permission java.security.AllPermission;

};

! Please note that this should only be done for testing, since all Java

programs now have all permission on the system.

For more information about Java security and policy files, please refer to: http://

download.oracle.com/javase/1.4.2/docs/guide/security/PolicyFiles.html


Recommended