> When PageA calls PageB, as soon as PageB finishes presenting 
> the form it doesn't stop but drops out the bottom and returns 
> immediately to PageA.

In bOP <http://www.bivio.net/hm/download-bOP> we use "FormContext" to
solve this problem.  PageB requires context and bOP knows how to
return to PageA through the saved context.  We call this "unwinding".
You can nest the stack as deep as you like.  The context is saved in
the URL if PageA isn't a form, or in the called form's hidden fields,
if it is.  The entire form state is saved in the latter case.

PageB and PageA are FormModels in bOP.  If you visit our Pet Shop demo
<http://petshop.bivio.net>, you'll form context this used in the
LoginForm, OrderConfirmationForm, and ShippingAddressForm.  Here's all
the business logic in our ShippingAddressForm:

    sub execute_ok {
        my($self) = @_;
        # copy the current values into the OrderForm context
        $self->put_context_fields(%{$self->internal_get});
        return;
    }

    sub internal_initialize {
        my($self) = @_;
        my($info) = {
            require_context => 1,
            version => 1,
            visible => [
                'Order.ship_to_first_name',
                'Order.ship_to_last_name',
                'EntityAddress_2.addr1',
                'EntityAddress_2.addr2',
                'EntityAddress_2.city',
                'EntityAddress_2.state',
                'EntityAddress_2.zip',
                'EntityAddress_2.country',
                'EntityPhone_2.phone',
            ],
        };
        return $self->merge_initialize_info(
                $self->SUPER::internal_initialize, $info);
    }

In this case, we get the shipping address from the user, execute_ok is
called which stuffs the forms values into the calling form's context.
The infrastructure automatically unwinds to the OrderForm with the
newly filled in values.

The OrderForm doesn't know about the ShippingAddressForm.
Technically, the ShippingAddressForm doesn't know about the OrderForm.
It only requires the calling form to have fields with the same name.

The relationship between the "pages" (tasks in bOP) is not specified
by the forms.  That's handled by the control logic.  If a task has a
form, it can specify the next and cancel tasks.  This way you can
reuse the business logic quite easily.  Tasks can control the use of
context.  FormModels specify whether they can accept it or not.

Hope this helps.

Rob

Reply via email to