0

I'm working on a project where I'm programmatically cherry picking elements from a webform and then creating a custom form with all sorts of alterations and additions to the "cloned" webform fields.

$my_custom_field = $webform->getElement($webform_field_id, TRUE);

I'm then rendering a number of custom fields like the above in a custom form that extends from FormBase. The custom webform consists of fields, custom containers, attributes etc.

Everything works fine, #states included, apart from the "pattern" state and a few other states that are based on relative values e.g. "greater" / "greater_equal" / "lower" / "lower_equal". I'm adding these #states programmatically to the custom fields.

Example:

$custom_field['#states'] = [
  'visible' => [
    ':input[name="controlling_field_name"]' => [
      'value' =>
        // I've tested this pattern, it works in the webform field fine.
        'pattern' => $some_regex_pattern,
      ],
    ],
  ],
];

Apart from 'pattern', I've tried 'between' and 'greater', 'greater_equal', 'lower' and 'lower_equal' with no success.

The same exact #states (same field being dependant on same controlling field under the same exact conditions) work fine on the original webform field (when I view the webform on the admin theme for example) which makes me think that something is missing from / messing up with these #states on my custom theme.

No JS errors in the console whatsoever.

The structure of "data-drupal-states" when I render this custom field (webform field "clone") in my custom theme is exactly the same as the webform field that's rendered on the admin theme ie in its "native" webform.

Other #states work fine for the custom field ("value", "checked" etc.).

Any ideas on what's possibly messing up these specific states?

1

Webform form elements have additional goodies, not available in Drupal Core. But you can add those additional features with just a few lines of code:

<?php
public function buildForm(array $form, FormStateInterface $form_state) {
 $config = $this->config('custom_module');
 // Define the element(s).
 $form['nodes'] = [
   '#type' => 'entity_autocomplete',
   '#title' => $this->t('Select favorite articles.'),
   '#multiple' => 15,
   '#target_type' => 'node',
   '#selection_handler' => 'default:node',
   '#selection_settings' => [
     'target_bundles' => ['article' => 'article'],
     'sort' => ['field' => 'title', 'direction' => 'ASC'],
   ],
   '#default_value' => $config->get('nodes'),
 ];
 // Process the element(s).
 $this->elementManager->processElement($form['nodes']);
 // Attach behaviors. Unsaved: Warn users about unsaved changes.
 $form['#attributes']['class'][] = 'js-webform-unsaved';
 $form['#attached']['library'][] = 'webform/webform.form.unsaved';
 return parent::buildForm($form, $form_state);
}

Notice the elementManager->process() and the additional libraries. Watch the video in the linked blog post to get an idea where to get the elementManager and the libraries.

https://www.jrockowitz.com/blog/webform-apis

1
  • Thanks for your answer, adding 'webform/webform.states' and 'webform/webform.element.states' libraries on top of 'webform/webform.form' to my custom form did the job.I find it weird that most #states worked fine before that but not 'pattern'. Thanks for your answer!
    – webmaniac
    Nov 22 '20 at 18:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.