I am currently trying to figure out how you can bind multiple fields in an MVC 3 view to 1 property on a view model and what is recommended when trying to achieve this.
Using an example for the number of minutes (only) that it takes to prepare something.
The form might look something like this:
Preparation time - Hours: [ 1 ] Minutes: [ 30 ]
and the submitted form values need to be converted into minutes and bound to the PreparationTimeInMinutes property of the ViewModel.
ViewModel property:
public short PreparationTimeInMinutes { get; set; }
and the View is strongly typed to the ViewModel and currently has the below:
<div class="editor-label">
@Html.LabelFor(model => model.PreparationTimeInMinutes)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.PreparationTimeInMinutes)
@Html.ValidationMessageFor(model => model.PreparationTimeInMinutes)
</div>
Here are a few things that I began thinking about in order to achieve this.
Does anyone have any suggestions on best practice for this sort of thing? or if I am way off.
Please let me know. Thanks
You should use the first option.
This is exactly what editor templates are made for.
If you want to, you can create a custom ModelBinder to bind two POSTed values to a single number (along with a similar editor template) and apply an attribute to the property to select that ModelBinder.
However, that would probably be overkill.
The Javascript isn't bad but not really MVCish. I would think the better approach would be a view model with those two fields or making a new class with the editor/display templates.
I agree with SLaks; you can create a custom model binder to handle this but it is probably overkill. I created a custom binder for a type with one date and two times based on this article, though mine is much simpler. But if you just want the practice or to learn more about model binding, it is doable.
EDIT: Sorry, just in case you decide to try the ModelBinder route, that example is a little old (maybe MVC 1?!). I forgot about having to make additional modifications. These links should help with updating that example. Good luck.
Thanks SLaks.
Using the first option I did the below in my view model
public TimeInMinutesViewModel PreparationTimeInMinutes { get; set; }
Made this view model
public class TimeInMinutesViewModel {
public string Label { get; set; }
public short Hours { get; set; }
public short Minutes { get; set; }
}
and this editor template
@model TimeInMinutesViewModel
<div>@Html.LabelFor(x => x.Label)</div>
<div class="editor-label">@Html.LabelFor(x => x.Hours)</div>
<div class="editor-field">@Html.EditorFor(x => x.Hours)</div>
<div class="editor-label">@Html.LabelFor(x => x.Minutes)</div>
<div class="editor-field">@Html.EditorFor(x => x.Minutes)</div>
and in the view
@Html.EditorFor(model => model.PreparationTimeInMinutes)
@Html.ValidationMessageFor(model => model.PreparationTimeInMinutes)
I haven't tested this yet and I might need to do some changes for the labels but this looks like it might work for 2 different properties that I want to use this approach for.
The problem I have got now is being able to map these to my entity property which is a short int.
I am using AutoMapper so I am hoping this will work with a custom type converter, at least in 1 direction but I'm not sure about both directions :(