On my website, I want to merge multiple instances of a form into one.

More specificlly, I have a set of nodes of type match, and I want my users to be able to register for all matches in one go.  I am baseing my solution on the ERF module, which enables me to design the registration form, of which I have a dynamic entity to represent the match.

The approach I've taken is to create an instance of the registration form to use as a template, and for each match, build a form that copies the widgets one by one from the template.  I then rename the widgets to be unique to the match (i.e. field_name becomes match_name||field_name).

This shows the form the way I want it to - namely, a list of every match this season with the user able to select whether or not they are available and add comments.

Issues:

1. The form_state input is populated, but not the form_state values

2. I don't know how to now push the values back into the original module to save in the relevant tables.

Any support gratefully received.

Thanks

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


$registration_list = array ();

$entity_list = \Drupal::entityTypeManager()->getDefinitions();

//Get all nodes of type match
$query = \Drupal::entityQuery('node')
->condition('status', 1) //published or not
->condition('type', 'match') //content type
;
$nids = $query->execute();

//get the default form structure
$bundle = array('type' => 'default',);
$entity = Registration::create($bundle);
$registration_form = \Drupal::service('entity.form_builder')->getForm($entity, 'default');

//cycle through all of the matches
foreach ($nids as $nid) {
$node = \Drupal\node\Entity\Node::load($nid);
$body = $node->body->value;
$title = $node->title->value;
$date = $node->field_match_date->value;

foreach ($registration_form as $key => $value)
{
$field_key = $title . '|' . $nid . '|'. $key;
if (substr($key, 0, 5) == 'field') {
//copy across the field definitions from the template form
$registration_list [$title . '.' . $key] = $registration_form [$key];
$registration_list [$title . '.' . $key] ['#sortkey'] = (date ( "Y m d", (strtotime ( $date )) ) . '.' . $nid . '.' . $registration_form [$key] ['#weight']);
$registration_list [$title . '.' . $key] ['widget'] ['#field_name'] = $field_key;
$registration_list [$title . '.' . $key] ['widget'] ['#name'] = $field_key;
$registration_list [$title . '.' . $key] ['widget'] ['#parents'] [0] = $field_key;
$registration_list [$title . '.' . $key] ['widget'] ['#array_parents'] [0] = $field_key;
//$registration_list [$title . '.' . $key] ['#tree'] = FALSE; //erase all the parents
//$registration_list [$title . '.' . $key] ['widget'] ['#tree'] = FALSE; //erase all the parents
}

if ($key == 'field_registration_match') {
//and then do some additional manipulations for the match field
$defaultvalue = array(0 => 'node-'.$nid);

$registration_list [$title . '.' . $key] ['widget'] ['#value'] = $defaultvalue;
$registration_list [$title . '.' . $key] ['widget'] ['#access'] = FALSE;

}

if (isset($registration_list [$title . '.' . $key] ['widget'] [0])) {
//likely to be a text field, so need another layer of setting the name
$registration_list [$title . '.' . $key] ['widget'] [0] ['value'] ['#name'] = $field_key . '[0][value]';
$registration_list [$title . '.' . $key] ['widget'] [0] ['value'] ['#parents'] [0] = $field_key;
$registration_list [$title . '.' . $key] ['widget'] [0] ['value'] ['#array_parents'] [0] = $field_key;
$registration_list [$title . '.' . $key] ['widget'] [0] ['#array_parents'] [0] = $field_key;
$registration_list [$title . '.' . $key] ['widget'] [0] ['#parents'] [0] = $field_key;
}

}

$registration_list [$title . '.title'] = [
'#markup' => '<H1><strong>' . $title . '</strong></H1> ' . (date ( "l, jS F Y", (strtotime ( $date )) )),
'#weight' => 0, // move to the top of the list
'#sortkey' => (date ( "Y m d", (strtotime ( $date )) ) . '.' . $nid . '.0')
];
}

//Execute the sort of the array - sort key is the date
$weight = 1;
$registration_list = $this->array_sort ( $registration_list, '#sortkey', SORT_ASC );
foreach ($registration_list as $key => $value) {
$registration_list[$key]['#weight'] = $weight;
$weight = $weight + 1;
}

 
$form ['registration_entity'] = $registration_list;
$form ['registration_entity'] ['#tree'] = FALSE;
 
$form['description'] = [
'#type' => 'item',
'#markup' => $this->t('Please enter your availability for this seasons matches'),
'#weight' => -1000000
];
 
$form['actions'] = [
'#type' => 'actions',
];

// Add a submit button that handles the submission of the form.
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Submit'),
];

return $form;
}