My answers below...

Slick Rick wrote:
> So I'm trying to make forms with the new 1.1 framework, and have several 
> questions about the way it works.
>  
> Here is my attempt to build a ClientForm:
>  
> ------- BEGIN CODE --------
> <?php
> class ClientForm extends sfForm
> {
>   protected $client;
>  
>   public function __construct($client, $defaults = null, $options = 
> array(), $CSRFSecret = null)
>   {
>     if (!$client instanceof Client)
>     {
>       throw new sfException('Object must be an instance of Client');
>     }
>    
>     $this->client = $client;
>    
>     parent::__construct($defaults, $options, $CSRFSecret);
>   }
>  
>   public function configure()
>   {
>     $i18n = sfContext::getInstance()->getI18N();
>    
>     $schema = new sfWidgetFormSchema(array(
>      'id' => new sfWidgetFormInputHidden(),
>      'general' => new sfWidgetFormSchema(array(
>        'name' => new sfWidgetFormInput(),
>        )),
>      'address' => new AddressFormSchema(), // AddressFormSchema extends 
> sfWidgetFormSchema
>      'additional' => new sfWidgetFormSchema(array(
>        'notes' => new sfWidgetFormTextarea(),
>        )),
>     ));
>    
>     $schema->setLabels(array(
>       'general' => array(
>         'name' => $i18n->__('Name'),
>         'notes' => $i18n->__('Notes'),
>       )
>     ));
>    
>     $schema->setHelps(array(
>       'general' => array(
>         'name' => $i18n->__('Enter a name for this client.'),
>         'notes' => $i18n->__('Enter any additional notes or profile 
> information.'),
>       )
>     ));   
>        
>     $this->setWidgetSchema($schema);
>    
>     $this->setValidatorSchema(
>      new sfValidatorSchema(array(
>        'name' => new sfValidatorString(array('min_length' => 2, 
> 'max_length' => 63)),
>      )));
>     
>     $input = array(
>       'id'   => $this->client->id,
>       'general' => array(
>         'name' => $this->client->name,
>         ),
>      'additional' => array(
>        'notes' => $this->client->notes,
>        ),
>     );
>    
>     $this->bind($input);
>   }
> }
>  
> ------- END CODE --------
>

I don't understand the end of the code where you bind() your form to an 
input. Is it just to package an example? If not, I don't understand what 
you're trying to do. If you want to change the default values, then use 
setDefaults(). The bind() method is to be used only when the client 
submit data.

> Here are some issues/questions that I have:
>  
> 1.) I don't think the Helps or the Labels work with my nested form 
> schema strucutre.  For instance, the labels just show the field name, 
> not the actual text that is defined. I don't receive an error or 
> anything, so I assume I have it setup right?

The setLabels() method can set labels for fields in the current widget 
schema. You must be able to change the label of the general field and 
also change the labels of the fields inside the general schema.

$schema->setLabel('general', 'General Things');

If you want to change the labels for the embedded schema, use:

$schema['general']->setLabels(array(
   'name'  => 'Name',
   'notes' => 'Notes',
));

>  
> 2.) The validator doesn't appear to work with the nested schema 
> structure.  If i have it set to array('general' => array('name' => 
> sfValidatorString())), it can't find the "name" field. 
>  
> 3.) Is I18N being handled the best way?  Seems like there might be a 
> more "integrated" approach?

Just remove everything i18n related and you're done. As of symfony 1.1.0 
beta4, the translations are managed automatically for you. The 
sfFactoryConfigHandler registers the i18n objects as the default 
translation callable for your forms:

sfWidgetFormSchemaFormatter::setTranslationCallable(array($this->factories['i18n'],
 
'__'));

>  
> 4.) I am wondering if the way that I am importing the address schema is 
> the correct/best method to do this. Will it work recursively if I want 
> to pass data from the $client variable into the address schema?  Will 
> validation work?  Should I somehow include another sfForm instead of a 
> schema?
>  

The best way to embed a form into another is to use the embedForm() 
method In your ClientForm configure() method, add:

$this->embedForm('address', new AddressForm());

symfony will automatically embed the address widgets and validators in 
the current form. It will also change the address name format 
accordingly. And now, just move all the labels, and helps stuff related 
to the address from ClientForm to the AddressForm to simplify things a bit.

And everything will work automatically, and recursively.

> 5.) Any general tips/best practices that I might be overlooking to make 
> this the work the most seamless/flexible way?

Here is your form rewritten will some improvements:

<?php

class AddressForm extends sfForm
{
   public function configure()
   {
     $this->setWidgets(array(...));
     $this->setValidators(array(...));

     $this->setLabels(...);
     $this->setHelps(...);
   }
}

class ClientGeneralForm extends sfForm
{
   public function configure()
   {
     $this->setWidgets(array(
       'name' => new sfWidgetFormInput(),
       'notes' => new sfWidgetFormTextarea(),
     ));

     $this->widgetSchema->setLabels(array('name'  => 'Name', 'notes' => 
'Notes'));
     $this->widgetSchema->setHelps(array(
       'name' => 'Enter a name for this client.',
       'notes' => 'Enter any additional notes or profile information.',
     ));
   }
}

class ClientForm extends sfForm
{
   protected $client;

   public function __construct(Client $client, $options = array(), 
$CSRFSecret = null)
   {
     $this->client = $client;

     parent::__construct(array(), $options, $CSRFSecret);
   }

   public function configure()
   {
     $this->setWidgetSchema(array(
      'id' => new sfWidgetFormInputHidden(),
     ));

     $this->widgetSchema->setNameFormat('client[%s]');

     $this->setValidators(array(
        'name' => new sfValidatorString(array('min_length' => 2, 
'max_length' => 63)),
      ));

     $this->embedForm('address', new AddressForm());
     $this->embedForm('general', new ClientGeneralForm());

     $this->setDefaults(array(
       'id' => $this->client->id,
       'general' => array(
         'name' => $this->client->name,
         'notes' => $this->client->notes,
        ),
     ));
   }
}

Now, when displaying the form, the id field will have a name of 
client[id] and the notes field will have a name of client[general][notes].

HTH,
Fabien

>  
> Thanks for any help or examples you can give me to get started in the 
> right direction.
>  
> -- ian
> 
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"symfony developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/symfony-devs?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to