하나의 엔티티 양식을 다른 엔티티 양식에 임베드하고 둘 다 저장 합리적이라고 생각한 경우에도 마찬가지입니다. 내가 지금 가지고있는 문제는

사용자 엔터티에 따라 사용자 지정 엔터티가 있습니다. 실제로, 사용자 프로필 양식 내에 엔터티 양식을 표시하는 것이 합리적이라고 생각한 경우에도 마찬가지입니다.

여기에 이미지 설명을 입력하십시오

내가 지금 가지고있는 문제는 다음과 같습니다. 2 개의 저장 버튼이 있습니다. 그리고 그것이 나쁘지 않으면, 사용자 (아래쪽)의 저장 버튼은 더 이상 작동하지 않으며 화이트 라벨 저장 버튼은 화이트 라벨 엔티티 만 저장합니다.

양식은 다음과 같이 사용자 양식으로 변경됩니다.

function whitelabel_form_user_form_alter(&$form, FormStateInterface $form_state) {

  $whitelabel = WhiteLabel::load(1);

  $whitelabel_form = \Drupal::service('entity.manager')
    ->getFormObject('whitelabel', 'default')
    ->setEntity($whitelabel);

  $form['whitelabel'] = array(
    '#type' => 'details',
    '#title' => t('White label settings'),
    '#open' => TRUE,
    'form' => \Drupal::formBuilder()->getForm($whitelabel_form),
  );
}

$whitelabel_formDrupal 7에서 작동했던 배열의 일부 매개 변수를 섞고 싶었지만 그 배열이 엄청 나서 필요한 제출 버튼과 처리기를 찾을 수 없었습니다.

문제는 이것이 가능합니까? 그리고 권장되는 방법은 무엇입니까?



답변

자신의 일을하려고하는 대신 인라인 엔터티 양식 모듈을 사용해보십시오 . 이 모듈은이 특정한 경우를 위해 만들어졌습니다 (엔터티 폼 내에서 엔터티 생성 / 편집).

Drupal Commerce의 워크 플로를 개선하기 위해이 작업에 많은 작업을 수행했음을 잘 알고 있습니다. 나는 그것을 직접 테스트하지는 않았지만 Drupal Commerce는 Drupal 8에서도 의존하기 때문에 이미 안정적이어야합니다.

이 모듈은 폼을 생성하는 엔티티 참조 필드에 위젯을 추가하여 작동하므로 플러그 앤 플레이 방식이 매우 중요합니다. 유일한 요구 사항은 사용자에게 사용자 지정 엔터티에 대한 참조가 있어야한다는 것입니다.


답변

나는 이것이 가능해야한다고 믿는다. 불행히도 오늘 코드를 작성할 시간이 없지만 다음 사항을 명심해야합니다.

  • 하위 양식을 추가하는 동안 제출 된 양식을 인식하기 위해 Drupal form_id과 같은 특수 항목을 제거해야합니다 form_build_id.
  • 두 번째 양식의 양식 단추를 원하지 않으면 unset($sub_form['actions'])하위 양식을 기본 양식에 추가하기 전에 양식 양식을 제거해야합니다 .
  • #treePOST 변수에서 별도의 포켓에있는 하위 양식 값을 잡을 수 있도록 양식 을 활성화해야합니다 . 예를 들어 $form['#tree'] = TRUE; $form['sub-form'] = $sub_form;
    하위 양식 값을에서 사용할 수있게됩니다 $form_state['values']['sub-form'].

    • 사용자가 하위 양식을 독립적으로 제출할 수있게하려면 나중에 어떤 버튼을 클릭했는지 인식 할 수 있도록 하위 양식에 대한 조치의 이름을 바꾸어야합니다. 사용자가 하나의 저장 버튼 만 사용하여 두 가지를 모두 저장하게하려면 문제가 덜 발생하므로이 하위 지점을 무시하십시오.
  • 이제 UI에 양식이 표시되므로 다음 단계는 제출을 처리하는 것입니다. 이렇게하려면 기본 양식에 양식 제출 콜백 을 추가 하십시오. 하위 양식의 유효성 검사 콜백을 기본 양식에 추가 할 수도 있습니다. 사용자 정의 콜백에서 하위 양식에 대한 제출 콜백을 트리거해야합니다. Drupal 7에서는 drupal_form_submit 을 사용했습니다 . Drupal 8과 같은 기능은 아직 없습니다. 또는 최악의 시나리오에서 하위 양식의 제출 콜백을 수동으로 트리거 할 수 있지만 sub-form값만 전달해야합니다 $form_state['values'](내가 의미하는 바를 이해하십시오).
  • 하위 양식 콜백이 오류없이 작동하면 두 양식이 모두 제출되고 처리되었다고 가정 할 수 있습니다.

그것이 도움이되기를 바랍니다! 실험의 지옥 같은 소리! 행운을 빕니다.


답변

이론적 대답 (작동하지 않지만 이것이 가장 가깝습니다). 참조를 위해 여기에 게시하고 다른 사람들을위한 출발점.

사용자 양식을 변경하십시오.

function whitelabel_form_user_form_alter(&$form, FormStateInterface $form_state) {
  $whitelabel = WhiteLabel::load(1);

  $whitelabel_form = \Drupal::entityTypeManager()
    ->getFormObject('whitelabel', 'default')
    ->setEntity($whitelabel);
  $renderable_form = \Drupal::formBuilder()->getForm($whitelabel_form);

  // Remove embedded form specific data.
  unset($renderable_form['actions']);
  unset($renderable_form['form_build_id']);
  unset($renderable_form['form_token']);
  unset($renderable_form['form_id']);

  // Also remove all other properties that start with a '#'.
  foreach ($renderable_form as $key => $value) {
    if (strpos($key, '#') === 0) {
      unset ($renderable_form[$key]);
    }
  }

  // Create a container for the entity's fields.
  $form['whitelabel'] = array(
    '#type' => 'details',
    '#title' => t('White label settings'),
    '#open' => TRUE,
    '#tree' => TRUE,
  );
  $form['whitelabel'] += $renderable_form;

  $form['actions']['submit']['#submit'][] = 'whitelabel_form_user_form_submit';
}

제출 핸들러 :

function whitelabel_form_user_form_submit(&$form, FormStateInterface $form_state) {
  $values = $form_state->getValues();

  $form_state = new FormState();
  $form_state->setValues($values);
  // Theoretically you'd want to use $values['entity_container']
  // for the dedicated entity values.

  // Obtain or create an entity. (You want to get this from the form.)
  if (!$whitelabel = WhiteLabel::load(1)) {
    $whitelabel = WhiteLabel::create();
  }

\Drupal::entityTypeManager()
  ->getFormObject('whitelabel', 'default')
  ->setEntity($whitelabel) // Current entity.
  ->buildEntity($form, $form_state) // Update with form values.
  ->save(); // Save updated entity.
}


답변