public static function WebformMultiple::processWebformMultiple in Webform 8.5
Same name and namespace in other branches
- 6.x src/Element/WebformMultiple.php \Drupal\webform\Element\WebformMultiple::processWebformMultiple()
Process items and build multiple elements widget.
1 call to WebformMultiple::processWebformMultiple()
- WebformSubmissionViews::processWebformMultiple in src/
Element/ WebformSubmissionViews.php - Process items and build multiple elements widget.
1 method overrides WebformMultiple::processWebformMultiple()
- WebformSubmissionViews::processWebformMultiple in src/
Element/ WebformSubmissionViews.php - Process items and build multiple elements widget.
File
- src/
Element/ WebformMultiple.php, line 94
Class
- WebformMultiple
- Provides a webform element to assist in creation of multiple elements.
Namespace
Drupal\webform\ElementCode
public static function processWebformMultiple(&$element, FormStateInterface $form_state, &$complete_form) {
// Set tree.
$element['#tree'] = TRUE;
// Remove 'for' from the element's label.
$element['#label_attributes']['webform-remove-for-attribute'] = TRUE;
// Set min items based on when the element is required.
if (!isset($element['#min_items']) || $element['#min_items'] === '') {
$element['#min_items'] = empty($element['#required']) ? 0 : 1;
}
// Make sure min items does not exceed cardinality.
if (!empty($element['#cardinality']) && $element['#min_items'] > $element['#cardinality']) {
$element['#min_items'] = $element['#cardinality'];
}
// Make sure empty items does not exceed cardinality.
if (!empty($element['#cardinality']) && $element['#empty_items'] > $element['#cardinality']) {
$element['#empty_items'] = $element['#cardinality'];
}
// If the number of default values exceeds the min items and has required
// sub-elements, set empty items to 0.
if (isset($element['#default_value']) && is_array($element['#default_value']) && count($element['#default_value']) >= $element['#min_items'] && static::hasRequireElement($element['#element'])) {
$element['#empty_items'] = 0;
}
// Add validate callback that extracts the array of items.
$element += [
'#element_validate' => [],
];
array_unshift($element['#element_validate'], [
get_called_class(),
'validateWebformMultiple',
]);
// Wrap this $element in a <div> that handle #states.
WebformElementHelper::fixStatesWrapper($element);
// Get unique key used to store the current number of items.
$number_of_items_storage_key = static::getStorageKey($element, 'number_of_items');
// Store the number of items which is the number of
// #default_values + number of empty_items.
if ($form_state
->get($number_of_items_storage_key) === NULL) {
if (empty($element['#default_value']) || !is_array($element['#default_value'])) {
$number_of_default_values = 0;
}
else {
$number_of_default_values = count($element['#default_value']);
}
$number_of_empty_items = (int) $element['#empty_items'];
$number_of_items = $number_of_default_values + $number_of_empty_items;
// Make sure number of items is greated than min items.
$min_items = (int) $element['#min_items'];
$number_of_items = $number_of_items < $min_items ? $min_items : $number_of_items;
// Make sure number of (default) items does not exceed cardinality.
if (!empty($element['#cardinality']) && $number_of_items > $element['#cardinality']) {
$number_of_items = $element['#cardinality'];
}
$form_state
->set($number_of_items_storage_key, $number_of_items);
}
$number_of_items = $form_state
->get($number_of_items_storage_key);
$table_id = implode('_', $element['#parents']) . '_table';
// Disable add operation when #cardinality is met
// and make sure to limit the number of items.
if (!empty($element['#cardinality']) && $number_of_items >= $element['#cardinality']) {
$element['#add'] = FALSE;
$number_of_items = $element['#cardinality'];
$form_state
->set($number_of_items_storage_key, $number_of_items);
}
// Add wrapper to the element.
$ajax_attributes = $element['#ajax_attributes'];
$ajax_attributes['id'] = $table_id;
$element += [
'#prefix' => '',
'#suffix' => '',
];
$element['#ajax_prefix'] = '<div' . new Attribute($ajax_attributes) . '>';
$element['#ajax_suffix'] = '</div>';
$element['#prefix'] = $element['#prefix'] . $element['#ajax_prefix'];
$element['#suffix'] = $element['#ajax_suffix'] . $element['#suffix'];
// DEBUG:
// Disable Ajax callback by commenting out the below callback and wrapper.
$ajax_settings = [
'callback' => [
get_called_class(),
'ajaxCallback',
],
'wrapper' => $table_id,
'progress' => [
'type' => 'none',
],
];
// Initialize, prepare, and finalize sub-elements.
static::initializeElement($element, $form_state, $complete_form);
// Build (single) element header.
$header = static::buildElementHeader($element);
// Build (single) element rows.
$row_index = 0;
$weight = 0;
$rows = [];
if (!$form_state
->isProcessingInput() && isset($element['#default_value']) && is_array($element['#default_value'])) {
$default_values = $element['#default_value'];
}
elseif ($form_state
->isProcessingInput() && isset($element['#value']) && is_array($element['#value'])) {
$default_values = $element['#value'];
}
else {
$default_values = [];
}
// When adding/removing elements we don't need to set any default values.
$action_key = static::getStorageKey($element, 'action');
if ($form_state
->get($action_key)) {
$form_state
->set($action_key, FALSE);
$default_values = [];
}
foreach ($default_values as $key => $default_value) {
// If #key is defined make sure to set default value's key item.
if (!empty($element['#key']) && !isset($default_value[$element['#key']])) {
$default_value[$element['#key']] = $key;
}
$rows[$row_index] = static::buildElementRow($table_id, $row_index, $element, $default_value, $weight++, $ajax_settings);
$row_index++;
}
while ($row_index < $number_of_items) {
$rows[$row_index] = static::buildElementRow($table_id, $row_index, $element, NULL, $weight++, $ajax_settings);
$row_index++;
}
// Build table.
$table_wrapper_attributes = $element['#table_wrapper_attributes'];
$table_wrapper_attributes['class'][] = 'webform-multiple-table';
if (count($element['#element']) > 1) {
$table_wrapper_attributes['class'][] = 'webform-multiple-table-responsive';
}
$element['items'] = [
'#prefix' => '<div' . new Attribute($table_wrapper_attributes) . '>',
'#suffix' => '</div>',
] + $rows;
// Display table if there are any rows.
if ($rows) {
$element['items'] += [
'#type' => 'table',
'#header' => $header,
'#attributes' => $element['#table_attributes'],
] + $rows;
// Add sorting to table.
if ($element['#sorting']) {
$element['items']['#tabledrag'] = [
[
'action' => 'order',
'relationship' => 'sibling',
'group' => 'webform-multiple-sort-weight',
],
];
}
}
elseif (!empty($element['#no_items_message'])) {
$element['items'] += [
'#type' => 'webform_message',
'#message_message' => $element['#no_items_message'],
'#message_type' => 'info',
'#attributes' => [
'class' => [
'webform-multiple-table--no-items-message',
],
],
];
}
// Build add more actions.
if ($element['#add_more'] && (empty($element['#cardinality']) || $number_of_items < $element['#cardinality'])) {
$element['add'] = [
'#prefix' => '<div class="webform-multiple-add js-webform-multiple-add container-inline">',
'#suffix' => '</div>',
];
$element['add']['submit'] = [
'#type' => 'submit',
'#value' => $element['#add_more_button_label'],
'#limit_validation_errors' => [],
'#submit' => [
[
get_called_class(),
'addItemsSubmit',
],
],
'#ajax' => $ajax_settings,
'#name' => $table_id . '_add',
];
$max = $element['#cardinality'] ? $element['#cardinality'] - $number_of_items : 100;
$element['add']['more_items'] = [
'#type' => 'number',
'#title' => $element['#add_more_button_label'] . ' ' . $element['#add_more_input_label'],
'#title_display' => 'invisible',
'#min' => 1,
'#max' => $max,
'#default_value' => $element['#add_more_items'],
'#field_suffix' => $element['#add_more_input_label'],
'#error_no_message' => TRUE,
'#access' => $element['#add_more_input'],
];
}
$element['#attached']['library'][] = 'webform/webform.element.multiple';
return $element;
}