I am trying to build an Ajax.BeginForm (that has a dropdown) which uses server side validation that checks the model's annotations. I am having trouble getting the dropdown to work properly. Originally I populated the dropdown using the viewbag as such:
view:
@Html.DropDownList("CheckIn_Location", ViewBag.CageLocationList as IEnumerable<SelectListItem>, "(Select one)", new { @class = "form-control" })
controller:
public void GetCageLocations()
{
IEnumerable<SelectListItem> selectList =
from c in db.Locations
select new SelectListItem
{
Text = c.LocationName,
Value = c.Id.ToString()
};
ViewBag.CageLocationList = selectList;
}
But that didn't seem to play friendly with server side validation so I am tried reworking my model/view/controllers as such:
Here is my Model:
public class CheckInViewModel
{
public int CheckIn_Id { get; set; }
[Required(ErrorMessage = "Location Required.")]
public IEnumerable<SelectListItem> CheckIn_Location { get; set; }
[Required(ErrorMessage = "Quantity Required.")]
[Range(1, 100, ErrorMessage = "Quantity must be between 1 and 100000")]
public int CheckIn_Quantity { get; set; }
public string CheckIn_Comment { get; set; }
}
Here is my Controller:
[HttpPost]
public ActionResult CheckIn(CheckInViewModel model)
{
if (ModelState.IsValid)
{
var New_Transaction = new Transaction
{
Id = model.CheckIn_Id,
Quantity = model.CheckIn_Quantity,
LocationId = Convert.ToInt32(model.CheckIn_Location),
TransactionDate = DateTime.Now,
TransactionComments = model.CheckIn_Comment.Replace("\r\n", " ")
};
unitOfWork.TransactionRepository.Insert(New_Transaction);
unitOfWork.Save();
return PartialView("CheckIn", model);
}
return PartialView("CheckIn", model);
}
Here is my PartialView called CheckIn.cshtml
@model ViewModels.CheckInViewModel
<!-- Modal -->
<div class="modal fade" id="CheckInModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h1 class="modal-title" id="CheckInModalLabel">Check In</h1>
</div>
<div class="modal-body">
@using (Ajax.BeginForm("CheckIn", "Cage", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "success", OnFailure = "failure"}, new { @id = "CheckInForm", @class = "form-horizontal" }))
{
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.CheckIn_Id, new { @class = "form-control" })
<div class="form-group">
<label for="CheckIn_Location" class="col-sm-4 control-label">Location</label>
<div class="col-sm-8">
@Html.DropDownListFor(x => x.CheckIn_Location, Model.CheckIn_Location, "Select One")
@Html.ValidationMessageFor(model => model.CheckIn_Location)
</div>
</div>
<div class="form-group">
<label for="CheckIn_Quantity" class="col-sm-4 control-label">Quantity</label>
<div class="col-sm-8">
@Html.TextBoxFor(model => model.CheckIn_Quantity, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.CheckIn_Quantity)
</div>
</div>
<div class="form-group">
<label for="CheckIn_Comment" class="col-sm-4 control-label">Comment</label>
<div class="col-sm-8">
@Html.TextAreaFor(model => model.CheckIn_Comment, new { @class = "form-control" })
</div>
</div>
}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="SubmitCheckInForm()">Check In</button>
</div>
</div>
</div>
</div>
here is the JS function that fire the submit:
function SubmitCheckInForm() {
$('#CheckInForm').submit();
}
Can someone show me how to:
- populate the dropdown with (value/text) using the model as the binding agent (not the viewbag as I previously did it)
- return the selected option to the controller and insert it into the transaction table's location element (which is an int)
- properly hook this all up so the server side annotations work and return messages when something is incorrect in the form.
Thanks in Advance!
If I have understood you correctly, there is more than one way to do this. For instance, you could have two properties in your model to manage the Dropdown control.
1- CheckIn_Location_Selected. To store the value selected by the user
2- CheckIn_Location_List. To fill the DropdownList.
This could be your model.
So now in your GET action you could have something like this:
And in your view:
We need to change a bit your POST action.