Gibt es eine einfache Möglichkeit, einen Standardwert für das Textformularfeld festzulegen?
Gibt es eine einfache Möglichkeit, einen Standardwert für das Textformularfeld festzulegen?
Antworten:
Kann während der Erstellung einfach verwendet werden mit:
->add('myfield', 'text', array(
'label' => 'Field',
'empty_data' => 'Default value'
))
'data'
Schlüssel auf'value'
empty_data
data
ist nutzlos - es überschreibt den gespeicherten Wert. empty_data
Zeigt den Wert nicht an, verwendet ihn bei der Übermittlung leerer Werte und macht es unmöglich, ungeprüfte Auswahlmöglichkeiten zu speichern.
Sie können den Standardwert mit festlegen empty_data
$builder->add('myField', 'number', ['empty_data' => 'Default value'])
Ich habe in der Vergangenheit ein paar Mal darüber nachgedacht und dachte, ich würde die verschiedenen Ideen aufschreiben, die ich hatte / verwendet habe. Etwas könnte von Nutzen sein, aber keines ist eine "perfekte" Symfony2-Lösung.
Konstruktor In der Entität können Sie $ this-> setBar ('Standardwert') ausführen. Dies wird jedoch jedes Mal aufgerufen, wenn Sie die Entität laden (db oder nicht) und ist etwas chaotisch. Es funktioniert jedoch für jeden Feldtyp, da Sie Datumsangaben erstellen können oder was auch immer Sie sonst noch benötigen.
Wenn Aussagen innerhalb von get's würde ich nicht, aber du könntest.
return ( ! $this->hasFoo() ) ? 'default' : $this->foo;
Fabrik / Instanz . Rufen Sie eine statische Funktion / sekundäre Klasse auf, die Ihnen eine Standardentität bereitstellt, die mit Daten gefüllt ist. Z.B
function getFactory() {
$obj = new static();
$obj->setBar('foo');
$obj->setFoo('bar');
return $obj;
}
Nicht wirklich ideal, da Sie diese Funktion beibehalten müssen, wenn Sie zusätzliche Felder hinzufügen. Dies bedeutet jedoch, dass Sie die Datensetzer / Standardwerte und die aus der Datenbank generierten trennen. Ebenso können Sie mehrere getFactories haben, wenn Sie unterschiedliche Standarddaten wünschen.
Erweiterte / reflektierende Entitäten Erstellen Sie eine erweiterte Entität (z. B. FooCreate erweitert Foo), die Ihnen die Standarddaten zum Zeitpunkt der Erstellung (über den Konstruktor) liefert. Ähnlich wie bei der Factory / Instance-Idee nur ein anderer Ansatz - ich persönlich bevorzuge statische Methoden.
Festlegen von Daten vor dem Erstellen des Formulars In den Konstruktoren / Diensten wissen Sie, ob Sie eine neue Entität haben oder ob sie aus der Datenbank ausgefüllt wurde. Es ist daher plausibel, Set-Daten für die verschiedenen Felder aufzurufen, wenn Sie eine neue Entität greifen. Z.B
if( ! $entity->isFromDB() ) {
$entity->setBar('default');
$entity->setDate( date('Y-m-d');
...
}
$form = $this->createForm(...)
Formularereignisse Wenn Sie das Formular erstellen, legen Sie beim Erstellen der Felder Standarddaten fest. Sie überschreiben diese Verwendung des PreSetData-Ereignis-Listeners. Das Problem dabei ist, dass Sie die Formularauslastung / den Duplizierungscode duplizieren und das Verwalten / Verstehen erschweren.
Erweiterte Formulare Ähnlich wie Formularereignisse, aber Sie rufen den unterschiedlichen Typ auf, je nachdem, ob es sich um eine Datenbank / eine neue Entität handelt. Damit meine ich, dass Sie FooType haben, das Ihr Bearbeitungsformular definiert. BarType erweitert FooType und setzt alle Daten auf die Felder. In Ihrem Controller wählen Sie dann einfach den zu initiierenden Formulartyp aus. Dies ist zum Kotzen, wenn Sie ein benutzerdefiniertes Thema haben und Ereignisse mögen, was zu viel Wartung für meinen Geschmack schafft.
Zweig Sie können Ihr eigenes Thema erstellen und die Daten standardmäßig mit der Wertoption festlegen, wenn Sie dies auf Feldbasis tun. Nichts hindert Sie daran, dies in ein Formularthema zu verpacken, wenn Sie Ihre Vorlagen sauber halten und das Formular wiederverwendbar machen möchten. z.B
form_widget(form.foo, {attr: { value : default } });
JS Es wäre trivial, das Formular mit einer JS-Funktion zu füllen, wenn die Felder leer sind. Sie könnten zum Beispiel etwas mit Platzhaltern machen. Dies ist jedoch eine schlechte, schlechte Idee.
Formulare als Service Für eines der großen formularbasierten Projekte, die ich durchgeführt habe, habe ich einen Service erstellt, der alle Formulare generiert, die gesamte Verarbeitung durchgeführt usw. Dies lag daran, dass die Formulare auf mehreren Controllern in mehreren Umgebungen und während der Formulare verwendet werden sollten wurden auf die gleiche Weise generiert / behandelt, sie wurden unterschiedlich angezeigt / interagiert (z. B. Fehlerbehandlung, Umleitungen usw.). Das Schöne an diesem Ansatz war, dass Sie Standarddaten erstellen, alles tun können, Fehler generisch behandeln usw. und alles an einem Ort zusammengefasst ist.
Fazit Aus meiner Sicht werden Sie immer wieder auf dasselbe Problem stoßen - wo leben die Standarddaten?
Zu diesem Zweck habe ich das Problem jedes Mal anders angegangen. Beispielsweise kann eine Option "Newsletter" für Anmeldeformulare einfach (und logisch) im Konstruktor unmittelbar vor dem Erstellen des Formulars festgelegt werden. Als ich Formularsammlungen erstellt habe, die miteinander verknüpft waren (z. B. welche Optionsfelder in verschiedenen Formulartypen miteinander verknüpft waren), habe ich Ereignis-Listener verwendet. Wenn ich eine kompliziertere Entität erstellt habe (z. B. eine, für die untergeordnete Elemente oder viele Standarddaten erforderlich sind), habe ich eine Funktion (z. B. 'getFactory') verwendet, um das Element nach Bedarf zu erstellen.
Ich glaube nicht, dass es einen "richtigen" Ansatz gibt, da er jedes Mal, wenn ich diese Anforderung hatte, etwas anders war.
Viel Glück! Ich hoffe, ich habe dir jedenfalls einige Denkanstöße gegeben und bin nicht zu viel gewandert;)
Wenn Sie einen Standardwert festlegen müssen und Ihr Formular sich auf die Entität bezieht, sollten Sie den folgenden Ansatz verwenden:
// buildForm() method
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
...
->add(
'myField',
'text',
array(
'data' => isset($options['data']) ? $options['data']->getMyField() : 'my default value'
)
);
}
Andernfalls wird myField
immer der Standardwert festgelegt, anstatt den Wert von der Entität abzurufen.
$options['data']->getMyField()
mit$option['data']['myField']
empty_data
: Diese Option bestimmt, welchen Wert das Feld zurückgibt, wenn der übermittelte Wert leer ist. Es wird kein Anfangswert festgelegt
Sie können den Standard für das zugehörige Feld in Ihrer Modellklasse festlegen (in der Zuordnungsdefinition oder den Wert selbst festlegen).
Darüber hinaus bietet FormBuilder die Möglichkeit, Anfangswerte mit der Methode setData () festzulegen . Der Formularersteller wird an die Methode createForm () Ihrer Formularklasse übergeben.
Überprüfen Sie auch diesen Link: http://symfony.com/doc/current/book/forms.html#using-a-form-without-a-class
Wenn Ihr Formular an eine Entität gebunden ist, legen Sie einfach den Standardwert für die Entität selbst mithilfe der Konstruktmethode fest:
public function __construct()
{
$this->field = 'default value';
}
'mapped' => false
). Verwenden Sie setData(...)
für diese.
Ansatz 1 (von http://www.cranespud.com/blog/dead-simple-default-values-on-symfony2-forms/ )
Legen Sie einfach den Standardwert in Ihrer Entität fest, entweder in der Variablendeklaration oder im Konstruktor:
class Entity {
private $color = '#0000FF';
...
}
oder
class Entity {
private $color;
public function __construct(){
$this->color = '#0000FF';
...
}
...
}
Ansatz 2 aus einem Kommentar im obigen Link und auch Dmitriys Antwort (nicht die akzeptierte) aus Wie wird der Standardwert für das Formularfeld in Symfony2 festgelegt?
Fügen Sie dem Datenattribut den Standardwert hinzu, wenn Sie das Feld mit dem FormBuilder hinzufügen, angepasst an die Antwort von Dmitriy.
Beachten Sie, dass dies davon ausgeht, dass die Eigenschaft nur dann den Wert null hat, wenn es sich um eine neue und keine vorhandene Entität handelt.
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('color', 'text', array(
'label' => 'Color:',
'data' => (isset($options['data']) && $options['data']->getColor() !== null) ? $options['data']->getColor() : '#0000FF'
)
);
}
Sie können einen Standardwert festlegen, z. B. für das Formular message
:
$defaultData = array('message' => 'Type your message here');
$form = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'email')
->add('message', 'textarea')
->add('send', 'submit')
->getForm();
Wenn Ihr Formular einer Entität zugeordnet ist, können Sie folgendermaßen vorgehen (z. B. Standardbenutzername):
$user = new User();
$user->setUsername('John Doe');
$form = $this->createFormBuilder($user)
->add('username')
->getForm();
Eine allgemeine Lösung für jeden Fall / Ansatz, hauptsächlich durch Verwendung eines Formulars ohne Klasse oder wenn wir Zugriff auf Dienste benötigen, um den Standardwert festzulegen:
// src/Form/Extension/DefaultFormTypeExtension.php
class DefaultFormTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if (null !== $options['default']) {
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($options) {
if (null === $event->getData()) {
$event->setData($options['default']);
}
}
);
}
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('default', null);
}
public function getExtendedType()
{
return FormType::class;
}
}
und registrieren Sie die Formularerweiterung:
app.form_type_extension:
class: App\Form\Extension\DefaultFormTypeExtension
tags:
- { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
Danach können wir verwenden default
Option in jedem Formularfeld verwenden:
$formBuilder->add('user', null, array('default' => $this->getUser()));
$formBuilder->add('foo', null, array('default' => 'bar'));
Verwenden Sie nicht:
'data' => 'Default value'
Lesen Sie hier: https://symfony.com/doc/current/reference/forms/types/form.html#data
"Die Datenoption überschreibt beim Rendern immer den Wert, der den Domänendaten (Objekt) entnommen wurde. Dies bedeutet, dass der Objektwert auch überschrieben wird, wenn das Formular ein bereits beibehaltenes Objekt bearbeitet, wodurch es beim Senden des Formulars seinen dauerhaften Wert verliert."
Verwenden Sie Folgendes:
Nehmen wir an, Sie haben für dieses Beispiel ein Entity Foo und es gibt ein Feld "aktiv" (in diesem Beispiel ist CheckBoxType, aber der Prozess ist für alle anderen Typen gleich), das Sie standardmäßig überprüfen möchten
Fügen Sie in Ihrer FooFormType-Klasse Folgendes hinzu:
...
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
...
public function buildForm( FormBuilderInterface $builder, array $options )
{
...
$builder->add('active', CheckboxType::class, array(
'label' => 'Active',
));
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function(FormEvent $event){
$foo = $event->getData();
// Set Active to true (checked) if form is "create new" ($foo->active = null)
if(is_null($foo->getActive())) $foo->setActive(true);
}
);
}
public function configureOptions( OptionsResolver $resolver )
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle:Foo',
));
}
'data' => $data['myfield'] ?? 'Default value'
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
$data = $event->getData();
if ($data == null) {
$form->add('position', IntegerType::class, array('data' => 0));
}
});
$event->setData()
Wenn Sie anrufen, anstatt das Feld zu lesen, wird es möglicherweise noch besser.
Nur damit ich das Problem verstehe.
Sie möchten die Art und Weise anpassen, in der das Formular basierend auf Daten in Ihrer Entität erstellt wird. Wenn die Entität erstellt wird, verwenden Sie einen Standardwert. Wenn die Entität vorhanden ist, verwenden Sie den Datenbankwert.
Persönlich denke ich, dass die Lösung von @ MolecularMans der richtige Weg ist. Ich würde tatsächlich die Standardwerte im Konstruktor oder in der Eigenschaftsanweisung festlegen. Aber Sie scheinen diesen Ansatz nicht zu mögen.
Stattdessen können Sie Folgendes befolgen: vorgehen http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html
Sie hängen einen Listener an Ihren Formulartyp und können dann Ihre Entität untersuchen und den Builder-> Add-Anweisungen entsprechend anpassen, basierend auf einer neuen oder vorhandenen Entität. Sie müssen Ihre Standardwerte noch irgendwo angeben, obwohl Sie sie einfach in Ihrem Listener codieren können. Oder übergeben Sie sie an den Formulartyp.
Scheint aber viel Arbeit zu sein. Es ist besser, die Entität einfach an das Formular zu übergeben, wobei die Standardwerte bereits festgelegt sind.
Wenn Sie FormBuilder
zum Generieren des Formulars eine in symfony 2.7 verwenden, können Sie die Anfangsdaten auch an die createFormBuilder
Methode des Controler übergeben
$values = array(
'name' => "Bob"
);
$formBuilder = $this->createFormBuilder($values);
$formBuilder->add('name', 'text');
Oft verwende ich für Init-Standardwerte der Form Fixtures. Natürlich ist dieser Weg nicht einfach, aber sehr bequem.
Beispiel:
class LoadSurgeonPlanData implements FixtureInterface
{
public function load(ObjectManager $manager)
{
$surgeonPlan = new SurgeonPlan();
$surgeonPlan->setName('Free trial');
$surgeonPlan->setPrice(0);
$surgeonPlan->setDelayWorkHours(0);
$surgeonPlan->setSlug('free');
$manager->persist($surgeonPlan);
$manager->flush();
}
}
Dennoch hat symfony Typ - Feld die Option Daten .
Beispiel
$builder->add('token', 'hidden', array(
'data' => 'abcdef',
));
Es gibt eine sehr einfache Möglichkeit, die Standardeinstellungen wie folgt festzulegen:
$defaults = array('sortby' => $sortby,'category' => $category,'page' => 1);
$form = $this->formfactory->createBuilder('form', $defaults)
->add('sortby','choice')
->add('category','choice')
->add('page','hidden')
->getForm();
Wenn Sie in Ihrem Erstellungsformular "Daten" festlegen, wird dieser Wert beim Bearbeiten Ihrer Entität nicht geändert.
Meine Lösung ist:
public function buildForm(FormBuilderInterface $builder, array $options) {
// In my example, data is an associated array
$data = $builder->getData();
$builder->add('myfield', 'text', array(
'label' => 'Field',
'data' => array_key_exits('myfield', $data) ? $data['myfield'] : 'Default value',
));
}
Tschüss.
'data' => $data['myfield'] ?? 'Default value',
Standardwerte werden durch Konfigurieren der entsprechenden Entität festgelegt. Bevor Sie die Entität an das Formular binden, setzen Sie ihr Farbfeld auf "# 0000FF":
// controller action
$project = new Project();
$project->setColor('#0000FF');
$form = $this->createForm(new ProjectType(), $project);
Wenn dieses Feld an eine Entität gebunden ist (eine Eigenschaft dieser Entität ist), können Sie einfach einen Standardwert dafür festlegen.
Ein Beispiel:
public function getMyField() {
if (is_null($this->MyField)) {
$this->setMyField('my default value');
}
return $this->MyField;
}
Normalerweise lege ich nur den Standardwert für ein bestimmtes Feld in meiner Entität fest:
/**
* @var int
* @ORM\Column(type="integer", nullable=true)
*/
protected $development_time = 0;
Dies funktioniert für neue Datensätze oder wenn nur vorhandene aktualisiert werden.
'empty_data'
ein Rückruf verwendet wird, um Konstruktorparameter für die Entität zuzulassen.
Als Brian fragte:
empty_data scheint das Feld nur dann auf 1 zu setzen, wenn es ohne Wert gesendet wird. Was ist, wenn das Formular standardmäßig 1 in der Eingabe anzeigt, wenn kein Wert vorhanden ist?
Sie können den Standardwert mit festlegen empty_value
$builder->add('myField', 'number', ['empty_value' => 'Default value'])