5

私はDrupalの8を学んでいる私は「2 dimensionnal」「別の項目を追加」形式が含まれているページを作成します。私のコードはほとんどうまく動作しますが、私は家に部屋を追加するとき、私は奇妙な行動を持って号:: getTriggeringElement()

を(FormStateInterface :: getTriggeringElement()からの私のデバッグログで奇妙な価値があり、コードの下に参照し、ログインします)

最初に:私は2つの構造、家屋と部屋を持っています。ユーザーは、いくつかの家を作成することができ、それぞれの家のために、彼はいくつかの部屋を作成することができます。

enter image description here

私はいくつかの家を追加すると、フォームが正常に動作します:

enter image description here

私はいくつかを追加する場合最後の家に部屋、フォームはあまりにも正常に動作します:

enter image description here

しかし、私はいくつかの部屋を "最後に残っていない"家に追加すると、フォームはうまくいきません(スクリーンショットでは、ブロックハウス '1'の「部屋を追加」に1回クリックします。 (?!)「家1」は「家2」になったとクリックで5つの部屋を追加する(?!):

enter image description here

ここに私のコードと奇妙なデバッグログ私が得る理由を、私は説明しません。この(getTriggeringElementから()room_addMoreSubmitコールバックで、これは私が考える問題である)値

<?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']; 
    } 

} 

ログ(room_addMoreSubmitにおけるD-D「」)私は「部屋を追加」ボタンをクリックしてください家の「1」:私は家の番号1で「部屋を追加」ボタンをクリックすると

enter image description here

、追加ボタンの配列の親を返しgetTriggeringElement。そして、あなたが見ることができるように、親である私は、家1のボタン「部屋を追加」をクリックすると、「2」ではなく「1」(住宅1) だから、これは特定されている家「2」で、家 "1"ではありません。 ... getTriggeringElementを使用して、なぜ私は理解していない

は良い方法ではないでしょうか?

答えて

3

ソリューション:

$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', 
      ), 
     ); 

一意の名前は私の問題の問題でした。だから、私はname属性を変更します。