function paragraphs_field_multiple_value_form in Paragraphs 7
Special handling to create form elements for multiple values.
Handles generic features for multiple fields:
- number of widgets
- AHAH-'add more' button
- drag-n-drop value reordering.
1 call to paragraphs_field_multiple_value_form()
- paragraphs_field_widget_form in ./
paragraphs.field_widget.inc - Implements hook_field_widget_form().
File
- ./
paragraphs.field_widget.inc, line 54 - Holds functions for the paragraphs widgets.
Code
function paragraphs_field_multiple_value_form($field, $instance, $langcode, $items, &$form, &$form_state, $delta, $original_element) {
$field_name = $field['field_name'];
$parents = $form['#parents'];
$field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
$max = $field_state['items_count'] - 1;
$title = check_plain($instance['label']);
$description = field_filter_xss($instance['description']);
$id_prefix = implode('-', array_merge($parents, array(
$field_name,
)));
$wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
$field_elements = array();
$function = $instance['widget']['module'] . '_field_widget_form_build';
$had_first = FALSE;
$actual_item_count = 0;
if (function_exists($function)) {
for ($delta = 0; $delta <= $max; $delta++) {
$multiple = TRUE;
$element = array(
'#entity_type' => $original_element['#entity_type'],
'#entity' => $original_element['#entity'],
'#bundle' => $original_element['#bundle'],
'#field_name' => $field_name,
'#language' => $langcode,
'#field_parents' => $parents,
'#columns' => array_keys($field['columns']),
// For multiple fields, title and description are handled by the
// wrapping table.
'#title' => $multiple ? '' : $title,
'#description' => $multiple ? '' : $description,
'#delta' => $delta,
'#weight' => $delta,
'#wrapper_id' => $wrapper_id,
);
if ($element = $function($form, $form_state, $field, $instance, $langcode, $items, $delta, $element)) {
// Input field for the delta (drag-n-drop reordering).
if ($multiple) {
// We name the element '_weight' to avoid clashing with elements
// defined by widget.
$element['_weight'] = array(
'#type' => 'weight',
'#title' => t('Weight for row @number', array(
'@number' => $delta + 1,
)),
'#title_display' => 'invisible',
// Note: this 'delta' is the FAPI 'weight' element's property.
'#delta' => $max,
'#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta,
'#weight' => 100,
);
}
// Because our deleted elements are still in the form, only the first
// shown element is required.
if (!$had_first && (!isset($element['#access']) || $element['#access'])) {
$had_first = TRUE;
$element['#required'] = $instance['required'];
}
if (!isset($element['#access']) || $element['#access']) {
$actual_item_count++;
}
// Allow modules to alter the field widget form element.
$context = array(
'form' => $form,
'field' => $field,
'instance' => $instance,
'langcode' => $langcode,
'items' => $items,
'delta' => $delta,
);
drupal_alter(array(
'paragraphs_field_widget_form',
'paragraphs_field_widget_' . $instance['widget']['type'] . '_form',
), $element, $form_state, $context);
$field_elements[$delta] = $element;
}
}
$field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
$field_state['real_items_count'] = $actual_item_count;
field_form_set_state($parents, $field_name, $langcode, $form_state, $field_state);
$field_elements += array(
'#theme' => 'paragraphs_field_multiple_value_form',
'#field_name' => $field['field_name'],
'#cardinality' => $field['cardinality'],
'#title' => $title,
'#required' => $instance['required'],
'#description' => $description,
'#prefix' => '<div id="' . $wrapper_id . '">',
'#suffix' => '</div>',
'#max_delta' => $max,
'#instance' => $instance,
'#element_validate' => array(
'_paragraphs_multiple_field_validate',
),
);
// Add 'add more' button, if not working with a programmed form.
if (empty($form_state['programmed'])) {
$available_bundles = paragraphs_bundle_load();
$select_bundles = array();
$select_bundles_weighted = array();
// By default, consider that no bundle has been explicitly picked.
$explicitly_enabled = FALSE;
foreach ($instance['settings']['allowed_bundles'] as $allowed_bundle_key => $allowed_bundle_value) {
if ($allowed_bundle_key === $allowed_bundle_value && isset($available_bundles[$allowed_bundle_key])) {
$select_bundles[$available_bundles[$allowed_bundle_key]->bundle] = $available_bundles[$allowed_bundle_key]->label;
// If an item has been explicitly selected, raise our flag.
$explicitly_enabled = TRUE;
}
elseif (isset($available_bundles[$allowed_bundle_key]->bundle)) {
$select_bundles_weighted[$available_bundles[$allowed_bundle_key]->bundle] = $available_bundles[$allowed_bundle_key]->label;
}
}
// If no bundle has been explicitly selected, give access to all of them.
if (!$explicitly_enabled) {
$select_bundles = $select_bundles_weighted;
foreach ($available_bundles as $bundle) {
if (!isset($select_bundles[$bundle->bundle])) {
$select_bundles[$bundle->bundle] = $bundle->label;
}
}
}
$removed_a_bundle = FALSE;
$weight = 0;
foreach ($select_bundles as $machine_name => $bundle) {
$select_bundles[$machine_name] = array(
'name' => $bundle,
'weight' => $weight,
);
/* @var $entity_shell ParagraphsItemEntity */
$entity_shell = entity_create('paragraphs_item', array(
'bundle' => $machine_name,
'field_name' => $field_name,
));
$entity_shell
->setHostEntity($original_element['#entity_type'], $original_element['#entity'], $langcode, FALSE);
if (!entity_access('create', 'paragraphs_item', $entity_shell)) {
unset($select_bundles[$machine_name]);
$removed_a_bundle = TRUE;
}
elseif (isset($instance['settings']['bundle_weights'][$machine_name])) {
$select_bundles[$machine_name]['weight'] = $instance['settings']['bundle_weights'][$machine_name];
}
$weight++;
}
$field_elements['#select_bundles'] = $select_bundles;
if ($removed_a_bundle && count($select_bundles) === 0) {
$field_elements['add_more'] = array(
'#type' => 'container',
'#tree' => TRUE,
);
$field_elements['add_more']['add_more'] = array(
'#type' => 'markup',
'#markup' => '<em>' . t('You are not allowed to add any of the bundles.') . '</em>',
);
}
elseif (count($select_bundles)) {
uasort($select_bundles, 'drupal_sort_weight');
$field = $field_state['field'];
if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $field_state['real_items_count'] < $field['cardinality']) {
if (!isset($instance['settings']['title'])) {
$instance['settings']['title'] = PARAGRAPHS_DEFAULT_TITLE;
}
$instance_title = t($instance['settings']['title']);
$field_elements['add_more'] = array(
'#type' => 'container',
'#tree' => TRUE,
);
$add_mode = isset($instance['settings']['add_mode']) ? $instance['settings']['add_mode'] : PARAGRAPHS_DEFAULT_ADD_MODE;
if ($add_mode == 'button') {
foreach ($select_bundles as $machine_name => $bundle) {
/* @var $entity_shell ParagraphsItemEntity */
$entity_shell = entity_create('paragraphs_item', array(
'bundle' => $machine_name,
'field_name' => $field_name,
));
$entity_shell
->setHostEntity($original_element['#entity_type'], $original_element['#entity'], $langcode, FALSE);
$field_elements['add_more']['add_more_bundle_' . $machine_name] = array(
'#type' => 'submit',
'#name' => strtr($id_prefix, '-', '_') . '_add_more_add_more_bundle_' . $machine_name,
'#value' => t('Add !title', array(
'!title' => $bundle['name'],
)),
'#access' => entity_access('create', 'paragraphs_item', $entity_shell),
'#attributes' => array(
'class' => array(
'field-add-more-submit',
'paragraphs-add-more-submit',
),
),
'#limit_validation_errors' => array(),
'#submit' => array(
'paragraphs_add_more_submit',
),
'#ajax' => array(
'callback' => 'paragraphs_add_more_js',
'wrapper' => $wrapper_id,
'effect' => 'fade',
),
);
}
}
else {
uasort($select_bundles, 'drupal_sort_weight');
$select_list = array();
foreach ($select_bundles as $machine_name => $bundle) {
$select_list[$machine_name] = $bundle['name'];
}
$field_elements['add_more']['type'] = array(
'#type' => 'select',
'#name' => strtr($id_prefix, '-', '_') . '_add_more_type',
'#title' => t('!title type', array(
'!title' => $instance_title,
)),
'#options' => $select_list,
'#attributes' => array(
'class' => array(
'field-add-more-type',
),
),
'#limit_validation_errors' => array(
array_merge($parents, array(
$field_name,
$langcode,
)),
),
);
// Hide the bundle selection if only one bundle is allowed.
if (count($select_list) == 1) {
$field_elements['add_more']['type']['#type'] = 'hidden';
$keys = array_keys($select_list);
$field_elements['add_more']['type']['#value'] = $keys[0];
}
if (isset($form_state['input'][strtr($id_prefix, '-', '_') . '_add_more_type'])) {
$field_elements['add_more']['type']['#default_value'] = $form_state['input'][strtr($id_prefix, '-', '_') . '_add_more_type'];
}
$text = t('Add new !title', array(
'!title' => $instance_title,
));
if ($max >= 0) {
$text = t('Add another !title', array(
'!title' => $instance_title,
));
}
$field_elements['add_more']['add_more'] = array(
'#type' => 'submit',
'#name' => strtr($id_prefix, '-', '_') . '_add_more_add_more',
'#value' => $text,
'#attributes' => array(
'class' => array(
'field-add-more-submit',
'paragraphs-add-more-submit',
),
),
'#limit_validation_errors' => array(),
'#submit' => array(
'paragraphs_add_more_submit',
),
'#ajax' => array(
'callback' => 'paragraphs_add_more_js',
'wrapper' => $wrapper_id,
'effect' => 'fade',
),
);
}
}
}
else {
$field_elements['add_more']['add_more'] = array(
'#type' => 'markup',
'#markup' => '<em>' . t('No bundles available, edit field settings') . '</em>',
);
}
}
}
if (module_exists('file')) {
// file.js triggers uploads when the main Submit button is clicked.
$field_elements['#attached']['js'] = array(
drupal_get_path('module', 'file') . '/file.js',
array(
'data' => drupal_get_path('module', 'paragraphs') . '/paragraphs.js',
'type' => 'file',
'weight' => 9999,
),
);
$form_state['has_file_element'] = TRUE;
}
return $field_elements;
}