Dots in form keys don't work

Created on 9 November 2015, over 9 years ago
Updated 9 February 2023, about 2 years ago

Problem/Motivation


    $form['foo.cc'] = [
      '#type' => 'textfield',
      '#title' => $this->t('CC address'),
      '#default_value' => $settings->get('foo.cc'),
    ];

When this form is submitted the form values are empty, when foo.cc is replaced with foo_cc, it works.

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

EDIT by cFreed

Sorry to intervene in the original post: a comment offers not enough space for what I want to show.
Currently porting a Drupal 7 module, I just fell into this problem and I don't agree with currently existing comments.

First let me say why this limitation is important to me (and possibly to many other developers).

In the D7 version of my module's configuration forms, I'd normalize the form keys names using the following rules:

  • say there is some fieldset key "foo" wrapping two input keys "bar" and "baz"
  • then I defined constants such as:
      define('MYMODULE_FOO_BAR', 'foo_bar');
      define('MYMODULE_FOO_BAZ', 'foo_baz');
  • these constants are used as key names in forms, but also in the definition of default configuration values, and finally again everywhere variable_get() and variable_set() are used
  • so it results in consistent and readable code:
    • in hook_form(), e.g.:
        $form['foo']['MYMODULE_FOO_BAR] = array(
          '#type' => 'radios',
          '#title' => ...,
          '#description' => ...,
          '#options' => array(...),
          '#default_value' => variable_get(MYMODULE_FOO_BAR, MYMODULE_default('MYMODULE_FOO_BAR)),
        );
      
    • in hook_install(), e.g.:
      variable_get(MYMODULE_FOO_BAR, MYMODULE_default('MYMODULE_FOO_BAR));

So when porting this to Drupal 8 and adapting it to the new configuration system:

  • the YAML default configuration values becomes naturally
    foo:
      bar: 'default for bar'
      baz: 'default for baz'
  • from that, the obvious consistent way is to write the form class like this:
    namespace Drupal\Mymodule\Form;
    use Drupal\Core\Form\ConfigFormBase;
    use Drupal\Core\Form\FormStateInterface;
    
    class MymoduleSomeForm extends ConfigFormBase{
      
      const FOO_BAR = 'foo.bar';
      const FOO_BAZ = 'foo.baz';
      
      public function buildForm(array $form, FormStateInterface $form_state) {
        
        $config = $this->config('mymodule.someform');
        
        $form['foo']['FOO_BAR] = array( // <-- #1
          '#type' => 'radios',
          '#title' => ...,
          '#description' => ...,
          '#options' => array(...),
          '#default_value' => $config->get(self::FOO_BAR), // <-- #2
        );
        
        return parent::buildForm($form, $form_state);
      }
    }
    

But if dot is not allowed in form keys, every instance like #1 above must be changed for its underscore'd version, while #2 must be keeped as is.
Please note that in my real example this regards 16 keys in 3 distinct forms: I'm not crying because of the corresponding work, but imagine how readability and consistency are deteriorated!

Now I want point out what puzzles me about the currently invoked reasons to let this limitation live for now.

In the generated output HTML form, an input like 'foo.bar' looks like this:

<input type="radio" class="form-radio" checked="checked" value="0"
  name="foo.bar" id="edit-foobar-0"
  aria-describedby="edit-uioptionsraw--description" data-drupal-selector="edit-uioptionsraw-0">

I observe that the input name is still "foo.bar" here, while the input id already lost its dot.
This means that at this stage it is possible to systematically scan every key name and replace any dot by a carefully chosen pattern. Then the inverse could apply at the top of the validate_form(), confirm_form(), and submit_form() functions, before data is potentially offered to the user-derived ConfigFormBase class equivalent functions.

Maybe I'm missing some complexity (or even something obvious!)?

πŸ› Bug report
Status

Postponed: needs info

Version

9.5

Component
FormΒ  β†’

Last updated 1 day ago

Created by

πŸ‡©πŸ‡ͺGermany dawehner

Live updates comments and jobs are added and updated live.
  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request β†’ as a guide.

    Could some update the issue summary with steps to reproduce and proposed solution.

    I tested on D10 with a textfield by adding "test.test" and it saved fine.

  • Status changed to Closed: cannot reproduce 11 days ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Since there hasn't been a follow up in 2+ years going to close out as can't reproduce. If still an issue in D11 please re-open.

Production build 0.71.5 2024