{"id":59540,"date":"2023-12-24T10:17:41","date_gmt":"2023-12-24T04:47:41","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=59540"},"modified":"2023-12-27T11:27:22","modified_gmt":"2023-12-27T05:57:22","slug":"how-to-create-dependent-fields-in-paragraph-entity-using-hooks-in-drupal-9-10","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/how-to-create-dependent-fields-in-paragraph-entity-using-hooks-in-drupal-9-10\/","title":{"rendered":"How to create dependent fields in Paragraph Entity using hooks in Drupal 9 &amp; 10"},"content":{"rendered":"<h3><b>Introduction<\/b><\/h3>\n<p style=\"font-weight: 400;\">When working with complex forms, you often have fields whose state depends on the input values of other fields in the form. For example, you might have a select list of options, the options for which depend upon the value selected for another field.<\/p>\n<p style=\"font-weight: 400;\">In this blog, I present one case study of my Drupal project where I had to achieve dependent fields in Paragraph Entity. So, in Paragraph Entity, the fields must use the widget \u201cSelect list.\u201d On selecting options from the select list, we have to show or hide the other corresponding fields in the same Paragraph Entity.<\/p>\n<h3><b>Problem Statement <\/b><\/h3>\n<p style=\"font-weight: 400;\">We already have the Dependent Field module, which is a contributed module and provides dependent field functionality. But this module doesn\u2019t provide support with Paragraph entities. So, we use hooks to solve the problem.<\/p>\n<h3><b>Initial Requirements<\/b><\/h3>\n<p style=\"font-weight: 400;\">We have to install the Paragraph module, which is a contributed module that helps us provide new ways of content creation. It allows you to make things cleaner so that you can give more editing power to your end users.<\/p>\n<p style=\"font-weight: 400;\">For this example, we have created a paragraph entity name &#8211; a gallery that contains 3 fields. The first field will be a select list with two options- image and document. Other fields will be image and file fields. We integrate the gallery paragraph in the Basic Page content type for representing the demo. Below are the screenshots for the paragraph and content type.<\/p>\n<p style=\"font-weight: 400;\"><strong>Screen 1 &#8211;<\/strong> Paragraph Entity with fields.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-59546\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1-1024x499.png\" alt=\"\" width=\"625\" height=\"305\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1-1024x499.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1-300x146.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1-768x375.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1-1536x749.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1-624x304.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen1.png 1743w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p style=\"font-weight: 400;\"><strong>Screen 2 &#8211;<\/strong> We\u2019ve created an entity reference field to link paragraphs in the Basic Page content type for the demo.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-59547\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2-1024x484.png\" alt=\"\" width=\"625\" height=\"295\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2-1024x484.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2-300x142.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2-768x363.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2-1536x727.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2-624x295.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen2.png 1763w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p style=\"font-weight: 400;\"><strong>Screen 3 &#8211;<\/strong> When we go to add a basic page, it will look like the one below.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-59548\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3-1024x809.png\" alt=\"\" width=\"625\" height=\"494\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3-1024x809.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3-300x237.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3-768x607.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3-1536x1213.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3-624x493.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen3.png 1842w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p>Now, we have to create a dependent field while selecting the option from the select list.<\/p>\n<p style=\"font-weight: 400;\">In <b>Drupal 9<\/b>, we use <b>hook_field_widget_WIDGET_TYPE_form_alter<\/b> in our custom module.<\/p>\n<p style=\"font-weight: 400;\">Below is a reference code from a custom module.<\/p>\n<pre>\/**\r\n* @file\r\n* Dependent fields module.\r\n*\/\r\n\r\n\r\nuse Drupal\\Core\\Form\\FormStateInterface;\r\n\r\n\r\n\/**\r\n* Implements hook_field_widget_WIDGET_TYPE_form_alter().\r\n*\/\r\nfunction demo_module_field_widget_paragraphs_form_alter(&amp;$element, FormStateInterface $form_state, $context) {\r\n \/** @var \\Drupal\\field\\Entity\\FieldConfig $fieldDefinition *\/\r\n $fieldDefinition = $context['items']-&gt;getFieldDefinition();\r\n $paragraphEntityReferenceFieldName = $fieldDefinition-&gt;getName();\r\n\r\n\r\n if ($paragraphEntityReferenceFieldName == 'field_attach_gallery') {\r\n   \/** @see \\Drupal\\paragraphs\\Plugin\\Field\\FieldWidget\\ParagraphsWidget::formElement() *\/\r\n   $widgetState = \\Drupal\\Core\\Field\\WidgetBase::getWidgetState($element['#field_parents'], $paragraphEntityReferenceFieldName, $form_state);\r\n\r\n\r\n   \/** @var \\Drupal\\paragraphs\\Entity\\Paragraph $paragraph *\/\r\n   $paragraphInstance = $widgetState['paragraphs'][$element['#delta']]['entity'];\r\n   $paragraphType = $paragraphInstance-&gt;bundle();\r\n\r\n\r\n   \/\/ Determine which paragraph type is being embedded.\r\n   if ($paragraphType == 'gallery') {\r\n     $dependeeFieldName = 'field_choose_type';\r\n     $selector = sprintf('select[name=\"%s[%d][subform][%s]\"]', $paragraphEntityReferenceFieldName, $element['#delta'], $dependeeFieldName);\r\n    \/\/ Dependent fields.\r\n     $element['subform']['field_document']['#states'] = [\r\n       'visible' =&gt; [\r\n         $selector =&gt; ['value' =&gt; 'file'],\r\n      ],\r\n     ];\r\n     $element['subform']['field_image']['#states'] = [\r\n       'visible' =&gt; [\r\n         $selector =&gt; ['value' =&gt; 'image'],\r\n       ],\r\n     ];\r\n   }\r\n }\r\n}<\/pre>\n<p style=\"font-weight: 400;\">In <b>Drupal 10<\/b>, we use <b>hook_field_widget_single_element_paragraphs_form_alter<\/b> in our custom module.<\/p>\n<p style=\"font-weight: 400;\">Below is a reference code from a custom module.<\/p>\n<pre>\/**\r\n* Implements hook_field_widget_single_element_paragraphs_form_alter().\r\n*\/\r\nfunction demo_module_field_widget_single_element_paragraphs_form_alter(&amp;$element, FormStateInterface $form_state, $context) {\r\n \/** @var \\Drupal\\field\\Entity\\FieldConfig $fieldDefinition *\/\r\n $fieldDefinition = $context['items']-&gt;getFieldDefinition();\r\n $paragraphEntityReferenceFieldName = $fieldDefinition-&gt;getName();\r\n\r\n\r\n if ($paragraphEntityReferenceFieldName == 'field_attach_gallery') {\r\n   \/** @see \\Drupal\\paragraphs\\Plugin\\Field\\FieldWidget\\ParagraphsWidget::formElement() *\/\r\n   $widgetState = \\Drupal\\Core\\Field\\WidgetBase::getWidgetState($element['#field_parents'], $paragraphEntityReferenceFieldName, $form_state);\r\n\r\n\r\n   \/** @var \\Drupal\\paragraphs\\Entity\\Paragraph $paragraph *\/\r\n   $paragraphInstance = $widgetState['paragraphs'][$element['#delta']]['entity'];\r\n   $paragraphType = $paragraphInstance-&gt;bundle();\r\n\r\n\r\n   \/\/ Determine which paragraph type is being embedded.\r\n   if ($paragraphType == 'gallery') {\r\n     $dependeeFieldName = 'field_choose_type';\r\n     $selector = sprintf('select[name=\"%s[%d][subform][%s]\"]', $paragraphEntityReferenceFieldName, $element['#delta'], $dependeeFieldName);\r\n    \/\/ Dependent fields.\r\n     $element['subform']['field_image']['#states'] = [\r\n       'visible' =&gt; [\r\n         $selector =&gt; ['value' =&gt; 'image'],\r\n      ],\r\n     ];\r\n     $element['subform']['field_document']['#states'] = [\r\n       'visible' =&gt; [\r\n         $selector =&gt; ['value' =&gt; 'file'],\r\n       ],\r\n     ];\r\n   }\r\n }\r\n}<\/pre>\n<p><span style=\"font-weight: 400;\">After the implementation of the above hooks in respective versions, we can achieve depend on fields functionality so when you select an image from the select list, then the image field display and file field will be hidden, and if you select the file option from the select list then document field will display an image field will be hidden.<\/span><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-59549\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4-1024x602.png\" alt=\"\" width=\"625\" height=\"367\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4-1024x602.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4-300x176.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4-768x451.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4-1536x902.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4-624x367.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen4.png 1842w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-59550\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5-1024x662.png\" alt=\"\" width=\"625\" height=\"404\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5-1024x662.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5-300x194.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5-768x496.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5-1536x992.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5-624x403.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen5.png 1842w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-large wp-image-59551\" src=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6-1024x662.png\" alt=\"\" width=\"625\" height=\"404\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6-1024x662.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6-300x194.png 300w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6-768x496.png 768w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6-1536x992.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6-624x403.png 624w, \/blog\/wp-ttn-blog\/uploads\/2023\/12\/Screen6.png 1842w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<h3><b>Conclusion<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">Drupal provides the best way by using hooks to make a few modifications to existing functionality. With the help of a few configurations, we can achieve complex forms and field dependency states with other field values quickly. Here, we provide hooks for Drupal 9 &amp; Drupal 10 only. Maybe in Drupal 11 or later, hook changes.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Let us know if you have any queries, and please feel free to reach out via comments.<\/span><\/p>\n<p>&nbsp;<\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction When working with complex forms, you often have fields whose state depends on the input values of other fields in the form. For example, you might have a select list of options, the options for which depend upon the value selected for another field. In this blog, I present one case study of my [&hellip;]<\/p>\n","protected":false},"author":1511,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":211},"categories":[3602],"tags":[5261,4884],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/59540"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1511"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=59540"}],"version-history":[{"count":4,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/59540\/revisions"}],"predecessor-version":[{"id":59589,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/59540\/revisions\/59589"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=59540"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=59540"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=59540"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}