사용자 엔터티에 따라 사용자 지정 엔터티가 있습니다. 실제로, 사용자 프로필 양식 내에 엔터티 양식을 표시하는 것이 합리적이라고 생각한 경우에도 마찬가지입니다.
내가 지금 가지고있는 문제는 다음과 같습니다. 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_form
Drupal 7에서 작동했던 배열의 일부 매개 변수를 섞고 싶었지만 그 배열이 엄청 나서 필요한 제출 버튼과 처리기를 찾을 수 없었습니다.
문제는 이것이 가능합니까? 그리고 권장되는 방법은 무엇입니까?
답변
자신의 일을하려고하는 대신 인라인 엔터티 양식 모듈을 사용해보십시오 . 이 모듈은이 특정한 경우를 위해 만들어졌습니다 (엔터티 폼 내에서 엔터티 생성 / 편집).
Drupal Commerce의 워크 플로를 개선하기 위해이 작업에 많은 작업을 수행했음을 잘 알고 있습니다. 나는 그것을 직접 테스트하지는 않았지만 Drupal Commerce는 Drupal 8에서도 의존하기 때문에 이미 안정적이어야합니다.
이 모듈은 폼을 생성하는 엔티티 참조 필드에 위젯을 추가하여 작동하므로 플러그 앤 플레이 방식이 매우 중요합니다. 유일한 요구 사항은 사용자에게 사용자 지정 엔터티에 대한 참조가 있어야한다는 것입니다.
답변
나는 이것이 가능해야한다고 믿는다. 불행히도 오늘 코드를 작성할 시간이 없지만 다음 사항을 명심해야합니다.
- 하위 양식을 추가하는 동안 제출 된 양식을 인식하기 위해 Drupal
form_id
과 같은 특수 항목을 제거해야합니다form_build_id
. - 두 번째 양식의 양식 단추를 원하지 않으면
unset($sub_form['actions'])
하위 양식을 기본 양식에 추가하기 전에 양식 양식을 제거해야합니다 . #tree
POST 변수에서 별도의 포켓에있는 하위 양식 값을 잡을 수 있도록 양식 을 활성화해야합니다 . 예를 들어$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.
}