Continuations have always been used with a 'forward thinking' approach. With that I mean that when you resume after you pause, the next code is executed using the same local variable state. This results in explanations like: you continue where you left off, or continuations contain the remaining work to be done, ... With this release of RIFE, however, we allow you to step back to a previous location in the code. Instead of resuming where you left off when you paused, you can now also resume where you left off in the previous continuation.
The availability of this features makes it extremely easy to add 'back' submit buttons to multi-step flows. You just have to detect that it has been clicked and execute the stepBack() method call. This use of continuations doesn't require an intermediate user reponse step to continue. Instead, it captures the state of the current continuation and immediately resumes where the previous continuation resumed (not the last pause() call, but the one before).
For example (you can try out an online version
of this example on the rifers.org website):
do {
generateForm(template, order);
template.setBlock("content_form", "content_shipping");
print(template);
pause();
template.clear();
order.resetValidation();
fillSubmissionBean(order);
} while (duringStepBack() || !order.validateGroup("shipping"));
do {
generateForm(template, order);
template.setBlock("content_form", "content_creditcard");
print(template);
pause();
template.clear();
order.resetValidation();
fillSubmissionBean(order);
if (hasParameterValue("back1")) stepBack();
} while (!order.validateGroup("creditcard"));
template.setBean(order);
template.setBlock("content", "content_overview");
print(template);
ContinuationContext.getActiveContext().removeContextTree();
Note that the first loop contains an additional check: "duringStepBack()". This is needed since the "shipping" group of the OrderData bean is already valid, otherwise it would not have been possible to get to the second while loop. Without the check for an active step-back continuation, the first loop would simply terminate immediately after the step-back and the execution would arrive at the location of the "stepBack()" method call.
A very nice feature of this setup is that the data of the second step (the credit card details) is filled into the bean but not validated when the back button is pressed. Users can thus fill in incomplete data, go to the previous step in the wizard without being interrupted, change the data in the first form, and after submission they will see the same incomplete data that they entered before stepping back.