How to get selected text from mvc disabled dropdown [duplicate] - javascript

I have an ASP.NET MVC application. I am having multiple drop-down list in my page (HTML SELECT), I have to disable them, as user goes on selected them one by one. When the user posts it back to the controller, I am getting null as the function (action method) paramters. I searched and found that HTML does not send value of disabled fields in the form data. Replacing disabled attribute with readonly would not work as it would render drop-down working.
I am generating the dropdowns dynamically using javascript as user goes on. So there isn't a single dropdown, but as many as user wants.
Can someone please tell me how should I get the values ?

One possibility is to make the dropdown list disabled="disabled" and include a hidden field with the same name and value which will allow to send this value to the server:
#Html.DropDownListFor(x => x.FooId, Model.Foos, new { disabled = "disabled" })
#Html.HiddenFor(x => x.FooId)
If you have to disabled the dropdown dynamically with javascript then simply assign the currently selected value of the dropdown to the hidden field just after disabling it.

This is the default behavior of disabled controls. I suggest you to add a hidden field and set the value of your DropDownList in this hidden field and work with this.
Something like:
//just to create a interface for the user
#Html.DropDownList("categoryDump", (SeectList)ViewBag.Categories, new { disabled = "disabled" });
// it will be send to the post action
#Html.HiddenFor(x => x.CategoryID)

You could also create your own DropDownListFor overload which accepts a bool disabled parameter and does the heavy lifting for you so your view isn't cluttered with if disablethisfield then ....
Something among these lines could do:
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, bool disabled)
{
if (disabled)
return MvcHtmlString.Create(htmlHelper.HiddenFor(expression).ToString() + htmlHelper.DropDownListFor(expression, selectList, new { disabled="disabled" }).ToString());
else
return htmlHelper.DropDownListFor(expression, selectList);
}
There are 6 overloads for DropDownListFor alone so it's a lot of monkeycoding but it pays off in the end imho.

Create a hidden field with a specified Id and set it before disabling the drop-down-list.
In MVC,
#Html.DropDownListFor(x => x.FooId, Model.Foos)
#Html.HiddenFor(x => x.FooId, new { #id = "hdnFooId" })
In JQuery,
function handleDropDownListFooChange(){
// Get the selected value from drop-down-list before disabling it.
var selectedFooId = $('#FooId').val();
$('#FooId').prop("disabled", "disabled");
$("#hdnFooId").val(selectedFooId);
// Load any data the depends on selected FooId using `selectedFooId` variable.
}
The selected value will automatically be binded to Model.FooId.

before submit call $('#FooId').removeAttr('disabled')

Related

Drop-down auto selection disabling

I have a form where I select a value in drop-down and submit it but when I try to access that form the value in the drop-down still remains selected, I want to deselect it on every new launch.
You can use the following to set the value of the dropdown to what you want.
document.querySelector('#idOfDropdown').value = desired_value;
// desired_value is the 'value' property of the option you want selected.
If the default option is written as
<option value=''>--select--</option>
...then, use this:
document.querySelector('#idOfDropdown').value = '';
I'm assuming that this line will be best placed at the end of the function that gets called when you submit the Form.

submit disabled dropdown mvc c#

I want to submit a dropdown value disabled:
View:
#Html.DropDownFor(model => model.Type_Id, Model.TypeDropDown)
#Html.HiddenFor(m => m.Type_Id)
Javascript:
$("#Type_Id").val("67").change();
document.getElementById("Type_Id").disabled = true;
$('#Type_Id').val(67);
But my value dont passed to c# controller.
Once you disable a dropdown it wont submit it's value, so you need to Store your value.
See : Disable Dropdown
use a hiddenfor with nameparameter to store the value.
use hidden field to store the value of the disabled dropdown . In your code you have to manually set the value of the hidden field which is inside the same form before posting it to controller like below . You have to add the "Type_id_hidden" property in your model to access the value in controller.
#Html.Hidden("Type_id_hidden") .
But in your code you used the same id both hidden field and dropdown. set the hidden field before posting to controller
var selectedVal = $("#Type_Id").val();
$("#Type_id_hidden").val(selectedVal);
Use an additional hidden field with the same value as drop-down to submit the value and let the dropdown just for showing the value.
You cannot submit the value of a disabled field.

How to post input fields conditionally

I have an MVC (Razor) web app. The form has 2 fields, one dropdown box (Kendo) and one input field for a date.
After the user makes a change on the dropdown, my 2nd input field is enabled or disabled based on the chosen type in the dropdown box. When the input field is disabled I fill the input with a default value.
When the user submits the form, I only get 2nd form field value posted in the viewmodel when the 2nd field is enabled, when disabled the value is not posted. I know this a common pattern in HTML, that disabled fields are not part of the POST.
My question: how can I solve this issue to get the value POSTed when the field is disabled ? It should be done in JS...
I had a similar requirement, what i did was, created a class , which would make the text box appear like disabled, by removing mouse events and styling a bit
[https://codepen.io/DawsonMediaD/pen/Dqrck][1]
or
Bit tricky, just before the post , enable all of them
Fixed it, in the onchange handler of the dropdown box attach this JS code:
var defaultDateValue = "2017-01-04"; //just for demo
var $effectiveToInput = $("##Html.IdFor(m => m.EffectiveToDate)");
$effectiveToInput.parent().append("<input type=\"hidden\" name=\"#Html.NameFor(m => m.EffectiveToDate)\" id=\"#Html.NameFor(m => m.EffectiveToDate)\" value=\"" + defaultDateValue +"\" />");
And for the other types, i clear the hidden fields with checks:
function removeHiddenEffectiveToDateField() {
var $effectiveToInput = $("##(Html.IdFor(m => m.EffectiveToDate))[type = hidden]");
if (null !== $effectiveToInput) {
$effectiveToInput.remove();
}
}

ASP MVC binding two controls to one field

In my view model I have a field. This field can be selected from a drop down list or entered in a textbox. I have two radio buttons which allows to select between drop and textbox.
<div class="frm_row" id="contractorRow">
#Html.RadioButton("IsContractorNew", "false", true)
#Html.Label(#Resources.SomeLabels.Existing)
#Html.RadioButton("IsContractorNew", "true", false)
#Html.Label(#Resources.SomeLabels.New)
<div class="frm_row_input" id="contractorDropDownList">
#Html.DropDownListFor(model => model.CONTRACTOR, Model.Contractors)
#Html.ValidationMessageFor(model => model.CONTRACTOR)
</div>
<div class="frm_row_input" id="contractorTextBox" style="display: none;">
#Html.TextBoxFor(model => model.CONTRACTOR)
#Html.ValidationMessageFor(model => model.CONTRACTOR)
</div>
</div>
I prepared a javascript code for hiding, showing and clearing controls while selecting radio buttons. The problem is - field is bound only to the first control (drop down list).
EDIT:
I solved this problem by creating one hidden field and scripting whole logic to bind active control with it and therefore with the model. Anyway if anyone knows simpler solution, please post it.
I know this is an old question, but for those dealing with this issue, here's a solution:
Explanation
When a form is submitted, input elements are bound to the model by their name attribute. Let's say you use HTML helpers to generate your form, and you generate two input fields which bind to the same property on the model. When rendered to the DOM, they both have the same name attribute.
<input name="Passport.BirthPlace" id="birthPlaceDropDown" ... >
<input name="Passport.BirthPlace" id="birthPlaceInfoTextbox" ... >
When the form is submitted, it will bind the first (in the DOM) input it finds to Passport.BirthPlace
A Solution
The quick and easy way to fix this is to use JQuery to change the name of the field you don't want bound on submit. For me, I use a checkbox to toggle which field shows. When the checkbox changes, I hide one control, change its name attribute, and show the other one (and change it's name attribute to Passport.BirthPlace) It looks like this, basically:
First, I run this on document ready
$('#birthPlaceInfoTextbox').attr('name', 'nosubmit'); // Change name to avoid binding on inactive element
Then, I create a listener for my checkbox which toggles which control should be bound:
$('#notBornUSCheckbox').change(function() {
if (this.checked) {
// Not born us was checked, hide state dropdown and show freeform text box
$('#stateDropDownSection').addClass('d-none'); // Hide drop down
$('#birthPlaceDropDown').attr('name', 'nosubmit'); // Change name to something other than Passport.BirthPlace
$('#birthPlaceInfoTextbox').attr('name', 'Passport.BirthPlace'); // Set this one to be bound to the model
$('#stateTextboxSection').removeClass('d-none'); // Show the textbox field
} else { // Opposite of above lines
$('#stateDropDownSection').removeClass('d-none');
$('#stateTextboxSection').addClass('d-none');
$('#birthPlaceInfoTextbox').attr('name', 'nosubmit');
$('#birthPlaceDropDown').attr('name', 'Passport.BirthPlace');
}
});
Instead of using Razor #Html.TextBoxFor... for your textbox, you could try using raw HTML e.g. <input />. Also, have your JavaScript code remove the other field from the DOM entirely when a radio button is clicked, before submitting the form.

Client side javaScript to toggle a dropdownlists effects reversed on postbacks?

I have the following JavaScript to toggle a dropdownlists in a ASP.NET page, which gets called when I click a button. I have like 4-5 dropdownlist/Toggle button pairs. Each toggle button toggles the enable/disable property on the associated dropdownlist.
function toggleDisableDropDown(dropDownID) {
var element = document.getElementById(dropDownID); // get the DOM element
if (element) { // element found
element.disabled = !element.disabled; // invert the boolean attribute
}
return false; // prevent default action
}
But one of my dropdownlist needs to do a postback everytime. I pick an item to populate another dropdownlist, what I noticed is that on this postback all of my other dropdownlist which were disabled by javascript (user clicks on the toggle button for these dropdownlist) gets enabled.
What is happening here? And how can I fix it?
Javascript DOM manipulation has no relevance to the control's saved state on the server. Changing the enabled property on the dropdownlists on the client side will not be known to the control state on the server.
Posting back re-creates the dropdownlist's using the last known state of the control. If you want to have them re-rendered using the last state on the client, you'll need to post some client tracking information as well. You could track each dropdownlist's client state in a hidden field, and use the posted value from those hidden fields to update the Enabled property of the dropdownlist on the server.
//Html
<input type="hidden" name="_trackingDropdown1" value="true" />
//Client Javascript
function toggleDisableDropDown(dropDownID) {
var element = document.getElementById(dropDownID); // get the DOM element
var trackingField = document.getElementById("_tracking" + dropDownID);
if (element) { // element found
element.disabled = !element.disabled; // invert the boolean attribute
trackingField.value = element.disabled;
}
return false; // prevent default action
}
//On Server during postback handling
if (Request.Params["_trackingDropDown1"] != null)
{
bool.TryParse(Request.Params["_trackingDropDown1"], out DropDownList1.Enabled);
}

Categories