I have a custom Drupal 8 form that shows a list of users and a "check" button for each user.
When clicking a check button, the submit handler needs to figure out which users "check" button was clicked.
I've tried this the following way, but it always returns the id of the last element instead of the correct element.
Is this a bug in Drupal Core Form API?
Any other way to do this? I'm open to suggestions!
This is just an example. What I'm actually trying to do is show a list of users that belong to a specific 'company' node. In that list there is a 'remove from company' button for each user.
<?php
namespace Drupal\form_multi_submit\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\User;
class MultiSubmitForm extends FormBase {
public function getFormId() {
return 'MultiSubmitForm';
}
public function buildForm(array $form, FormStateInterface $form_state) {
// Get all users from database
$ids = \Drupal::entityQuery('user')
->condition('status', 1)
->execute();
$users = User::loadMultiple($ids);
// Set form table header
$form['users'] = array (
'#type' => 'table',
'#header' => array('ID', 'Remove'),
);
// Loop through all users
foreach ($users as $user) {
// Show user ID
$form['users'][$user->id()]['id'] = array(
'#type' => 'label',
'#title' => $user->id(),
);
// Show button for each user
$form['users'][$user->id()]['removememberbutton']['dummyNode'] = array(
'#type' => 'submit',
'#value' => 'Check',
'#submit' => array([$this, 'removeMember']),
);
}
return $form;
}
// Submit handler
public function removeMember(array &$form, FormStateInterface $form_state) {
$userid = $form_state->getTriggeringElement()['#array_parents'][1];
drupal_set_message($userid, 'status');
}
public function validateForm(array &$form, FormStateInterface $form_state) {
// Nothing to do here.
}
public function submitForm(array &$form, FormStateInterface $form_state) {
// Nothing to do here.
}
}
Drupal considers buttons with the same #value as the same button, unless they have a different #name
So all I had to do was add a unique #name to my buttons to get this to work properly:
$form['users'][$user->id()]['dummyNode-' . $user->id()] = array(
'#type' => 'submit',
'#value' => 'Check',
'#name' => 'check_' . $user->id(),
'#submit' => array([$this, 'removeMember']),
);