Skip to content
This repository was archived by the owner on Apr 18, 2024. It is now read-only.

Commit 4534ee3

Browse files
author
David Barratt
committed
Issue #2460503 by davidwbarratt: Move the "Draggable Table" Entity Reference Widget into it's own module
1 parent e817f10 commit 4534ee3

7 files changed

+371
-360
lines changed

entityqueue.info

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dependencies[] = system (>7.11)
88
dependencies[] = ctools
99
dependencies[] = entity
1010
dependencies[] = entityreference
11+
dependencies[] = entityqueue_dragtable
1112

1213
; EntityQueue and EntitySubqueue classes.
1314
files[] = includes/entityqueue_queue.class.inc

entityqueue.module

-315
Original file line numberDiff line numberDiff line change
@@ -681,10 +681,6 @@ function entityqueue_theme() {
681681
'variables' => array('status' => NULL, 'html' => TRUE),
682682
'file' => 'includes/entityqueue.theme.inc',
683683
),
684-
'entityqueue_dragtable' => array(
685-
'render element' => 'form',
686-
'file' => 'includes/entityqueue.theme.inc',
687-
),
688684
);
689685
}
690686

@@ -842,317 +838,6 @@ function _entityqueue_create_entityreference_field($queue, $field_name, $entity_
842838
}
843839
}
844840

845-
/**
846-
* Implements hook_field_widget_info().
847-
*/
848-
function entityqueue_field_widget_info() {
849-
return array(
850-
'entityqueue_dragtable' => array(
851-
'label' => t('Draggable table'),
852-
'field types' => array('entityreference'),
853-
'settings' => array(
854-
'match_operator' => 'CONTAINS',
855-
'size' => 60,
856-
),
857-
'behaviors' => array(
858-
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
859-
),
860-
),
861-
);
862-
}
863-
864-
/**
865-
* Implements hook_field_widget_settings_form().
866-
*/
867-
function entityqueue_field_widget_settings_form($field, $instance) {
868-
$widget = $instance['widget'];
869-
$settings = $widget['settings'] + field_info_widget_settings($widget['type']);
870-
871-
$form = array();
872-
873-
if ($widget['type'] == 'entityqueue_dragtable') {
874-
$target_type = $field['settings']['target_type'];
875-
$info = entity_get_info($target_type);
876-
$target_label = isset($info['plural label']) ? $info['plural label'] : $info['label'];
877-
$form['match_operator'] = array(
878-
'#type' => 'select',
879-
'#title' => t('Autocomplete matching'),
880-
'#default_value' => $settings['match_operator'],
881-
'#options' => array(
882-
'STARTS_WITH' => t('Starts with'),
883-
'CONTAINS' => t('Contains'),
884-
),
885-
'#description' => t('Select the method used to collect autocomplete suggestions. Note that <em>Contains</em> can cause performance issues on sites with thousands of @entities.', array(
886-
'@entities' => $target_label,
887-
)),
888-
);
889-
$form['size'] = array(
890-
'#type' => 'textfield',
891-
'#title' => t('Size of textfield'),
892-
'#default_value' => $settings['size'],
893-
'#element_validate' => array('_element_validate_integer_positive'),
894-
'#required' => TRUE,
895-
);
896-
}
897-
898-
return $form;
899-
}
900-
901-
/**
902-
* Implements hook_field_widget_form().
903-
*/
904-
function entityqueue_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
905-
if ($instance['widget']['type'] == 'entityqueue_dragtable') {
906-
$subform = array();
907-
$entity_type = $element['#entity_type'];
908-
$field_name = $element['#field_name'];
909-
$target_type = $field['settings']['target_type']; // The referenced entity_type
910-
$entity = isset($element['#entity']) ? $element['#entity'] : FALSE;
911-
// Abort early if we don't have a reference to the parent entity.
912-
if (!$entity) {
913-
return $element;
914-
}
915-
916-
list($entity_id) = entity_extract_ids($entity_type, $entity);
917-
$value_key = key($field['columns']);
918-
$subform['#value_key'] = $value_key;
919-
// We don't use drupal_html_id() here because our ajax callback needs
920-
// to be able to know what the table id is. We should never have
921-
// the same form field multiple times on a page anyway.
922-
$table_id = drupal_clean_css_identifier('entityqueue-dragtable-' . $field_name);
923-
$table_classes = array(
924-
'entityqueue-dragtable',
925-
'entityqueue-dragtable-field-' . $field_name,
926-
'entityqueue-dragtable-entity-type-' . $entity_type,
927-
);
928-
drupal_add_tabledrag($table_id, 'order', 'sibling', 'item-weight');
929-
$subform['items'] = array(
930-
'#theme' => 'entityqueue_dragtable',
931-
'#attributes' => array(
932-
'id' => $table_id,
933-
'class' => $table_classes,
934-
),
935-
'#attached' => array(
936-
'js' => array(
937-
drupal_get_path('module', 'entityqueue') . '/js/entityqueue.widget.js' => array('type' => 'file'),
938-
),
939-
),
940-
);
941-
942-
$rows = array();
943-
$values = isset($form_state['values'][$field_name][$langcode]) ? $form_state['values'][$field_name][$langcode] : $items;
944-
if (!empty($values)) {
945-
$entity_ids = array();
946-
foreach ($values as $key => $item) {
947-
$entity_ids[] = $item[$value_key];
948-
}
949-
$entities = entity_load($target_type, $entity_ids);
950-
}
951-
$count = count($values);
952-
953-
// When ajax element is clicked, don't lose the destination.
954-
if (current_path() == 'system/ajax') {
955-
if (isset($form_state['destination'])) {
956-
$destination = $form_state['destination'];
957-
}
958-
}
959-
else {
960-
$destination = drupal_get_destination();
961-
$form_state['destination'] = $destination;
962-
}
963-
964-
$weight = 0; // Keeps track of existing items index
965-
foreach ($values as $key => $item) {
966-
$target_id = $item[$value_key];
967-
$actions = array();
968-
969-
if (!isset($entities[$target_id])) {
970-
// Skip entities that no longer exist.
971-
continue;
972-
}
973-
974-
if (entity_access('view', $target_type, $entities[$target_id])) {
975-
$label = entity_label($target_type, $entities[$target_id]);
976-
$uri = entity_uri($target_type, $entities[$target_id]);
977-
$label = l($label, $uri['path']);
978-
}
979-
else {
980-
$label = t('- Restricted access -');
981-
}
982-
983-
$actions[] = array(
984-
'#type' => 'button',
985-
'#value' => t('Remove'),
986-
'#name' => $field_name . '_remove_' . $weight,
987-
'#validate' => array(),
988-
'#ajax' => array(
989-
'callback' => 'entityqueue_field_widget_ajax_callback',
990-
'wrapper' => $table_id,
991-
),
992-
);
993-
994-
$subform['items'][$weight] = array(
995-
'label' => array(
996-
'#type' => 'markup',
997-
'#markup' => $label,
998-
),
999-
$value_key => array(
1000-
'#type' => 'value',
1001-
'#value' => $target_id,
1002-
),
1003-
'actions' => array(
1004-
'#type' => 'container',
1005-
$actions,
1006-
),
1007-
'weight' => array(
1008-
'#type' => 'weight',
1009-
'#delta' => $count,
1010-
'#default_value' => $weight,
1011-
'#title' => '',
1012-
'#attributes' => array('class' => array('item-weight')),
1013-
),
1014-
);
1015-
1016-
$weight++;
1017-
}
1018-
// This is stolen from entityreference_field_widget_form() and trimmed down
1019-
// for our purposes.
1020-
$autocomplete_path = 'entityreference/autocomplete/single/';
1021-
$autocomplete_path .= $field_name . '/' . $entity_type . '/' . $instance['bundle'] . '/';
1022-
$id = 'NULL';
1023-
if ($entity_id) {
1024-
$id = $entity_id;
1025-
}
1026-
$autocomplete_path .= $id;
1027-
$subform['add'] = array(
1028-
'#type' => 'container',
1029-
'#attributes' => array('class' => array('container-inline')),
1030-
'#weight' => 10,
1031-
'entity' => array(
1032-
'#type' => 'textfield',
1033-
'#maxlength' => 1024,
1034-
'#default_value' => '',
1035-
'#autocomplete_path' => $autocomplete_path,
1036-
'#size' => $instance['widget']['settings']['size'],
1037-
'#element_validate' => array('_entityreference_autocomplete_validate'),
1038-
'#attributes' => array(
1039-
'id' => $table_id . '-add',
1040-
),
1041-
),
1042-
'submit' => array(
1043-
'#type' => 'submit',
1044-
'#value' => t('Add item'),
1045-
'#ajax' => array(
1046-
'callback' => 'entityqueue_field_widget_ajax_callback',
1047-
'wrapper' => $table_id,
1048-
),
1049-
),
1050-
);
1051-
1052-
if (!empty($instance['description'])) {
1053-
$subform['description'] = array(
1054-
'#markup' => field_filter_xss($instance['description']),
1055-
'#prefix' => '<div class="description">',
1056-
'#suffix' => '</div>',
1057-
'#weight' => 11,
1058-
);
1059-
}
1060-
1061-
$subform['#element_validate'] = array('entityqueue_widget_dragtable_element_validate');
1062-
return $subform;
1063-
}
1064-
}
1065-
1066-
/**
1067-
* Element validate callback.
1068-
* @see entityqueue_field_widget_form()
1069-
*/
1070-
function entityqueue_widget_dragtable_element_validate($element, &$form_state) {
1071-
$items = array();
1072-
$value_key = $element['#value_key'];
1073-
$field_name = $element['#field_name'];
1074-
$lang = $element['#language'];
1075-
if (isset($form_state['values'][$field_name][$lang]['items'])) {
1076-
$existing_values = $form_state['values'][$field_name][$lang]['items'];
1077-
}
1078-
else {
1079-
$existing_values = array();
1080-
}
1081-
// If the trigger was a remove button.
1082-
$triggering_element = $form_state['triggering_element'];
1083-
$offset = drupal_strlen($field_name) + 8;
1084-
if (drupal_substr($triggering_element['#name'], 0, $offset) == $field_name . '_remove_') {
1085-
$remove_key = drupal_substr($triggering_element['#name'], $offset);
1086-
unset($existing_values[$remove_key]);
1087-
}
1088-
$values = array();
1089-
$weights = array();
1090-
foreach ($existing_values as $key => $row) {
1091-
$values[] = $row[$value_key];
1092-
$weights[] = $row['weight'];
1093-
}
1094-
array_multisort($weights, SORT_ASC, $existing_values);
1095-
foreach ($existing_values as $key => $row) {
1096-
$items[] = array(
1097-
$value_key => $row[$value_key],
1098-
);
1099-
}
1100-
$new_value = $form_state['values'][$field_name][$lang]['add'];
1101-
if (!empty($new_value['entity'])) {
1102-
$items[] = array(
1103-
$value_key => $new_value['entity'],
1104-
);
1105-
}
1106-
form_set_value($element, $items, $form_state);
1107-
// Rebuild form if ajax callback button was clicked.
1108-
if (current_path() == 'system/ajax') {
1109-
$form_state['rebuild'] = TRUE;
1110-
}
1111-
}
1112-
1113-
/**
1114-
* Ajax form callback.
1115-
*/
1116-
function entityqueue_field_widget_ajax_callback($form, $form_state) {
1117-
$field_name = $form_state['triggering_element']['#parents'][0];
1118-
$lang = $form[$field_name]['#language'];
1119-
$form_state['rebuild'] = TRUE;
1120-
$form[$field_name][$lang]['add']['#value'] = '';
1121-
$markup = drupal_render($form[$field_name]);
1122-
1123-
$commands[] = ajax_command_replace('.' . drupal_clean_css_identifier('field-name-' . $field_name) , $markup);
1124-
1125-
1126-
$add_id = drupal_clean_css_identifier('entityqueue-dragtable-' . $field_name . '-add');
1127-
$commands[] = ajax_command_invoke('#' . $add_id, 'val', array(''));
1128-
$settings = array(
1129-
drupal_clean_css_identifier('entityqueue-dragtable-' . $field_name) => true,
1130-
);
1131-
drupal_add_js(array('entityqueue_changed' => $settings), 'setting');
1132-
return array(
1133-
'#type' => 'ajax',
1134-
'#commands' => $commands,
1135-
);
1136-
}
1137-
1138-
/**
1139-
* Ajax form callback.
1140-
*/
1141-
function entityqueue_subqueue_ajax_callback($form, $form_state) {
1142-
$settings = array(
1143-
drupal_clean_css_identifier('entityqueue-dragtable-' . $form_state['field_name']) => true,
1144-
);
1145-
drupal_add_js(array('entityqueue_changed' => $settings), 'setting');
1146-
1147-
$markup = drupal_render($form);
1148-
$commands[] = ajax_command_replace('#' . $form_state['form_wrapper_id'] , $markup);
1149-
1150-
return array(
1151-
'#type' => 'ajax',
1152-
'#commands' => $commands,
1153-
);
1154-
}
1155-
1156841
/**
1157842
* Workaround for missing breadcrumbs on callback and action paths.
1158843
*

includes/entityqueue.theme.inc

-45
Original file line numberDiff line numberDiff line change
@@ -46,48 +46,3 @@ function theme_entityqueue_status($variables) {
4646
return $html ? "<span class='entityqueue-status-custom' title='$help'>" . $label . "</span>" : $label;
4747
}
4848
}
49-
50-
/**
51-
* Themes the subqueue items as a dragtable.
52-
*/
53-
function theme_entityqueue_dragtable($variables) {
54-
$form = $variables['form'];
55-
56-
$output = '';
57-
$rows = array();
58-
$table_id = $form['#attributes']['id'];
59-
drupal_add_tabledrag($table_id, 'order', 'sibling', 'item-weight');
60-
foreach (element_children($form) as $key) {
61-
if (isset($form[$key]['label'])) {
62-
$row = array();
63-
64-
$row[] = drupal_render($form[$key]['label']);
65-
$row[] = drupal_render($form[$key]['actions']);
66-
$row[] = drupal_render($form[$key]['weight']);
67-
68-
$rows[] = array(
69-
'data' => $row,
70-
'class' => array('draggable')
71-
);
72-
}
73-
}
74-
75-
if (empty($rows)) {
76-
$rows[] = array(array('data' => t('No items.'), 'colspan' => 3));
77-
}
78-
$header = array(
79-
t('Label'),
80-
t('Actions'),
81-
t('Weight'),
82-
);
83-
$output .= theme('table', array(
84-
'header' => $header,
85-
'rows' => $rows,
86-
'attributes' => array(
87-
'id' => $table_id,
88-
'class' => $form['#attributes']['class'],
89-
),
90-
));
91-
92-
return $output;
93-
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name = Draggable Table
2+
description = Provides a Draggable Table Widget for Entity Reference Fields.
3+
package = Entityqueue
4+
core = 7.x
5+
6+
dependencies[] = system (>7.11)
7+
dependencies[] = entity
8+
dependencies[] = entityreference

0 commit comments

Comments
 (0)