0

I'm new to Drupal and still have to figure out a lot. This might also be just a general programming question.

I wrote a module that has some js-libraries which should be attached to forms on different conditions. For one of those libraries, I want to add it in case the form array has an element with the class "remove-button", which could be at any depth.

I searched for different recursive approaches, but it doesn't work somehow. I was able to attach the library without a condition so it attaches to all forms, so the problem lies within my recursive function.

Snippet from hook_form_alter in my .module file:

function my_module_form_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id)
{
  // remove-button
  $hasRemoveButton = containsClass($form, 'remove-button');
  if ($hasRemoveButton) {
    $form['#attached']['library'][] = 'my_module/remove-button';
  }
}

Recursive search function (last code I tried):

/**
 * Search a class in $form.
 */
function containsClass($array, $class)
{
  if (!is_array($array)) {
    return false;
  }
  if (isset($array['class']) && in_array($class, $array['class'])) {
    return true;
  }
  foreach ($array as $subarray) {
    containsClass($subarray, $class);
  }
}

Anyone an idea how this can be achieved? Maybe with a different approach than a recursion?

2
  • If you can use xdebug to step through your code while you execute you can have a clear view of what part is doing what you expect and what not. I'd say also you should have an 'else' in your 'if' to return FALSE otherwise your containsClass function might not return anything.
    – wranvaud
    Apr 9, 2020 at 12:55
  • Yes, this is probably off-topic. I don't think your containsClass function returns a boolean in all cases.
    – mradcliffe
    Apr 10, 2020 at 13:10

1 Answer 1

0

You can try this for your recursive function.

function containsClass($array, $class) {
  if (is_array($array)) {
    if (in_array($class, $array['class'])) {
      return true;
    }

    foreach ($array as $element) {
      if (containsClass($element, $class)) {
        return TRUE;
      }
    }
  }

  return FALSE;
}

The problem with your function was that it's not returning the result of containsClass() when it's called recursively. However, you only want to return the value if it's TRUE, which is why I added the conditional to check that. Finally, after all items have been looped through, if no TRUE value is found, FALSE should be returned.

2
  • 1
    Thank you so much, this worked! There was only an "undefined index" error which was quickly solved by adding an isset() check on $array['class']. I will definitely have to improve my recursion skills :)
    – mly
    Apr 9, 2020 at 18:06
  • Glad it worked. Recursive functions are a bit tricky to wrap your head around. You were almost there!
    – Jaypan
    Apr 9, 2020 at 18:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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