Skip to content

[WIP][Form] Implement field order #6111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion src/Symfony/Component/Form/ButtonBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Exception\FormException;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\InvalidConfigurationException;

/**
* A builder for {@link Button} instances.
Expand Down Expand Up @@ -52,6 +53,11 @@ class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
*/
private $options;

/**
* @var null|string|array
*/
private $position;

/**
* Creates a new button builder.
*
Expand Down Expand Up @@ -446,7 +452,7 @@ public function setDataLocked($locked)
* This method should not be invoked.
*
* @param FormFactoryInterface $formFactory
*
*
* @return void
*
* @throws \BadMethodCallException
Expand All @@ -456,6 +462,20 @@ public function setFormFactory(FormFactoryInterface $formFactory)
throw new \BadMethodCallException('Buttons do not support form factories.');
}

/**
* {@inheritdoc}
*/
public function setPosition($position)
{
if (is_string($position) && ($position !== 'first') && ($position !== 'last')) {
throw new InvalidConfigurationException('If you use position as string, you can only use "first" & "last".');
} elseif (is_array($position) && !isset($position['before']) && !isset($position['after'])) {
throw new InvalidConfigurationException('If you use position as array, you must at least define the "before" or "after" option.');
}

$this->position = $position;
}

/**
* Builds and returns the button configuration.
*
Expand Down Expand Up @@ -728,6 +748,14 @@ public function getOption($name, $default = null)
return array_key_exists($name, $this->options) ? $this->options[$name] : $default;
}

/**
* {@inheritdoc}
*/
public function getPosition()
{
return $this->position;
}

/**
* Unsupported method.
*
Expand Down
3 changes: 3 additions & 0 deletions src/Symfony/Component/Form/Extension/Core/Type/FormType.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
->setData(isset($options['data']) ? $options['data'] : null)
->setDataLocked(isset($options['data']))
->setDataMapper($options['compound'] ? new PropertyPathMapper($this->propertyAccessor) : null)
->setPosition($options['position'])
;

if ($options['trim']) {
Expand Down Expand Up @@ -167,10 +168,12 @@ public function setDefaultOptions(OptionsResolverInterface $resolver)
'label_attr' => array(),
'virtual' => false,
'compound' => true,
'position' => null,
));

$resolver->setAllowedTypes(array(
'label_attr' => 'array',
'position' => array('null', 'string', 'array'),
));
}

Expand Down
35 changes: 34 additions & 1 deletion src/Symfony/Component/Form/FormConfigBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace Symfony\Component\Form;

use Symfony\Component\Form\Exception\BadMethodCallException;
use Symfony\Component\Form\Exception\Exception;
use Symfony\Component\Form\Exception\InvalidConfigurationException;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\PropertyAccess\PropertyPath;
use Symfony\Component\PropertyAccess\PropertyPathInterface;
Expand Down Expand Up @@ -132,6 +132,11 @@ class FormConfigBuilder implements FormConfigBuilderInterface
*/
private $dataLocked;

/**
* @var null|string|array
*/
private $position;

/**
* @var FormFactoryInterface
*/
Expand Down Expand Up @@ -427,6 +432,14 @@ public function getDataLocked()
return $this->dataLocked;
}

/**
* {@inheritdoc}
*/
public function getPosition()
{
return $this->position;
}

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -687,6 +700,26 @@ public function setFormFactory(FormFactoryInterface $formFactory)
return $this;
}

/**
* {@inheritdoc}
*/
public function setPosition($position)
{
if ($this->locked) {
throw new FormException('The config builder cannot be modified anymore.');
}

if (is_string($position) && ($position !== 'first') && ($position !== 'last')) {
throw new InvalidConfigurationException('If you use position as string, you can only use "first" & "last".');
} elseif (is_array($position) && !isset($position['before']) && !isset($position['after'])) {
throw new InvalidConfigurationException('If you use position as array, you must at least define the "before" or "after" option.');
}

$this->position = $position;

return $this;
}

/**
* {@inheritdoc}
*/
Expand Down
34 changes: 34 additions & 0 deletions src/Symfony/Component/Form/FormConfigBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,40 @@ public function setDataLocked($locked);
*/
public function setFormFactory(FormFactoryInterface $formFactory);

/**
* Sets the form position.
*
* * The position can be `null` to reflect the original forms order.
*
* * The position can be `first` to place this form at the first position.
* If many forms are defined as `first`, the original order between these forms is maintained.
* Warning, `first` does not mean "very first" if there are many forms which are defined as `first`
* or if you set up an other form `before` this form.
*
* * The position can be `last` to place this form at the last position.
* If many forms are defined as `last`, the original order between these forms is maintained.
* Warning, `last` does not mean "very last" if there are many forms which are defined as `last`
* or if you set up an other form `after` this form.
*
* * The position can be `array('before' => 'form_name')` to place this form before the `form_name` form.
* If many forms defines the same `before` form, the original order between these forms is maintained.
* Warning, `before` does not mean "just before" if there are many forms which defined the same `before` form.
*
* * The position can be `array('after' => 'form_name')` to place this form after the `form_name` form.
* If many forms defines the same after form, the original order between these forms is maintained.
* Warning, `after` does not mean "just after" if there are many forms which defined the same `after` form.
*
* You can combine the `after` & `before` options together or with `first` and/or `last` to achieve
* more complex use cases.
*
* @param null|string|array $position The form position.
*
* @throws InvalidConfigurationException If the position is not valid.
*
* @return self The configuration object.
*/
public function setPosition($position);

/**
* Builds and returns the form configuration.
*
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Component/Form/FormConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,13 @@ public function hasOption($name);
* @return mixed The option value.
*/
public function getOption($name, $default = null);

/**
* Gets the form position.
*
* @see FormConfigBuilderInterface::setPosition
*
* @return null|string|array The before form name.
*/
public function getPosition();
}
Loading