Problem
My custom field type will not save data. Every time I save the entity it is attached to (it doesn't matter what entity I do this on) the value always comes out NULL and SQL throws an error because that field can not be NULL in the database.
Research
I'm currently working on a module that will provide a custom field type to be used on entities. I have done my best from looking at the docs for Field Types API and seeing how other modules have implemented this e.g. Entity Reference, Examples, and Address Field.
Attempt
Below is my attempt and can not figure out what is wrong with the code.
.install file
/**
* Implements hook_field_schema().
*/
function civsearch_code_reference_field_schema($field) {
$columns = array(
'target_id' => array(
'description' => 'The id of the target code.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
);
return array(
'columns' => $columns,
'indexes' => array(
'target_id' => array('target_id'),
),
);
}
.module file
/**
* Implements hook_field_info().
*/
function civsearch_code_reference_field_info() {
return array(
'civsearch_code_reference' => array(
'label' => t('Code Reference'),
'description' => t('This field stores the target_id of the referenced code.'),
'settings' => array(
'code_type' => '',
),
'instance_settings' => array(),
'default_widget' => 'civsearch_code_reference_autocomplete_tags',
'default_formatter' => 'civsearch_code_reference_label',
),
);
}
/**
* Implements hook_field_settings_form().
*/
function civsearch_code_reference_field_settings_form($field, $instance, $has_data) {
$settings = $field['settings'];
$options = array(
'muni_cloud_bulk' => t('Bulk'),
'muni_cloud_bulk_exception' => t('Bulk Exception'),
'muni_cloud_bulk_zoning_district' => t('Bulk Zoning District'),
'muni_cloud_exception' => t('Exception'),
'muni_cloud_jurisdiction' => t('Jurisdiction'),
'muni_cloud_use' => t('Use'),
'muni_cloud_use_unit' => t('Use Unit'),
'muni_cloud_use_regulation' => t('Use Regulation'),
'muni_cloud_use_zoning_district' => t('Use Zoning District'),
'muni_cloud_zoning_category' => t('Zoning Category'),
'muni_cloud_zoning_district' => t('Zoning District'),
);
$form['code_type'] = array(
'#type' => 'select',
'#title' => t('Code Type'),
'#options' => $options,
'#description' => t('The code type to be referenced.'),
'#default_value' => $settings['code_type'],
'#required' => TRUE,
);
return $form;
}
/**
* Implements hook_field_widget_info().
*/
function civsearch_code_reference_field_widget_info() {
return array(
'civsearch_code_reference_autocomplete_tags' => array(
'label' => t('Autocomplete (Tags style)'),
'description' => t('An autocomplete text field.'),
'field types' => array('civsearch_code_reference'),
'settings' => array(
'match_operator' => 'CONTAINS',
'size' => 60,
'path' => '',
),
'behaviors' => array(
'multiple values' => FIELD_BEHAVIOR_CUSTOM,
),
),
);
}
/**
* Implements hook_field_widget_settings_form().
*/
function civsearch_code_reference_field_widget_settings_form($field, $instance) {
$widget = $instance['widget'];
$settings = $widget['settings'];
$form = array();
$form['match_operator'] = array(
'#type' => 'select',
'#title' => t('Autocomplete matching'),
'#default_value' => $settings['match_operator'],
'#options' => array(
'STARTS_WITH' => t('Starts with'),
'CONTAINS' => t('Contains'),
),
'#description' => t('Select the method used to collect autocomplete suggestions.'),
);
$form['size'] = array(
'#type' => 'textfield',
'#title' => t('Size of textfield'),
'#default_value' => $settings['size'],
'#element_validate' => array('_element_validate_integer_positive'),
'#required' => TRUE,
);
return $form;
}
/**
* Implements hook_field_widget_form().
*/
function civsearch_code_reference_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
$element += array(
'#type' => 'textfield',
'#maxlength' => 1024,
'#defaul_value' => 'bob',
'#size' => $instance['widget']['settings']['size'],
);
return array('target_id' => $element);
}
/**
* Implements hook_field_formatter_info().
*/
function civsearch_code_reference_field_formatter_info() {
return array(
'civsearch_code_reference_label' => array(
'label' => t('Label'),
'description' => t('Display the label of the referenced codes.'),
'field types' => array('civsearch_code_reference'),
'settings' => array(
'link' => FALSE,
),
),
);
}
/**
* Implements hook_field_formatter_settings_form().
*/
function civsearch_code_reference_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$element = array();
if ($display['type'] == 'civsearch_code_reference_label') {
$element['link'] = array(
'#title' => t('Link label to the referenced code.'),
'#type' => 'checkbox',
'#default_value' => $settings['link'],
);
}
return $element;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function civsearch_code_reference_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = array();
if ($display['type'] == 'civsearch_code_reference_label') {
$summary[] = $settings['link'] ? t('Link to the referenced code') : t('No link');
}
return implode('<br />', $summary);
}
/**
* Implements hook_field_is_empty().
*/
function civsearch_code_reference_field_is_empty($item, $field) {
return empty($item);
}
Error
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column
'field_jurisdiction_target_id' cannot be null: INSERT INTO
{field_data_field_jurisdiction} (entity_type, entity_id, revision_id, bundle,
delta, language, field_jurisdiction_target_id) VALUES
(:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2,
:db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5,
:db_insert_placeholder_6); Array ( [:db_insert_placeholder_0] =>
civsearch_property [:db_insert_placeholder_1] => 17 [:db_insert_placeholder_2]
=> 17 [:db_insert_placeholder_3] => test [:db_insert_placeholder_4] => 0
[:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => ) in
field_sql_storage_field_storage_write() (line 452 of
/var/dev/modules/field/modules/field_sql_storage/field_sql_storage.module)
Debug Backtrace
15: field_sql_storage_field_storage_write() (Array, 2 elements)
14: call_user_func_array() (Array, 1 element)
13: module_invoke() (Array, 2 elements)
12: field_attach_insert() (Array, 2 elements)
11: EntityAPIController->invoke() (Array, 2 elements)
10: EntityAPIController->save() (Array, 2 elements)
9: Entity->save() (Array, 2 elements)
8: civsearch_property_edit_form_submit() (Array, 2 elements)
7: form_execute_handlers() (Array, 2 elements)
6: drupal_process_form() (Array, 2 elements)
5: drupal_build_form() (Array, 2 elements)
4: drupal_get_form() (Array, 2 elements)
3: civsearch_property_form_wrapper() (Array, 2 elements)
2: call_user_func_array() (Array, 1 element)
1: menu_execute_active_handler() (Array, 2 elements)
0: main() (Array, 2 elements)