Showing posts with label forms. Show all posts
Showing posts with label forms. Show all posts

2009-01-28

symfony & mark fields as required, part 2

In previous post - "symfony & mark fields as required" we have a solution for symfony to mark required forms field automatically.

But - it's not fully OOP. so ...

1. the main idea - create custom formatter.

2. inheritence


Base class for all generated forms - is BaseFormPropel
It's also generated from template sfPropelFormBaseTemplate.php which is in propel plugin.
Fix it. (class will be extends from CustomBaseForm instead of sfFormPropel)

[?php

/**
* Project form base class.
*
* @package ##PROJECT_NAME##
* @subpackage form
* @author ##AUTHOR_NAME##
* @version SVN: $Id: sfPropelFormBaseTemplate.php 9304 2008-05-27 03:49:32Z dwhittle $
*/
abstract class BaseFormPropel extends CustomBaseForm
{
public function setup()
{
}
}


3. create CustomBaseForm (put it to /lib/form )

/**
* Custom form base class.
*
* @package shopportal
* @subpackage form
* @author gEndelf
*/
abstract class CustomBaseForm extends sfFormPropel
{
public function getTranslationCatalogue() {
return "";
}

public function render($attributes = array())
{
$formatterObj = $this->widgetSchema->getFormFormatter();

if(!is_null($formatterObj)) {
$formatterObj->setValidatorSchema($this->getValidatorSchema());

if(($translationCatalogue = $this->getTranslationCatalogue()) != "") {
$this->widgetSchema->getFormFormatter()->setTranslationCatalogue($translationCatalogue);
}
}

return parent::render($attributes);
}

public function __toString()
{
try
{
return $this->renderUsing("Store");
}
catch (Exception $e)
{
self::setToStringException($e);
// we return a simple Exception message in case the form framework is used out of symfony.
return 'Exception: '.$e->getMessage();
}
}
}


3. If your form uses translation catalogue


/**
* Contacts form.
*/
class ContactsForm extends BaseContactsForm
{
public function configure()
{
// ...
}

public function getTranslationCatalogue() {
return "contact_form";
}
}


4. Last step

symfony propel:build-all
symfony cc


Advantages - you form doesn't contain repeatable code (guys - it's OOP :)

2009-01-19

symfony & mark fields as required



By default required fields in symfony form framework are not marked with '*'

How could we do this ?
- you could manually create form with fields (a lot of code, a lot of efforts)
- create own form formatter and using it with form class. It will automatically mark fields as we need ! (that's nice news :)

so - let's go !
1. Create own formatter (sfWidgetFormSchemaFormatter%)

class sfWidgetFormSchemaFormatterStore extends sfWidgetFormSchemaFormatter
{
protected
$rowFormat = "\n %label%\n %error%%field%%help%%hidden_fields%\n\n",
$errorRowFormat = "\n%errors%\n",
$helpFormat = '
%help%',
$decoratorFormat = "\n %content%
",
$requiredTemplate= ' *',
$validatorSchema = null;

/**
* Generates the label name for the given field name.
*
* @param string $name The field name
* @return string The label name
*/
public function generateLabelName($name)
{
$label = parent::generateLabelName($name);

$fields = $this->validatorSchema->getFields();
if($fields[$name] != null) {
$field = $fields[$name];
if($field->hasOption('required') && $field->getOption('required')) {
$label .= $this->requiredTemplate;
}
}
return $label;
}

public function setValidatorSchema(sfValidatorSchema $validatorSchema)
{
$this->validatorSchema = $validatorSchema;
}
}


we have some useful changes:
- add css classes
- add $requiredTemplate with required field template
- add injection of validatorSchema

2. Owerride __toString method (form class) - for using own formatter

class StoreRegistrationForm extends BaseStoreDetailsForm
{
public function configure()
{
// ...
}

public function render($attributes = array())
{
$formatterObj = $this->widgetSchema->getFormFormatter();
if(!is_null($formatterObj)) { $formatterObj->setValidatorSchema($this->getValidatorSchema()); $this->widgetSchema->getFormFormatter()->setTranslationCatalogue("register_store_form");
}
return parent::render($attributes);
}

public function __toString()
{
try
{
return $this->renderUsing('Store');
}
catch (Exception $e)
{
self::setToStringException($e);
// we return a simple Exception message in case the form framework is used out of symfony.
return 'Exception: '.$e->getMessage();
}
}
}


3. as you see - TranslationCatalogue has been injected not in configure method.
If you use other than messages.xml - you should call setTranslationCatalogue in render block

public function render($attributes = array())
{
$formatterObj = $this->widgetSchema->getFormFormatter();

if(!is_null($formatterObj)) {
$formatterObj->setValidatorSchema($this->getValidatorSchema());
$this->widgetSchema->getFormFormatter()->setTranslationCatalogue("register_store_form");
}

return parent::render($attributes);
}


that's all )