Disabled form inputs do not appear in the request
Asked Answered
N

14

428

I have some disabled inputs in a form and I want to send them to a server, but Chrome excludes them from the request.

Is there any workaround for this without adding a hidden field?

<form action="/Media/Add">
    <input type="hidden" name="Id" value="123" />

    <!-- this does not appear in request -->
    <input type="textbox" name="Percentage" value="100" disabled="disabled" /> 

</form>
Novia answered 9/9, 2011 at 4:47 Comment(0)
G
872

Elements with the disabled attribute are not submitted or you can say their values are not posted (see the second bullet point under Step 3 in the HTML 5 spec for building the form data set).

I.e.,

<input type="textbox" name="Percentage" value="100" disabled="disabled" /> 

FYI, per 17.12.1 in the HTML 4 spec:

  1. Disabled controls do not receive focus.
  2. Disabled controls are skipped in tabbing navigation.
  3. Disabled controls cannot be successfully posted.

You can use readonly attribute in your case, by doing this you will be able to post your field's data.

I.e.,

<input type="textbox" name="Percentage" value="100" readonly="readonly" />

FYI, per 17.12.2 in the HTML 4 spec:

  1. Read-only elements receive focus but cannot be modified by the user.
  2. Read-only elements are included in tabbing navigation.
  3. Read-only elements are successfully posted.
Gardy answered 9/9, 2011 at 4:59 Comment(10)
To answer my own question: No, readony only works for <input/> form control of type='text' and type='password' and for <textarea/>. What readonly does is preventing the user from changing the controls value. Preventing the user from changing value of a checkbox (or input of type radio) does not make much sense...Floating
@danielson317 You can keep the select element "disabled" but also add another hidden input with the same value.Gardy
@AlphaMale But the hidden element cannot have the same name (or shouldn't). I got past this by allowing the element to be empty and just puling the original value from the saved form state. It's just worth noting readonly does not work on select form items.Costanzo
Unfortunately hidden input's still sends data even if they are wrapped into disabled container... (Pedant
readonly doesn't work for checkboxes. It looks disabled, but the user can still modify it.Adductor
@Costanzo It doesn't need the same name, the disabled select can have any name (as it is not submitted) the hidden field should have the true name (the one you want in the request)Thrasher
Hi Googler, Lemme save you a few keystrokes. caniuse.com/#search=readonlyHumboldt
Do you ever find something out and think, "What in the heck made them think this would be obvious?" If I go to the trouble of including an input field that may or may not be disabled, that means I don't want the user to change it, not that it should effectively act as if it was never declared at all!Placidia
Thank you this was helpful and both the answer and the response.Sahara
@NickBedford, especially when you think "Ooh, I can deal with this quickly and safely by adding the disabled attribute."Shape
M
25

Using Jquery and sending the data with ajax, you can solve your problem:

<script>

$('#form_id').submit(function() {
    $("#input_disabled_id").prop('disabled', false);

    //Rest of code
    })
</script>
Millett answered 21/1, 2014 at 13:11 Comment(5)
+1 the good thing about this solution is that you can still using the red disable icon when user over the input =)Weariless
@ArielMaduro you can do that with css cursor:not-allowed;Outrage
@Outrage oh really?? Can you provide an example?Weariless
like this solution more than use readonly, because disabled fields can't receive focusErl
Note, this solution doesn't work if Javascript is turned off. It is better to use the "readonly" feature which is native HTML.Gosling
M
14

To post values from disabled inputs in addition to enabled inputs, you can simply re-enable all of the form's inputs as it is being submitted.

<form onsubmit="this.querySelectorAll('input').forEach(i => i.disabled = false)">
    <!-- Re-enable all input elements on submit so they are all posted, 
         even if currently disabled. -->

    <!-- form content with input elements -->
</form>

If you prefer jQuery:

<form onsubmit="$(this).find('input').prop('disabled', false)">
    <!-- Re-enable all input elements on submit so they are all posted, 
         even if currently disabled. -->

    <!-- form content with input elements -->
</form>

For ASP.NET MVC C# Razor, you add the submit handler like this:

using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post,
    // Re-enable all input elements on submit so they are all posted, even if currently disabled.
    new { onsubmit = "this.querySelectorAll('input').forEach(i => i.disabled = false)" } ))
{
    <!-- form content with input elements -->
}
Mackintosh answered 14/3, 2018 at 15:40 Comment(1)
there is a missing one of quotes on jquery optionBrundage
A
9

If you absolutely have to have the field disabled and pass the data you could use a javascript to input the same data into a hidden field (or just set the hidden field too). This would allow you to have it disabled but still post the data even though you'd be posting to another page.

Ardis answered 19/7, 2013 at 17:39 Comment(1)
This solution is what Ive been using too - but as I just learned - the readonly property is a far better solutionFloating
G
6

I'm updating this answer since is very useful. Just add readonly to the input.

So the form will be:

<form action="/Media/Add">
    <input type="hidden" name="Id" value="123" />
    <input type="textbox" name="Percentage" value="100" readonly/>
</form>
Grande answered 28/5, 2014 at 17:30 Comment(1)
This not work with select elements.Tittivate
D
4

I find this works easier. readonly the input field, then style it so the end user knows it's read only. inputs placed here (from AJAX for example) can still submit, without extra code.

<input readonly style="color: Grey; opacity: 1; ">
Dzoba answered 20/9, 2018 at 23:21 Comment(0)
T
4

Semantically this feels like the correct behaviour

I'd be asking myself "Why do I need to submit this value?"

If you have a disabled input on a form, then presumably you do not want the user changing the value directly

Any value that is displayed in a disabled input should either be

  1. output from a value on the server that produced the form, or
  2. if the form is dynamic, be calculable from the other inputs on the form

Assuming that the server processing the form is the same as the server serving it, all the information to reproduce the values of the disabled inputs should be available at processing

In fact, to preserve data integrity - even if the value of the disabled input was sent to the processing server, you should really be validating it. This validation would require the same level of information as you would need to reproduce the values anyway!

I'd almost argue that read-only inputs shouldn't be sent in the request either

Happy to be corrected, but all the use cases I can think of where read-only/disabled inputs need to be submitted are really just styling issues in disguise

Thrasher answered 4/10, 2018 at 14:49 Comment(5)
not to forget that it's value can be manipulated with the chrome developer tools directlyThrob
it's always tempting the imagine "all the use cases I can think of" == "all possible use cases". Imagine, for example, a dynamic form where an input is editable only under certain conditions, but locked for editing under others. The value of this input may change, but then be disabled do to some condition occuring. Backend still needs to updated value, even though input was eventually disabled.Frederickson
@Frederickson I wasn't tempted to imagine that I'd thought of all cases, that's why I made the distinction. I guess there could be a game mechanic where you would want to stop a value increasing after certain condition occurs.. and still submit it to the backend; but you'd still need to be wary of data-integrity and validation issues as this value can still be manipulated by a semi-competent user. For the most part, however, when an input becomes disabled its because it is dependent on another form value that has changed.. and thus can be inferred from itThrasher
one should never rely on the client-side to sanitize POST data. Disabling the input widget does nothing to prevent a moderately competent user from submitting POST data for that field. Onus is always on the backend. And I do understand the general use-case, just taking issue with "all the use cases I can think of". HTTP likely works this way for historical reasons (e.g., limited bandwidth, static content), but that doesn't make it semantically correct.Frederickson
@Frederickson Yes, which is exactly the point I was making, because you have to sanitise the input in the backend anyway - and it's likely inferable from whatever conditions disabled the input - you likely don't need it submitted. Not expecting/reading the disabled input will protect you from malicious users submitting erroneous data for it. OK, well if you have a specific use-case which requires you to submit disabled inputs, then I'd suggest using one of the other answers. This answer is more of an 'Are you asking the right question?'Thrasher
F
2

Simple workaround - just use hidden field as placeholder for select, checkbox and radio.

From this code to -

<form action="/Media/Add">
    <input type="hidden" name="Id" value="123" />

    <!-- this does not appear in request -->
    <input type="textbox" name="Percentage" value="100" disabled="disabled" /> 
    <select name="gender" disabled="disabled">
          <option value="male">Male</option>
          <option value="female" selected>Female</option>
    </select>

</form>

that code -

<form action="/Media/Add">
    <input type="hidden" name="Id" value="123" />

    <input type="textbox" value="100" readonly /> 

    <input type="hidden" name="gender" value="female" />
    <select name="gender" disabled="disabled">
          <option value="male">Male</option>
          <option value="female" selected>Female</option>
    </select>
</form>
Fluctuant answered 3/11, 2020 at 14:52 Comment(0)
K
1

In addition to Tom Blodget's response, you may simply add @HtmlBeginForm as the form action, like this:

 <form id="form" method="post" action="@Html.BeginForm("action", "controller", FormMethod.Post, new { onsubmit = "this.querySelectorAll('input').forEach(i => i.disabled = false)" })"
Keon answered 26/6, 2020 at 18:31 Comment(2)
Have you tried this code? Because I don't see how it would work. @Html.BeginForm(...) {...} renders <form ...> ... </form>, which would not be a great thing to have in an attribute. Perhaps you meant @Url.Action("action", "controller"), which renders a URL?Cocotte
I tried this code, Heretic. It worked here. Before, I was using as you mentioned, with @Url.Action, but there were not all the params. Perhaps the "using" is better practive, but I'm not sureKeon
G
1

use

<input type="textbox" name="" value="100" disabled/>

or

<input type="textbox" name="" value="100" readonly/>

if your are using framework like PHP Laravel, element without name attribute will read as unset

<input type="textbox" value="100" disabled/>
Grouper answered 16/9, 2022 at 9:9 Comment(0)
D
0

Define Colors With RGBA Values

Add the Following code under style

<!DOCTYPE html>
<html>
<head>
<style>
#p7 {background-color:rgba(215,215,215,1);}
</style>
</head>
<body>
Disabled Grey none tranparent
<form action="/Media/Add">
    <input type="hidden" name="Id" value="123" />

    <!-- this does not appear in request -->
    <input id="p7" type="textbox" name="Percentage" value="100" readonly="readonly"" /> 

</form>

result

Defluxion answered 29/8, 2020 at 20:58 Comment(0)
K
0

I had exactly the same problem, but did not work for me, because I have select HTML element, and it's read-only state allowed to change its value. So I used select in one condition and input in another:

   <% If IsEditWizard Then   %>
                            <%For Each item In GetCompaniesByCompanyType("ResponsibleEntity")%>
                            <% If item.CompanyCode.EqualsIgnoreCase(prCompany.GetAsString("LinkedCompany")) Then   %>
                            <input type="text" value="<%: item.CompanyName  %>" tabindex="3" size="12" maxlength="12" readonly="readonly" />
                            <input type="hidden" id="LinkedCompany" name="LinkedCompany" value="<%:item.CompanyCode %>" tabindex="3" size="12" maxlength="12" />
                            <%End If %>
                            <%Next %>
                            <%Else %>
                            <select id="LinkedCompany" name="LinkedCompany" class="w-auto" <%= If(IsEditWizard, "disabled", "") %>>
                                <option value="">Please Select</option>
                                <%For Each item In GetCompaniesByCompanyType("ResponsibleEntity")%>
                                <option value="<%:item.CompanyCode %>" <%: IIf(item.CompanyCode.EqualsIgnoreCase(prCompany.GetAsString("LinkedCompany")), "selected", String.Empty) %>><%: item.CompanyName %></option>
                                <%Next %>
                            </select>

                            <%End If %>
Keynes answered 10/11, 2022 at 5:22 Comment(0)
M
0

Make it readonly with proper style:

<input name="client1" readonly> 

input:read-only {
   background-color: var(--bs-secondary-bg);
   ...
}
Mycenaean answered 3/2 at 7:27 Comment(0)
D
-7

You can totally avoid disabling, it is painful since html form format won't send anything related to <p> or some other label.

So you can instead put regular

<input text tag just before you have `/>

add this readonly="readonly"

It wouldn't disable your text but wouldn't change by user so it work like <p> and will send value through form. Just remove border if you would like to make it more like <p> tag

Discrete answered 6/1, 2016 at 20:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.