To implement your own form fields, you need to have a thorough understanding of the data flow within a form field. A form field stores its data in three different representations: (1) the format required by the form's object (2) a normalized format for internal processing (3) the format used for display A date field, for example, may store a date as "Y-m-d" string (1) in the object. To facilitate processing in the field, this value is normalized to a DateTime object (2). In the HTML representation of your form, a localized string (3) is presented to and modified by the user. In most cases, format (1) and format (2) will be the same. For example, a checkbox field uses a Boolean value both for internal processing as for storage in the object. In these cases you simply need to set a value transformer to convert between formats (2) and (3). You can do this by calling setValueTransformer() in the configure() method. In some cases though it makes sense to make format (1) configurable. To demonstrate this, let's extend our above date field to store the value either as "Y-m-d" string or as timestamp. Internally we still want to use a DateTime object for processing. To convert the data from string/integer to DateTime you can set a normalization transformer by calling setNormalizationTransformer() in configure(). The normalized data is then converted to the displayed data as described before.
Author: Bernhard Schussek (bernhard.schussek@symfony-project.com)
Inheritance: extends Symfony\Component\Form\Configurable, implements Symfony\Component\Form\FieldInterface
コード例 #1
0
ファイル: HybridField.php プロジェクト: skoop/symfony-sandbox
 /**
  * {@inheritDoc}
  */
 public function bind($data)
 {
     if ($this->mode === self::GROUP) {
         parent::bind($data);
     } else {
         Field::bind($data);
     }
 }
コード例 #2
0
 /**
  * {@inheritDoc}
  */
 protected function configure()
 {
     // default precision is locale specific (usually around 3)
     $this->addOption('precision');
     $this->addOption('grouping', false);
     $this->addOption('rounding-mode', NumberToLocalizedStringTransformer::ROUND_HALFUP);
     parent::configure();
     $this->setValueTransformer(new NumberToLocalizedStringTransformer(array('precision' => $this->getOption('precision'), 'grouping' => $this->getOption('grouping'), 'rounding-mode' => $this->getOption('rounding-mode'))));
 }
コード例 #3
0
 /**
  * {@inheritDoc}
  */
 protected function configure()
 {
     $this->addOption('value');
     parent::configure();
     $this->setValueTransformer(new BooleanToStringTransformer());
 }
コード例 #4
0
ファイル: Form.php プロジェクト: noelg/symfony-demo
 /**
  * {@inheritDoc}
  */
 public function writeProperty(&$objectOrArray)
 {
     $isReference = false;
     // If the data is identical to the value in $objectOrArray, we are
     // dealing with a reference
     if ($this->getPropertyPath() !== null) {
         $isReference = $this->getData() === $this->getPropertyPath()->getValue($objectOrArray);
     }
     // Don't write into $objectOrArray if $objectOrArray is an object,
     // $isReference is true (see above) and the option "by_reference" is
     // true as well
     if (!is_object($objectOrArray) || !$isReference || !$this->getOption('by_reference')) {
         parent::writeProperty($objectOrArray);
     }
 }
コード例 #5
0
ファイル: HybridField.php プロジェクト: rooster/symfony
 /**
  * {@inheritDoc}
  */
 public function isEmpty()
 {
     if ($this->mode === self::FORM) {
         return parent::isEmpty();
     }
     return Field::isEmpty();
 }
コード例 #6
0
ファイル: FieldGroup.php プロジェクト: notbrain/symfony
 /**
  * {@inheritDoc}
  */
 public function addError(FieldError $error, PropertyPathIterator $pathIterator = null, $type = null)
 {
     if (null !== $pathIterator) {
         if ($type === self::FIELD_ERROR && $pathIterator->hasNext()) {
             $pathIterator->next();
             if ($pathIterator->isProperty() && $pathIterator->current() === 'fields') {
                 $pathIterator->next();
             }
             if ($this->has($pathIterator->current()) && !$this->get($pathIterator->current())->isHidden()) {
                 $this->get($pathIterator->current())->addError($error, $pathIterator, $type);
                 return;
             }
         } else {
             if ($type === self::DATA_ERROR) {
                 $iterator = new RecursiveFieldIterator($this);
                 $iterator = new \RecursiveIteratorIterator($iterator);
                 foreach ($iterator as $field) {
                     if (null !== ($fieldPath = $field->getPropertyPath())) {
                         if ($fieldPath->getElement(0) === $pathIterator->current() && !$field->isHidden()) {
                             if ($pathIterator->hasNext()) {
                                 $pathIterator->next();
                             }
                             $field->addError($error, $pathIterator, $type);
                             return;
                         }
                     }
                 }
             }
         }
     }
     parent::addError($error);
 }
コード例 #7
0
 /**
  * {@inheritDoc}
  */
 public function submit($data)
 {
     if ($this->mode === self::FORM) {
         parent::submit($data);
     } else {
         Field::submit($data);
     }
 }
コード例 #8
0
 /**
  * Sets the locale of this field.
  *
  * @see Localizable
  */
 public function setLocale($locale)
 {
     parent::setLocale($locale);
     foreach ($this->fields as $field) {
         $field->setLocale($locale);
     }
 }
コード例 #9
0
 protected function configure()
 {
     $this->addOption('foo');
     $this->addRequiredOption('bar');
     parent::configure();
 }
コード例 #10
0
 /**
  * Expose method for testing purposes
  */
 public function getNormalizedData()
 {
     return parent::getNormalizedData();
 }
コード例 #11
0
 /**
  * {@inheritDoc}
  */
 public function getAttributes()
 {
     return array_merge(parent::getAttributes(), array('type' => 'text/javascript', 'src' => $this->_src));
 }
コード例 #12
0
ファイル: Form.php プロジェクト: GromNaN/GitWikiApp
 /**
  * {@inheritDoc}
  */
 public function writeProperty(&$objectOrArray)
 {
     $data = $this->getData();
     // Don't update parent if data is a composite type (object or array)
     // and "by_reference" option is true, because then we expect that
     // we are working with a reference to the parent's data
     if (!(is_object($data) || is_array($data)) || !$this->getOption('by_reference')) {
         parent::writeProperty($objectOrArray);
     }
 }
コード例 #13
0
 /**
  * Distributes the generator among all nested fields
  *
  * @param HtmlGeneratorInterface $generator
  */
 public function setGenerator(HtmlGeneratorInterface $generator)
 {
     parent::setGenerator($generator);
     // TESTME
     foreach ($this->fields as $field) {
         $field->setGenerator($generator);
     }
 }