protected function ComponentSectionForm::buildComplexFormElement in Module Builder 8.3
Builds a form element with multiple child elements.
Helper for buildFormElement().
Note that buildFormElement() is responsible for some attributes of the element.
1 call to ComponentSectionForm::buildComplexFormElement()
- ComponentSectionForm::buildFormElement in src/
Form/ ComponentSectionForm.php - Builds the form element for a data item.
File
- src/
Form/ ComponentSectionForm.php, line 482
Class
- ComponentSectionForm
- Generic form for entering a section of data for a component.
Namespace
Drupal\module_builder\FormCode
protected function buildComplexFormElement(&$form, FormStateInterface $form_state, DataItem $data) {
// Set up a wrapper for AJAX.
$wrapper_id = Html::getId($data
->getAddress() . '-complex-wrapper');
$element = [
'#type' => 'details',
'#title' => $data
->getLabel(),
'#open' => TRUE,
'#attributes' => [
'id' => $wrapper_id,
],
];
// Don't show an optional and single-valued complex element until the user
// requests it. This is to keep the form clear, and to prevent validation
// errors of the complex element has required properties but the user
// doesn't want it.
if (!$data
->isRequired() && $data
->isEmpty() && !$data
->isDelta()) {
$element[':add_button'] = [
'#type' => 'submit',
// This allows FormAPI to figure out which button is the triggering
// element. The name must be unique across all buttons in the form,
// otherwise, the first matching name will be taken by FormAPI as being
// the button that was clicked, with unexpected results.
// See \Drupal\Core\Form\FormBuilder::elementTriggeredScriptedSubmission().
'#name' => $data
->getAddress() . '_add',
'#value' => $this
->t('Add @component', [
'@component' => $data
->getLabel(),
]),
'#limit_validation_errors' => [],
'#submit' => [
'::addComplexDataSubmit',
],
'#data_address' => $data
->getAddress(),
'#ajax' => [
'callback' => '::complexButtonAjax',
'wrapper' => $wrapper_id,
'effect' => 'fade',
],
'#prefix' => '<div>',
'#suffix' => '</div>',
];
return $element;
}
foreach ($data as $data_item) {
$this
->buildFormElement($element, $form_state, $data_item);
}
if (!$data
->isRequired() && !$data
->isEmpty() && !$data
->isDelta()) {
$element[':remove_button'] = [
'#type' => 'submit',
// This allows FormAPI to figure out which button is the triggering
// element. The name must be unique across all buttons in the form,
// otherwise, the first matching name will be taken by FormAPI as being
// the button that was clicked, with unexpected results.
// See \Drupal\Core\Form\FormBuilder::elementTriggeredScriptedSubmission().
'#name' => $data
->getAddress() . '_remove',
'#value' => $this
->t('Remove @component', [
'@component' => $data
->getLabel(),
]),
'#limit_validation_errors' => [],
'#submit' => [
'::removeComplexDataSubmit',
],
'#data_address' => $data
->getAddress(),
'#ajax' => [
'callback' => '::complexButtonAjax',
'wrapper' => $wrapper_id,
'effect' => 'fade',
],
'#prefix' => '<div>',
'#suffix' => '</div>',
];
}
// NO! has to go immediately after the variant property!
if ($data
->isMutable()) {
if (count($data
->getProperties()) == 1 && $data
->getVariantData()->value) {
$element['count_notice'] = [
'#type' => 'container',
'notice' => [
'#plain_text' => $this
->t("The @variant variant has no additional properties.", [
'@variant' => $data
->getVariantData()
->getLabel(),
]),
],
];
}
// Set up a wrapper for AJAX.
// Note that we don't to use Html::getUniqueId() because the data's
// address is already unique, and furthermore, we don't WANT uniqueness
// because we want the same data item to produce the same HTML ID when
// we're looking at the variant property form element further on.
// TODO: this assumes only one root data item in the form, as another
// data item could have the same addresses!
$wrapper_id = Html::getId($data
->getAddress() . '-mutable-wrapper');
$element['#attributes'] = [
'id' => $wrapper_id,
];
// WARNING: assumes the form structure!
$mutable_property_form_address = explode(':', $data
->getAddress());
$variant_property_address = array_merge($mutable_property_form_address, [
$data
->getVariantData()
->getName(),
]);
$element[':update_variant'] = [
'#type' => 'submit',
// Needs to be full address for uniquess in the whole form.
'#name' => $data
->getAddress() . '_update_variant',
// TODO: customisable!
'#value' => $data
->isEmpty() ? $this
->t('Set variant') : $this
->t('Change variant and delete data for this item'),
// We need to validate the variant property so we get its value in the
// submit handler for this button.
'#limit_validation_errors' => [
$variant_property_address,
],
'#element_validate' => [
'::updateVariantValidate',
],
'#submit' => [
'::updateVariantSubmit',
],
'#data_address' => $data
->getVariantData()
->getAddress(),
'#variant_data_name' => $data
->getVariantData()
->getName(),
'#ajax' => [
'callback' => '::variantButtonAjax',
'wrapper' => $wrapper_id,
'effect' => 'fade',
],
'#prefix' => '<div>',
'#suffix' => '</div>',
'#weight' => -10,
];
// Also tweak the weight of the variant property so it goes above the
// button to change the variant.
$variant_property_name = $data
->getVariantData()
->getName();
$element[$variant_property_name]['#weight'] = -20;
}
return $element;
}