如何为Drupal 7的Entity Reference选择列表添加可输入文本的‘Other’选项
Hey there! Let's figure out how to add that 'Other' option with a text input to your Drupal 7 Entity Reference select field. I've got two solid approaches for you—one using a module (quick and easy) and another with custom code (for more control):
This module is purpose-built for exactly this scenario, so it's the fastest way to get up and running:
- First, download and enable the Entity Reference Other module (make sure you grab the Drupal 7 compatible version).
- Navigate to your field's configuration page (e.g.,
admin/structure/types/manage/[your-content-type]/fields/[your-entity-ref-field]). - Scroll down to the Entity Reference Other Settings section, check the box to "Add 'Other' option", and set the label for the text field (like "Custom Value").
- Save your settings, then test the form! When users select "Other" from the dropdown, the text field will appear automatically, and their input will be stored and displayed alongside the entity reference field.
If you need more flexibility (or prefer not to add another module), you can build this functionality yourself with a custom module:
Step 1: Add the 'Other' Option and Text Field to the Form
Use hook_field_widget_form_alter to modify the entity reference widget and inject the "Other" option and hidden text field:
function my_custom_module_field_widget_form_alter(&$element, &$form_state, $context) { // Replace 'field_my_entity_ref' with your actual field machine name if ($context['field']['field_name'] == 'field_my_entity_ref' && $context['instance']['widget']['type'] == 'options_select') { // Add "Other" to the select list options $element['#options']['_other'] = t('Other'); // Add a text field that only shows when "Other" is selected $element['_other_text'] = array( '#type' => 'textfield', '#title' => t('Custom Value'), '#states' => array( 'visible' => array( ':input[name="' . $element['#name'] . '"]' => array('value' => '_other'), ), ), '#weight' => $element['#weight'] + 1, '#required' => FALSE, // We'll add validation for this later ); // Attach a custom validation function $element['#element_validate'][] = 'my_custom_module_entity_ref_other_validate'; } }
Step 2: Validate the 'Other' Text Input
Make sure users can't select "Other" without entering a value:
function my_custom_module_entity_ref_other_validate($element, &$form_state) { $selected_value = drupal_array_get_nested_value($form_state['values'], $element['#parents']); $other_text_value = drupal_array_get_nested_value($form_state['values'], array_merge($element['#parents'], array('_other_text'))); if ($selected_value == '_other' && empty(trim($other_text_value))) { form_error($element['_other_text'], t('Please enter a custom value for "Other".')); } }
Step 3: Store the Custom Value
First, add a plain text field to your content type (e.g., field_custom_other_value) to store the user's input. Then use hook_node_presave to save the value when the form is submitted:
function my_custom_module_node_presave($node) { $entity_ref_field = 'field_my_entity_ref'; $other_text_field = 'field_custom_other_value'; // Check if "Other" was selected if (isset($node->$entity_ref_field[LANGUAGE_NONE][0]['value']) && $node->$entity_ref_field[LANGUAGE_NONE][0]['value'] == '_other') { // Save the custom text to our dedicated field if (!empty($node->$other_text_field[LANGUAGE_NONE][0]['value'])) { $node->$other_text_field[LANGUAGE_NONE][0]['value'] = trim($node->$other_text_field[LANGUAGE_NONE][0]['value']); } // Clear the entity reference field (or leave '_other' if you want to track it) $node->$entity_ref_field[LANGUAGE_NONE][0]['value'] = ''; } else { // Clear the custom text field if "Other" wasn't selected $node->$other_text_field[LANGUAGE_NONE][0]['value'] = ''; } }
Step 4: Display the Custom Value
Update the node display to show the custom value instead of an empty entity reference field. Use hook_node_view_alter for this:
function my_custom_module_node_view_alter(&$build) { $node = $build['#node']; $entity_ref_field = 'field_my_entity_ref'; $other_text_field = 'field_custom_other_value'; // Check if the entity reference is empty but we have a custom value if (empty($node->$entity_ref_field[LANGUAGE_NONE][0]['target_id']) && !empty($node->$other_text_field[LANGUAGE_NONE][0]['value'])) { // Replace the entity reference field's markup with our custom text $build[$entity_ref_field]['#markup'] = t('Other: @value', array('@value' => $node->$other_text_field[LANGUAGE_NONE][0]['value'])); } }
Pro Tips
- Don't forget to replace all placeholder names (like
my_custom_module,field_my_entity_ref) with your actual module and field names. - If you're working with entities other than nodes (like users or taxonomy terms), adjust the hooks accordingly (e.g.,
hook_user_presaveinstead ofhook_node_presave). - Test thoroughly! Make sure the text field shows/hides correctly, validation works, and the value saves and displays as expected.
内容的提问来源于stack exchange,提问作者Emad Samir Zaki

