Hi

I'm trying to add States in some paragraph fields, for being able to make visible some fields depending on the value of others.

Which is the best way to achive that? i've being trying with hook_entity_form_display_alter but with no luck.

Thanks in advance.
Regards.

Comments

aheredia created an issue. See original summary.

dajjen’s picture

I'm also interested in this, have tried several hooks and also tried to override paragraphwidget but no luck.

jaimecalvo’s picture

I found this one:
https://www.drupal.org/node/2868155

then you can use hook_form_paragraphs_subform_alter().

slydevil’s picture

Status: Active » Needs review

This module will allow you to do that: https://www.drupal.org/project/field_states_ui

You'll need the patch I just created as well: https://www.drupal.org/project/field_states_ui/issues/2857300

srijeeta’s picture

Field States UI worked perfectly with patch.
But for this modules returns a lot of warnings and notices.
Example:

  1. Notice: Undefined index: #required in Drupal\file\Plugin\Field\FieldWidget\FileWidget->formMultipleElements()
  2. Notice: Undefined index: #upload_validators in Drupal\file\Plugin\Field\FieldWidget\FileWidget->formMultipleElements()
  3. Notice: Undefined index: #type in drupal_process_states() (
afeijo’s picture

Here is a simple working example:

function custom_module_field_widget_entity_reference_paragraphs_form_alter(&$element, &$form_state, $context) {
  if ($element['#paragraph_type'] != 'paragraph_machine_name') {
    return;
  }
  $field_name = 'field_image';
  custom_module_paragraph_field_state($element, $field_name, 'invisible', ["value" => $value, ]); 
}


function custom_module_paragraph_field_state(&$element, $field_name, $state_key, array $conditions) {
  if (!isset($element['subform'][$field_name])) {
    return;
  }

  $variation_field = $element['subform']['field_options'];

  // construct variation input name to use it in #states
  $variation_input_name = array_shift($variation_field['widget']['#parents']);
  $variation_input_name .= '[' . implode('][', $variation_field['widget']['#parents']) . ']';
  $element['subform'][$field_name]['#states'][$state_key][':input[name="' . $variation_input_name . '"]'][] = $conditions;
}

Have fun ;)

GAMe’s picture

Hi afeijo,

Thanks for the code example. Im struggling with the same and trying to decipher what I need from this. I currently have a paragraph type with 2 fields in which I need one field to be visible if a value from the select field is set. Fields are:

Paragraph type: pg_our_food_section
Select field with values: field_food_taste_type (value = 3)
Field to show if above value is set: field_food_flavour_type

I should also add im adding this code in the .theme file rather than a custom module.

Any help or direction on getting this working would be amazing.

Thanks

:-)

afeijo’s picture

hi GAMe,

Did you follow my code? Just copy it, and change the $field_name line to your field that will be controlled

and for the field with the options, change this line to your proper field name:

$variation_field = $element['subform']['field_options'];

in my example, it is named field_options

dbgilbert’s picture

Hi afeijo,

Your example looks like exactly what I'm looking for, but inside the 'subform' object I do not see any fields for the paragraph's I'm trying to apply states to. I see it has '#attributes' and '#access' but nothing else. This is for a paragraph field that can have multiple paragraphs of different types. Each paragraph in the field triggers the widget form alter function and I can differentiate them by the '#paragraph_type' but 'subform' lists no fields in any of the many widgets.

interactivestrategies.com’s picture

Running in to the exact same issue as @dbgilbert in #9 -- "subform" has no fields in it, only #attributes and #access. I was pointed to hook_field_widget(_multivalue)_WIDGET_TYPE_form_alter() after reviewing #2868155, but something else seems to be resetting $element somehow. FWIW I'm on core 8.7.5 and Paragraphs 1.8.

natemow’s picture

Figured out the empty "subform" issue when using these hooks -- the paragraph widget settings need to be set with Edit Mode "Open"; "Closed" and "Preview" will return empty subform arrays, and just not fire at all from the AJAX edit callback. Seems to behave the same using both the Classic and Experimental widgets. Not sure I love the UX of having to leave stuff Open by default, but can work around with a bit of JS.

huberbuber’s picture

I am also having issues with this, I am trying to change the state of Field A depending in Field B inside the same paragraph. I have used the bellow code, but do not get any change.

function orange_field_widget_paragraphs_form_alter(&$element, &$form_state, $context) {
  if ($element['#paragraph_type'] != 'paragraph_apple') {
    return;
  }
  $field_name = 'A';
  orange_paragraph_field_state($element, $field_name, 'invisible', ["value" => '3']); 
}

function orange_paragraph_field_state(&$element, $field_name, $state_key, $conditions){
  if (!isset($element['subform'][$field_name])) {
    return;
  }

  $variation_field = $element['subform']['B'];

  // construct variation input name to use it in #states
  $variation_input_name = array_shift($variation_field['widget']['#parents']);
  $variation_input_name .= '[' . implode('][', $variation_field['widget']['#parents']).']';
  $element['subform'][$field_name]['#states'][$state_key][':input[name="' . $variation_input_name . '"]'][] = $conditions;
}
Poindexterous’s picture

I'm also running into some trouble with this and I've been grappling with it for a few days.

I have a paragraph with a checkbox called "field_automatic" and a select list for taxonomy called "field_blog_topic". I'd like to set this up so when "field_automatic" is checked, the "field_blog_topic" is invisible. I've modified afeijo's code accordingly but it doesn't seem to be working, though I'm not sure what I'm going wrong here:

function my_module_field_widget_entity_reference_paragraphs_form_alter(&$element, &$form_state, $context) {
  if ($element['#paragraph_type'] != 'my_paragraph_type') {
    return;
  }
  $field_name = 'field_blog_topic';
  my_module_paragraph_field_state($element, $field_name, 'invisible', ["checked" => TRUE, ]);
}


function my_module_paragraph_field_state(&$element, $field_name, $state_key, array $conditions) {

  if (!isset($element['subform'][$field_name])) {
    return;
  }
  $variation_field = $element['subform']['field_automatic'];

  // construct variation input name to use it in #states
  $variation_input_name = array_shift($variation_field['widget']['#parents']);
  $variation_input_name .= '[' . implode('][', $variation_field['widget']['#parents']) . ']';
  $element['subform'][$field_name]['#states'][$state_key][':input[name="' . $variation_input_name . '"]'][] = $conditions;
}

Looking at the object in Kint, I am seeing the #states array added to my blog_topic field, but the visibility doesn't toggle on or off when I check the "field_automatic" field. Am I overlooking something? My paragraph is using classic mode and is set to "open"

Note: I'm trying to alter the paragraph forms inside a block form and also the layout builder.

Thanks!

Berdir’s picture

Status: Needs review » Fixed

The key is an arbitrary jquery selector. If you struggle with the parents, which is indeed tricky, you could try to just add a custom class to the form element and use that to select it.

diegoluisr’s picture

The problem is related to paragraph rendering, I have the same problem, in addition, I have modified the title and description but those element doesn't see applied with the custom information.

function custom_module_field_widget_entity_reference_paragraphs_form_alter(&$element, &$form_state, $context) {
  $widget = &$element['subform']['field_conditioned']['widget'];
  $widget['#title'] = 'Altered title';
  $widget['#title_display'] = 'Altered title';
  $widget['#description'] = 'Altered description';
  
  $widget['#states']['visible'][':input[name="field_conditional"]'] = [
    'value' => $term_id,
  ];
}

Above example must work, but it hasn't

Berdir’s picture

The name is definitely not field_conditional on a paragraphs field, those field names are deeply nested.

diegoluisr’s picture

Could explain yourself?

Find below the keys when I call the array_keys function over $element['subform'], You could see that both fields (field_conditioned, field_conditional) are in the proper position.

Array
(
    [0] => #type
    [1] => #parents
    [2] => #fieldgroups
    [3] => #group_children
    [4] => #entity_type
    [5] => #pre_render
    [6] => #process
    [7] => field_conditioned
    [8] => field_conditional
    [9] => #cache
    [10] => #attributes
    [11] => #access
)

And the next code shows the array position for "#states", but this is never rendered, This is the same situation if I want to modify the title or the description. Paragraphs seem as is not getting those changes.

Array
(
    [visible] => Array
        (
            [:input[name="field_conditional"]] => Array
                (
                    [value] => 1
                )

        )

)
Berdir’s picture

I'm not sure what you mean with the correct position, but again, I'm pretty certain that this is not the complete name of the paragraph field. #states is about client-side javascript, forget the render array for a moment, and just look at the HTML and the actual name attribute of the input element you want to work with.

diegoluisr’s picture

@Berdir, Thanks a lot, your comments gave me the clues to find the issue (my mistake), In my environment `$variation_field['widget']['#parents']` doesn't exist, I don't know why, but, I solved if modifying the function that @afeijo suggested.

/**
 * Implements hook_field_widget_WIDGET_TYPE_form_alter().
 */
function custom_module_field_widget_entity_reference_paragraphs_form_alter(
  &$element,
  &$form_state,
  $context
) {
  if ($element['#paragraph_type'] == 'form_national') {

    $widget = &$element['subform']['field_dprtmnt_impleme_diff']['widget'][0];

    $widget['#title'] = 'Altered title';
    $widget['#states']['visible'][':input[name="field_have_dprtmnt_implem_diffs"]'] = [
      'value' => 1,
    ];

    paragraph_field_state($element, 'field_dprtmnt_impleme_diff', 'visible', [
      'checked' => TRUE,
    ]);
  }
}

/**
 * Auxiliar function to add state to element.
 */
function paragraph_field_state(&$element, $field_name, $state_key, array $conditions) {
  if (!isset($element['subform'][$field_name])) {
    return;
  }

  $subform = &$element['subform'];

  $parents = $subform['#parents'];
  $parents[] = 'field_have_dprtmnt_implem_diffs';
  $parents[] = 'value';

  $field_id = array_shift($parents);
  $field_id .= '[' . implode('][', $parents) . ']';
  $subform[$field_name]['#states'][$state_key][':input[name="' . $field_id . '"]'] = $conditions;
}

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.