Now we’ll configure the SubmitDocument data adapter.
-
We should be back at the data connections dialog box. Click Add....
-
Select the Create a new connection to radio button. Then choose Receive data. Click Next in the wizard. Note: you are choosing Receive data even though think of the operation as submitting the document. This is a result of how the web service method was defined.
-
Under From where do you want to receive your data?, choose Web service. Click Next.
-
Enter the location of the Qdabra DBXL Document web service, same as above in step 6. Click Next.
-
Select the operation called SubmitDocument, near the bottom of the list. Click Next.
-
No value is needed for any of the parameters on this panel. Just click Next.
-
There is no need to store a copy of the data in the form template. Just click Next.
-
Uncheck the box Automatically retrieve data when the form is opened. Our code will do that instead. Then click Finish.
-
Back at the data connections dialog box, click Close.
Adding the On Load and Submit handlers
In this series of steps we will hook up the On Load and Submit handlers to form code using Visual Studio Tools for Applications (VSTA). However, we won’t fill in the event handlers yet.
-
Click the Tools menu, locate the submenu Programming, and choose the item Loading Event.... VSTA will launch and show code for an empty event handler, called FormEvents_Loading.
-
Back in InfoPath Designer, go to the Tools menu and choose Submit Options....
-
In Expense Report, Allow users to submit this form will already be checked. If it is not for your form template, check it now.
-
Choose Perform custom action using Code.
-
Click Edit Code.... VSTA will flash on the task bar. If you switch to it you’ll notice another empty submit handler, called FormEvents_Submit, has appeared.
-
Back in InfoPath Designer, click OK to dismiss the submit handler dialog box.
Writing the custom code to query and submit the DBXL document
In this series of steps we will hook up the On Load and Submit handlers to form code using Visual Studio Tools for Applications (VSTA). However, we won’t fill in the event handlers yet.
-
We’ll need to add some subroutines to the form code which will handle querying the web services we added earlier.
a. If you are programming in Visual Basic, insert the following code just before the End Class statement at the bottom of the file:
Private Function GetDocTypeName() As String
' Return the document type name that will be used in DBXL to identify the documents.
' For tutorial simplicity this is hard-coded, but can be obtained via more flexible methods for production templates.
Return "MyDocType"
End Function
Private Function LoadFromDbxl(ByVal docType As String, ByVal docId As String) As Boolean
Try
Dim domGetDocument As XPathNavigator = DataSources("GetDocument").CreateNavigator()
' Set docId argument for the DBXL web service call.
domGetDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:GetDocument/tns:docId", NamespaceManager).SetValue(docId)
' Invoke the web service method to query DBXL for the document.
Dim connGetDocument As DataConnection = DataConnections("GetDocument")
connGetDocument.Execute()
' Check for error.
If Not domGetDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:GetDocumentResponse/tns:GetDocumentResult/tns:Success", NamespaceManager).ValueAsBoolean Then
Throw New Exception("GetDocument failed")
End If
' Replace main DOM with obtained document.
Dim root As XPathNavigator = MainDataSource.CreateNavigator().SelectSingleNode("/child::*", NamespaceManager)
Dim newDoc As XPathNavigator = domGetDocument.CreateNavigator().SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:GetDocumentResponse/tns:docInfo/tns:Content/node()", NamespaceManager)
root.InnerXml = newDoc.InnerXml
' Add new or updated QdabraDBXL PI so subsequent saves will overwrite DBXL document.
InsertQdabraDbxlPi(docType, docId)
Catch
Return False ' Failure.
End Try
Return True ' Success.
End Function
Private Function SubmitToDbxl(ByVal docType As String, ByVal name As String, ByVal author As String, ByVal description As String) As Boolean
Dim domMainDocument As XPathNavigator = MainDataSource.CreateNavigator()
Dim domSubmitDocument As XPathNavigator = DataSources("SubmitDocument").CreateNavigator()
Try
' Set the arguments for the SubmitDocument web service call.
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:docTypeName", NamespaceManager).SetValue(docType)
' Notice that tns:xml will contain the entire main document being submitted to DBXL.
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:xml", NamespaceManager).SetValue(MainDataSource.CreateNavigator().OuterXml)
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:name", NamespaceManager).SetValue(name)
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:author", NamespaceManager).SetValue(author)
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:description", NamespaceManager).SetValue(description)
' Invoke the web service method to submit the document data to DBXL.
Dim connSubmit As DataConnection = DataConnections("SubmitDocument")
connSubmit.Execute()
' Check for error.
If Not domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:SubmitDocumentResponse/tns:SubmitDocumentResult/tns:Success", NamespaceManager).ValueAsBoolean Then
Throw New Exception("SubmitDocument failed")
End If
' Add new or updated QdabraDBXL PI so subsequent saves will overwrite DBXL document.
Dim docId As String = domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:SubmitDocumentResponse/tns:docId", NamespaceManager).Value
InsertQdabraDbxlPi(docType, docId)
Catch
Return False ' Failure.
End Try
Return True ' Success.
End Function
Private Sub InsertQdabraDbxlPi(ByVal docType As String, ByVal docId As String)
Dim domMainDocument As XPathNavigator = MainDataSource.CreateNavigator()
' Remove any existing QdabraDBXL PI.
Dim oldPi As XPathNavigator = domMainDocument.SelectSingleNode("/processing-instruction()[local-name(.) = 'QdabraDBXL']", NamespaceManager)
If Not oldPi Is Nothing Then
oldPi.DeleteSelf()
End If
If docId <> "" Then
' Add new or updated QdabraDBXL PI so subsequent saves will overwrite DBXL document.
Dim newPi As String = String.Format("<?QdabraDBXL docid='{0}' doctype='{1}' ?>", docId, docType)
domMainDocument.SelectSingleNode("/processing-instruction()[local-name(.) = 'mso-infoPathSolution']", NamespaceManager).InsertBefore(newPi)
End If
End Sub
b. If you are programming in Visual C#, use this code instead, inserted just after the closing brace for the empty FormEvents_Submit function:
public string GetDocTypeName()
{
// Return the document type name that will be used in DBXL to identify the documents.
// For tutorial simplicity this is hard-coded, but can be obtained via more flexible methods for production templates.
return "MyDocType";
}
private bool LoadFromDbxl(string docType, string docId)
{
try
{
XPathNavigator domGetDocument = DataSources["GetDocument"].CreateNavigator();
// Set docId argument for the DBXL web service call.
domGetDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:GetDocument/tns:docId", NamespaceManager).SetValue(docId);
// Invoke the web service method to query DBXL for the document.
DataConnection connGetDocument = DataConnections["GetDocument"];
connGetDocument.Execute();
// Check for error.
if (!domGetDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:GetDocumentResponse/tns:GetDocumentResult/tns:Success", NamespaceManager).ValueAsBoolean)
throw new Exception("GetDocument failed");
// Replace main DOM with obtained document.
XPathNavigator root = MainDataSource.CreateNavigator().SelectSingleNode("/child::*", NamespaceManager);
XPathNavigator newDoc = domGetDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:GetDocumentResponse/tns:docInfo/tns:Content/node()", NamespaceManager);
root.InnerXml = newDoc.InnerXml;
// Add new or updated QdabraDBXL PI so subsequent saves will overwrite DBXL document.
InsertQdabraDbxlPi(docType, docId);
}
catch
{
return false; // Failure.
}
return true; // Success.
}
private bool SubmitToDbxl(string docType, string name, string author, string description)
{
XPathNavigator domMainDocument = MainDataSource.CreateNavigator();
XPathNavigator domSubmitDocument = DataSources["SubmitDocument"].CreateNavigator();
try
{
// Set the arguments for the SubmitDocument web service call.
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:docTypeName", NamespaceManager).SetValue(docType);
// Notice that tns:xml will contain the entire main document being submitted to DBXL.
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:xml", NamespaceManager).SetValue(MainDataSource.CreateNavigator().OuterXml);
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:name", NamespaceManager).SetValue(name);
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:author", NamespaceManager).SetValue(author);
domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitDocument/tns:description", NamespaceManager).SetValue(description);
// Invoke the web service method to submit the document data to DBXL.
DataConnection connSubmit = DataConnections["SubmitDocument"];
connSubmit.Execute();
// Check for error.
if (!domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:SubmitDocumentResponse/tns:SubmitDocumentResult/tns:Success", NamespaceManager).ValueAsBoolean)
throw new Exception("Submit failed");
// Add new or updated QdabraDBXL PI so subsequent saves will overwrite DBXL document.
string docId = domSubmitDocument.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:SubmitDocumentResponse/tns:docId", NamespaceManager).Value;
InsertQdabraDbxlPi(docType, docId);
}
catch
{
return false; // Failure.
}
return true; // Success.
}
private void InsertQdabraDbxlPi(string docType, string docId)
{
XPathNavigator domMainDocument = MainDataSource.CreateNavigator();
// Remove any existing QdabraDBXL PI.
XPathNavigator oldPi = domMainDocument.SelectSingleNode("/processing-instruction()[local-name(.) = 'QdabraDBXL']", NamespaceManager);
if (oldPi != null)
{
oldPi.DeleteSelf();
}
if (docId != "")