Apologies, I should have mentioned that I was using the controller code from my first mail. I have attached my test controller as Test.pm.

Thank you for your explanation about how $c->formbuilder works with forwards, that makes some of what I am seeing make more sense (and that I had some incorrect assumptions about how forwards worked, will brush up on the catalyst docs).

I should clarify my question from the previous mail, reading it again it wasn't very clear.

Based on the code you provided, I created a new Action::TT that attempts to place a copy of the fb objects in a hash so it can be later accessed by form name in the template (ex: forms.foo.FormBuilder). My base controller is attached as Multiple.pm and my modified Action::TT is attached as TT.pm.

The problem is that, even though the C::C::FormBuilder code is called twice (once for each action), only the last form to be processed is kept in $controller->_formbuilder. Makes sense, given what you explained below about forwards, but that still leaves me wondering how to:

a) grab the name of the form so I can put multiple forms in a stash hash (since _formbuilder->name is always that of the last form forwarded to)

b) put the correct form data in the stash for each form, since the data for the last form processed will always be in _formbuilder.

To see this in action, here is the log snippet from my last e-mail (you can see that C::C::FB runs against both actions, foo and foo_search, but that foo_search's data is the only thing that ends up in _formbuilder for both). See attached TT.pm for how I am grabbing the form data, maybe I am doing it wrong...

  [debug] Form (foo): Looking for config file foo.fb
[debug] Form (foo): Found form config /home/dwarren/MyApp/root/forms/foo.fb

  [debug] Form (foo_search): Looking for config file foo_search.fb
[debug] Form (foo_search): Found form config /home/dwarren/MyApp/foo_search.fb

  [debug] ACTION: foo
  [debug] REAL ACTION: foo_search
  [debug] FORM NAME: foo_search

  [debug] ACTION: foo
  [debug] REAL ACTION: foo
  [debug] FORM NAME: foo_search


I also ran the same code you provided in your last e-mail, and it happens there as well - the data is for the last form that was forwarded to. I would expect that C::C::FormBuilder is called as it comes across the action (which it is) but it looks like "setup_template_vars" happens later, once $_formbuilder has been populated with the forwarded data.

If I am just not grasping something, let me know. Maybe there is something funky with my Catalyst environment as well (if your sample code works for you and it does not for me)?

Sorry again if this confusing or long-winded. I have just been pulling my hair out on this one, and I don't think I know the guts of catalyst well enough yet to properly debug and explain what I am seeing.

Thank you again for your time!
Danny


Juan Camacho wrote:
On 2/12/07, Danny Warren <[EMAIL PROTECTED]> wrote:
It looks to me that forwarding from one "Form" action to another "Form"
action causes the FormBuilder data from the first action to be
overwritten.


Can you confirm this, or am I doing something wrong here?  I am still
somewhat green with Catalyst, so I might be misunderstanding exactly how
forwards work.  From reading the docs, I was under the impression that
two actions should not clobber each other upon forwarding (since
forwarded actions are processed inside an eval).


Each action will have it's own formbuilder object instance. After you
return from the forward to another form action, $self->formbuilder
will be a brand new FormBuilder object.

sub foo : Form('foo') {
  my ($self, $c) = @_;
  # $self->formbuilder is for foo form
  $self->forward('bar');
  # now $self->formbuilder is for bar form
}

sub bar : Form('bar') { ... }

Consequently, each action should do it's own thing with it's
FormBuilder object -- e.g. validate, add or change form fields). Not
sure what kind of problem you are having as a result of this since you
didn't provide sample Controller code.

_______________________________________________
List: [email protected]
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/

package Catalyst::Controller::FormBuilder::Multiple;

use strict;
use base qw| Catalyst::Controller::FormBuilder |;

sub __setup
{
  my $self = shift;
  my $class = ref $self;
  
  # Get a copy of the template setting or use default
  # NOTE: Duplicated from parent, unsure of best way to do this cleanly
  my $config = $self->config->{'Controller::FormBuilder'} || {};
  my $tmpl_type = $config->{template_type} || "TT";
  
  # Override the action value from the config to point to our template
  # actions, which will be passed on to the parent's setup method
  $config->{action} ||= 
"Catalyst::Controller::FormBuilder::Multiple::Action::$tmpl_type";
  
  $self->SUPER::__setup();
}

1;
package MyApp::Controller::Test;

use strict;
use warnings;
use base 'Catalyst::Controller::FormBuilder::Multiple';

sub foo : Local Form
{
  my ( $self, $c ) = @_;
  my $foo_form = $self->formbuilder;
  my $foo_search_form = $c->forward('foo_search');
}

sub foo_search : Local Form
{
  my ( $self, $c ) = @_;
  my $form = $self->formbuilder;
  return $form;
}

1;
package Catalyst::Controller::FormBuilder::Multiple::Action::TT;

use strict;
use base qw| Catalyst::Controller::FormBuilder::Action::TT |;

sub setup_template_vars
{
  my $self = shift;
  my ( $controller, $c ) = @_; 
  
  $self->SUPER::setup_template_vars(@_); 
  
  # Get the name of the current form, and the stash and obj names that have 
already
  # been created
  my $form_name  = $controller->_formbuilder->name;
  my $stash_name = $controller->_fb_setup->{stash_name};
  my $obj_name   = $controller->_fb_setup->{obj_name};
  
  # If a form name is defined, create aliases to this form by name
  # NOTE: Will make multiple form hash key configurable later
  if ( defined $form_name )
  {
    $c->stash->{forms}{$form_name}{$stash_name} = $c->stash->{$stash_name};
    $c->stash->{forms}{$form_name}{$obj_name} = $c->stash->{$obj_name};
  }
  
  # DEBUG, will remove later
  $c->log->debug("REAL ACTION: " . ( $self->_attr_params->[0] || $self->reverse 
) );
  $c->log->debug("ACTION: " . $c->action );
  $c->log->debug("FORM NAME: " . $form_name);
}

1;
_______________________________________________
List: [email protected]
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/

Reply via email to