How do I submit disabled input in ASP.NET MVC? - c#

How do I submit disabled input in ASP.NET MVC?

Can't you make the field readonly="readonly" instead of disabled="disabled"? A readonly field value will be submitted to the server while still being non-editable by the user. A SELECT tag is an exception though.

Thanks to everyone:
The way i resolved this:
document.getElementById("Costo").readOnly = true;
document.getElementById("Costo").style.color = "#c0c0c0";
Note:
I got this information on the answer but i got editted.

#ppumkin mentioned this on his comment on this answer but I wanted to highlight it as I was unable to find other resources on submitting data from a disabled <select>. I also believe it is relevant to the question as selects are not <input>s but they are "input"s.
Just include a Hidden field for the disabled select and its all sorted.
Example:
#Html.DropDownListFor(model => model.SelectedID, ... , new { disabled = "disabled"}) #* Won't be posted back *#
#Html.HiddenFor(model => model.SelectedID) #* Will be posted back *#
Caution: this will put two tags on the page with the same ID, which is not really valid HTML and could cause headaches with javascript. For me, I have javascript to set the value of the dropdown by its html id, and if you put the hidden field first, the javascript will find that instead of the select.

Typically, if I have a field that is "read-only" but needs to be submitted back to the server, I will make the display disabled (or simply text), but then add a hidden field with the same name. You still need to make sure that the field is not actually modified on the server-side -- just don't update it from the model in your action -- but the model state will still be accurate if there are errors.

You can also use code like this before the form submits:
$(":disabled", $('#frmMain')).removeAttr("disabled");

By design browsers do not support that.
Either make them readonly which allows submitting values to server
or if you're dealing with controls that are still usable with readonly attribute such as Select, add css style pointer-events: none; to make them non-interactive
Kind of a hack, but works! It also works when you are submitting form directly with submit button without using javascript. No extra work required!
Eg:
<select asp-for="TypeId"
asp-items="#(new SelectList(await TypeRepository.FetchTypesAsync(), "TypeId", "Name"))"
class="form-control form-control-sm"
readonly
style="pointer-events: none;">
</select>

You can create an editor template like the one below
CSS
.disabled {
background-color:lightgray;
}
Editor Template
#model string
#Html.TextBoxFor(x => x,new {#class="disabled", #readonly=true })

This will help in submit model values in ASP.net:
$("#iD").attr("style", "pointer-events: none;background-color:rgb(220,220,220)");

when we are dealing with disabled but checked checkboxes and we want to post the value, we need to ensure our hidden field appears before the #Html.CheckBoxFor hidden field.
following is the link from where I found the answer.
http://davecallan.com/posting-disabled-checkboxes-mvc-razor-views/#comment-11033

I usually use this way for CheckBox or CheckBoxFor because making it disabled is causing the losing the value. Readonly doesn't work on checkbox neither.
#Html.DisplayFor(m => m.Order.Transfer)
#Html.HiddenFor(m => m.Order.Transfer)

expanding Tasos' (":disabled", $('#xxxForm')).removeAttr("disabled"); you can use:
$("#xxxForm").submit(function (e) {
e.preventDefault();
var form = this;
$('#Field1')[0].disabled = false;
$('#Field2')[0].disabled = false;
...
$('#FieldN')[0].disabled = false;
form.submit(); // submit bypassing the jQuery bound event
});

Just put this script in #section scripts in your page.
this will enable inputs when you submit the page, and you should redirect user to another page after submit.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js">
$("form").submit(function () {
if ($('form').valid()) {
$("input").removeAttr("disabled");
}
});
</script>

Just make that property [Required] in the ViewModel linked to that view.

Related

Posting results when checkbox is checked in MVC 4

I've been asked to repost this question with more detail.
I'm new to MVC and I'd appreciate any supporting explanations although I am quite grounded in .NET development.
Scenario
I have a calendar that posts to a calendar with information when it's selected. It looks like this:
#foreach (var OfflineCalendar in Model.OfflineCalendars.Skip(1))
{
<li data-name="#OfflineCalendar.Name" data-val="#OfflineCalendar.Id">#Html.ActionLink(OfflineCalendar.Name, "Index", new { Id = OfflineCalendar.Id }, new { #class = "location" })</li>
}
The calendar only returns data for a month which passes some data to a ContentResult method.
I've added a Checkbox for archived data.
<label>
Archived
#Html.CheckBox("checkedArchive")
</label>
My Task
I want to add an archived button where a user can view historic data. If this checkbox is checked, it changes some parameters in the ContentResult Data method.
The Dilemma
In .NET I would easily check for whether a checkbox is checked and fire an event based on the calendar that's selected. I'm struggling to do the MVC equivalent.
All I want to do is check if it's checked WHEN a calendar location is selected. If it is, return a bool of true or false. Which will affect the ContentResult.
I don't want to use Ajax. I just simply want to check whether a checkbox is checked when a location is selected. That's all.
Here's the related question I asked: clicky
Thank you for reading.
It sounds like you want to do all of this server side through your existing code and just want to access the value of the checkbox.
If that is correct, I would modify the ViewModel to include a boolean "IncludeArchived" and then add it to your page:
#Html.CheckBoxFor(model => model.IncludeArchived)
When you submit your form the value should be included in your Model.
Alternatively, you could check Request.Form["checkedArchive"] on the server side and parse that into a boolean.
you need to write checkbox event in jquery and check if checkbox is checked post the form and return content from server else don't post the form.
Like this:
View:
<form action="" method="POST" id="MyForm">
<label>
Archived
#Html.CheckBox("checkedArchive")
</label>
</form>
Jquery:
$('#checkedArchive').on('change',function(){
if(this.checked)
{
$('#MyForm').submit();
}
});

Hidden Fields are not storing certain values in MVC

In my ASP.NET MVC view I have the following hidden variables.
#Html.HiddenFor(m => m.TotalAmount)
#Html.HiddenFor(m => m.SelectedAmount)
Which I was able to display in the page using,
#Model.TotalAmount
I used AJAX to get these hidden fields as below.
$("#TotalAmount").val() and $("#SelectedAmount").val().
TotalAmount is always 0 and I am getting SelectedAmount correctly.
Please help me to find what wrong with this.
Update:
From developers tool I see :
However I am getting the value of Model.TotalAmount printed in the page using #String.Format(new CultureInfo("en-US"), "{0:N}", #Model.TotalAmount)
You can always just print the value to your script like so:
<script type="text/javascript">
function myFunction() {
var totalAmount = #Model.TotalAmount;
}
</script>
Ofcourse you still need the hidden fields if you want to keep the values in your model in submit.
This is just one solution to your problem.
Try this:
this will help you for the same purpose
<input type="hidden" name="Step" value="#Model.TotalAmount" />

MVC4: How do I get value from partial view for insert/edit

I am new to MVC and I am just trying to get a grip on certain aspects of MVC that I will be using in the project I have coming up. So, I have a view where the user will input data regarding training: name, id, location, and training dates. I have created partial view that will be used for the dates, it incorporates the jQuery date picker and a date mask. This pv will replace date fields where needed. It all works fine, but, I do not know how to get the value placed in the partial view to be passed back into the model, once the user clicks the "Create" or "Edit" button.
Here is my code (Edit View):
#Html.Partial("partialview", Model.ValueToPass)
And For the partial view:
#model Nullable<DateTime>
#{
string dt = string.Empty;
if (Model != null) { dt = Model.Value.tostring("MM/dd/yyyy"); }
<script type="text/javascript">.......</script>
<p> #Html.TextBox("Test", dt, new {#class = "DateTextArea"}) </p>
As stated, I can get a preexisting date from the model loaded into the textbox, without issue, its just retrieving that value or new value, if the user enters a new date, and putting it into the database. Any help or direction would be of great help. Thank you.
If the partial view is within a form element at the top level page, then it will be posted back as if it was part of the original form.
Think of a partial view as being only used at render time. By the time you see the page in your browser, think of it as being one complete page (Not groups of partial views). So any page submit will be done with the whole form in mind.
SOLVED:
I'd like to thank each of you for your inputs as they did help me in finding a solution. The main part I was missing was this:
#Html.Partial("partialview"), Model.ValueToSend, new ViewDataDictionary(ViewData) {
TemplateInfo = new System.Web.Mvc.TemplateInfo {HtmlFieldPrefix = "ValueToSend"
})
I was missing the templateinfo portion on the parent view. Also, I did change my textbox to TextBoxFor and used:
TextBoxFor(model => model, new { #class = .....)
DO NOT go with model.Value, as I had that in there earlier and was still retrieving a null date value on postback. The solution code does not require a hidden field to be populated, the templateinfo code adds an id to the input field in the partial view and the parent controller automatically grabs the data in the partial's input field to get sent to the database, as if it were one of the other auto generated elements on the parent view.
To make the hidden field idea work, with multiples of the same partial view on the parent view, set the hidden field and date textfield (in this example) to the same id; the hiddenfield you'd put an h in front of it ( e.g. date and hdate). Then you'd need to set a javascript variable to get the id of the active element
var id;
($(".datepickerclass").change(function(){
id = $(this).attr('id');
)}
Additionally, if you're using the datepicker
$(".datepickerclass").datepicker(
.....
beforeShow:
id = $(this).attr('id')
And then add the value to the correct hidden element within the change or blur event of the textbox or within the datepicker:
onSelect:
var val = $(id).val()
$('#h'+ id).val(val)
Pardon if the jQuery may be off a bit, I shut down my development machine and I'm typing this without fully testing the jQuery code, but I think you'd get the point. Thanks again for all the help. Next up will be tackling a jQuery grid.
Edit:
Unfortunately since my rating is not high enough, I cannot upvote the answers provided, as they deserve to be.
Use #Html.TextBoxForModel instead of #Html.TextBox(....). This will cause the input to be created with the correct name so that it will bind correctly to your model when you post the page.
You don't need to format the date yourself, you can use the dateFormat option on the jQuery date picker to format the value.
If you use EditorForModel instead of TextBoxForModel, it will create the input with the correct type to use the browsers built in date picker, if available. You can then use Modernizr to test if dates are supported and use the jQuery date picker if it is not. Here is a decent tutorial about it.
You have to be aware that anything you do with C# and razor in your views happens before the HTTP response. So once the response is sent to the client, all your #Model.value or #if(something) { #Html.Partial(...) } statements will have already translated into pure HTML.
Something you can do to get values from a partial view to your main view is use jQuery:
Imagine a main view like:
#Html.HiddenFor(m=>m.ChosenName, new { id="hiddenGlobalName" }
and a partial view like this:
<input type="text" id="partialNameField" />
<input type="button" value="Save and close popup" id="closeButton" />
<script>
$(function(){
$('#closeButton').click(function(){
var partialValue = $('#partialNameField').val(); // get the value
$('#hiddenGlobalName').val(partialValue); // "save" to main view
});
});
</script>
Because the DOM will be constructed after the HTTP request is over, you have access to all elements of a main view from any included partial view at the time the user sees them.
Hope this can help you!

In a C# MVC app is it possible to submit variables from a web page in controls that did not change?

I have a C# MVC application and a <form> in my page.cshtml file. In that form I have <input type="text" ... /> elements. If I submit this form I only get the values in Response.Params or Response.Form from the inputs where I changed the value manually (i.e. Entered the text box then typed something).
If I change the value with jQuery, $('#myInput').val('some value'); this does not count as a change in the input's value and I do not get myInput's value when I submit the form.
Is there any way to make sure all inputs are submitted? If not then is there a good workaround for this, maybe in some event that occurs before my model gets bound? I need to know all the input values from the form when submitted whether they changed or not.
Some additional info:
The form and other values are getting submitted correctly and I am receiving my model when the POST action is called in my controller.
The real issue is when my model is being bound. It is being created and bound with all values except the one not being submitted because it is not in the Request.Params collection.
I have only ever seen this behaviour when a field is disabled. Due to this, I commonly have a javascript function that handles the form submission and re-enables them on submit, this way the correct values get sent to the server.
Something like this does the trick for me (NOTE: I am using JQuery):
$(document).ready() {
$("#ButtonSubmit").click(SubmitForm);
}
function SubmitForm(e) {
e.preventDefault();
//ensure fields are enabled, this example does text and checkbox types
$("[type='text']").attr("disabled", false);
$("[type='checkbox']").attr("disabled", false);
//submit the form
document.forms[0].submit();
}
I am unaware of any easier way to do this, it would be nice if you could 'flag' something that instructs all fields to be submitted. But I don't know if this exists, maybe somebody else can offer a better solution.
EDIT: It appears that disabled fields not submitting is just the nature of HTML, and is not something that is tied to MVC.
It seems that if you make the fields readonly instead of disabled then the values will still submit. However, with this approach you lose the 'disabled' styling. The exception to this rule is select control, it seems this will not submit under readonly either. More information on this can be in this question
Try using the razor helper to build the form tag.
#using(Html.BeginForm()) {
..
// make sure this is a submit button
<input type="submit" value="Save" />
}
In your controller action post method make sure you decorate it [HttpPost].
e.g.,
[HttpPost]
public ActionResult Edit(YourModel model) {
}

Remove browser autocompletion in MVC

I am currently trying to remove the form autocompletion done by the user's browser which can cause some critical behavior since it fills the password field. I have already added the autocompletion attribute to all of my textbox fields but when I try with firefox it stills load my current login information into the fields.
Does anyone know how to resolve this issue?
EDIT: Since it's not clear, I have already added the aucompletion attribute with the value set to "off".
There is an autocomplete=off property in html.
It is used in the top right search box on this very page, inspect the html you'll see:
<input autocomplete=​"off" name=​"q" class=​"textbox" placeholder=​"search" ..... />
See this MDN article: https://developer.mozilla.org/en/How_to_Turn_Off_Form_Autocompletion
In MVC you would implement this at the form or for a textbox like so:
Html.BeginForm(
action, controller, FormMethod.Post, new {autocomplete="off"})
OR
Html.TextBoxFor(model => model.EmployerNumber, new {autocomplete="off"})
If you check HERE, setting autocomplete="off" on the form should do the trick.
The HTML5 have a add-on syntax for form/input elements, it is called autocomplete="off".
See http://www.w3schools.com/html5/att_form_autocomplete.asp
You can randomize id and name attributes of your textboxes - this will make browser autocomplete functions not working.
My implementation
In view:
<%
var guidString = Guid.NewGuid().ToString();
%>
<%=Html.TextBox(guidString, String.Empty)%>
<%=Html.Hidden("NameGuid", guidString) %>
in Controller:
string userName = Request[model.NameGuid];
...

Categories