5

Ich lerne drupal 8. Ich möchte eine Seite erstellen, die ein 'zweidimensional' 'fügen Sie ein anderes Element' Formular enthalten. Mein Code funktioniert fast gut, aber ich habe ein seltsames Verhalten, wenn ich Räume zu einem Haus hinzufüge (es gibt einen seltsamen Wert in meinen Debug-Logs von der FormStateInterface :: getTriggeringElement(), siehe den unteren Rand für den Code und log)Problem für ein "zwei Dimentional" ein weiteres Element hinzufügen "" mit FormStateInterface :: getTriggeringElement()

Erstens: Ich habe zwei Strukturen, Häuser und Räume. Der Benutzer kann einige Häuser erstellen und für jedes Haus, kann er einige Räume schaffen:

enter image description here

Als ich einige Häuser hinzufügen, das Formular funktioniert:

enter image description here

Als ich einige hinzufügen Zimmer bis zum letzten Haus, arbeitet die Form auch in Ordnung:

enter image description here

Aber wenn ich einige Zimmer zu einem "nichtletzten" Haus hinzufüge, funktioniert das Formular nicht gut (auf dem Screenshot klicke ich einmal auf "Zimmer hinzufügen" im Blockhaus "1", das Label des "Haus 1" wurde "Haus 2" und auf Klick 5 Zimmer hinzufügen (?!) (?!):

enter image description here

Hier meinen Code und ein seltsames Debug-Protokoll, ich nicht erklären, warum ich dieser Wert (aus dem getTriggeringElement() in dem room_addMoreSubmit Rückruf und das ist das Problem, das ich denke)

<?php 

namespace Drupal\projet\Form; 
use Drupal\Core\Form\FormBase; 
use Drupal\Core\Form\FormStateInterface; 

class HouseForm extends FormBase { 

    public function getFormId(){ 
    return 'custom_rooms_form'; 
    } 

    function buildForm(array $form, FormStateInterface $form_state) { 



    $house_count = $form_state->get('house_count'); 

    if (is_null($house_count)) { 
     $house_count = 1; 
     $form_state->set('house_count', $house_count); 
    } 

    $form['house'] = array(
     //'#tree' => TRUE, 
     '#prefix' => '<div id="house-replace">', 
     '#suffix' => '</div>' 
    ); 

    for ($house_delta = 0; $house_delta < $house_count; $house_delta++) { 
     if (!isset($form['house'][$house_delta])) { 

     $room_count[$house_delta] = $form_state->get('room_count_'.$house_delta); 

     if (is_null($room_count[$house_delta])) { 
      $room_count[$house_delta] = 1; 
      $form_state->set('room_count_'.$house_delta, $room_count[$house_delta]); 
     } 

     dd($room_count, "room_COUNT"); 

     $form['house'][$house_delta]['room'] = array(
      '#type' => 'fieldset', 
      '#title' => t('house : '.$house_delta), 
      //'#tree' => TRUE, 
      '#prefix' => '<div id="room-replace-'.$house_delta.'">', 
      '#suffix' => '</div>' 
     ); 

     for ($room_delta = 0; $room_delta < $room_count[$house_delta]; $room_delta++) { 
      if (!isset($form['house'][$house_delta]['room'][$room_delta])) { 
      $room = array(
       '#type' => 'textfield' 
      ); 
      $check = array(
       '#type' => 'checkbox' 
      ); 
      $form['house'][$house_delta]['room'][$room_delta] = array(
       '#type' => 'fieldset', 
       '#title' => t('room : '.$house_delta.'.'.$room_delta), 
      ); 
      $form['house'][$house_delta]['room'][$room_delta]['text'] = $room; 
      $form['house'][$house_delta]['room'][$room_delta]['check'] = $check; 
      } 
     } 

     $form['house'][$house_delta]['room']['add'] = array(
      '#type' => 'submit', 
      '#name' => 'add', 
      '#value' => t('Add room'), 
      '#attributes' => array('class' => array('field-add-more-submit'), 'house_delta' => array($house_delta)), 
      '#submit' => array(array(get_class($this), 'room_addMoreSubmit')), 
      '#ajax' => array(
       'callback' => array($this, 'room_addMoreCallback'), 
       'wrapper' => 'room-replace-'.$house_delta, 
       'effect' => 'fade', 
      ), 
     ); 

     } 
    } 

    $form['house']['add'] = array(
     '#type' => 'submit', 
     '#name' => 'add', 
     '#value' => t('Add house'), 
     '#attributes' => array('class' => array('field-add-more-submit')), 
     '#submit' => array(array(get_class($this), 'house_addMoreSubmit')), 
     '#ajax' => array(
      'callback' => array($this, 'house_addMoreCallback'), 
      'wrapper' => 'house-replace', 
      'effect' => 'fade', 
     ), 
    ); 


    $form['submit'] = array(
     '#type' => 'submit', 
     '#value' => t('Create'), 
    ); 

    return $form; 
    } 

    public function room_addMoreSubmit(array $form, FormStateInterface $form_state) { 
    dd($form_state->getTriggeringElement(), "room : getTriggeringElement()"); // below, the log when I add a room to the house '1' (result see above with the last screenshot: "the house 1" became "house 2" and one click add 5 rooms) 
    $house = $form_state->getTriggeringElement()["#array_parents"][1]; 
    $c = $form_state->get('room_count_'.$house) + 1; 
    $form_state->set('room_count_'.$house, $c); 
    $form_state->setRebuild(TRUE); 
    } 

    public function room_addMoreCallback(array $form, FormStateInterface $form_state) { 
    $house = $form_state->getTriggeringElement()["#array_parents"][1]; 
    return $form['house'][$house]['room']; 
    } 

    public function house_addMoreSubmit(array $form, FormStateInterface $form_state) { 
    dd($form_state->getTriggeringElement()["#array_parents"], "house : getTriggeringElement()"); 
    $c = $form_state->get('house_count') + 1; 
    $form_state->set('house_count', $c); 
    $form_state->setRebuild(TRUE); 
    } 

    public function house_addMoreCallback(array $form, FormStateInterface $form_state) { 
    return $form['house']; 
    } 

} 

das Protokoll (‚dd‘ im room_addMoreSubmit), wenn ich auf dem Button „Raum hinzufügen“ klicken in das Haus "1":

enter image description here

Wenn ich auf dem in der Hausnummer 1, kehrt die Array-Eltern der Schaltfläche Hinzufügen getTriggeringElement Button "Raum hinzufügen" klicken. Und, wie Sie sehen können, ist das Elternteil "2" nicht "1" (das Haus 1) So, wenn ich auf den "addiere Raum" Knopf des Hauses 1 klicke, ist dies das Haus "2", das identifiziert wird und nicht das Haus "1".

Ich verstehe nicht warum ... Verwenden Sie das getTriggeringElement ist nicht der gute Weg?

Antwort

3

Die Lösung:

$form['house'][$house_delta]['room']['add'] = array(
      '#type' => 'submit', 
      '#name' => 'add-'.$house_delta, 
      '#value' => t('Add room'), 
      '#attributes' => array('class' => array('field-add-more-submit'), 'house_delta' => array($house_delta)), 
      '#submit' => array(array(get_class($this), 'room_addMoreSubmit')), 
      '#ajax' => array(
       'callback' => array($this, 'room_addMoreCallback'), 
       'wrapper' => 'room-replace-'.$house_delta, 
       'effect' => 'fade', 
      ), 
     ); 

Der eindeutige Name war das Thema meines Problems. Also ändere ich das Namensattribut.

Verwandte Themen