Last active
May 11, 2017 14:17
-
-
Save opi/bc892fe62974d67d9af1b2d57ba0d6c6 to your computer and use it in GitHub Desktop.
Drupal multiple field : Add new item on top of the list
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// Insert new item on top of the list. | |
// Display file input first for better UI (https://lut.im/0AkZwIQOUa/dtzEPerqgp3hQ3hk.png) | |
// In a .module | |
/** | |
* Implements hook_field_attach_form(). | |
* Inspired from add_to_top contrib module | |
*/ | |
function MYMODULE_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode = NULL) { | |
if (isset($form['#entity_type']) && isset($form['#bundle'])) { | |
// Get all field instances on this bundle. | |
$field_info_instances = field_info_instances($form['#entity_type'], $form['#bundle']); | |
// Iterate over each instance. | |
foreach ($field_info_instances as $field_name => $field_info_instance) { | |
if ($field_name == 'field_my_multiple_field' && isset($form[$field_name])) { | |
$langcode = $form[$field_name]['#language']; | |
// Make a reference to the position in the array. | |
$field = &$form[$field_name][$langcode]; | |
// First get the delta of the new (last) item. | |
$max = max(array_keys($field)); | |
// Set the _weight to -100 so its always at the top. | |
$field[$max]['_weight']['#default_value'] = -100; | |
$field[$max]['#weight'] = -100; | |
} | |
} | |
} | |
} | |
// In the theme's template.php file | |
/** | |
* Override theme_file_widget_multiple(). | |
*/ | |
function MYTHEME_file_widget_multiple($variables) { | |
$element = $variables['element']; | |
if ($element['#field_name'] != 'field_my_multiple_field') { | |
// Default theme function | |
return theme_file_widget_multiple($variables); | |
} | |
else { | |
// Note: Same as theme_file_widget_multiple() default function except that | |
// the items table is render at the end | |
// Special ID and classes for draggable tables. | |
$weight_class = $element['#id'] . '-weight'; | |
$table_id = $element['#id'] . '-table'; | |
// Build up a table of applicable fields. | |
$headers = array(); | |
$headers[] = t('File information'); | |
if ($element['#display_field']) { | |
$headers[] = array( | |
'data' => t('Display'), | |
'class' => array('checkbox'), | |
); | |
} | |
$headers[] = t('Weight'); | |
$headers[] = t('Operations'); | |
// Get our list of widgets in order (needed when the form comes back after | |
// preview or failed validation). | |
$widgets = array(); | |
foreach (element_children($element) as $key) { | |
$widgets[] = &$element[$key]; | |
} | |
usort($widgets, '_field_sort_items_value_helper'); | |
$rows = array(); | |
foreach ($widgets as $key => &$widget) { | |
// Save the uploading row for last. | |
if ($widget['#file'] == FALSE) { | |
$widget['#title'] = $element['#file_upload_title']; | |
$widget['#description'] = $element['#file_upload_description']; | |
continue; | |
} | |
// Delay rendering of the buttons, so that they can be rendered later in the | |
// "operations" column. | |
$operations_elements = array(); | |
foreach (element_children($widget) as $sub_key) { | |
if (isset($widget[$sub_key]['#type']) && $widget[$sub_key]['#type'] == 'submit') { | |
hide($widget[$sub_key]); | |
$operations_elements[] = &$widget[$sub_key]; | |
} | |
} | |
// Delay rendering of the "Display" option and the weight selector, so that | |
// each can be rendered later in its own column. | |
if ($element['#display_field']) { | |
hide($widget['display']); | |
} | |
hide($widget['_weight']); | |
// Render everything else together in a column, without the normal wrappers. | |
$widget['#theme_wrappers'] = array(); | |
$information = drupal_render($widget); | |
// Render the previously hidden elements, using render() instead of | |
// drupal_render(), to undo the earlier hide(). | |
$operations = ''; | |
foreach ($operations_elements as $operation_element) { | |
$operations .= render($operation_element); | |
} | |
$display = ''; | |
if ($element['#display_field']) { | |
unset($widget['display']['#title']); | |
$display = array( | |
'data' => render($widget['display']), | |
'class' => array('checkbox'), | |
); | |
} | |
$widget['_weight']['#attributes']['class'] = array($weight_class); | |
$weight = render($widget['_weight']); | |
// Arrange the row with all of the rendered columns. | |
$row = array(); | |
$row[] = $information; | |
if ($element['#display_field']) { | |
$row[] = $display; | |
} | |
$row[] = $weight; | |
$row[] = $operations; | |
$rows[] = array( | |
'data' => $row, | |
'class' => isset($widget['#attributes']['class']) ? array_merge($widget['#attributes']['class'], array('draggable')) : array('draggable'), | |
); | |
} | |
drupal_add_tabledrag($table_id, 'order', 'sibling', $weight_class); | |
$output = ''; | |
// Magic happens here. | |
// File input element first | |
$output .= drupal_render_children($element); | |
// Then items table | |
$output .= empty($rows) ? '' : theme('table', array('header' => $headers, 'rows' => $rows, 'attributes' => array('id' => $table_id))); | |
return $output; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment