The problem for "two dimentionnal" is adding another "" element with FormStateInterface :: getTriggeringElement ()

I am learning drupal 8. I want to create a page that contains the form "two dimensionnal" add another item. My code works well, but I have strange behavior when I add rooms to the house (in my debug logs there is a strange value from FormStateInterface :: getTriggeringElement (), see below for code and log)

Firstly: I have two structures, houses and rooms. The user can create several houses and for each house, he can create several rooms:

enter image description here

When I add some at home, the form works fine:

enter image description here

When I add some rooms to the last house, the form works fine too:

enter image description here

But when I add some rooms to any "last" house, the form does not work normally (in the screenshot I click once on the "added room" in block house "1", the shortcut from "house 1" became "house 2" (?! ) and click add 5 rooms (?!):

enter image description here

Here is my code and a strange debug log, I donโ€™t explain why I get this value (from getTriggeringElement () in the room_addMoreSubmit callback, and this is the problem, I think)

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

The log ('dd' in room_addMoreSubmit) when I click the add room button in house 1:

enter image description here

When I click the add room button in house number 1, getTriggeringElement returns the add button to the parents of the array. And, as you see, the parent "2" is not "1" (house 1) Therefore, when I click the "add room" button at home 1, this is house "2", which is identified, not house "1".

I donโ€™t understand why ... Using getTriggeringElement is not so good?

+5
source share
1 answer

Decision:

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

The unique name was the problem of my problem. So, I am changing the name attribute.

+3
source

Source: https://habr.com/ru/post/1234805/


All Articles