ChatGPT解决这个技术问题 Extra ChatGPT

How to ensure a <select> form field is submitted when it is disabled?

I have a select form field that I want to mark as "readonly", as in the user cannot modify the value, but the value is still submitted with the form. Using the disabled attribute prevents the user from changing the value, but does not submit the value with the form.

The readonly attribute is only available for input and textarea fields, but that's basically what I want. Is there any way to get that working?

Two possibilities I'm considering include:

Instead of disabling the select, disable all of the options and use CSS to gray out the select so it looks like its disabled.

Add a click event handler to the submit button so that it enables all of the disabled dropdown menus before submitting the form.

sorry for joining late, however solutions provided by @trafalmadorian workest the best. It disables all the inputs that are not selected. It would also work if it select has multiple options enabled. $('#toSelect')find(':not(:selected)').prop('disabled',true);
Alternatively, you could leave the control as disabled on the UI but retrieve the value in the action method: public ActionResult InsertRecord(MyType model) { if (model.MyProperty == null) { model.MyProperty = Request["MyProperty"]; } }

T
Tres

Disable the fields and then enable them before the form is submitted:

jQuery code:

jQuery(function ($) {        
  $('form').bind('submit', function () {
    $(this).find(':input').prop('disabled', false);
  });
});

This is the one I settled on, mainly because it's the least obtrusive.
jQuery docs recommend using .prop and .removeProp for 'checked', 'selected' and 'disabled' instead of .attr and .removeAttr see http://api.jquery.com/prop/
Relevant bit of @JimBergman's comment - "Properties generally affect the dynamic state of a DOM element without changing the serialized HTML attribute. Examples include the value property of input elements, the disabled property of inputs and buttons, or the checked property of a checkbox. The .prop() method should be used to set disabled and checked instead of the .attr() method. The .val() method should be used for getting and setting value." - from api.jquery.com/prop
You are genius one (Y)
This is one of the most incredible tricks I know about. Works perfectly. Thanks.
J
Jordan S. Jones
<select disabled="disabled">
    ....
</select>
<input type="hidden" name="select_name" value="selected value" />

Where select_name is the name that you would normally give the <select>.

Another option.

<select name="myselect" disabled="disabled">
    <option value="myselectedvalue" selected="selected">My Value</option>
    ....
</select>
<input type="hidden" name="myselect" value="myselectedvalue" />

Now with this one, I have noticed that depending on what webserver you are using, you may have to put the hidden input either before, or after the <select>.

If my memory serves me correctly, with IIS, you put it before, with Apache you put it after. As always, testing is key.


How would this be dependant on the web server? Isn't it the client that renders the page with the select field, and thus in case of conflict like that it would be the client that decides whether to send the value to the server or not?
It depends on how the server handles multiple inputs with the same name.
You'd better not rely on a specific server type, so I think the first approach is cleaner and less error-prone..
@Jordan: Browsers do not send disabled fields values to the server, which is why they are empty when you try to handle them server-side. If you have a hidden field with the desired value, and the visible field(s) are disabled, only the hidden field will be sent to the server. Ergo, the hidden field should only be created (via JS or server-side code) when the visible fields are disabled and there is no priority issue.
This is only option if you need a form that works without javascript.
J
Jean Paul Rumeau

I`ve been looking for a solution for this, and since i didnt find a solution in this thread i did my own.

// With jQuery
$('#selectbox').focus(function(e) {
    $(this).blur();
});

Simple, you just blur the field when you focus on it, something like disabling it, but you actually send its data.


Wow Great and easy solution. Thanks.. +1 from me :)
I like this a lot.. depending on interactions in my form, elements become enabled/disabled back-n-forth... how to I re-enable a 'blurred' field in this scenario?
From googling, looks like $('#selectbox').off('focus'); would do the trick of re-enabling
works for text boxes, doesnt work for select boxes, plus super easy to get around by clicking and holding down button
c
chhalpha

it dows not work with the :input selector for select fields, use this:

    jQuery(function() {

    jQuery('form').bind('submit', function() {
        jQuery(this).find(':disabled').removeAttr('disabled');
    });

    });

A
AkuLink1

I faced a slightly different scenario, in which I only wanted to not allow the user to change the selected value based on an earlier selectbox. What I ended up doing was just disabling all the other non-selected options in the selectbox using

$('#toSelect').find(':not(:selected)').prop('disabled',true);

Thanks, I found yours the most logically simplest. However attr should changed with prop, would look something like $('#toSelect')find(':not(:selected)').prop('disabled',true);
C
Community

Same solution suggested by Tres without using jQuery

<form onsubmit="document.getElementById('mysel').disabled = false;" action="..." method="GET">

   <select id="mysel" disabled="disabled">....</select>

   <input name="submit" id="submit" type="submit" value="SEND FORM">
</form>

This might help someone understand more, but obviously is less flexible than the jQuery one.


But, it's not nice for multiple selectors. May be we can use getElementsByTagName('select')?
A
Alex PARISOT

The easiest way i found was to create a tiny javascript function tied to your form :

function enablePath() {
    document.getElementById('select_name').disabled= "";
}

and you call it in your form here :

<form action="act.php" method="POST" name="form_name" onSubmit="enablePath();">

Or you can call it in the function you use to check your form :)


d
dimcookies

I use next code for disable options in selections

<select class="sel big" id="form_code" name="code" readonly="readonly">
   <option value="user_played_game" selected="true">1 Game</option>
   <option value="coins" disabled="">2 Object</option>
   <option value="event" disabled="">3 Object</option>
   <option value="level" disabled="">4 Object</option>
   <option value="game" disabled="">5 Object</option>
</select>

// Disable selection for options
$('select option:not(:selected)').each(function(){
 $(this).attr('disabled', 'disabled');
});

P
PPB

Just add a line before submit.

$("#XYZ").removeAttr("disabled");


B
Byron Whitlock

Or use some JavaScript to change the name of the select and set it to disabled. This way the select is still submitted, but using a name you aren't checking.


J
Josh Mc

I whipped up a quick (Jquery only) plugin, that saves the value in a data field while an input is disabled. This just means as long as the field is being disabled programmaticly through jquery using .prop() or .attr()... then accessing the value by .val(), .serialize() or .serializeArra() will always return the value even if disabled :)

Shameless plug: https://github.com/Jezternz/jq-disabled-inputs


D
Doglas

Based on the solution of the Jordan, I created a function that automatically creates a hidden input with the same name and same value of the select you want to become invalid. The first parameter can be an id or a jquery element; the second is a Boolean optional parameter where "true" disables and "false" enables the input. If omitted, the second parameter switches the select between "enabled" and "disabled".

function changeSelectUserManipulation(obj, disable){
    var $obj = ( typeof obj === 'string' )? $('#'+obj) : obj;
    disable = disable? !!disable : !$obj.is(':disabled');

    if(disable){
        $obj.prop('disabled', true)
            .after("<input type='hidden' id='select_user_manipulation_hidden_"+$obj.attr('id')+"' name='"+$obj.attr('name')+"' value='"+$obj.val()+"'>");
    }else{
        $obj.prop('disabled', false)
            .next("#select_user_manipulation_hidden_"+$obj.attr('id')).remove();
    }
}

changeSelectUserManipulation("select_id");

the 'obj' parameter must be a jquery object
A
Alftheo

I found a workable solution: remove all the elements except the selected one. You can then change the style to something that looks disabled as well. Using jQuery:

jQuery(function($) {
    $('form').submit(function(){
        $('select option:not(:selected)', this).remove();
    });
});

T
Thxopen
<select id="example">
    <option value="">please select</option>
    <option value="0" >one</option>
    <option value="1">two</option>
</select>



if (condition){
    //you can't select
    $("#example").find("option").css("display","none");
}else{
   //you can select
   $("#example").find("option").css("display","block");
}

P
Phillip Whelan

Another option is to use the readonly attribute.

<select readonly="readonly">
    ....
</select>

With readonly the value is still submitted, the input field is grayed out and the user cannot edit it.

Edit:

Quoted from http://www.w3.org/TR/html401/interact/forms.html#adef-readonly:

Read-only elements receive focus but cannot be modified by the user.

Read-only elements are included in tabbing navigation.

Read-only elements may be successful.

When it says the element may be succesful, it means it may be submitted, as stated here: http://www.w3.org/TR/html401/interact/forms.html#successful-controls


The control is NOT grayed out and the user CAN edit it. You failed to read the whole section and I quote: "The following elements support the readonly attribute: INPUT and TEXTAREA."
I know that this is an old answer, but this actually works. I don't know the reason of many downvotes.