Require form controls to have unique name (form-dup-name)

While not strictly required by the HTML standard using the same name on multiple form controls can be confusing to read and is often an oversight by the developer. Submitting form with duplicate names are converted to arrays and some javascript frameworks assume the name is unique when serializing form data.

The form control name also plays a role in the autocomplete heurestics so using good names is important to get accurate results.

By default, radiobuttons (<input type="radio">) is generally ignored by this rule as they are typically using the same name on purpose but they cannot share the same name as other controls.

Each <form> tracks the names separately, i.e. you can have two forms with colliding names.

Rule details

Examples of incorrect code for this rule:

<form>
    <input name="foo">
    <input name="foo">
</form>
error: Duplicate form control name "foo" (form-dup-name) at inline:3:18:
  1 | <form>
  2 |     <input name="foo">
> 3 |     <input name="foo">
    |                  ^^^
  4 | </form>


1 error found.

Examples of correct code for this rule:

<form>
    <input name="foo">
    <input name="bar">
</form>

Radiobuttons

By default, radiobuttons may share the same name:

<form>
    <input name="foo" type="radio">
    <input name="foo" type="radio">
</form>

They cannot share the same name as other controls:

<form>
    <input name="foo" type="text">
    <input name="foo" type="radio">
</form>
error: Duplicate form control name "foo" (form-dup-name) at inline:3:18:
  1 | <form>
  2 |     <input name="foo" type="text">
> 3 |     <input name="foo" type="radio">
    |                  ^^^
  4 | </form>


1 error found.

See the shared option to add this behaviour for other controls.

Options

This rule takes an optional object:

{
  "allowArrayBrackets": true,
  "shared": ["radio"]
}

allowArrayBrackets

Form control names ending with [] is typically used to signify arrays. With this option names ending with [] may be shared between controls.

With this option disabled the following is incorrect:

<form>
    <input name="foo[]">
    <input name="foo[]">
</form>
error: Duplicate form control name "foo[]" (form-dup-name) at inline:3:18:
  1 | <form>
  2 |     <input name="foo[]">
> 3 |     <input name="foo[]">
    |                  ^^^^^
  4 | </form>


1 error found.

With this option enabled the following is correct:

<form>
    <input name="foo[]">
    <input name="foo[]">
</form>

shared

By default only <input type="radio"> can have a shared common name. This options lets you specify additional controls that may have a shared common name.

With this option set to the default (["radio"]) the following is incorrect:

<form>
    <input name="foo" type="checkbox">
    <input name="foo" type="checkbox">
</form>
error: Duplicate form control name "foo" (form-dup-name) at inline:3:18:
  1 | <form>
  2 |     <input name="foo" type="checkbox">
> 3 |     <input name="foo" type="checkbox">
    |                  ^^^
  4 | </form>


1 error found.

With this option set to ["radio", "checkbox"] the following is correct:

<form>
    <input name="foo" type="checkbox">
    <input name="foo" type="checkbox">
</form>

The name cannot be shared between different types of controls:

<form>
    <input name="foo" type="checkbox">
    <input name="foo" type="radio">
</form>
error: Duplicate form control name "foo" (form-dup-name) at inline:3:18:
  1 | <form>
  2 |     <input name="foo" type="checkbox">
> 3 |     <input name="foo" type="radio">
    |                  ^^^
  4 | </form>


1 error found.

Metadata

This rule check all elements marked as formAssociated with the listed property.

To use with custom elements set the listed property to true:

const { defineMetadata } = require("html-validate");

module.exports = defineMetadata({
  "custom-element": {
    formAssociated: {
      listed: true,
    },
  },
});

Version history