Author: annis
Date: 2010-04-29 10:07:41 +0200 (Thu, 29 Apr 2010)
New Revision: 29311
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationField.php
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationsContainerForm.php
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/web/
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/web/js/
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/web/js/ahDoctrineEasyEmbeddedRelationsPlugin.jQuery.js
Modified:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
Log:
Merge branch 'master' into HEAD
Modified: plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README
===================================================================
--- plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README 2010-04-29
07:45:22 UTC (rev 29310)
+++ plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/README 2010-04-29
08:07:41 UTC (rev 29311)
@@ -34,13 +34,17 @@
}
}
- * Change the parent class in `lib/form/doctrine/BaseFormDoctrine.class.php`
to `ahBaseFormDoctrine `
+ * Change the parent class in `lib/form/doctrine/BaseFormDoctrine.class.php`
to `ahBaseFormDoctrine`
[php]
abstract class BaseFormDoctrine extends ahBaseFormDoctrine
{
...
}
+
+ * Publish the plugin assets
+
+ symfony plugin:publish-assets
* Clear your cache
@@ -84,6 +88,10 @@
'newFormAfterExistingRelations' => false,
'multipleNewForms' => true,
'newFormsInitialCount' => 2,
+ 'newFormsContainerForm' => null, // pass BaseForm object
here or we will create ahNewRelationsContainerForm
+ 'newRelationButtonLabel' => '+',
+ 'newRelationAddByCloning' => true,
+ 'newRelationUseJSFramework' => 'jQuery'
),
'...' => array(
...
@@ -184,8 +192,16 @@
* `multipleNewForms` (boolean, not required): set this option to true if you
want to have multiple new related object forms
- * `newFormsInitialCount`: (integer, not required, default: 1): number of new
object forms initially displayed (you may insert/delete those forms dynamically
using JavaScript, all submitted subforms will be processed and validated.)
+ * `newFormsInitialCount` (integer, not required, default: 1): number of new
object forms initially displayed (you may insert/delete those forms dynamically
using JavaScript, all submitted subforms will be processed and validated.)
+ * `newFormsContainerForm` (form object, not required): if not passed, plugin
will create custom ahNewRelationsContainerForm form with a single
`ahAddRelation` button below the new relation form(s)
+
+ * `newRelationButtonLabel` (string, not required, default: '+'): label for
the `ahAddRelation` new relation button; the setting is used only when the
`newFormsContainerForm` option is empty.
+
+ * `newRelationAddByCloning` (boolean, not required, default: true): Should
the plugin add new relation forms by cloning them client-side (with
JavaScript). If set to false, you should add the behaviour yourself to the
`ahAddRelation` form button. The setting is used only when the
`newFormsContainerForm` option is empty.
+
+ * `newRelationUseJSFramework` (string, not required, default: 'jQuery'): the
JavaScript framework that should handle the client-side logic of the
`ahAddRelation` new relation button to dynamically add new forms in the
browser. There is currently only a jQuery version available but a MooTools
version is on my TODO list. :)
+
## Questions, bugs, feature requests? ##
I can be reached via e-mail: [email protected]
Modified:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
2010-04-29 07:45:22 UTC (rev 29310)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/config/ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php
2010-04-29 08:07:41 UTC (rev 29311)
@@ -6,7 +6,7 @@
* @package ahDoctrineEasyEmbeddedRelationsPlugin
* @subpackage config
* @author Daniel Lohse, Steve Guhr <[email protected]>
- * @version SVN: $Id: PluginConfiguration.class.php 12675 2008-11-06
08:07:42Z Kris.Wallsmith $
+ * @version SVN: $Id:
ahDoctrineEasyEmbeddedRelationsPluginConfiguration.class.php 136 2010-04-26
21:16:52Z koto $
*/
class ahDoctrineEasyEmbeddedRelationsPluginConfiguration extends
sfPluginConfiguration
{
Modified:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
2010-04-29 07:45:22 UTC (rev 29310)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahBaseFormDoctrine.class.php
2010-04-29 08:07:41 UTC (rev 29311)
@@ -5,14 +5,38 @@
*
* @package ahDoctrineEasyEmbeddedRelationsPlugin
* @subpackage form
- * @author Daniel Lohse, Steve Guhr <[email protected]>, Krzysztof
Kotowicz <kkotowicz at gmail dot com>
+ * @author Daniel Lohse <[email protected]>
+ * @author Steve Guhr <[email protected]>
+ * @author Krzysztof Kotowicz <kkotowicz at gmail dot com>
*/
abstract class ahBaseFormDoctrine extends sfFormDoctrine
{
protected
$scheduledForDeletion = array(), // related objects scheduled for deletion
- $embedRelations = array(); // so we can check which relations are
embedded in this form
+ $embedRelations = array(), // so we can check which relations are
embedded in this form
+ $defaultRelationSettings = array(
+ 'considerNewFormEmptyFields' => array(),
+ 'noNewForm' => false,
+ 'newFormLabel' => null,
+ 'newFormClass' => null,
+ 'newFormClassArgs' => array(),
+ 'formClass' => null,
+ 'formClassArgs' => array(),
+ 'displayEmptyRelations' => false,
+ 'newFormAfterExistingRelations' => false,
+ 'multipleNewForms' => false,
+ 'newFormsInitialCount' => 1,
+ 'newFormsContainerForm' => null, // pass BaseForm object here or we
will create ahNewRelationsContainerForm
+ 'newRelationButtonLabel' => '+',
+ 'newRelationAddByCloning' => true,
+ 'newRelationUseJSFramework' => 'jQuery'
+ );
+ protected function addDefaultRelationSettings(array $settings)
+ {
+ return array_merge($this->defaultRelationSettings, $settings);
+ }
+
public function embedRelations(array $relations)
{
$this->embedRelations = $relations;
@@ -21,38 +45,46 @@
foreach ($relations as $relationName => $relationSettings)
{
+ $relationSettings = $this->addDefaultRelationSettings($relationSettings);
+
$relation = $this->getObject()->getTable()->getRelation($relationName);
- if (!isset($relationSettings['noNewForm']) ||
!$relationSettings['noNewForm'])
+ if (!$relationSettings['noNewForm'])
{
+ $containerName = 'new_'.$relationName;
if (($relation->isOneToOne() &&
!$this->getObject()->relatedExists($relationName)) || !$relation->isOneToOne())
{
- $formLabel = isset($relationSettings['newFormLabel']) ?
$relationSettings['newFormLabel'] : null;
- if (!empty($relationSettings['multipleNewForms'])) // allow multiple
new forms for this relation
+ $formLabel = $relationSettings['newFormLabel'];
+ if ($relationSettings['multipleNewForms']) // allow multiple new
forms for this relation
{
-
- $newFormsCount = !empty($relationSettings['newFormsInitialCount'])
? $relationSettings['newFormsInitialCount'] : 1;
-
- $subForm = new sfForm();
- unset($subForm[sfForm::$CSRFFieldName]);
+ $newFormsCount = $relationSettings['newFormsInitialCount'];
+
+ $subForm = $this->newFormsContainerFormFactory($relationSettings,
$containerName);
for ($i = 0; $i < $newFormsCount; $i++)
{
- // we need to create new forms with cloned object inside
(otherwise only the last new values would be saved)
+ /*
+ * we need to create new forms with cloned object inside
+ * (otherwise only the last new values would be saved)
+ */
$newForm = $this->embeddedFormFactory($relationName,
$relationSettings, $relation, $i + 1);
$subForm->embedForm($i, $newForm);
}
$subForm->getWidgetSchema()->setLabel($formLabel);
- $this->embedForm('new_'.$relationName, $subForm);
+ $this->embedForm($containerName, $subForm);
}
else // just a single new form for this relation
{
$newForm = $this->embeddedFormFactory($relationName,
$relationSettings, $relation, $formLabel);
- $this->embedForm('new_'.$relationName, $newForm);
+ $this->embedForm($containerName, $newForm);
}
}
}
-
- $formClass = !isset($relationSettings['formClass']) ? null :
$relationSettings['formClass'];
- $formArgs = array_merge((!isset($relationSettings['formClassArgs']) ?
array() : $relationSettings['formClassArgs']),
array(array('ah_add_delete_checkbox' => true)));
+
+ $formClass = $relationSettings['formClass'];
+ $formArgs = array_merge(
+ $relationSettings['formClassArgs'],
+ array(array('ah_add_delete_checkbox' => true))
+ );
+
$this->embedRelation($relationName, $formClass, $formArgs);
/*
@@ -67,14 +99,14 @@
((!$relation->isOneToOne()) &&
(count($this->getEmbeddedForm($relationName)->getEmbeddedForms()) === 0)) ||
($relation->isOneToOne() &&
$this->getEmbeddedForm($relationName)->isNew())
) &&
- (!isset($relationSettings['displayEmptyRelations']) ||
!$relationSettings['displayEmptyRelations'])
+ (!$relationSettings['displayEmptyRelations'])
)
{
unset($this[$relationName]);
}
if (
- isset($relationSettings['newFormAfterExistingRelations']) &&
$relationSettings['newFormAfterExistingRelations'] &&
+ $relationSettings['newFormAfterExistingRelations'] &&
isset($this[$relationName]) && isset($this['new_'.$relationName])
)
{
@@ -101,8 +133,10 @@
}
/**
- * Here we just drop the embedded creation forms if no value has been
provided for them (this simulates a non-required embedded form),
- * please provide the fields for the related embedded form in the call to
$this->embedRelations() so we don't throw validation errors
+ * Here we just drop the embedded creation forms if no value has been
+ * provided for them (this simulates a non-required embedded form),
+ * please provide the fields for the related embedded form in the call
+ * to $this->embedRelations() so we don't throw validation errors
* if the user did not want to add a new related object
*
* @see sfForm::doBind()
@@ -111,11 +145,13 @@
{
foreach ($this->embedRelations as $relationName => $keys)
{
- if (!isset($keys['noNewForm']) || !$keys['noNewForm'])
+ $keys = $this->addDefaultRelationSettings($keys);
+
+ if (!$keys['noNewForm'])
{
$containerName = 'new_'.$relationName;
- if (!empty($keys['multipleNewForms'])) // just a single new form for
this relation
+ if ($keys['multipleNewForms']) // just a single new form for this
relation
{
if (array_key_exists($containerName, $values))
{
@@ -295,7 +331,7 @@
*/
protected function isNewFormEmpty(array $values, array $keys)
{
- if (!isset($keys['considerNewFormEmptyFields']) ||
count($keys['considerNewFormEmptyFields']) == 0 || !isset($values)) return
false;
+ if (count($keys['considerNewFormEmptyFields']) == 0 || !isset($values))
return false;
$emptyFields = 0;
foreach ($keys['considerNewFormEmptyFields'] as $key)
@@ -314,7 +350,7 @@
{
return true;
}
-
+
return false;
}
@@ -330,8 +366,8 @@
private function embeddedFormFactory($relationName, array $relationSettings,
Doctrine_Relation $relation, $formLabel = null)
{
$newFormObject = $this->embeddedFormObjectFactory($relationName,
$relation);
- $formClass = !isset($relationSettings['newFormClass']) ?
$relation->getClass().'Form' : $relationSettings['newFormClass'];
- $formArgs = !isset($relationSettings['newFormClassArgs']) ? array() :
$relationSettings['newFormClassArgs'];
+ $formClass = empty($relationSettings['newFormClass']) ?
$relation->getClass().'Form' : $relationSettings['newFormClass'];
+ $formArgs = empty($relationSettings['newFormClassArgs']) ? array() :
$relationSettings['newFormClassArgs'];
$r = new ReflectionClass($formClass);
$newForm = $r->newInstanceArgs(array_merge(array($newFormObject),
array($formArgs)));
@@ -352,7 +388,7 @@
{
$newForm->getWidgetSchema()->setLabel($formLabel);
}
-
+
return $newForm;
}
@@ -373,7 +409,34 @@
{
$newFormObject = $this->getObject()->$relationName;
}
-
+
return $newFormObject;
}
+
+ /**
+ * Create and initialize form that will embed 'newly created relation'
subforms
+ * If no object is given in 'newFormsContainerForm' parameter, it will
+ * initialize custom form bundled with this plugin
+ * @param array $relationSettings
+ * @return sfForm (ahNewRelationsContainerForm by default)
+ */
+ private function newFormsContainerFormFactory(array $relationSettings,
$containerName)
+ {
+ $subForm = $relationSettings['newFormsContainerForm'];
+
+ if (!$subForm)
+ {
+ $subForm = new ahNewRelationsContainerForm(
+ array('new_relation' => $relationSettings['newRelationButtonLabel']),
+ array(
+ 'containerName' => $containerName,
+ 'addByCloning' => $relationSettings['newRelationAddByCloning'],
+ 'useJSFramework' => $relationSettings['newRelationUseJSFramework']
+ )
+ );
+ }
+
+ unset($subForm[$subForm->getCSRFFieldName()]);
+ return $subForm;
+ }
}
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationField.php
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationField.php
(rev 0)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationField.php
2010-04-29 08:07:41 UTC (rev 29311)
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * This class displays the button to add new embedded relation forms; it
relies on client-side JavaScript to work.
+ * @author Krzysztof Kotowicz <kkotowicz at gmail dot com>
+ */
+class ahNewRelationField extends sfWidgetForm
+{
+
+ protected function configure($options = array(), $attributes = array())
+ {
+ $this->addRequiredOption('containerName');
+ $this->addOption('addJavascript', false);
+ $this->addOption('useJSFramework', 'jQuery');
+ }
+
+ public function render($name, $value = null, $attributes = array(), $errors
= array())
+ {
+ return $this->renderContentTag('button', $value !== null ? $value : '+',
array('type' => 'button', 'class' => 'ahAddRelation', 'rel' =>
$this->getOption('containerName')));
+ }
+
+ public function getJavaScripts()
+ {
+ if (false === $this->getOption('addJavascript')) return array();
+
+ return
array(sprintf('/ahDoctrineEasyEmbeddedRelationsPlugin/js/ahDoctrineEasyEmbeddedRelationsPlugin.%s.js',
$this->getOption('addJavascript')));
+ }
+}
\ No newline at end of file
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationsContainerForm.php
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationsContainerForm.php
(rev 0)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/lib/form/ahNewRelationsContainerForm.php
2010-04-29 08:07:41 UTC (rev 29311)
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * Class used to embed new object forms in parent form
+ *
+ * @package ahDoctrineEasyEmbeddedRelationsPlugin
+ * @subpackage form
+ * @author Krzysztof Kotowicz <kkotowicz at gmail dot com>
+ */
+class ahNewRelationsContainerForm extends BaseForm
+{
+ public function configure()
+ {
+ $button = new ahNewRelationField(array(
+ 'containerName' => $this->getOption('containerName'),
+ 'addJavascript' => $this->getOption('addByCloning'),
+ 'useJSFramework' => $this->getOption('useJSFramework')
+ ));
+
+ $this->setWidget('_', $button);
+ }
+
+ /**
+ * Moves button below embedded forms
+ * @inheritdoc
+ * @param string $name
+ * @param sfForm $form
+ * @param string $decorator
+ */
+ public function embedForm($name, sfForm $form, $decorator = null)
+ {
+ parent::embedForm($name, $form, $decorator);
+ $this->widgetSchema->moveField('_', sfWidgetFormSchema::LAST);
+ }
+}
\ No newline at end of file
Added:
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/web/js/ahDoctrineEasyEmbeddedRelationsPlugin.jQuery.js
===================================================================
---
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/web/js/ahDoctrineEasyEmbeddedRelationsPlugin.jQuery.js
(rev 0)
+++
plugins/ahDoctrineEasyEmbeddedRelationsPlugin/trunk/web/js/ahDoctrineEasyEmbeddedRelationsPlugin.jQuery.js
2010-04-29 08:07:41 UTC (rev 29311)
@@ -0,0 +1,66 @@
+/**
+ * Code needed to clone nested relations forms
+ * @plugin ahDoctrineEasyEmbeddedRelationsPlugin
+ * @author Krzysztof Kotowicz <kkotowicz at gmail dot com>
+ */
+(function($) {
+
+ /**
+ * Increments field IDs and names by one
+ */
+ $.fn.incrementFields = function(container) {
+ return this.each(function() {
+ var nameRe = new RegExp('\\[' + container +
'\\]\\[(\\d+)\\]');
+ var idRe = new RegExp('_' + container + '_(\\d+)_');
+
+ $(this).find(':input').each(function() { // find each
input
+ var matches;
+ if (matches = nameRe.exec(this.name)) { //
check if its name contains [container][number]
+ // if so, increase the number in field
name
+ this.name =
this.name.replace(nameRe,'[' + container + '][' + (parseInt(matches[1],10)+1) +
']');
+ if (this.id) { // and id
+ this.id =
this.id.replace('_'+container+'_'+matches[1]+'_',
+
'_'+container+'_'+(parseInt(matches[1],10)+1)+'_');
+ }
+ }
+ $(this).trigger('change.ah'); // trigger
onchange event just for a case
+ }).end();
+
+ // fix labels
+ $(this).find('label:for').each(function() {
+ var matches;
+ if (matches = idRe.exec($(this).attr('for'))) {
// check if its name contains _container_number_
+ // if so, increase the number in label
for attribute
+ $(this).attr('for',
$(this).attr('for').replace(idRe,'_' + container + '_' +
(parseInt(matches[1],10)+1) + '_'));
+ }
+ });
+
+ // increase the number in first <th>
+ $header = $(this).find('th').eq(0);
+ if ($header.text().match(/^\d+$/)) {
+ $header.text(parseInt($header.text(),10) + 1);
+ }
+ $(this).end();
+ });
+ }
+
+})(jQuery);
+
+jQuery(function($) {
+
+ // when clicking the 'add relation' button
+ $('.ahAddRelation').click(function() {
+
+ // find last row of my siblings (each row represents a subform)
+ $row = $(this).parents('tr').siblings(':last');
+
+ // clone it, increment the fields and insert it below,
additionally triggering events
+ $row.clone()
+ .incrementFields($(this).attr('rel'))
+
.trigger('beforeadd.ah').insertAfter($row).trigger('afteradd.ah');
+
+ //use events to further modify the cloned row like this
+ // $(document).bind('beforeadd.ah', function(event) {
$(event.target).hide() /* event.target is cloned row */ });
+ // $(document).bind('afteradd.ah', function(event) { });
+ })
+});
\ No newline at end of file
--
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.