48

Is it legal to have an HTML form with more than one "hidden" control element with the same name? I expect to get the values of all of these elements at the server. If it is legal, do the major browsers implement the behavior correctly?

Brian
  • 1,281
  • 2
  • 14
  • 26

8 Answers8

36

The browsers are OK with it. However, how the application library parses it may vary.

Programs are supposed to group identically named items together. While the HTML specification doesn't explicitly say this, it is implicitly stated in the documentation on checkboxes:

Several checkboxes in a form may share the same control name. Thus, for example, checkboxes allow users to select several values for the same property.

Powerlord
  • 82,184
  • 16
  • 119
  • 164
  • 8
    Side note (6 years later): ASP.NET uses hidden form fields alongside its checkbox controls so that it knows the checkbox controls exist. This is a workaround for HTML not sending the named of unchecked checkboxes. – Powerlord Jan 20 '15 at 14:59
26

Different server-side technologies will vary. With PHP, you can use an array-style syntax for the name to force a collection to be created on the server-end. If posted to the server, $_POST['colors'] will be an array with two values, #003366 and #00FFFF:

<input type="hidden" name="colors[]" value="#003366" />
<input type="hidden" name="colors[]" value="#00FFFF" />

Generally speaking, you'll want to use a standard name without square brackets. Most server-side technologies will be able to parse the resulting data, and provide a collection of some type. Node.js provides helpful functionality via querystring.parse:

const querystring = require('querystring')

querystring.parse('foo=bar&abc=xyz&abc=123') // { foo: 'bar', abc: ['xyz', '123'] }
Sampson
  • 251,934
  • 70
  • 517
  • 549
  • 1
    I've never seen that array syntax before. – Brian Jan 16 '09 at 21:30
  • 3
    If you are passing a collection of related details through to the server, this method is extremely helpful in that it allows them to travel as a group, rather than numerous independent values. – Sampson Jan 16 '09 at 21:32
  • 15
    The thing with the square brackets is PHP's invention, not any kind of web standard. Other languages and form-reading libraries have different mechanisms for accessing multiple submissions with the same name, not necessarily involving changing the name like this. – bobince Jan 16 '09 at 22:15
  • 2
    In ASP.net you can get the posted value array by calling `Request.Form.GetValues`. For example: `string[] postedValues = Request.Form.GetValues("name_of_the_elements");` Or `Request.QueryString.GetValues("name_of_the_elements")`. – Akos Lukacs Jun 28 '12 at 10:42
  • How can I serialize this group in javascript ? I want to pass this group of values threw ajax ? – TIGER Nov 21 '15 at 13:40
  • 1
    7 years now, does this still work? Does this array technique work with other server-side technologies like node.js for example? – iWillGetBetter Oct 10 '16 at 13:02
  • 1
    @iWillGetBetter I think this was PHP only (or very uncommon). Node provides a helpful functionality by way of `querystring.parse` that will merge multiple values like this into an array: https://nodejs.org/api/querystring.html#querystring_querystring_parse_str_sep_eq_options – Sampson Oct 11 '16 at 06:04
  • @AkosLukacs your comment deserves to be an answer :) – hardkoded Dec 31 '18 at 20:19
19

If you have something like this:

<input type="hidden" name="x" value="1" />
<input type="hidden" name="x" value="2" />
<input type="hidden" name="x" value="3" />

Your query string is going to turn out looking like x=1&x=2&x=3... Depending on the server software you are using to parse the query string this might not work well.

DavGarcia
  • 17,702
  • 14
  • 52
  • 94
  • 5
    Do you know if the ordering is specified? I only found that it will be a sequence, but not that is ordered in the way it is declared. So could it be that you get `x=2&x=3&x=1`? – niels Sep 16 '10 at 06:31
  • 7
    order is preserved: http://stackoverflow.com/questions/4027635/do-browsers-preserve-order-of-inputs-with-same-name-on-get-post – Jarrett Aug 30 '12 at 20:06
  • 9
    In case anyone is wondering, PHP will **always** use the value from the last input element with this type of example – shea Mar 13 '13 at 05:23
5

Yes, and most application servers will collect the matching elements and concatenate them with commas, such that a form like this:

<html>
<form method="get" action="http://myhost.com/myscript/test.asp">
<input type="hidden" name="myHidden" value="1">
<input type="hidden" name="myHidden" value="2">
<input type="hidden" name="myHidden" value="3">
<input type="submit" value="Submit">
</form>
</html>

... would resolve to a URL (in the GET case -- POST would work the same way, though) like this:

http://myhost.com/myscript.asp?myHidden=1&myHidden=2&myHidden=3

... and would be exposed to you in code like this: (e.g., following something like Response.Write(Request.QueryString("myHidden")):

1, 2, 3

So to grab the values, you'd just split the string and access them as an array (or whatever's comparable in your language of choice).

(Should be clarified: In PHP, it's slightly different (as Johnathan points out, bracket notation exposes the items as an array to your PHP code), but ASP, ASP.NET, and ColdFusion all expose the values as a comma-separated list. So yes, the duplicate naming is completely valid.)

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Christian Nunciato
  • 9,968
  • 1
  • 32
  • 44
  • 1
    Sorry, I should've been more specific: "everything except PHP." ;) ASP, ASP.NET, CF all operate this way. PHP privileges the final item in the list, unless the bracket notation is specified, as Johnathan mentions in his answer. The point is that the HTML syntax is valid. – Christian Nunciato Jan 16 '09 at 22:53
  • 1
    Added the PHP note for clarification. – Christian Nunciato Jan 16 '09 at 22:58
  • 12
    So everything except PHP, Perl CGI.pm, Python cgi.py, htmlform, django etc., Ruby on Rails, Java Servlet... – bobince Jan 17 '09 at 10:22
  • I thought CGI.pm worked this way -- certainly it does for checkboxes. My current experiments with CGI::Application (which lead me to this question in the first place) now seem to agree. – James Green Nov 02 '11 at 17:11
  • If you're using asp.net, and you want to get individual values without commas, you can use `request.QueryString.GetValues("myHidden")` to return an array. http://msdn.microsoft.com/en-us/library/4ba5htte%28v=vs.90%29.aspx – Matthew May 01 '13 at 16:53
2

HTML5

The non-normative section 4.10.1.3 Configuring a form to communicate with a server explicitly says that it is valid:

Multiple controls can have the same name; for example, here we give all the checkboxes the same name, and the server distinguishes which checkbox was checked by seeing which values are submitted with that name — like the radio buttons, they are also given unique values with the value attribute.

The normative version of this is simply that it is not forbidden anywhere, and the form submission algorithm says exactly what request should be generated:

2

Specifically for PHP I made some tests with array names in hidden inputs and I share here my results:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Post Hidden 2D Arrays</title>
  </head>
  <body>
    <form name="formtest" method="POST" target="_self">
      <input type="hidden" name="elem['name'][]" value="first">
      <input type="hidden" name="elem['name'][]" value="second">
      <input type="hidden" name="elem['name'][]" value="third">
      <input type="hidden" name="elem['name'][]" value="fourth">
      <input type="hidden" name="elem['type'][]" value="normal">
      <input type="hidden" name="elem['type'][]" value="classic">
      <input type="hidden" name="elem['type'][]" value="regular">
      <input type="hidden" name="elem['type'][]" value="basic">
      <input type="hidden" name="elem['size'][]" value="4">
      <input type="hidden" name="elem['size'][]" value="7">
      <input type="hidden" name="elem['size'][]" value="3">
      <input type="hidden" name="elem['size'][]" value="6">
      <input type="hidden" name="elem['form'][]" value="triangle">
      <input type="hidden" name="elem['form'][]" value="square">
      <input type="hidden" name="elem['form'][]" value="hexagon">
      <input type="hidden" name="elem['form'][]" value="circle">
      <input type="submit" name="sendtest" value="Test">
    </form>
    <xmp>
<?php
    print_r($_POST);
?>
    </xmp>
  </body>
</html>

Submitting the form generates the next result:

Array
(
[elem] => Array
    (
        ['name'] => Array
            (
                [0] => first
                [1] => second
                [2] => third
                [3] => fourth
            )
        ['type'] => Array
            (
                [0] => normal
                [1] => classic
                [2] => regular
                [3] => basic
            )
        ['size'] => Array
            (
                [0] => 4
                [1] => 7
                [2] => 3
                [3] => 6
            )
        ['temp'] => Array
            (
                [0] => triangle
                [1] => square
                [2] => hexagon
                [3] => circle
            )
    )
[sendtest] => Test
)

After viewing this result I made more tests looking a better arrange of array values and ended with this (I will show only the new hidden inputs):

    <input type="hidden" name="elem[0]['name']" value="first">
    <input type="hidden" name="elem[1]['name']" value="second">
    <input type="hidden" name="elem[2]['name']" value="third">
    <input type="hidden" name="elem[3]['name']" value="fourth">
    <input type="hidden" name="elem[0]['type']" value="normal">
    <input type="hidden" name="elem[1]['type']" value="classic">
    <input type="hidden" name="elem[2]['type']" value="regular">
    <input type="hidden" name="elem[3]['type']" value="basic">
    <input type="hidden" name="elem[0]['size']" value="4">
    <input type="hidden" name="elem[1]['size']" value="7">
    <input type="hidden" name="elem[2]['size']" value="3">
    <input type="hidden" name="elem[3]['size']" value="6">
    <input type="hidden" name="elem[0]['temp']" value="triangle">
    <input type="hidden" name="elem[1]['temp']" value="square">
    <input type="hidden" name="elem[2]['temp']" value="hexagon">
    <input type="hidden" name="elem[3]['temp']" value="circle">

Obtaining this result after submitting form:

Array
(
[elem] => Array
    (
        [0] => Array
            (
                ['name'] => first
                ['type'] => normal
                ['size'] => 4
                ['temp'] => triangle
            )
        [1] => Array
            (
                ['name'] => second
                ['type'] => classic
                ['size'] => 7
                ['temp'] => square
            )
        [2] => Array
            (
                ['name'] => third
                ['type'] => regular
                ['size'] => 3
                ['temp'] => hexagon
            )
        [3] => Array
            (
                ['name'] => fourth
                ['type'] => basic
                ['size'] => 6
                ['temp'] => circle
            )
    )
[sendtest] => Test
)

I hope this helps a few.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Melo Waste
  • 141
  • 1
  • 8
0

I believe it is legal, at least in cases of radio buttons and check boxes. When I have to dynamically add textbox inputs in XSLT, I give them all the same name; in ASP.NET, Request.Form["whatever_name"] is a string of all these values comma-seperated.

0

I have just tried using the same control name, counties[] for several SELECT inputs so that counties in England, Scotland, Wales and Ireland in each are are all passed as values for the same parameter. PHP handles it fine, but HTML validator gives a warning. I don't know if all browsers would handle this the same way.

Nick Iredale
  • 69
  • 2
  • 11