Custom widget field only saves first letter, disappears on edit I'm trying to create a custom module for Drupal 7 that makes two widgets available for Text fields. They autocomplete from a database table using #autocomplete_path. The autocomplete works fine and when a match is selected it is made the value for the field, but when the node is saved only the first letter from that field is shown. Then when the node is edited, the field comes up blank in the edit form.

Here's my module code:

&lt;?php
/**
 * Implements hook_menu().
 */
function autocomplete_jsb_users_menu() {
    $items['jsbu/speaker/autocomplete'] = array(
        'page callback' =&gt; 'jsbu_speaker_autocomplete',
        'access callback' =&gt; TRUE,
        'weight' =&gt; 1,
    );
    $items['jsbu/venue/autocomplete'] = array(
        'page callback' =&gt; 'jsbu_venue_autocomplete',
        'access callback' =&gt; TRUE,
        'weight' =&gt; 2,
    );
    return $items;
}

/**
 * Implements hook_field_widget_info().
 *
 * Two widgets are provided.
 * - A textfield Speaker name autocomplete widget.
 * - A textfield Venue name autocomplete widget.
 */
function autocomplete_jsb_users_field_widget_info() {
    return array(
        'autocomplete_speaker_name' =&gt; array(
            'label' =&gt; t('Autocomplete Speaker Name'),
            'field types' =&gt; array('text'),
        ),
        'autocomplete_venue_name' =&gt; array(
            'label' =&gt; t('Autocomplete Venue Name'),
            'field types' =&gt; array('text'),
        ),
    );
}

/**
 * Implements hook_field_widget_form().
 */
function autocomplete_jsb_users_field_widget_form(&amp;$form, &amp;$form_state, $field, $instance, $langcode, $items, $delta, $element) {
    // set the default text instance
    $element += array(
        '#type' =&gt; 'textfield',
        '#size' =&gt; $instance['widget']['settings']['size'],
        '#maxlength' =&gt; $field['settings']['max_length'],
        '#attributes' =&gt; array('class' =&gt; array('text-full')),
    );

    if ($instance['widget']['type'] == 'autocomplete_speaker_name') {
        $element['#autocomplete_path' ] = 'jsbu/speaker/autocomplete';
    } else if($instance['widget']['type'] == 'autocomplete_venue_name') {
        $element['#autocomplete_path' ] = 'jsbu/venue/autocomplete';
    }

    return $element;
}

/**
 * Implements the autocomplete_jsbu_speaker() callback.
 */
function jsbu_speaker_autocomplete() {
    $matches = array();

    // Query the database
    $query = db_select('field_data_field_speaker_name', 'sn');

    // Select rows that match the string
    $query
        -&gt;fields('sn', array('field_speaker_name_value'))
        -&gt;orderBy('field_speaker_name_value', 'DESC')
        -&gt;distinct();

    $result = $query-&gt;execute();

    // add matches to $matches  
    foreach ($result as $row) {
        $matches[$row-&gt;field_speaker_name_value] = check_plain($row-&gt;field_speaker_name_value);
    }

    // return for JS
    drupal_json_output($matches);
}

/**
 * Implements the autocomplete_jsbu_venue() callback.
 */
function jsbu_venue_autocomplete() {
    $matches = array();

    // Query the database
    $query = db_select('field_data_field_venue_name', 'vn');

    // Select rows that match the string
    $query
        -&gt;fields('vn', array('field_venue_name_value'))
        -&gt;orderBy('field_venue_name_value', 'DESC')
        -&gt;distinct();

    $result = $query-&gt;execute();

    // add matches to $matches  
    foreach ($result as $row) {
        $matches[$row-&gt;field_venue_name_value] = check_plain($row-&gt;field_venue_name_value);
    }

    // return for JS
    drupal_json_output($matches);
}


Any ideas? Thanks!
It may help to just wrap the returned array from the _field_widget_form in yet another array

return array('anything' =&gt; $element);


Worked for me ;)