2

I can't seem to retrieve correct posted checkbox form element values using an array-style key in a call to the FormState::getValue method. If I flatten the elements into a non-nested structure, the getValue method works. But, I need to lay out the components using a table form element. The values that I get back (empty or "0") do not match the actual user-checked box states by the time they post in submitForm. I've also tried a zillion variants of reversed #parent array hints, #array_parent hints, #return_value, etc. It feels like there may be a bug in the getValues method in how it handles array-style keys? Or, am I doing something dumb?

class DataFsFolderSharingForm extends ContentEntityForm {

  // … stripped down to the bare essentials...

  public function buildForm(array $form, FormStateInterface $form_state, DataFsFolderInterface $folder = NULL) {
    // Documentation for for element attributes (eg: '#parents’, '#array_parents’, '#return_value’, etc):
    //   @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21FormElement.php/class/FormElement/8.2.x

    $form = [];
    $form['#tree'] = TRUE;

    // Show the current access settings as a table.
    //   @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Table.php/class/Table/8.2.x
    $form['access'] = [
      '#type'    => 'table',
      '#caption' => $this->t('Sharing Access'),
      '#header'  => [
        $this->t('User Email'),
        $this->t('View'),
        $this->t('Edit'),
        $this->t('Operation'),
      ],
      // '#array_parents' => array( 'access' ),
      // '#name' => 'access',
    ];

    // Non-nested element structure doesn’t break getValue method.
    $form['flat'] = [
      '#type' => 'checkbox',
      // '#name' => 'check-2',
      // '#return_value' => 1,
      // '#default_value' => 1,
      // '#array_parents' => array( 'flat' ),
    ];

    // Nested element structure breaks getValue method.
    //   @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Render%21Element%21Table.php/class/Table/8.2.x
    $form['access'][0]['view'] = [
      '#type'          => 'checkbox',
      // '#name' => 'check-1',
      // '#return_value' => 1,
      '#default_value' => 1,
      // '#array_parents' => array( 'access', 0, 'view' ),
    ];

    // ...more table elements added, who's rows are indexed by the middle integer array value...

    return $form;
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    // The non-nested getValue returns the correct checkbox state (checked or unchecked).
    $checked = $form_state->getValue('flat');

    // The nested getValue returns the incorrect checkbox state (checked or unchecked).
    //  @see https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormState.php/function/FormState%3A%3AgetValue/8.2.x
    $checked = $form_state->getValue(['access', 0, 'view']);

    // Also tried ['access', '0', 'view’ ]
    // Also tried ['view’, 0, 'access’ ]
    // Also tried ['view’, '0', 'access’ ]
    // Also tried setting '#parents’ form element attribute.
    // Also tried not setting '#array_parents’ form element attribute.
    // Also tried reversed version of '#parents’ form element attribute.
    // Also tried reversed version of '#array_parents’ form element attribute.
    // Also tried setting '#return_value’ form element attribute (using 1, 0, TRUE, FALSE, '0’, '1’, etc).
    // Also tried setting '#default_value’ form element attribute (using 1, 0, TRUE, FALSE, '0’, '1’, etc).
  }
}
  • Have you tried with a string not a number 0. like array('access', 'one', 'view') ? What returns FormState->getValues() ? – rémy May 25 '16 at 20:45
1

Anyone still having this problem please allow collections of form elements using #tree set to TRUE. Its applied to the "parent" element, as the #tree property cascades to sub-elements. Use where you previously used in form calls. See D7 #tree and #parents on drupal.org.

Solution

Example for above case, change $form['#tree'] = TRUE; to $form['access']['#tree'] = TRUE; then the value will be obtained using $checked = $form_state->getValue(['access', 0, ‘view']);.

0

It appears that ContentEntityForm ignores all posted form element values for anything but the intrinsic fields of the entity. I switched to sub-classing the FormBase class and the getValue calls started returning values reflected by user-entered form values as expected.

  • 2
    What do you mean by sub-classing, I'm running into the same issue. – hugronaphor Aug 8 '17 at 18:59
  • 1
    Could you please extend your answer to add some working code snippet? – leymannx Aug 26 '18 at 6:16

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.