2

I'm trying to create a field that is a combination of two fields. The first field needs to a reference to another entity (just like in the entityreference module). The second field is just a text field (using the textarea widget).

Here's the code I have so far.

sample.install:

function sample_field_schema($field) {
    $schema = array(
        'columns' => array(
            'place_id' => array(
                'type' => 'int',
                'unsigned' => true,
                'not null' => true
            ),
            'quote' => array(
                'type' => 'text',
                'size' => 'big',
                'not null' => false
            )
        ),
        'indexes' => array(
            'place_id' => array('place_id')
        ),
        'foreign keys' => array()
    );

    $entity_type = 'place';
    $bundles = field_info_bundles('node');
    if (!empty($bundles['place'])) {
        $schema['foreign keys']['place'] = array(
            'table' => 'place',
            'columns' => array('place_id' => 'nid')
        );
    }

    return $schema;
}

sample.module:

function sample_field_info() {
    return array(
        'sample_field' => array(
            'label' => t('Label'),
            'description' => t('description.'),
            'default_widget' => 'sample_field_widget',
            'default_formatter' => 'sample_field_formatter',
            'settings' => array(),
            'instance_settings' => array(),
        )
    );
}

function sample_field_formatter_info() {
    return array(
        'sample_field_formatter' => array(
            'label' => t('sample formatter'),
            'field types' => array('sample_field')
        )
    );
}

function sample_field_formatter_view($entity_type, $entity, $field, $instance, $lang, $items, $display) {
    $element = array();

    switch ($display['type']) {
        case 'sample_field_formatter':
            // I'm not really familiar with these bits ... this is just to output *something*
            $element[]['#markup'] = var_export($items, true);
            break;
    }

    return $element;
}

function sample_field_widget_form(&$form, &$form_state, $field, $instance, $lang, $items, $delta, $element) {
    switch ($instance['widget']['type']) {
        case 'sample_field_widget':
            $element['place_id'] = array(
                '#type' => 'textfield',
                '#maxlength' => 1024,
                '#title' => t('Place'),
                '#default_value' => isset($items[$delta]['place_id']) ? $items[$delta]['place_id'] : null,
                '#required' => $element['#required'],
                '#weight' => (int)$element['#weight'],
                '#delta' => $delta,
                '#size' => 'big',
                '#autocomplete_path' => 'api/find/places'
            );

            $element['quote'] = array(
                '#type' => 'textarea',
                '#title' => t('Quote'),
                            '#default_value' => isset($items[$delta]['quote']) ? $items[$delta]['quote'] : null,
            );
            break;
    }

    return $element;
}

function sample_widget_error($element, $error, $form, &$form_state) {
    switch ($error['error']) {
        case 'sample_field_invalid':
            form_error($element, $error['message']);
            break;
    }
}

function sample_field_is_empty($item, $field) {
    if (empty($item['sample_field'])) {
        return true;
    }
}

function sample_field_widget_info() {
    return array(
        'sample_field_widget' => array(
            'label' => t('Sample Field Widget'),
            'field types' => array('sample_field'),
            'settings' => array(),
            'behaviors' => array(
                'default value' => FIELD_BEHAVIOR_NONE
            )
        )
    );
}

So this all gives me a new field type and a new widget for that field. When I edit/create new content that has this field type, the widget shows up properly with both fields but when I submit to insert/update the content, the fields are not saved. How can I get the form to save the field data for this custom field and how can I get that data to be loaded again when the content is edited?

2 Answers 2

3

You're missing hook_field_validate() which apparently is required for this to work. See this blog post (which you may have already -- I'm just comparing what he did to your code) ... http://www.agileapproach.com/blog-entry/compound-fields-drupal-7

1
  • ah, thanks for that. that seems like an important hook ... but that didn't fix this issue. Turns out that my hook_field_is_empty was not properly checking for empty (getting false trues).
    – gregghz
    Jun 26, 2012 at 22:50
2

It was my hook_field_is_empty() implementation. It was returning true in cases where it shouldn't have. Just make sure hook_field_is_empty() is properly checking for empty values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.