XForms patterns – the submission chain
Motivation: execute a submission only if another submission succeeds.
One of the most powerful features of XForms is the submission module. It is not comparable to the simple submission of a HTML form. Instead it allows you to have multiple submissions with different protocols, event handling and error reporting. However some powerful solution patterns are not obvious especially for XForms beginners.
A XForms submission is triggered by executing a XForms ‘send’ action so first thing most people try when they come to needing more than submission is to write:
<xf:action> <xf:send submission="submission1"/> <xf:send submission="submission2"/> </xf:action>
This is fine as long as each submission is completely independent from the other and you even don’t care about the order in which they return. But most often this is not the case and you want more control.
Assume you have a situation where one submission depends on the outcome of another submission. Very often you do not want to even try a submit if a certain condition hasn’t been met. By chaining submissions you can achieve this. Consider the following example – we have two submissions ‘register’ and ‘postComment’. We want that it’s only possible to post a comment to our application if the user has been registered before. By using the XForms submission events we can tie the execution of ‘postComment’ to the ‘xforms-submit-done’ event of the ‘register’ submission.
If the registration fails we can inform the user and cancel the posting. If everything goes well we fire the second submission. Again here we can inform the user if a problem occurs.
<xf:submission id="register" method="POST" ref="instance('userdata')" resource="registration" replace="none"> <xf:action ev:event="xforms-submit-done"> <xf:send submission="postComment"/> <xf:message level="ephemeral">You have been registered successfully</xf:message> </xf:action> <xf:action ev:event="xforms-submit-error"> <xf:message>Sorry - your registration failed. You won't be able to submit your comment</xf:message> </xf:action> </xf:submission> <xf:submission id="postComment" method="POST" resource="postComment"> <xf:action ev:event="xforms-submit-done"> <xf:message>Your comment has been posted - thank you</xf:message> </xf:action> <xf:action ev:event="xforms-submit-error"> <xf:message>You have been registered but the posting of your message failed</xf:message> </xf:action> </xf:submission>
Of course you can add as many submissions to the chain as you like.
With conditional execution of actions (XForms ‘if’ Attribute) and the ‘event()’ function you can further refine the functionality to give more detailed information about errors or even trigger arbitrary logic to handle the different outcomes. Especially when interacting with webservices (in the broad sense) chained submissions give you very good control to handle service outages and give optimal feedback to the user.