As I had hoped, I got the opportunity over the weekend to spend some
significant time hacking on the Dialog2 APIs (and the legacy version of the
implementation), and I'm getting pretty happy with the results.  The test
program (shale-test-dialog2-legacy) includes scenarios for multiple windows
(both frames and a popup window running the same dialog), as well as a
parent-child popup scenario, and it seems we've addressed the majority of
the original issues on our requirements list[1].  The most important one
that remains to be considered is dealing with browser navigation buttons.

Nearly all of the dynamic behavior of a DialogContext are now encapsulated
in three public methods:

   // Start the execution of this dialog, and proceed until
   // a view needs to be rendered.  Navigate to that view
   // and return.
   public void start(FacesContext context);

   // Continue the execution of this dialog, using the
   // specified logical outcome (returned by the action
   // method that was executed for the previously rendered
   // view) to drive the initial transition.  Proceed until another
   // view needs to be rendered.  Navigate to that view
   // and return.
   public void advance(FacesContext context, String outcome);


   // Stop the execution of this dialog prematurely.  After
   // this method returns, there wll be no active DialogContext
   // instance associated with the current view.
   public void stop(FacesContext context);

A DialogContext now also has an optional "parent" property, pointing at the
DialogContext for a different window or frame belonging to the same user.
(This is different from subdialogs, which performs nested dialog execution
for the *same* window).  The classic use case is a popup window that needs
to be associated with a main window, and the popup needs to do things like
(a) pull data from the main window's data object, (b) do some computations
and/or interactions with the user, and (c) push some results back into the
main window's data object.  The test application has an example of this, on
the second page, where you can use a mini-wizard to select
city/state/zipcode to be pushed back into the main window.  NOTE - there are
two outstanding issues related to this test that should be finished off to
make it act more like a real app:

* JavaScript code to push client side updated values back into the main
window
 (to correspond to what is happening on the server side data objects).

* JavaScript code to close the popup window when it is finished or
cancelled.

As an example of the simplicity of the new APIs, here's the final code to
cover one of Sean's use cases -- a menu command that can cancel an
in-progress dialog and start a different one.

   public String checkout() {

       // Cancel any currently active dialog
       FacesContext context = FacesContext.getCurrentInstance();
       DialogContext dcontext = (DialogContext)
         context.getApplication().getVariableResolver().resolveVariable(context,
Constants.CONTEXT_BEAN);
       if (dcontext != null) {
           dcontext.stop(context);
       }

       // Start a new "checkout" dialog
       DialogContextManager manager = (DialogContextManager)
         context.getApplication().getVariableResolver().resolveVariable(context,
Constants.MANAGER_BEAN);
       dcontext = manager.create(context, "checkout");
       dcontext.start();
       return null;

   }

Please give this code a whirl by building shale-dialog2,
shale-dialog2-legacy, and shale-test-dialog2-legacy in the sandbox.  Note
that, at the moment, none of these APIs depend on the rest of Shale at all,
so they can be used on pretty much any JSF-based application that only needs
dialog management capabilities.  I'm leaning towards keeping things that way
(moving towards a philosophy that Shale is a set of fine grained features
that can be used a la carte), unless we have compelling reasons to establish
a dependency.

Craig

PS:  Now, on to getting the SCXML implementation up to date with the API
changes ...

Reply via email to