How will model binder deals with Readonly & disabled - asp.net-mvc

I have the following two items , one which is readonly:-
#Html.TextBoxFor(model => model.Technology.Tag, new
{ #readonly = "readonly" })
While the other is Disabled:-
#Html.DropDownListFor(model => model.Customer.NAME, ((IEnumerable<TMS.Models.AccountDefinition>)ViewBag.Customers).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.ORG_NAME),
Value = option.ORG_NAME.ToString(),
Selected = (Model != null) && (Model.Customer != null) & (option.ORG_NAME == Model.Customer.NAME)
}), "Choose...", new { disabled = "disabled" })
so will the asp.net mvc model binder bind the two items? , or it will ignore any read-only and any disabled fields ?

It will bind them, but as long as you have populated them with the correct data, that shouldn't matter. Also, you can have your code that maps these models to the entity, assuming you are using view models, just ignore the values in question. Assuming this is a standard HTTP Post from the form, HTTP will not post disabled or readonly fields, which means they will be null or the default value in the model, so you need to account for that.
If you want the binder to ignore these values, use TextBox and DropDownList and make sure they are not named the same as your properties. If you do not use 'For' you will need to add code in the view to set the values.

ReadOnly text fields get bound.
I've been trying to find a way around the unbound dropdownboxfor values. Here's what I came up with:
$('#xxx').change(function() {$(this).val(lastSel_xxx);});
var lastSel_xxx = $("#xxx option:selected").val();
Use the code above for each HTML element in your view (this will require you to document each ID output) and replace 'xxx' with the element name.
When a user selects another option besides the initial option selected, it reverts back to the original.
HOpe this helps!

Related

HTML.TextBoxFor is set readonly before value set

I have the following HTML helper textbox:
#Html.TextBoxFor(m => m.Email, Model.Active ? new { #readonly = "readonly", #style = "background:#E8E8E8" } : new Object { })
When I change the email value in the action (in the model being returned) then set the active=true (which is also in the model) to make it readonly, the email textbox value isnt updated with the new value coming from the model, and i checked to confirm that the model is going back with the new email and active=1.
Its as if the readonly is being set before the value from the model is being rendered.
Any help is appreciated, thankx
When you post back a model, its values are added to ModelState. Html helpers bind to the vales in ModelState, not the values of the model properties, so modifying the value of a model property in the POST method will not be reflected in the view unless you first clear model state before setting the value using
ModelState.Clear(); // clears all properties
or
if (ModelState.ContainsKey("active"))
{
ModelState["active"].Errors.Clear(); //clears the property 'active'
}
The reason for this behavior is explained in the second part of this answer.
However, clearing ModelState should be used with caution as it also clears validation errors, and in any case the correct approach is to follow the PRG pattern

One Model field not populating when the rest of the Model is

I'm using an MVC 3 view which has a Model inherited:
Inherits="System.Web.Mvc.ViewPage<MyModel>"
I use html helpers to populate model properties:
<td><%=Html.TextBoxFor(i => Model.partA, new { #style = "width:25px;", #maxLength = 3})%></td>
<td><%=Html.TextBoxFor(t => Model.partB, new { #style = "width:35px;", #maxLength = 5 })%></td>
The problem is in my controller 'partB' gets the value from my TextBoxFor helper but 'partA' is empty. There's other parts of the model but I use this as an example.
It's the same model based on the same table in my entity framework. I checked the properties and they're both intergers with Nullable set to (none). In SQl Server MS, the table fields it's refering to appear to be the same also. Both are set (int, null).
I don't see what the difference is that causes partB to be populated and partA to be empty.
What else can I check?
OK, it was because I had a textbox also named 'partA' in a control being rendered in my page. The empty value in the control seemed to be overwriting 'partA' on my view.

Client-side validation for custom editor templates in MVC4

I have a viewModel that contains an object. I've defined a custom editor template for that object, which allows me to edit each of the children of that object. The children values aren't required serverside (so I don't have any Required annotations), however if the user reaches this particular input, it should be required.
Is there any way I can inspect the values of these children objects (within the viewModel) in the POST method, and return some errors to the view if they are null?
I'm using Razor.
On the server-side, you could check the child objects of the class in your action,
[HttpPost]
public ActionResult Edit(MyClass myClass)
{
if (myClass.Children.Any(child => child == null))
{
foreach(var child in myClass.Children
.Where(child => child == null)
.Select((item, index) => new { Item = item, Index = index))
{
ModelState.AddModelError(
string.Format("Children[{0}]", child.Index),
"Must be required");
}
return this.View("...");
}
}
What you can do is to write a function that will be check user input (on change in that field)
if the user reaches this particular input
and if user reaches that particular input you use jQuery to add #class = "required" HTML attribute to your object. From that moment on it will become required
Take a look here: this is jQuery validator for required field based on some condition. I think this is exactly what you're after
Edit
Your other option is to use AJAX to go back to server to verify what you're looking for. Example is here
Hope this makes sense and is of help to you.

Dropdown in ASP.NET MVC 3

I am new to MVC so probably confused . can somebody please explain me the dropdown in razor.my questions are-
What is the difference in dropdownlist and dropdownlistfor
how do i Pass ID column of my database table as value and NAME column as text.
How do i add "other" to the dropdownlist.
how do i access the selectedlistitem in code behind.
if possible please explain with an example.
DropDownList is generated by code like this:
#Html.DropDownList("PersonId", new SelectList(Model.People, "Id", "Text");
On the other hand, DropDownListFor is generated like this:
#Html.DropDownListFor(m => m.PersonId, new SelectList(Model.People, "Id", "Text")
Problem with DropDownList is that it has a magic string and if you decide to refactor the model later on, there's a high change you'll forget to change the magic string too.
You could do a LINQ query like this:
var datalist = New SelectList(from x in _peopleService
select new SelectListItem { Text = x.Name, Value = x.Id});
If you don't have a service or an ORM between it you need to apply it to your situation, but you can generate a list like that.
After nr 2, you can
datalist.Add(new SelectListItem() { Text = "Other", Value = "-1"});
Also you have to put that datalist in your viewmodel/model that is passed to the View, so you can generate a selectlist item with that. In this case you could just do:
#Html.DropDownListFor(x => x.PersonId, Model.PersonList);
if you stored the list as PersonList in Model.
In your Viewmodel (Well, model in mvc) you have a property where the selected item will be stored, look at the 1st question - In this instance the selected item's id will be stored in the PersonId property.

DropDownListFor Not Displaying/Persisting Null for First Choice in List

I have an MVC app via SharpArch. In the view I have:
Html.DropDownListFor(x => x.Location,
new SelectList(Model.PossibleLocations, "Id", "Address"),
"-- No Location --")
I have 2 issues.
The Dropdown is not getting updated when the view gets bound to the model.
A selection gets persisted correctly except when I try the top "no location".
I was able to take care of the first point by changing x.Location to x.Location.Id but then I had other issues.
I can find plenty of examples for DropDownList, but none in which saving a null is shown.
Any help is appreciated.
Thanks
UPDATE:
I just upgraded Resharper (a minor update) and am getting prompted to fill it DropDownListFor. Why would that make a difference? It was working enough to bind and now it doesn't work at all.
You could always insert the "empty" SelectListItem into your PossibleLocations collection before passing to the View and check for that "empty" value (0 for instance) when the form is posted
model.PossibleLocations.Insert(0,
new SelectListItem() { Text = "-- No Location --", Value = "0" };
Try "flattening" your model class so that LocationId is the actual value you're binding to (i.e. add a "LocationId" property to your model, and create a DropDownList for x => x.LocationId).

Resources