it-swarm.com.de

Dynamisches Hinzufügen von Feldern zum Formular

Hy,

Ich versuche ein Formular zu erstellen, in das Sie Benutzernamen eingeben können. Ich möchte dynamisch neue Textfelder per Knopfdruck hinzufügen. Ich habe meinen Code auf dem folgende Frage basiert (weil er auch drupal 8) verwendet und angeblich funktionieren sollte).

Leider werden die Felder nicht hinzugefügt. Der Code, den ich derzeit verwende, sieht folgendermaßen aus:

<?php
    /**
     * @file
     * Contains \Drupal\bulk_email\Form\EmailForm.
     */

    namespace Drupal\bulk_email\Form;
    use Drupal\Core\Form\FormBase;
    use Drupal\Core\Form\FormStateInterface;
    use Drupal\Component\Utility\UrlHelper;

    class EmailForm extends FormBase {
        public function getFormId() {
            return "bulk_email_form";
        }

        public function buildForm(array $form, FormStateInterface $form_state) {
            $form['#tree'] = TRUE;

            $form['users'] = array(
              '#type' => 'fieldset',
              '#title' => t('Users'),
              '#prefix' => '<div id="users-wrapper">',
              '#suffix' => '</div>',
            );

            $num_users = $form_state->getValue('num_users');
            if (empty($num_users)) {
                $num_users = 1;
            }
            for ($i = 0; $i < $num_users; $i++) {
                $form['users'][$i] = array(
                    '#type'  => 'textfield',
                    '#description' => t('Select a user.'),
                );
            }

            $form['users']['users_more'] = array(
                '#type' => 'submit',
                '#value' => t('Add one'),
                '#submit' => array($this, 'bulk_email_addfieldsubmit'),
                '#ajax' => array(
                     'callback' => array($this, 'bulk_email_add_more_callback'),
                     'wrapper' => 'users-wrapper',
                ),
            );

            $form['actions'] = array('#type' => 'actions');
            $form['submit'] = array(
                '#type' => 'submit',
                '#value' => t('Send'),
            );
            return $form;
        }

        public function submitForm(array &$form, FormStateInterface $form_state) {
            // submit code
        }

        public function bulk_email_addfieldsubmit(array &$form, FormStateInterface $form_state) {
            $num_users = $form_state->get('num_users') + 1;
            $form_state->set('num_users', $num_users);
            $form_state->setRebuild(TRUE);
        }

        public function bulk_email_add_more_callback(array &$form, FormStateInterface $form_state) {
            return $form['users'];
        }
    }
?>

Ich vermisse höchstwahrscheinlich ein kleines Detail, aber ich kann es scheinbar nicht finden ... Jede Hilfe wird geschätzt.

Mit freundlichen Grüßen.

2

Ich könnte mich irren, aber Sie können auch versuchen, den Ajax-Rückruf in zu ändern, vorausgesetzt, Bulk_email_add_more_callback wird nicht tatsächlich aufgerufen.

'#ajax' => array(
                 'callback' => '::bulk_email_add_more_callback',
                 'wrapper' => 'users-wrapper',
            ),

Und dann erhalten Sie im eigentlichen Rückruf Ihre Werte aus dem vollständigen Formular. Dies war mein Problem, alle Werte waren korrekt, aber dann gab ich die alten Werte zurück.

public function bulk_email_add_more_callback(array &$form, FormStateInterface $form_state) {
        $form = $form_state->getCompleteForm()
        return $form['users'];
    }
1
Johann

Ich habe keine Lösung für mein Problem gefunden und frage mich, ob es eine schlechte Designentscheidung oder ein Fehler ist.

Für andere Benutzer habe ich die folgende Problemumgehung verwendet:

Zuerst habe ich den gesamten Code entfernt, als ich dieses zusätzliche Feld hinzugefügt habe. Ich habe nur das eigentliche Textfeld behalten, in dem Sie den Benutzernamen eingeben. Dann habe ich ein neues verstecktes Feld namens Benutzersammlung hinzugefügt.

Der Rest wurde durch Hinzufügen eines benutzerdefinierten Javascript erledigt. Dieses Skript erkennt, ob ein Benutzername eingegeben wurde (basierend auf der automatischen Vervollständigung). Es würde dann ";" auf den Wert der Benutzersammlung. Anschließend wird das Textfeld gelöscht. Das Ergebnis ist ein Benutzererfassungsfeld, das alle eingegebenen Benutzernamen enthält. Schließlich habe ich auch ein visuelles Feedback hinzugefügt, das den Inhalt der Benutzersammlung zeigt (nach einigem Parsen).

Es ist nur eine Umgehung und hat mich auch ziemlich viel Mühe gekostet, aber es ist besser als nichts.

1

Haben Sie überprüft, ob der Submit in Ihrer Ajax-Anfrage aufgerufen wird?

public function bulk_email_addfieldsubmit(array &$form, FormStateInterface $form_state) {
    $num_users = $form_state->get('num_users') + 1;
    $form_state->set('num_users', $num_users);

Wenn nicht, können Sie diesen Code in buildForm() einfügen. In diesem Fall müssen Sie überprüfen, ob das auslösende Element das richtige ist.

Und noch ein kleines Problem, diese Zeile in buildForm():

$num_users = $form_state->getValue('num_users');

Sollte get('num_users') sein, da getValue() für Benutzereingaben vorgesehen ist.

1
4k4

sie können so etwas verwenden.

if (!empty($form_state['values']['field_name'])) {
    $form[]=array();//add your form elements to be shown after submit.
}
else {
    $form[]=array();//here your original form.
}
return $form;

in Ihrem Formular einreichen hinzufügen

$form_State['rebuild']=true;
1
ana

ich habe auch das gleiche Szenario. Ich kann die Textfelder dynamisch erfolgreich mit Ajax in drupal 8.) hinzufügen und entfernen. Ich habe den folgenden Code angehängt. Eigentlich denke ich, dass Sie den Beispielen des FAPI-Moduls folgen und mehr Formular hinzufügen, oder?

es gibt ein Problem in Fapi. Fügen Sie mehr Form in drupal 8. und Patch ist auch da. Also habe ich den Code für mein Szenario selbst korrigiert.

Erster Schritt : Wir arbeiten hinter der Logik von Formstate-Variablen. Den Wert von Formstate-Variablen können wir die Felder dynamisch addieren oder subtrahieren.

sie müssen die Eigenschaft $ form ['# tree'] = TRUE; festlegen, wenn das erste Formular erstellt wird. Nur dann können Sie die richtigen übermittelten Werte in der Übermittlungsfunktion abrufen.

 $veritas_id = $form_state->get('veritas_id');
if ($veritas_id === NULL) {
  $veritas_id = $form_state->set('veritas_id', 0);
  $veritas_id = 0;
  }

zweiter Schritt

$form['veritasIds'] = [
  '#type' => 'fieldset',
  //'#title' => $this->t('#ID'),
  '#prefix' => '<div id="veritas-id-wrapper">',
  '#suffix' => '</div>',
  ];



  $form['veritasIds']['actions']['add_name'] = [
  '#type' => 'submit',
  '#limit_validation_errors' => array(),
  '#value' => t('add row'),
  //'#name'=>$veritas,
  '#submit' => array('::addOneVeritas'),
  '#ajax' => [
  'callback' => '::addmoreCallbackVeritas',
  'wrapper' => 'veritas-id-wrapper',
  ],

  '#attributes' => array('class'=> array('btn-transparent')),
  ];

  //if ($num_names > 1) {

  $form['veritasIds']['actions']['remove_name'] = [
  '#type' => 'submit',
  '#limit_validation_errors' => array(),
  '#value' => t('delete row'),
  '#submit' => array('::removeoneVeritas'),
  '#ajax' => [
    'callback' => '::addmoreCallbackVeritas',
    'wrapper' => 'veritas-id-wrapper',
  ],
  '#name'=>t('veritasremove'),

  '#attributes' => array('class'=> array('btn-transparent')),
  '#suffix' => t('<div class="id-wrapper">#ID</div>'),
  ];

  for ($i = 0; $i < $veritas_id; $i++) {
  $form['veritasIds']['id'][$i] = [
  '#type' => 'textfield',
  '#attributes' => array('class'=> array('veritas-addfield')),
  //'#title' => t('Name'),
  ];
  }

hier wird ein Fieldset erstellt. Innerhalb des Feldsatzes werden nur weitere Zeilen hinzugefügt und weitere Schaltflächen gelöscht. Hinzugefügte dynamische Felder werden dort angezeigt.

dritter Schritt $ form_state-> setCached (FALSE); wird benötigt Submit und Ajax Callback Funktionen werden

public function addmoreCallbackVeritas(array &$form, FormStateInterface $form_state) {
  $veritas_id = $form_state->get('veritas_id');
  return $form['veritasIds'];

}}

public function addOneVeritas(array &$form, FormStateInterface $form_state) {
    $veritas_id = $form_state->get('veritas_id');
    $add_button1 = $veritas_id + 1;
    $form_state->set('veritas_id', $add_button1);
    $form_state->setRebuild();
  }

fühlen Sie sich frei, irgendwelche Zweifel daran zu stellen

1
Vinodhini