Author: francois
Date: 2010-05-13 22:09:55 +0200 (Thu, 13 May 2010)
New Revision: 29449

Added:
   
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaDecoratorEscaped.class.php
   
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaOptional.class.php
Modified:
   plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php
   plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php
   plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormPlain.php
Log:
[1.5] Allowed embedded relation form to add new related objects (WIP)

Modified: plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php      
2010-05-13 20:01:46 UTC (rev 29448)
+++ plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropel.class.php      
2010-05-13 20:09:55 UTC (rev 29449)
@@ -21,6 +21,7 @@
 abstract class sfFormPropel extends sfFormObject
 {
   protected $fixedValues = array();
+  protected $optionalForms = array();
   
   /**
    * Constructor.
@@ -93,6 +94,26 @@
   }
 
   /**
+   * Binds the form with input values.
+   *
+   * It triggers the validator schema validation.
+   *
+   * @param array $taintedValues  An array of input values
+   * @param array $taintedFiles   An array of uploaded files (in the $_FILES 
or $_GET format)
+   */
+  public function bind(array $taintedValues = null, array $taintedFiles = null)
+  {
+    foreach ($this->optionalForms as $name => $form) {
+      $i = 1;
+      while (isset($taintedValues[$name . $i])) {
+        $this->embedForm($name . $i, clone $form);
+        $i++;
+      }
+    }
+    return parent::bind($taintedValues, $taintedFiles);
+  }
+
+  /**
    * @see sfFormObject
    */
   protected function doUpdateObject($values)
@@ -363,7 +384,7 @@
       'embedded_form_class'   => null,
       'item_pattern'          => '%index%',
       'add_empty'             => false,
-      'empty_name'            => null,
+      'empty_label'           => null,
       'hide_on_new'           => false,
     ), $options);
     
@@ -399,22 +420,22 @@
     ));
     
     // add empty form for addition
-    // FIXME new relations saved at each edit
     if ($options['add_empty'])
     {
-      if (null === $options['empty_name']) {
-        $options['empty_name'] = 'new' . $relationMap->getName();
-      }
       $relatedClass = $relationMap->getRightTable()->getClassname();
       $formClass = $collectionForm->getFormClass();
       $emptyForm = new $formClass(new $relatedClass());
-      $relationValues = array();
+      if ($label = $options['empty_label']) {
+        $emptyForm->getWidgetSchema()->setLabel($label);
+      }
       foreach ($relationFields as $leftCol => $field)
       {
         unset($emptyForm[$field]);
         $emptyForm->setFixedValue($field, 
$this->getObject()->getByName($leftCol, BasePeer::TYPE_COLNAME));
       }
-      $collectionForm->embedForm($options['empty_name'], $emptyForm);
+      $emptyName = 'new' . $relationMap->getName();
+      $collectionForm->embedOptionalForm($emptyName, $emptyForm);
+      $this->optionalForms[$emptyName] = $emptyForm;
     }
     
     return $collectionForm;
@@ -435,4 +456,8 @@
     return $this->fixedValues;
   }
 
+  public function __clone()
+  {
+    $this->object = clone $this->object;
+  }
 }

Modified: 
plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php    
2010-05-13 20:01:46 UTC (rev 29448)
+++ plugins/sfPropel15Plugin/trunk/lib/form/sfFormPropelCollection.class.php    
2010-05-13 20:09:55 UTC (rev 29449)
@@ -76,4 +76,35 @@
     
     return $class;
   }
+
+  /**
+   * Embeds an optional sfForm into the current form.
+   *
+   * @param string $name       The field name
+   * @param sfForm $form       A sfForm instance
+   * @param string $decorator  A HTML decorator for the embedded form
+   */
+  public function embedOptionalForm($name, sfForm $form, $decorator = null)
+  {
+    $name = (string) $name;
+    if (true === $this->isBound() || true === $form->isBound())
+    {
+      throw new LogicException('A bound form cannot be embedded');
+    }
+
+    $form = clone $form;
+    unset($form[self::$CSRFFieldName]);
+
+    $this->setDefault($name, $form->getDefaults());
+
+    $widgetSchema = $form->getWidgetSchema();
+    
+    $decorator = null === $decorator ? 
$widgetSchema->getFormFormatter()->getDecoratorFormat() : $decorator;
+
+    $this->widgetSchema[$name] = new sfWidgetFormSchemaOptional($widgetSchema, 
$decorator);
+    
+    $this->validatorSchema[$name] = new sfValidatorPass();
+
+    $this->resetFormFields();
+  }
 }
\ No newline at end of file

Modified: plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormPlain.php
===================================================================
--- plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormPlain.php     
2010-05-13 20:01:46 UTC (rev 29448)
+++ plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormPlain.php     
2010-05-13 20:09:55 UTC (rev 29449)
@@ -9,7 +9,7 @@
  */
 
 /**
- * sfWidgetFormTextarea represents a textarea HTML tag.
+ * sfWidgetFormPlain represents a non editable text.
  *
  * @package    symfony
  * @subpackage widget

Added: 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaDecoratorEscaped.class.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaDecoratorEscaped.class.php
                              (rev 0)
+++ 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaDecoratorEscaped.class.php
      2010-05-13 20:09:55 UTC (rev 29449)
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the symfony package.
+ * (c) Fabien Potencier <[email protected]>
+ * 
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * sfWidgetFormSchemaDecoratorEscaped wraps an escaped form schema widget 
string
+ * inside a given HTML snippet.
+ *
+ * @package    symfony
+ * @subpackage widget
+ * @author     Francois Zaninotto
+ */
+class sfWidgetFormSchemaDecoratorEscaped extends sfWidgetFormSchemaDecorator
+{
+  
+  /**
+   * @param  string $name        The element name
+   * @param  string $value       The value displayed in this widget
+   * @param  array  $attributes  An array of HTML attributes to be merged with 
the default HTML attributes
+   * @param  array  $errors      An array of errors for the field
+   *
+   * @return string An HTML tag string
+   *
+   * @see sfWidgetForm
+   */
+  public function render($name, $value = null, $attributes = array(), $errors 
= array())
+  {
+    $widgetString = $this->widget->render($name, $value, $attributes, $errors);
+    $widgetString = $this->escape($widgetString);
+    return strtr($this->getDecorator($name), array('%content%' => 
$widgetString));
+  }
+  
+  /**
+   * Escape string for inclusion as a JavaScript string
+   * Code identical to EscapingHelper::esc_js_no_entities()
+   * @param String $string the string to escape
+   * @
+   */
+  protected function escape($string)
+  {
+    return str_replace(
+      array("\\"  , "\n"  , "\r" , "\""  , "'"  ),
+      array("\\\\", "\\n" , "\\r", "\\\"", "\\'"),
+      $string);
+  }
+  
+  protected function getDecorator($name)
+  {
+    return $this->decorator;
+  }
+}


Property changes on: 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaDecoratorEscaped.class.php
___________________________________________________________________
Added: svn:keywords
   + "Id Revision Author Date Rev"
Added: svn:eol-style
   + native

Added: 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaOptional.class.php
===================================================================
--- 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaOptional.class.php  
                            (rev 0)
+++ 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaOptional.class.php  
    2010-05-13 20:09:55 UTC (rev 29449)
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the symfony package.
+ * (c) Fabien Potencier <[email protected]>
+ * 
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+/**
+ * sfWidgetFormActivable represents link capable of adding a widget schema to 
a form
+ *
+ * @package    symfony
+ * @subpackage widget
+ * @author     Francois Zaninotto
+ */
+class sfWidgetFormSchemaOptional extends sfWidgetFormSchemaDecoratorEscaped
+{
+
+  /**
+   * Constructor.
+   *
+   * @param sfWidgetFormSchema $widget     A sfWidgetFormSchema instance
+   * @param string             $decorator  A decorator string
+   *
+   * @see sfWidgetFormSchema
+   */
+  public function __construct(sfWidgetFormSchema $widget, $decorator, $options 
= array())
+  {
+    parent::__construct($widget, $decorator);
+    $this->addOption('add_link', 'Add new');
+    $this->addOption('max_additions', 0);
+    $this->options = array_merge($this->options, $options);
+  }
+  
+  protected function getDecorator($name)
+  {
+    $strippedName = substr($name, strrpos($name, '[') + 1, strrpos($name, ']') 
- strrpos($name, '[') - 1);
+    $decorator = $this->escape($this->decorator);
+    $decorator = "
+<script type=\"text/javascript\">
+var added{$strippedName} = 0;
+function add{$strippedName}Widget()
+{
+  added{$strippedName} += 1;
+  var content = \"{$decorator}\";
+  var spanTag = document.createElement(\"span\");
+  spanTag.innerHTML = content.replace(/([_\[]){$strippedName}([_\]])/g, 
'\$1{$strippedName}' +  + added{$strippedName} + '\$2');
+  document.getElementById('add_{$strippedName}').appendChild(spanTag);
+  document.getElementById('add_{$strippedName}').style.display='block';";
+    if ($this->getOption('max_additions') > 0) {
+        $decorator .= "
+  if (added{$strippedName} == {$this->getOption('max_additions')})
+  {
+    document.getElementById('add_{$strippedName}_link').style.display='none';
+  }";
+    }
+  $decorator .= "
+}
+</script>
+<div id=\"add_{$strippedName}\" style=\"display:none\">
+</div>
+<a href=\"#\" id = \"add_{$strippedName}_link\" 
onclick=\"add{$strippedName}Widget();return false;\">
+  {$this->getOption('add_link')}
+</a>";
+      
+    return $decorator;
+  }
+}


Property changes on: 
plugins/sfPropel15Plugin/trunk/lib/widget/sfWidgetFormSchemaOptional.class.php
___________________________________________________________________
Added: svn:keywords
   + "Id Revision Author Date Rev"
Added: svn:eol-style
   + native

-- 
You received this message because you are subscribed to the Google Groups 
"symfony SVN" 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-svn?hl=en.

Reply via email to