When a Custom Field includes a text value that uses a 'Select list' widget, the allowed values don't appear to be available when the field is used in a view.

I have a Custom Field field_phone_type that includes two data items:
- phone_type_number is of type Telephone for the phone number
- phone_type_type is a text item using a select list widget, with the following allowed values:

  office|Office
  mobile|Mobile
  fax|Fax

When I add the field to a view and attempt to set the formatter settings, there is no option to select whether to display the 'Key' or the 'Label', as there is when using the formatter on "Manage Display" for an entity containing the same field.

Manage display formatter settings - works as expected
Formatter settings on a Manage Display page for an entity

View formatter settings - display option missing
Formatter settings on a view

Additionally, when the view is rendered, I get the warning:

Warning: Undefined array key "key_label" in Drupal\custom_field\Plugin\CustomField\FieldFormatter\StringFormatter->formatValue() (line 91 of modules/contrib/custom_field/src/Plugin/CustomField/FieldFormatter/StringFormatter.php).
Drupal\custom_field\Plugin\CustomField\FieldFormatter\StringFormatter->formatValue(Array) (Line: 277)
Drupal\custom_field\Plugin\Field\FieldFormatter\BaseFormatter->getFormattedValues(Object, 'en') (Line: 45)
Drupal\custom_field\Plugin\Field\FieldFormatter\CustomFormatter->viewValue(Object) (Line: 232)
Drupal\custom_field\Plugin\Field\FieldFormatter\BaseFormatter->viewElements(Object, 'en') (Line: 89)
Drupal\Core\Field\FormatterBase->view(Object, 'en') (Line: 265)
Drupal\Core\Entity\Entity\EntityViewDisplay->buildMultiple(Array) (Line: 266)
Drupal\layout_builder\Entity\LayoutBuilderEntityViewDisplay->buildMultiple(Array) (Line: 256)
Drupal\views\Entity\Render\EntityFieldRenderer->buildFields(Array) (Line: 143)
Drupal\views\Entity\Render\EntityFieldRenderer->render(Object, Object) (Line: 833)
Drupal\views\Plugin\views\field\EntityField->getItems(Object) (Line: 1151)
Drupal\views\Plugin\views\field\FieldPluginBase->advancedRender(Object) (Line: 238)
template_preprocess_views_view_field(Array, 'views_view_field', Array)
...

Full stack trace attached.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

justcaldwell created an issue. See original summary.

justcaldwell’s picture

Issue summary: View changes
apmsooner’s picture

Thanks for reporting this @justcaldwell. I'm looking into it now to see if i can reproduce and therefore provide a quick fix!

justcaldwell’s picture

Thanks for the quick reply! I haven't had a moment to debug, but let me know if I can provide any more info.

apmsooner’s picture

Where I'm at so far is that for some reason, the field_settings part of this https://git.drupalcode.org/project/custom_field/-/blob/2.0.x/src/Plugin/... is turning up empty when passed to view. So... the correct widget settings are never getting passed in.

running ksm() on the definition in the view is returning:

#definition: array:2 [▼
      "type" => "field_item:custom"
      "settings" => array:2 [▼
        "columns" => array:2 [▼
          "text" => array:8 [▶]
          "node" => array:9 [▶]
        ]
        "field_settings" => []
      ]
    ]

but in manage display page... the field_settings array is filled properly. So not sure why at this point.

justcaldwell’s picture

StatusFileSize
new817 bytes

I spent some time debugging today with no luck. I tried tracing things a bit further back and ended up setting a breakpoint on the CustomFieldTypeBase() constructor function (line 93). The only thing I noticed is that, each time a view is rendered, CustomFieldTypeBase gets instantiated 4 times for each custom item. The first two times the $configuration (where the widget settings live) array is empty; the next two times, the $configuration array is fully-loaded and all the widget settings, allowed values, etc. are present. Why is well over my head, but I thought it might be a clue for someone.

So unfortunately the only thing I can offer is this simple patch, which is NOT a fix for the issue, but will suppress the warning until it's sorted out.

apmsooner’s picture

Thanks for testing things out. I will submit a patch that fixes the warning and also a bug I found with ajax/visibility paths in views as there are different array parents in views so the formatter plugin type is not actually working in views when changed. The field settings not getting passed to views though is an odd thing that seems like some sort of core bug. The schema is clearly defined so it's certainly over my head at the moment as well. I could possibly just always display the key_label dropdown in the formatter settings with some help text regardless of the widget type. That seems like it might have to be the only immediate solution so I'll test that out as well to make sure it checks out. I should be able to followup with a patch tonight that should hopefully resolve the issue with some workaround.

Thanks!

apmsooner’s picture

StatusFileSize
new6.21 KB

@ justcaldwell - try this new patch. This will expose the field always regardless of the widget being used. I added some help text to try to explain its dependent on widget. The formatValue() should work fine as is now but let me know if you see anything new. Additionally, i modified some logic for the ajax and visibility path so when selecting a different formatter, the correct fields should be displayed.

apmsooner’s picture

Status: Active » Needs review
justcaldwell’s picture

Thanks @apmsooner! I really appreciate the quick turnaround.

Tried it out, and it worked well with in both a view and and a "standard" entity view display, so I decided to test with Layout Builder as well. As soon as I enable Layout Builder on the entity view display, I get the error below. Quite possibly a separate issue, but I haven't had a moment to dig in.

TypeError: Drupal\custom_field\CustomFieldGenerateData::getRandomOptions(): Return value must be of type array, string returned in Drupal\custom_field\CustomFieldGenerateData::getRandomOptions() (line 276 of modules/contrib/custom_field/src/CustomFieldGenerateData.php).
Drupal\custom_field\CustomFieldGenerateData::getRandomOptions(Array) (Line: 43)
Drupal\custom_field\CustomFieldGenerateData->generateFieldData(Array, Array) (Line: 105)
Drupal\custom_field\Plugin\Field\FieldType\CustomItem::generateSampleValue(Object) (Line: 253)
Drupal\Core\Field\FieldItemList->generateSampleItems() (Line: 245)
Drupal\Core\Entity\ContentEntityStorageBase->createWithSampleValues('person') (Line: 55)
Drupal\layout_builder\Entity\LayoutBuilderSampleEntityGenerator->get('node', 'person') (Line: 229)
Drupal\layout_builder\Plugin\SectionStorage\DefaultsSectionStorage->getContextsDuringPreview() (Line: 71)
Drupal\layout_builder_restrictions\Form\FormAlter->getPopulatedContexts(Object) (Line: 53)
Drupal\layout_builder_restrictions\Form\FormAlter->getBlockDefinitions(Object) (Line: 135)
Drupal\layout_builder_restrictions\Form\FormAlter->alterEntityViewDisplayForm(Array, Object, 'entity_view_display_edit_form') (Line: 58)
layout_builder_restrictions_form_entity_view_display_edit_form_alter(Array, Object, 'entity_view_display_edit_form') (Line: 562)
Drupal\Core\Extension\ModuleHandler->alter('form', Array, Object, 'entity_view_display_edit_form') (Line: 840)
Drupal\Core\Form\FormBuilder->prepareForm('entity_view_display_edit_form', Array, Object) (Line: 284)
Drupal\Core\Form\FormBuilder->buildForm(Object, Object) (Line: 73)
Drupal\Core\Controller\FormController->getContentResult(Object, Object) (Line: 39)
Drupal\layout_builder\Controller\LayoutBuilderHtmlEntityFormController->getContentResult(Object, Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 580)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 169)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 81)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 718)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
apmsooner’s picture

Cool, I'll try to reproduce the layout builder issue and supplement the patch when i work it out.

apmsooner’s picture

Oh, i think the getRandomOptions is just incorrectly typed. It should be returning a random string|int in the array_rand call. So it's unrelated to this issue but an important one to fix :)

apmsooner’s picture

StatusFileSize
new7.07 KB

@ justcaldwell - try this one please.

justcaldwell’s picture

Status: Needs review » Reviewed & tested by the community

That's got it. Works everywhere I can think to test it. Thanks again @apmsooner!

  • apmsooner committed 5a9f6d97 on 2.0.x
    Issue #3390698 by apmsooner, justcaldwell: Text "allowed values"...
apmsooner’s picture

Version: 2.0.0-rc3 » 2.0.x-dev
Status: Reviewed & tested by the community » Fixed

Merged into dev. Will cut a new release soon.

apmsooner’s picture

Status: Fixed » Closed (fixed)