Skip to main content link. Accesskey S
  • Anonymous
  • Log on
  • Help
  • IBM logo
  • Lotus Notes and Domino Application Development wiki
  • All Wikis
  • Home
  • Community Articles
  • Product Documentation
  • Learning Center


Search

Advanced Search

Categories

Tag Cloud

  • 6.0
  • 6.5
  • 8.0
  • 8.5
  • 8.5.1
  • 8.5.2
  • 8.5.3
  • action bar
  • Agents
  • Ajax
  • app dev
  • Application
  • beginner
  • C&S
  • calendaring and scheduling
  • client
  • composite applications
  • Controls
  • converters
  • css
  • Custom controls
  • Data Binding
  • db2
  • design elements
  • dialog boxes
  • Documents
  • Dojo
  • Domino
  • Domino Designer
  • Domino Designer 8.5
  • DXL
  • Eclipse
  • error handling
  • errors
  • extensions
  • FAQ
  • Forms
  • formulas
  • getting started
  • globalization
  • Help
  • html
  • Installation
  • interface
  • internationalization
  • iPhone
  • Java
  • JavaScript
  • localization
  • Lotus Domino Designer
  • LotusScript
  • LotusSphere
  • LotusTechInfo
  • menu bar
  • Mobile
  • new user
  • Notes
  • Notes 8
  • notes.ini
  • NSD
  • OpenNTF
  • partial update
  • performance
  • Pickers
  • Portal
  • presentations
  • programming
  • Redbooks
  • Requested Articles
  • roadmap
  • rooms and resources
  • samples
  • Scripting
  • security
  • tabs
  • templates
  • themes
  • Tips
  • toolbar
  • troubleshooting
  • tutorials
  • validation
  • variables
  • video
  • VideoFest
  • View
  • view control
  • ViewPanel
  • Views
  • web
  • Web apps
  • Web services
  • webdev
  • XML
  • Xpage
  • XPages
  • XPages Extensibility API
  • xsp-config
  • データソース
  • 九州地区ノーツパートナー会
InformationInformation
You are currently viewing machine translated content. IBM translation might be available. Click IBM Translated Product Documentation to see what is available.X


Home > IBM Redbooks: Building Domino Web Applications using Domino 8.5.1 > Form Design - XPage enabling an existing Notes client application
Rate this article 1 starRate this article 2 starsRate this article 3 starsRate this article 4 starsRate this article 5 stars

Form Design - XPage enabling an existing Notes client application 

expanded Abstract
collapsed Abstract
No abstract provided.
ShowTable of Contents
HideTable of Contents
  • 1 Form styling
    • 1.1 Field layout
    • 1.2 Add a control property definition to the theme
    • 1.3 Form title
    • 1.4 Submit button
  • 2 Action buttons
    • 2.1 Edit button
    • 2.2 Cancel link
    • 2.3 Define action visibility
  • 3 ComputeWithForm
  • 4 Validations and type ahead
    • 4.1 Client side validation
    • 4.2 Server side validation
    • 4.3 Disable validation on links
    • 4.4 Type ahead
  • 5 Reviewers
    • 5.1 Preparing the form table
    • 5.2 Reviewers fields
    • 5.3 Adding reviewer names to the list
    • 5.4 Adding reviewers without data validation
    • 5.5 Clearing the sessionScope variable
    • 5.6 Writing the reviewers list to the data field
    • 5.7 Adding type ahead
    • 5.8 Field hint
    • 5.9 Data validation
    • 5.10 Hide the field DataReviewers
    • 5.11 Populate the List Box at page load
    • 5.12 Add a Clear button
  • 6 Review options
    • 6.1 Review options fields
    • 6.2 Copy field values from the Notes client
    • 6.3 Copy a choicelist value formula from the Notes client
    • 6.4 Update Time Limit in function of Review Type
    • 6.5 Display the review time in function of the review window
      • 6.5.1 ReviewWindow onchange
      • 6.5.2 Visibility of ReviewTime
      • 6.5.3 Combining getValue and getSubmittedValue
  • 7 Summary
Table of contents | Previous Page | Next Page

This section describes how we will leverage the basic form created in the previous chapter to a fully featured Document Library input form. Form styling will be applied, action buttons will be added and field validations and type-ahead will be implemented. And finally, a review section including reviewer names and review options will be added.

Form styling



Before starting with including form functionality, we will add some OneUI styling to the existing form components.

Field layout


Open ccFormDocument.
Select the main form table in the Outline view and give it the style class "lotusFormTable":


Select the Subject field and set its width to 400px by clicking on the field and then entering the width in the Properties view, on the Edit Box tab (select Units first and then enter a value).
Assign the style class "lotusText" to the Subject (Style tab in the properties).

Do the same for the WebCategories field: add a width 400px and the style class "lotusText".

Give the Rich Text field a height of 200px and also assign the class "lotusText".

Now click in the table cell that contains the field label "Subject". Make sure you have the table cell selected and not the Subject label itself. Give the table cell a width of 120px, and assign it the style class "lotusFormLabel".

Assign the same class to the other cells that contain field labels.

If you now preview formDocument.xsp, you will notice that the layout of the field labels hasn't changed. This is because most of the OneUI styling definition for formlabels works only in conjunction with the lotusForm style class.
Extract from the OneUI v2 forms.css:


.lotusForm td.lotusFormLabel {
vertical-align:top;
text-align:right;
padding-right:10px;
padding-top:1px
}


The lotusForm class needs to be assigned to the <form> tag in the html source code. XPages don't provide direct access to this tag: there is no "Form" element of which you can set the style.
This is where the use of themes proves its usefulness again: with themes, you can assign style classes (and other properties) to html tags.

Add a control property definition to the theme



Open the theme resource called "oneuiv2-core" and add a "control" section to the source code:


<control>
<name>Form</name>
<property>
<name>styleClass</name>
<value>lotusForm</value> 
</property>
</control>


Save and close the theme and preview formDocument.xsp in the browser. The field labels are now right aligned an in bold. In html source code in the browser you will notice that the form tag now has the class "lotusForm" assigned.

Form title


We will add a title to the Library Document form:

In ccFormDocument, add a table row in the beginning of the form table.
Merge the two table cells (select both cells and right-click: merge)
Go to the custom control Source view and in the merged table cell, add the text "Library Document" between <h2> tags:


<xp:table styleClass="lotusFormTable">
<xp:tr>
<xp:td colspan="2"><h2>Library Document</h2></xp:td> 
</xp:tr>


Alternatively, if you prefer to use the Designer GUI view rather than the source code view, you could achieve the same result by dragging a Computed Field into the table cell, set its content type to "HTML":

Then, give it the value "<h2>Library Document</h2>". Make sure to select the option "Compute on page load" rather than "Compute dynamically". (it doesnt need to recompute during form edits, as it is a fixed text):

Submit button


The submit button on the bottom of the form still could use some styling.

In ccFormDocument, merge the two table cells on the bottom row of the form table (=containing the submit button).
Assign the style class "lotusFormFooter" to the merged table cell.
Select the button and give it the class "lotusFormButton".
Also, change its name to buttonSave and its label to "Save" (to avoid confusion with the "submit for review" action, which will be added later on when building the workflow).

Save and preview the result. The form looks more satisfying now.

Back to Top

Action buttons


Time to add some more action buttons to the form, like Edit and Cancel actions.

Edit button


In ccFormDocument, add a button next to the Submit button and give it the following properties:
    Name: buttonEdit
    Label: Edit
    Button type: Button
Assign the style lotusFormButton

In the Events view, add a simple action: Change Document Mode: Edit Mode

Save the custom control and open a open the page viewAllDocuments.xsp in the browser. Click on a document to open it in read mode. When you click on the Edit button, you will notice the page refreshes, but nothing happens. The document remains in read mode.
Click once again on Edit. The second click opens the document in edit mode.
This is not the intended behaviour. This is actually a know issue in Domino 8.5.1. It is linked to the place where the data source is defined.

Edit buttons and data source defintion in Domino 8.5.1

In Domino 8.5.1, the data source defintion needs to be done at XPage level instead of at custom control level, in order to make an Edit button change the document to edit mode with a single click. This is a known issue which will be addressed in a future release.
It is more logic to define the data source in the custom control, rather than in the XPage: and XPage can contain several custom controls, which each point to a different data source. For example, when displaying a main document and a response document on the same XPage.
Because of the above constraint, you might need to be creative in order to handle this kind of situations. Later on in this tutorial, the combination of two data sources in one XPage will be discussed.

In order to solve the above issue, we will move the data binding to the XPage:

In ccFormDocument, go to the Data tab in the custom control properties view. Remove the data source "dominoDoc":

The data source list is now empty.
You might notice that the data binding at individual control level is still present: select the Subject field and click on the Data tab in its properties: the data source is still set to dominoDoc.

Data source definition and data binding

The above example demonstrates that removing the data source definition does not remove the data binding. This is because the data source does not necessarily need to be defined in the same component as the one where the data binding is used. For example, you can define a data source at XPage level, and then perform data binding to that source in various custom controls that are used in the XPage.
In any case, a data source needs to be defined somewhere, in order bind data to it.

Defining the data source in the same XPage/custom control as where you intend to do the binding, makes it easier to do the data binding: you can drag fields from the data palette, select the data source from a dropdown list. A possible approach to facilitate development is to first define a data source in the custom control where you want to do data binding, then use this data source for the actual binding, and then remove the data source (assuming the data source is defined elsewhere).

Save and close ccFormDocument.
Open the XPage formDocument, and in the XPage properties, go to the Data tab.
Add a data source, exactly in the same way as we have intially done in the custom control: the name must be the same: dominoDoc. And its definition needs to be the same as well: Form: Document; Default action: Create document.
Save and close the XPage.

Open the view viewAllDocuments again in the browser and open a document in read mode. The Edit button will now work as expected: it will switch to edit mode with a single click on the button.

Cancel link


In ccFormDocument, drag a core control of type "Link" to the right hand side of the Edit button.
Give it the name "linkCancel" and the label "Cancel":
On the Style tab, add the class "lotusAction".
Under Events, add a simple action to the onclick event: Open Page: Previous Page

Save the custom control and open a library document in the browser (either in edit or on read mode): the cancel returns to the view from where the document has been opened.

Define action visibility


Next thing to do is make the action buttons only visible when needed (="hide-whens"): the Edit button should only be available in read mode, the Save button should only be displayed in edit mode.

In ccFormDocument, select the Save button and in the properties, on the Button tab, click on the diamond next to Visible:


Select "Compute value..."
In the script editor window, write following the Server Side JavaScript:

 currentDocument.isEditable()


Accessing the current document context

In the above script, currentDocument represents the document associated with the XPage context in which the server script is running. The variable currentDocument is of type NotesXspDocument, which is in some way comparable to the NotesUiDocument class in the Notes client.

In the Script Editor window, select the XSP Library on the Reference tab on the left and expand the NotesXspDocument class to view the available methods:

Alternatively, instead of using currentDocument in the above example, we could have used this:

 dominoDoc.isEditable()


Where dominoDoc is the name of the data source linked to the XPage. If the XPage contains multiple data source, using the data source name lets you access a specific data source, while currentDocument represents the closest document in the current context. You might also want to use currentDocument to write reusable code, which is independent of the data source name.


The Edit action button ccFormDocument should only be visible in read mode:

Add a computed value for the visible property of the Edit button:

 !currentDocument.isEditable()


Above, we have used computed values for visibility instead of a static value. In XPages, almost every property or value of XPage components can be computed: there is a diamond next to most of the property fields. This makes XPages very powerful and flexible.

Save ccFormDocument and check the result in the browser. The Edit and Save buttons now display in the right mode.

Back to Top

ComputeWithForm


In the Notes client, have a look at the document properties of a library document that was created via the web browser:

The document only contains some system fields, a form field and the 3 data fields that have been defined in ccFormDocument.
All the remaining fields defined in the notes Document form are absent.
There's no need to define them in the XPage though: there is a possibility to compute the data document with the Notes form:

Open the XPage formDocument and go to the All Properties tab in the properties view.
Under data\data\dominoDocument[0], set the property computeWithForm to "onsave":

Save the XPage and create a new document on the web.

The document will now have all notesitems as defined in the Notes form, as if it was created with this form
Form calculations have been done as if the document was created with the Notes form. In other words, all data manipulation, but no front-end interactions. For example, input translations will execute, but input validations won't .
The field "Categories" will now have the same value as WebCategories.

Validations and type ahead


In this chapter, the Subject field will be made mandatory and field input will be enhanced with type-ahead.

Client side validation


In ccFormDocument, select the field Subject and in the Properties view, go to the Validation tab. Mark the field as required and enter a required field message.
Enter a minimum number of characters and add a validation error message:

Test the result in the web browser: the validation messages appear in the form of client side JavaScript popup windows.

Server side validation


By default, valitions defined on the Validations tab of the fields are executed client side. They can also be set to execute as server side:

In ccFormDocument, go to the Properties of the Subject field and open the All Properties tab.
Under "data", set the value of disableClientSideValidation to true:

If you would now save the custom control and preview the XPage, you will notice the form cannot be submitted without subject of at least 3 characters, but no error message appears. In order to see server side error messages, we need to add a control to display the messages:

Drag a core control of type "Error message" next to the Subject field in ccFormDocument. In the error message control properties, set "Show error messages for: subject1":

The validation error messages will now be displayed next to the Subject field.

Disable validation on links


If we now create a new document without subject and press cancel, the subject field validations will be executed as well, and the form will not be closed. Reason: by default, vallidation is performed for any link or button. This needs to be disabled explicitly:

Select the Cancel link in ccFormDocument and in the events view, and set the server option "Do not validate or update data":

The same needs to be done on any link in the XPage, including the ones in the layout framework (banner, title bar, left navigation, footer).

Type ahead


We will now provide the Tag field with type-ahead: when an author starts typing a tag name, a list of matching tag names that were used previously will appear:

Open the Type Ahead tab of the properties of the WebCategories field in ccFormDocument.
Enable Type Ahead and select Partial Mode.
Click on the diamond nex to the suggestions field and add a computed value:

return @DbColumn("","ByCategory",1);


Uncheck the option "Case-sensitive".
Place a comma in the fields "Suggestion separator" and "Client separator" and enter 1 for "Minimum characters":

Test the XPage formDocument in the browser: when typing a value in the Tag field, previously entered tag names appear. Also, multiple tags can be entered, and type ahead works on multiple values.

Back to Top

Reviewers


The Notes client Document Library application has a workflow: authors of documents can select one or more reviewers and then submit the document for review, either in a parallel or a serial approval cycle.

In this chapter, the interface for adding reviewers will be added to the form. In the Notes client, reviewers stored in a multi-value names field, and they are selected via an Address dialog. XPages currently don't have a built-in address dialog component. On the web, you can find some custom build address dialog solutions for XPages, or you can build your own.

In this sample application, we'll provide a simple alternative. Authors will be able to type a name in a text field with type ahead. They can then add the name to a list of reviewers:

In order to ensure data integrity, validations will be added to the input field: only names that exist in the Address Book can be added to the list, and the author cannot add himself as reviewer. This corresponds with the data validations in the Notes client version of the document library.

Preparing the form table



In ccFormDocument, add two table rows above the bottom table row (=with the action buttons).
In the first of the two new rows, merge the two cells.
In this merged cell, drag a panel container control and name it "panelReview",
Drag a table container control into the panel: 3 rows x 4 columns, 100% width.
Set the width of the cell in this table to 120px.

The outline of the third last table row in the main table now looks like this:


Reviewers fields


We will create 3 fields:
  • A text input field to add new names
  • A listbox field to display the list of already added names
  • A hidden multiline text field to store that actual name values in the back-end document

In the newly added table, add two Label core controls in the first column:
    on row 2: label "Add reviewer""
    on row 3: label "Reviewers:"

In column 2, add an Edit Box control in row 2 with the name "AddReviewer" and with a width of 400px.
Make it visible only in edit mode:

currentDocument.isEditable();


In the same column, on row 3, add a List Box core control with the following properties:
    Name: "ListReviewers"
    Height: 60px
    Width: 400px
    Visible
    Disabled



Under that field, but still in the same table cell, add a Multiline Edit Box control, with the name "DataReviewers" with the same width and height as ListReviewers, and leave it Visible (we'll hide it later on).

This field will have the data binding with the reviewers field in the underlying Notes document:
On the Data tab of the field properties, no data source is available. This is because earlier, we have removed the data source defintion from the custom control and moved it to the XPage.
Instead of using Simple data binding, click on Advanced and select to use Expression Language (EL) and enter "currentDocument.ReviewerList" as value:

Adding reviewer names to the list


In order to add newly entered reviewers to the list, we will make add a button next to the AddReviewer field and make use of scoped variables to transfer the value of this field to the list box field and the multiline edit box field.

Scoped variables

Scoped variables are JavaScript variables that share values within a certain scope:
  • sessionScope: allows you to share values across pages for the duration of a session
  • applicationScope: allows you to share values across pages for the duration of an application
  • viewScope: allows to share values across a view. Note that this is not a Notes view but an <xp:view> (this is the root tag of an XPage)
  • requestScope: allows you to share values across pages for the duration of a request. This is commonly used in search functions.

In our XPage, we will use a requestScope variable to capture the value of the AddReviewer field, and a sessionScope variable to populate the ListReviewers field:

Select the field AddReviewer, and in the Data tab of the Properties, select Advanced: Use Scoped Variable.
Select Request Scope and enter the Variable name "reviewerName":


Add a button on the right of the field AddReviewer.
Give it the label "Add" and set the Button type to "Submit" (we will change that later!)
Give it a style class "lotusBtn".
Add the following onclick event Server Side JavaScript:


var v = requestScope.reviewerName;
if(v!=null){
if(sessionScope.reviewerName!=null){
v +=",";
sessionScope.reviewerName += v; 
}else {
sessionScope.reviewerName = v;
}

requestScope.reviewerName = ""; //clear the AddReviewer field
}


The above code retrieves the value from the requestScope variable "reviewerName", which is the value of the AddReviewer field. It then adds it to a sessionScope variable with the same name (the names doen't need to be the same, they are just kept the same here to make it easier to remember the variable name).
Finally, the requestScope variable is cleared. This will empty the AddReviewer field, so that another reviewer can be added.

Accessing field values in an XPage

The above example demonstrates how the value of the field AddReviewer is accessed by using a scoped variable. This works, because the field's data binding was done to that variable.
There are other ways to access a field value via Server Side JavaScript:


currentDocument.getItemValueString("AddReviewer"); //NotesXspDocument
dominoDoc.getItemValueString("AddReviewer"); //NotesXspDocument

getComponent("AddReviewer").getValue(); //getComponent gets the base object for a UI component

dominoDoc.getDocument().getFirstItem("Subject").getValueString() //for back-end data access: getDocument returns a NotesDocument object


To access a field value via Client Side JavaScript, you can use this:


dojo.byId("#{id:AddReviewer}").value;



In order to write a value to a field, you could use:

currentDocument.replaceItemValue("AddReviewer","new value");
getComponent("AddReviewer").setValue("new value");



Back to Top

In the Server Options of the Add button's onclick event, select "Partial Update" and select the element to update: "panelReview". This is the panel containing the reviewer table and fields.


Next step is to display the values from sessionScope.reviewerName into the list of values of the List Box field.

In the List Box tab of the ListReviewers field properties, make sure the option "Allow multiple selections" is switched on. This doesn't seem to make much sense (we're not going to select values in the list box), but not having this option selected causes a run time error.
Leave the Data tab untouched: there is no data binding needed for this field, as it will serve for display only.
On the Values tab, click "Add Formula Item..." and enter the following Server Side JavaScript:


@Explode(sessionScope.reviewerName,",",0)


This is splitting the sessionScope variable into separate values.

Now open formDocument.xsp in the browser, and test the form:
Make sure you enter a Subject of at least 3 characters in the form before testing the Add Reviewer function.
Then, enter a reviewer name and click Add. The name is added to the list. Additional reviewers can be added to the list.

If you now empty the subject field and try to add an other reviewer, you will see it won't work. This is caused by the validations on the Subject field. Since we did not disable the validations for the Add button (checkbox "Do not validate or update data" in the Event tab is disabled), the form validations are performed, but not error message is displayed.
Setting the Add button not to validate data won't solve the problem, as this will also not update the data (and thus add the reviewer name to the list).

Accessing field values before validation

Field values can be accessed before validation, by using the following methods:
getComponent("AddReviewer").getSubmittedValue();instead of getValue
getComponent("AddReviewer").setSubmittedValue();
instead of setValue

Adding reviewers without data validation


Knowing this, we can update the Add button to work without form validation:

In the onclick event of the Add button do the following:

    Under Server Options, enable the option "Do not validate or update data"
    In the script editor, replace the existing Server Side JavaScript by this:


    var rev = getComponent("AddReviewer");
    var v = rev.getSubmittedValue(); //Get the value of the reviewername
    rev.setSubmittedValue("");
    if((v!="")&&(v!=null)){
    if(sessionScope.reviewerName!=null){
    v +=",";
    sessionScope.reviewerName += v; 
    }else {
    sessionScope.reviewerName = v;
    }
    }



Important
Change the button type to "Cancel" (instead of Submit).
I can't give a decent explanation for this, but with it appears to be the only way to get it working: with the type set to "Submit", values are not added to the list box. If it is set to "Button", a new document is created (in the background, with subject "Untitled") each time a reviewer name is added to the list.

Save ccFormDocument and test the result in the browser.
Now, you can add reviewers even when the Subject field is left blank, because the validations are not executed anymore.

Clearing the sessionScope variable


The variable sessionScope.reviewerName needs to be cleared when opening the XPage. Otherwise, it will load the ReviewersList list box in any new document form that is opened within the same session with its existing values.

Select the Custom Control in the ourline of ccFormDocument (=top level of the hierarchy) and then open the Events view. In the beforePageLoad event, clear the sessionScope variable:

When a new library document is created, the list of reviewers will now be empty.

Writing the reviewers list to the data field


We now manage to add reviewers to the list, but they are not stored yet in the document, when it is saved: we need to populate the field DataReviewers, which will be saved to the item ReviewerList in the Document form.

Add the following code to the Add button's onclick event, under the existing code:


var lst = @Explode(sessionScope.reviewerName,",",0);
var txt = getComponent("DataReviewers");
txt.setSubmittedValue(sessionScope.reviewerName) //write the updated list of names to the hidden text field


Save and preview the result: the added values are now also written to the DataReviewers field. When you open an existing library document in read mode, the List Box field is empty, but the multiline text field now is populated with the reviewer names.

Adding type ahead


In order to facilitate the input of reviewer names, we will add a type ahead feature to the AddReviewer field, and build a list of suggestions from the Public Address Book:

On the Type Ahead tab of the Properties of the field AddReviewers, enable type ahead.
Select "Partial" mode and add a computed value for the suggestions:

Disable case sensitive.

Test the result: type a first letter of a name in the NAB in the AddReviewer field.

Type ahead and styles

The fields "Tags" and "Add reviewer" have a slightly different look in the web form than the other editable fields: their height is less than the subject field, and the field border is slightly differen. Also, these field are a couple of pixels indended, in comparison to other fields.
This is because the type ahead feature adds an extra <span> tag around the field.
The form might need some additional style tweaking to get all fields aligned properly.

Back to Top

 
Warning: If the user is not authenticated and the Address Book does not allow read access to Anonymous users, the type-ahead will not work. Granting reader access to "Anonymous" on the NAB is not recommended.

Field hint


Now we will add a field hint to the field AddReviewer: a text that appears in the field and explains the user what to do. Once he clicks in the field, the hint disappears.

On the Data tab of the properties of AddReviewer, add a default value:



In the Events view, add an onfocus event for the AddReviewer field, to clear the field as soon as the user clicks in it.
Enter the following Client Side JavaScript:


dojo.byId("#{id:Reviewers}").value = "";




Save ccFormDocument and test the result.

With appropriate styling, you could make the field hint text appear as grayed out (gray font). It would take some experimenting, but there must be a way to change the font color back to black when the user enters the first reviewer name.


Understanding events

Above, we have added an onfocus event to the field AddReviewers. This creates an event handler. It is not the same as a simple onfocus property of an html input field. This last property can be set by going to the All Properties tab of the field properties:
This onfocus event has no value.
To better understand the difference, add a simple Client Side JavaScript alert to the onfocus event in the All Properties tab, and then inspect the Source code of the custom control. The simple onfocus source code looks like this:

<xp:this.onfocus><![CDATA[alert("onfocus")]]></xp:this.onfocus>


The eventhandler onfocus (=via the Events view) source code looks like this:


<xp:eventHandler event="onfocus"submit="false">
<xp:this.script><![CDATA[dojo.byId("#{id:AddReviewer}").value = "";]]></xp:this.script>
</xp:eventHandler>


The first code will translate to a simple onfocus property in the browser, while the second will generate a JavaScript event handler function (check the html source in the brower).



Data validation


The type ahead feature in AddReviewers is helpful, but it doesn't prevent users from entering inexisting names and adding them to the reviewers list. Therefore, we will add some validations to AddReviewers:
  • only existing user names should be added
  • the author of the document cannot add himself as reviewer

Extend the "Add" button JavaScript with the above validations:

var dbname = new Array(@Subset(@DbName(), 1),"names.nsf");
var nabNames = @DbColumn(dbname,"($VIMPeople)",1);
var user = session.getEffectiveUserName();
var userAbbr = @Name("[ABBREVIATE]",user);

var revComponent = getComponent("AddReviewer");
var reviewer = revComponent.getSubmittedValue();

var v = @Name("[ABBREVIATE]",reviewer);

if(@LowerCase(v)==@LowerCase(userAbbr)) {
revComponent.setSubmittedValue("You cannot add yourself as reviewer");
}else if(@IsNotMember(reviewer,nabNames)){
revComponent.setSubmittedValue("Please enter a valid name");
}else
{

revComponent.setSubmittedValue("");
if((v!="")&&(v!=null)){
v +=",";
sessionScope.reviewerName += v;
}

var lst = @Explode(sessionScope.reviewerName,",",0);
var txt = getComponent("DataReviewers");
txt.setSubmittedValue(sessionScope.reviewerName)
}

Back to Top

Hide the field DataReviewers


This field is intended for data storage only and not for data display. Therefore, it will be made hidden. Disabling the Visibility property is not a good idea here. The field would then simply not be rendered in the XPage and would not be accessible by the JavaScript behind the Add button. Instead, we will set the style to not display the field:

Select the field DataReviewers and in the Properties view, go to the All Properties tab.
Under "styling", replace the existing value of the property "style" by "display:none":
This style applies to an input field. In read mode, the field will be rendered as text instead of an input field, and will still be visible.

In read mode, you could either display the field ListReviewers or DataReviewers. Hide the other field by adding a computed visibility:


currentDocument.isEditable();


Add the same visibility value to the "Add" button, in order to hide it in read mode.

Populate the List Box at page load


When an existing document is opened, the list box of reviewers is empty. This is because the sessionScope variable is cleared when then page is loaded (Chapter 5.5 Clearing the sessionScope variable).
In order to display the list of reviewers in existing documents, we need to populate the sessionScope variable at page load:

Select the custom control in the Outline view (=top level of the three), and open the Events view.
Clear the code in the beforePageLoad event.
Instead, add the following code to the afterPageLoad event:


if(!dominoDoc.isNewNote()){
sessionScope.reviewerName = getComponent("DataReviewers").getValue();
}else{
sessionScope.reviewerName = "";
};


Add a Clear button


In this step, we will add a "Clear" button, allowing users to clear the list of reviewers:

Drag a new Button control next to the ReviewersList field.
Leave the type "Button" and give it a label "Clear".
Assign a style class "LotusBtn" en set its visibility to display in edit mode only.
Add an onclick event with the following Server Side JavaScript:


sessionScope.reviewerName = "";
var txt = getComponent("inputTextarea1");
txt.setSubmittedValue("")


In the event's Server Options, select Partial Update: panelReview and enable the property "Do not validate or update data".

Review options


In the Notes client version of the Document Library, the author can specify some review options: type of review (serial or parallel), time limit, and notication options. In this chapter, we will add these options to the custom control ccFormDocument.

Review options fields


Select the 3 cells in the last column of the table contained in panelReview, and merge these cells:

Drag a Section container control in this cell, and give this section the name "sectionReviewOptions" and a label "Review Options".
Enable the option "Section is closed by default".
Assign the style class "lotusSection".
Drag a new table into this section of 4 rows and 2 columns.

In this table, add the following fields:
    Label
    Type
    Name
    Bind to
    Type of review:
    Combo Box
    comboReviewType
    dominoDoc.ReviewType
    Time limit:
    Combo Box
    comboReviewWindow
    dominoDoc.ReviewWindow
    Time limit (days):
    Edit Box
    editReviewTime
    dominoDoc.ReviewTime
    Notify originator after:
    Combo Box
    comboNotifyAfter
    dominoDoc.NotifyAfter

Give the Combo Box fields a width of 250px.
On the Data tab of the Edit Box, set Display type to "Number".

Copy field values from the Notes client


In order to populate a Combo Box field with a list of available values, you can either type the values one by one, compute the values with JavaScript, or import them as a text list.
The last option is useful when web enabling existing Notes applications: you can copy the list of choices from the Notes form and import them in the XPage Combo Box field. We are going to do this for the Review Type field.

Open the form Document in Notes Designer and copy the values of the dialog list ReviewType to the clipboard.
In the Values tab of the comboReviewType field properties, click on "Import List..."
Paste the values from the form in the text field.
Now, remove any space characters before and after the vertical bar. This is essential to make the values work!!
On the bottom of the dialog window, specify a custom separator, and enter the vertical bar:

Press OK and the values appear in the values list in the properties view.

Use the same approach to populate the values of the field comboNotifyAfter.

In the above cases, importing values clearly doesn't speed up the work much, as there are only 2 values. But with longer lists, this is very helpful.

Copy a choicelist value formula from the Notes client


The dialog list field ReviewWindow in the Document form populates its values with an @formula, because the available options are in function of the selected review type:


Serial := "No time limit for each review|0" : 
"Move to next reviewer after time limit expires|1": "Keep sending reminders after time limit expires|2";

Parallel := "No time limit for each review|0" : "|1" : "Keep sending reminders after time limit expires|2";
WebParallel:= "No time limit for each review|0" : "Keep sending reminders after time limit expires|2";
@If(
@ClientType !="Notes" & ReviewType="2"; WebParallel;
ReviewType = "1"; Serial; ReviewType = "2" ; Parallel; "")


This can easily be converted to JavaScript:

Copy the formula from the Notes field.
In ccFormDocmument, go to the Values tab in the properties of comboReviewWindow.
Select "Add Formula Item..." and past the formula in the Server Side JavaScript editor. As expected, a lot of errors are highlighted in the margin, because this is not JavaScript yet.
Before transforming to JavaScript, clean-up the code, by removing the parts that apply to the Notes client only:


Serial := "No time limit for each review|0" : 
"Move to next reviewer after time limit expires|1": "Keep sending reminders after time limit expires|2";

WebParallel:= "No time limit for each review|0" : "Keep sending reminders after time limit expires|2";
@If(ReviewType="2"; WebParallel;Serial)


Now, replace any @Formula syntax by JavaScript syntax, and access the value of the ReviewType field by using getSubmittedValue(). The result would be something like this:


var revComponent = getComponent("comboReviewType");
var ReviewType = revComponent.getSubmittedValue();

var Serial = new Array("No time limit for each review|0","Move to next reviewer after time limit expires|1",
"Keep sending reminders after time limit expires|2");
var WebParallel= new Array("No time limit for each review|0","Keep sending reminders after time limit expires|2");
var list = @If(ReviewType=="2", WebParallel,Serial);

return list


Again, this example is quite simple and could probably easily be rewritten from scratch, but copying the formula allows to reuse the code structure and avoid type errors in literal strings. And you can use the same @Functions in JavaScript as in @Formula.

Before exiting the JavaScript editor, make sure the compute condition is set to Compute Dynamically:

Update Time Limit in function of Review Type


In order to make the time limit options adapt to the selected review type, we need to tell the first Combo Box to update the second onchange:

Select comboReviewType and in the Events view, go to the onchange event.
Under Server Options, select Partial Update and select the element comboReviewWindow.
Enable "Do not validate or update data":

Preview the result in the browser: the time limit options are now available in function of the selected review type.

Display the review time in function of the review window


The ReviewTime field only needs to be displayed if the ReviewWindow implies it. That is, if the ReviewWindow is different from "No time limit for each review".
In order to achieve this, we need to:
  • Add an onchange event in comboReviewWindow to trigger a refresh of the ReviewTime
  • Compute the visibility of the field editReviewTime and its label

ReviewWindow onchange


In the Events view of the field comboReviewWindow, set the following options for the onchange event:
  • Partial Update: sectionReviewOptions
  • Do not validate or update data

Selecting the appropriate element for partial update

For partial updates, you can often choose between several elements to be updated. For example, in the above onchange event, we could have decided to update panelReview instead of sectionReviewOptions.
In general, you want to have the smallest possible element to update, to reduce unneeded data transfer from the server.
In the above example, sectionReviewOptions appears to be the best choice:
Partially refreshing only the ReviewTime field is not sufficient, since we also want to update the field label.
We could have assigned an id to the table row containing the ReviewTime field and its label (via the All Properties tab of the table row), but that wouln't work, because then, this row is only rendered (=visible) in function of the value of ReviewWindow. Which means that its ID wouldn't be accessible in case it is not rendered (=hidden). In that case, an error would occur:

Visibility of ReviewTime


Via the Outline, select the table row containing the editReviewTime and its label.
In the All Properties tab, add a computed value for the rendered property:

var revComponent = getComponent("comboReviewWindow");
var revWindow = revComponent.getSubmittedValue();

revWindow !="0"


Result
The visiblilty is correctly calculated when the ReviewWindow is modified during edit of a document. But the visibility is incorrect
  • when creating a new document (default for ReviewWindow is "No time limit", but the ReviewTime is still displayed)
  • when opening an existing document

In both cases, getSubmittedValue doesn't return a value for the ReviewWindow, because this method only returns a value during a partial update.
The computed value for the visiblity needs to be extended.

Combining getValue and getSubmittedValue

  • use getSubmittedValue if it is not null
  • else, use getValue
  • if both are null (= when creating a new document), return false: do not display the time limit (because by default, the ReviewWindow is "No time limit"

The new computed value for the rendered property would be:


var revComponent = getComponent("comboReviewWindow");
var revWindowV = revComponent.getValue();
var revWindowSV = revComponent.getSubmittedValue();

if(revWindowSV!=null){
return(revWindowSV!="0");
}else if(revWindowV!=null){
return(revWindowV!="0");
}else{
return(false)
}


The visibility of the time limit is now always correctly computed.

Back to Top


Summary


This page was a long and interesting journey along the features and potential pitfalls when developing a web form with XPages.

After discussing form layout, we have covered common form features like action buttons, element visibility, validations, type-ahead, partial refresh,...

By doing this, we have come in touch with various XPage concepts, including source definition and data binding, scoped variables, accessing the document context and field values, accessing field values before validation and event handlers.

For now, we will consider the Library Document form as completely functional, apart from workflow, which will be discussed on the next page.

expanded Article information
collapsed Article information
Category:
IBM Redbooks: Building Domino Web Applications using Domino 8.5.1
Tags:

This Version: Version 11 February 16, 2010 9:40:18 AM by John Bergland  IBMer

expanded Attachments (34)
collapsed Attachments (34)

 


File TypeSizeFile NameCreated On
image/x-png 1 KB backtotop.png 1/15/10 11:06 AM
image/x-png 81 KB tablerow-rendered.png 1/15/10 11:06 AM
image/x-png 60 KB error-partial-refresh.png 1/15/10 11:06 AM
image/x-png 10 KB compute-dynamically.png 1/15/10 11:06 AM
image/x-png 76 KB reviewoptions-type.png 1/15/10 11:06 AM
image/x-png 35 KB reviewoptions-import-list.png 1/15/10 11:06 AM
image/x-png 30 KB reviewoptions-merge-cells.png 1/15/10 11:06 AM
image/x-png 9 KB reviewers-data-style.png 1/15/10 11:06 AM
image/x-png 11 KB add-reviewer-allproperties.png 1/15/10 11:06 AM
image/x-png 31 KB add-reviewer-type-ahead.png 1/15/10 11:06 AM
image/x-png 38 KB reviewer-onfocus.png 1/15/10 11:06 AM
image/x-png 16 KB reviewer-field-hint.png 1/15/10 11:06 AM
image/x-png 11 KB beforepageload.png 1/15/10 11:06 AM
image/x-png 6 KB add-reviewer-options.png 1/15/10 11:06 AM
image/x-png 15 KB add-reviewer-binding.png 1/15/10 11:06 AM
image/x-png 13 KB datareviewers-options.png 1/15/10 11:06 AM
image/x-png 14 KB listreviewers-options.png 1/15/10 11:06 AM
image/x-png 4 KB tablerow-outline.png 1/15/10 11:06 AM
image/x-png 12 KB type-ahead-options.png 1/15/10 11:06 AM
image/x-png 12 KB type-ahead-options.png 1/15/10 11:06 AM
image/x-png 6 KB reviewers-preview.png 1/15/10 11:06 AM
image/x-png 8 KB doc-properties.png 1/15/10 11:06 AM
image/x-png 12 KB computewithform.png 1/15/10 11:06 AM
image/x-png 8 KB button-visible.png 1/15/10 11:06 AM
image/x-png 11 KB disable-client-validation.png 1/15/10 11:06 AM
image/x-png 6 KB error-properties.png 1/15/10 11:06 AM
image/x-png 18 KB field-validation.png 1/15/10 11:06 AM
image/x-png 17 KB formtable-style.png 1/15/10 11:06 AM
image/x-png 9 KB form-title-html.png 1/15/10 11:06 AM
image/x-png 24 KB form-title-value.png 1/15/10 11:06 AM
expanded Versions (11)
collapsed Versions (11)
Version Comparison     
Version Date Changed by               Summary of changes
This version (11) Feb 16, 2010 9:40:18 AM John Bergland  
11 Jan 15, 2010 6:19:56 AM John Bergland  
10 Feb 15, 2010 4:45:41 AM Pascal David  
9 Feb 15, 2010 4:40:47 AM Pascal David  
8 Feb 15, 2010 4:38:10 AM Pascal David  
7 Feb 15, 2010 4:35:39 AM Pascal David  
6 Feb 15, 2010 4:29:40 AM Pascal David  
5 Feb 8, 2010 2:07:13 PM Patrick Picard  
4 Feb 8, 2010 2:05:45 PM Patrick Picard  
3 Feb 8, 2010 2:04:46 PM Patrick Picard  
2 Jan 15, 2010 11:00:24 AM John Bergland  
expanded Comments (0)
collapsed Comments (0)
Copy and paste this wiki markup to link to this article from another article in this wiki.
Go ElsewhereStay ConnectedSubscribe to RSSHelpAbout
  • All Lotus and WebSphere Portal wikis
  • IBM developerWorks
  • IBM Software support
  • IBM Social Business User Experience Blog
  • IBMSocialBizUX on Twitter
  • IBMSocialBizUX on Facebook
  • Lotus product forums
  • IBM Social Business UX blog
  • IBM Collaboration Solutions
  • Recently added feedRecently added
  • Recently edited feedRecently edited
  • Recently added comments feedRecently Added Comments
  • Wiki Help
  • Forgot user name/password
  • Wiki design feedback
  • Content feedback
  • About the wiki
  • About IBM
  • Privacy
  • Contact IBM
  • IBM Terms of use
  • Wiki terms of use