Submitting and retrieving data

Bound data items can be submitted to their data sources as new and replacement documents.

Shown here are the simplest devices for creating, retrieving, and replacing documents. Data can also be manipulated through simple actions and the Domino® library in JavaScript™. Controls other than views, such as data tables, can be used to retrieve data.

Creating documents

A Button control of type Submit sends bound data to its source. By default a new document is created. The following example shows an entire page. It contains a Domino document data source (the form named main), an input box bound to an item on the data source, and a submit button. If the user enters a value in the input box and clicks the button, a document is created in the data store.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
	<xp:this.data>
		<xp:dominoDocument var="document1" formName="main"></xp:dominoDocument>
	</xp:this.data>
	<xp:inputText id="inputText1" value="#{document1.subject}"></xp:inputText>
	<xp:br></xp:br>
	<xp:button value="submit" id="button1">
		<xp:eventHandler event="onclick" submit="true"
			refreshMode="complete" immediate="false" save="true">
		</xp:eventHandler>
	</xp:button>
	<xp:button value="cancel" id="button2"></xp:button>
</xp:view>

Clicking the submit button causes a request to be sent to the server. The server processes the request, creating the new document, and sends a response to the client. The default response is to open a fresh copy of the same XPage.

You might also place a Button control of type Cancel on the page. This button sends a request and gets the response, but the server does not process the data.

Retrieving documents

A view can be adjusted to retrieve documents:
  • The View property pageName specifies an XPage to open if the user selects an element that is a link. In Design mode, click on the View tab for the View control and specify At runtime, open selected document using. By default, the XPage associated with the data source's form is used.
  • The View Column property displayAs allows the user to use the element as a link to the underlying document. In Design mode, click on the Display tab for the View Column control and check Show values in this column as links.
The following View control opens the XPage named replace if the user clicks a link, and sets up the first column, which contains the value of the subject item, as a link. When the replace XPage opens, it is populated with any bound data from the target document in the view.
<xp:viewPanel rows="30" id="viewPanel1" pageName="/replace.xsp">
	<xp:this.facets>
	 <xp:pager partialRefresh="true" layout="Previous Group Next"
			xp:key="headerPager" id="pager1">
		</xp:pager>
	</xp:this.facets>
	<xp:this.data>
		<xp:dominoView var="view1" viewName="main"></xp:dominoView>
	</xp:this.data>
	<xp:viewColumn columnName="subject" id="viewColumn1"
		displayAs="link">
		<xp:viewColumnHeader value="subject"
			id="viewColumnHeader1">
		</xp:viewColumnHeader>
	</xp:viewColumn>
	<xp:viewColumn columnName="$1" id="viewColumn2">
		<xp:viewColumnHeader value="last modified"
			id="viewColumnHeader2">
		</xp:viewColumnHeader>
	</xp:viewColumn>
</xp:viewPanel>

Replacing documents

To modify an existing document, you first retrieve it, for example, as outlined in the previous section. The user can then make modifications on the XPage. Submission of the XPage results in a replacement when action="editDocument" is specified for the data source. You can set this on the Data tab for the XPage or other container.
The following example shows an entire XPage. It is the replace page opened as a result of clicking on a link in the View control shown in the previous section. The page contains an input box which is populated by the subject item from the retrieved document. Notice also that the XPage has a navigation rule that opens the main XPage after a submission.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
	<xp:this.data>
		<xp:dominoDocument formName="main" var="document1" action="editDocument" />
	</xp:this.data>
	<xp:inputText id="inputText1" value="#{document1.subject}"></xp:inputText>
	<xp:br></xp:br>
	<xp:button value="submit" id="button1">
		<xp:eventHandler event="onclick" submit="true"
			refreshMode="complete" immediate="false" save="true">
		</xp:eventHandler>
	</xp:button>
	<xp:button value="cancel" id="button2">
		<xp:eventHandler event="onclick" submit="true"
			refreshMode="complete" immediate="true" save="false">
		</xp:eventHandler>
	</xp:button>
	<xp:this.navigationRules>
		<xp:navigationRule outcome="xsp-success" viewId="/main.xsp"></xp:navigationRule>
	</xp:this.navigationRules>
</xp:view>

At run time, the user clicks a link on the view on the main page. This opens and populates the replace page. The user can make changes on this page. Submitting the page causes the existing document to be replaced and the main page to be opened.

Query save agent

You can call an agent to process a document before it is saved. This agent can cancel the save operation.

Under All Properties for the page, open the pertinent data source (under data > data). For the WebQuerySaveAgent property, specify the name of an agent in the current application.

When the user makes a submission to the data source, the agent is called after field values are applied but before the document is saved. The agent can access the in-memory document through DocumentContext in the LotusScript® NotesAgentContext class or getDocumentContext in the Java™ AgentContext class. The agent can cancel the save operation by appending an item named SaveOptions with a value of 0 (zero). Any other value for SaveOptions results in the document being saved but without the SaveOptions item.

The following XPage calls the agent saveAgentJava before final submission on a save operation.
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

	<xp:this.data>
		<xp:dominoDocument var="document1" formName="City"
			webQuerySaveAgent="saveAgentJava">
		</xp:dominoDocument>
	</xp:this.data>
	<xp:messages id="messages1"></xp:messages>
	<xp:table>
		<xp:tr>
			<xp:td colspan="2">
				<xp:label
					value="If the field#1 is empty, then the agent will prevent it from being saved"
					id="label0"></xp:label>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td>
				<xp:label value="Field1:" id="label1" for="inputText1"></xp:label>
			</xp:td>
			<xp:td>
				<xp:inputText value="#{document1.Field1}" id="inputText1"></xp:inputText>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td>
				<xp:label value="Field2:" id="label2" for="inputText2">
				</xp:label>
			</xp:td>
			<xp:td>
				<xp:inputText value="#{document1.Field2}" id="inputText2"></xp:inputText>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td>
				<xp:label value="Agent calculated Value:" id="label3">
				</xp:label>
			</xp:td>
			<xp:td>
				<xp:text escape="true" id="computedField2" value="#{document1.AgentValue}"></xp:text>
			</xp:td>
		</xp:tr>
		<xp:tr>
			<xp:td></xp:td>
			<xp:td>
				<xp:button value="Save" id="button1">

					<xp:eventHandler event="onclick" submit="true"
						refreshMode="complete">
						<xp:this.action>
							<xp:saveDocument var="document1"></xp:saveDocument>
						</xp:this.action>
					</xp:eventHandler>
				</xp:button>
			</xp:td>
		</xp:tr>
	</xp:table>
</xp:view>
Here is the code for saveAgentJava which conditionally cancels the save operation.
import lotus.domino.*;

public class JavaAgent extends AgentBase {

    public void NotesMain() {

      try {
          Session session = getSession();
          AgentContext agentContext = session.getAgentContext();

          // (Your code goes here)
          Document doc = agentContext.getDocumentContext();
          doc.replaceItemValue("AgentValue", "Processed by Java: "+doc.getItemValueString("Field1")+","+doc.getItemValueString("Field2"));
          
          String field1 = doc.getItemValueString("Field1");
          if(field1==null || field1.length()==0) {
        	  doc.replaceItemValue("SaveOptions", Integer.valueOf(0));
          }
          
      } catch(Exception e) {
          e.printStackTrace();
       }
   }
}