function hook_field_widget_form

You are here

7 field.api.php hook_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element)

Return the form for a single field widget.

Field widget form elements should be based on the passed-in $element, which contains the base form element properties derived from the field configuration.

Field API will set the weight, field name and delta values for each form element. If there are multiple values for this field, the Field API will invoke this hook as many times as needed.

Note that, depending on the context in which the widget is being included (regular entity form, field configuration form, advanced search form...), the values for $field and $instance might be different from the "official" definitions returned by field_info_field() and field_info_instance(). Examples: mono-value widget even if the field is multi-valued, non-required widget even if the field is 'required'...

Therefore, the FAPI element callbacks (such as #process, #element_validate, #value_callback...) used by the widget cannot use the field_info_field() or field_info_instance() functions to retrieve the $field or $instance definitions they should operate on. The field_widget_field() and field_widget_instance() functions should be used instead to fetch the current working definitions from $form_state, where Field API stores them.

Alternatively, hook_field_widget_form() can extract the needed specific properties from $field and $instance and set them as ad-hoc $element['#custom'] properties, for later use by its element callbacks.

Other modules may alter the form element provided by this function using hook_field_widget_form_alter().

Parameters

$form: The form structure where widgets are being attached to. This might be a full form structure, or a sub-element of a larger form.

$form_state: An associative array containing the current state of the form.

$field: The field structure.

$instance: The field instance.

$langcode: The language associated with $items.

$items: Array of default values for this field.

$delta: The order of this item in the array of subelements (0, 1, 2, etc).

$element: A form element array containing basic properties for the widget:

  • #entity_type: The name of the entity the field is attached to.
  • #bundle: The name of the field bundle the field is contained in.
  • #field_name: The name of the field.
  • #language: The language the field is being edited in.
  • #field_parents: The 'parents' space for the field in the form. Most widgets can simply overlook this property. This identifies the location where the field values are placed within $form_state['values'], and is used to access processing information for the field through the field_form_get_state() and field_form_set_state() functions.
  • #columns: A list of field storage columns of the field.
  • #title: The sanitized element label for the field instance, ready for output.
  • #description: The sanitized element description for the field instance, ready for output.
  • #required: A Boolean indicating whether the element value is required; for required multiple value fields, only the first widget's values are required.
  • #delta: The order of this item in the array of subelements; see $delta above.

Return value

The form elements for a single widget for this field.

See also

field_widget_field()

field_widget_instance()

hook_field_widget_form_alter()

hook_field_widget_WIDGET_TYPE_form_alter()

Related topics

7 functions implement hook_field_widget_form()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

field_test_field_widget_form in modules/field/tests/field_test.field.inc
Implements hook_field_widget_form().
file_field_widget_form in modules/file/file.field.inc
Implements hook_field_widget_form().
image_field_widget_form in modules/image/image.field.inc
Implements hook_field_widget_form().
number_field_widget_form in modules/field/modules/number/number.module
Implements hook_field_widget_form().
options_field_widget_form in modules/field/modules/options/options.module
Implements hook_field_widget_form().

... See full list

File

modules/field/field.api.php, line 883

Code

function hook_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $element += array(
    '#type' => $instance['widget']['type'],
    '#default_value' => isset($items[$delta]) ? $items[$delta] : '',
  );
  return array('value' => $element);
}

Comments

If you plan on creating a custom field, which also has an alternate widget type of "options_select", or "options_buttons", and you don't override the default form hooks, you absolutely MUST implement:
hook_field_options_list() or your options list will always appear empty.

... where you'll find complete lists of available #types of element etc etc, along with all the appropriate attributes for each: forms_api_reference.html

It seems $items really does only ever contain the default values for your field.

If you want to manipulate or test the actual values for the actual items in your actual fields, it seems you have to use either hook_field_widget_form_alter or set up a pre_render callback function.

Using jquery with hook_field_widget_form doesn't act the same as with the form api. I define a child element with a class of 'example_button' in the widget form but jquery can't seem to find it based on $('input.example_button'). How do I get jquery to recognize DOM elements in the widget form? What am I missing?

This works:

function entityreference_textfield_field_widget_form(
    &$form, &$form_state, $field, $instance, $langcode, $items,
    $delta, $element) {
...
  $element += array(
    '#type' => 'textfield',
    '#title' => t('Referenced nids'),
    '#default_value' => $current_value,
    '#element_validate' => array('_entityreference_textfield_validate', ),
    '#custom' => array('field_name' => $field['field_name']),
  );
  return $element;
}

Note the += in $element += array(. This adds to $element, with a union. Initially, I tried: $element['entityreference_textfield'] = array(. This looks more like normal FAPI code, but doesn't work in this context.

The code in the Example field module at http://api.drupal.org/api/examples/field_example!field_example.module/fu... seems to be wrong.

I will add that the plus (or plus-equals) array union operator prefers the left array or, in the case of all the examples we see in the drupalsphere for element field api examples, the original element. For example:

<?php
// Given an inbound array:
$element = array(
  ...
 
'#title' => t('Generic Label'),
  ...
);
// The original $element '#title' array element's value will not be overridden:
$element += array(
  ...
 
'#title' => t('Just kidding!'),
  ...
);
// In this case, reference the existing element directly, such as:
$element['#title'] = t('My Specific Label');

// Think of += as:
$final_element = $original_element + $current_element
?>

My task was to create a simple widget that changes a textfield to an autocomplete lookup. I know I could do it with form_alter instead, but I wanted it to be a widget, because in my case it's just a simpler version of a much more complicated widget and it wouldn't make logical sense to put them in two different places.

My problem was that the widget passed the value just fine in the POST submit, but for some reason it wasn't saved to the database. So if your problem is that your simple text field widget looks perfect, but the value isn't saved to the database, read on:

This works for me:

function ydd_api_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
      $element['value'] = array(
        '#title' => t('Yle Programs Api Id'),
        '#type' => 'textfield',
        '#size' => 100,
        '#default_value' => !empty($items[0]['value']) ? $items[0]['value'] : '',
        '#autocomplete_path' => 'yddapi/programs/autocompletesimple',
      );
      return $element;
}

At first, I just had $element += array(); like in all the examples, but it turns out my value doesn't get saved unless I create an array index called "value" in my $element:

$element['value'] = array();

<?php
// source http://stackoverflow.com/a/6495142/103211
function youtubefield_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta,\
$element) {
 
$main_widget = array();
  switch (
$instance['widget']['type']) {
  case
'youtubefield_video_widget':
   
$main_widget = $element + array(
     
'#type' => 'textfield',
     
'#default_value' => isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL,
      );
    break;
  }
 
$element['value'] = $main_widget;
  return
$element;
}
?>

Nice advice.

Thank you for sharing.