Score:0

Render Submitted Fields of a Form to Email with Title + Value

in flag

I have a quite complex form based on \Drupal\Core\Form\FormBase with many (partially nested) fields and want to send the full contents in an email on submit.

Currently I have

public function submitForm(array &$form, FormStateInterface $form_state)
{

   foreach ($form_state->getValues() as $key => $value) {
     if (!empty($form[$key]['#title']) && $key != 'images') {
       $values[$form[$key]['#title']->render()] = $value;
     }
   }
...
# later I will format the $values array as a HTML list

This would only show fields on the top-level of the form, but I have fields within groups.

Is there a nice and clean way to render all the field's values? Or do I have to iterate and parse manually over the $form array?

Could I even use a renderer for this?

EDIT:

public function buildForm(array $form, FormStateInterface $form_state) {


    // ...

    $form['company'] = [
        '#type' => 'container',
    ];

    $form['company']['nameofcompany'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Name of Company'),
    ];

To sum it up:

How can I iterate over all the fields, including those which are in containers and get the values + the label (not only the technical name)? Are there some nice helpers for this or do I have to do it all manually?

apaderno avatar
us flag
That code would not work and it doesn't make sense. Why do you need `$form[$key]['#title']` to access a value in `$form_state`? Furthermore, since `$form[$key]['#title']` is a string, it doesn't implement any `render()` method.
apaderno avatar
us flag
It would also help to see the code building the form. It's not clear what you mean by *groups* and if *fields* means *form elements*.
in flag
the code currently does work, #title is an object, I believe that's because the form is already built. My only problem is to iterate over all form elements, because they are nested in groups. I add some example code how the initial $form array is built.
apaderno avatar
us flag
Without seeing all the form elements, it's not possible to understand what you mean by *groups*. As for the shown code, it's sufficient to use `'nameofcompany'`, not what returned by `$this->t('Name of Company')`. You already have `$values['nameofcompany']`; you don't need `$values[$this->t('Name of Company')]` set to the same value.
in flag
I need the labels, not the internal names
in flag
I have edited the question - with groups I mean containers. See the sample code. Does this make it more clear? Let me know, if you have questions.
in flag
@apaderno I posted an answer ... but I am wondering if there is a nicer - not so low-level - way.
Score:0
in flag

This is what I came up with, I am just wondering if there is a more elegant way, than this "low-level" parsing

/**
 * Return an array with labels as keys, submitted values as values, based on the original form
 *
 * @param FormStateInterface $form_state
 * @return array
 */
private function generateLabelsWithValues(FormStateInterface $form_state): array {
  $form = $form_state->getCompleteForm();
  $result = $this->iterateAndAddValues($form, $form_state);
  return $result;
}

/**
 * Iterate over form or container and add up the values
 */
private function iterateAndAddValues(array $formOrContainer, FormStateInterface $form_state, array $result = []) {
  foreach ($formOrContainer as $key => $element) {
    if ($key[0] === '#' || $key === 'form_build_id' || $key === 'form_id' || $key === 'submit') {
      continue;
    }
    if ($element['#type'] === 'container' || $element['#type'] === 'fieldset') {
      $result = $this->iterateAndAddValues($element, $form_state, $result);
      continue;
    }

    if ($value = $form_state->getValue($key)) {
      $result[(string)$element['#title']] = $value;
    }
  }

  return $result;
}
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.