I'm creating a custom field for use with a bundle. I'm mentioning 'bundle' explicitly because the details of creating the field for use with an entity are slightly different.
- The module enables cleanly.
- The field table contains the property as defined in the field schema.
- The field name appears in the Add Field dialog.
- The field is added to a bundle cleanly, and its settings form contains the property in the default settings pane, properly.
- When content is created, the field and its property appear in the node edit form correctly.
- The node saves without throwing any errors.
When the node is saved and then re-edited, the field property is empty. In inspecting the field in the database, the instance meta such as bundle, and entity_id are populated, but the property column is NULL.
If the fieldset is removed, the value is saved as expected.
Here is the field code: web/modules/custom/test_video_widget/src/Plugin/Field/FieldType/TestVideoWidgetField.php
<?php
namespace Drupal\test_video_widget\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\TypedData\DataDefinition;
/**
* @FieldType(
* id = "test_video_widget",
* module = "test_video_widget",
* label = @Translation("Test Video Widget"),
* description = @Translation("This field stores video meta information."),
* default_widget = "TestVideoWidgetW",
* default_formatter = "TestVideoWidgetFormatter",
* )
*/
class TestVideoWidgetField extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) {
$properties = [];
$properties['video_title'] = DataDefinition::create('string')
->setLabel(t('Video Title'))
->setDescription(t('Optional title to be displayed instead of the node title.'));
return $properties;
}
/**
* {@inheritdoc}
*/
public static function schema(FieldStorageDefinitionInterface $field_definition) {
$columns = array(
'video_title' => array(
'description' => 'Optional title to be displayed instead of the node title.',
'type' => 'varchar',
'length' => 255,
),
);
$schema = array(
'columns' => $columns,
'indexes' => [],
//'foreign keys' => array(),
);
return $schema;
}
Here is the field widget code that does NOT work: web/modules/custom/test_video_widget/src/Plugin/Field/FieldWidget/TestVideoWidgetW.php
<?php
namespace Drupal\test_video_widget\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
/**
*
* @FieldWidget(
* id = "TestVideoWidgetW",
* label = @Translation("Test Video Widget - Widget"),
* description = @Translation("Test Video Widget - Widget"),
* field_types = {
* "test_video_widget",
* },
* )
*/
class TestVideoWidgetW extends WidgetBase {
/**
* {@inheritdoc}
*/
public function formElement(
FieldItemListInterface $items,
$delta,
array $element,
array &$form,
FormStateInterface $form_state
) {
$element['video_meta'] = [
'#type' => 'fieldset',
'#title' => t('Video Meta'),
];
$element['video_meta']['video_title'] = [
'#type' => 'textfield',
'#title' => t('Video Title'),
'#default_value' => isset($items[$delta]->video_title) ? $items[$delta]->video_title : NULL,
'#placeholder' => t(''),
'#size' => 60,
];
return $element;
}
}
and here is the same method without the fieldset, which DOES work:
public function formElement(
FieldItemListInterface $items,
$delta,
array $element,
array &$form,
FormStateInterface $form_state
) {
$element['video_title'] = [
'#type' => 'textfield',
'#title' => t('Video Title'),
'#default_value' => isset($items[$delta]->video_title) ? $items[$delta]->video_title : NULL,
'#placeholder' => t(''),
'#size' => 60,
];
return $element;
}
also, the resulting field table for the field added to the bundle:
node__field_svideo;
+--------------------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------------+------------------+------+-----+---------+-------+
| bundle | varchar(128) | NO | MUL | | |
| deleted | tinyint(4) | NO | PRI | 0 | |
| entity_id | int(10) unsigned | NO | PRI | NULL | |
| revision_id | int(10) unsigned | NO | MUL | NULL | |
| langcode | varchar(32) | NO | PRI | | |
| delta | int(10) unsigned | NO | PRI | NULL | |
| field_svideo_video_title | varchar(255) | YES | | NULL | |
+--------------------------------+------------------+------+-----+---------+-------+