我正在尝试创建一个调度MVC应用程序。在ViewModel中,我组合了字段(来自CodeFirst EF字段)以包括会议主持人,访问者和时间等。我希望能够从这个表单创建一个新的访问者,如果他们不存在并通过回发Ajax更新可用访问者列表。
视图模型:
public class AppointmentViewModel
{
public int HostID{ get; set; }
public IEnumerable<SelectListItem> HostList{ get; set; }
public int? VisitorID { get; set; }
public IEnumerable<SelectListItem> VisitorList { get; set; }
public string VisitorTitle { get; set; }
public string VisitorFirstName{ get; set; }
public string VisitorSurname { get; set; }
public string VisitorCompany { get; set; }
public DateTime VisitTime { get; set; }
}
控制器:
public class AppointmentController : Controller
{
private VisitorManagerContext db = new VisitorManagerContext();
// GET: Appointment
public ActionResult Create()
{
ViewBag.HostID = new SelectList(db.Hosts.OrderBy(x => x.Name), "id", "Name");
//ViewBag.VisitorID = new SelectList(db.Visitors.OrderBy(x => x.LastName).ThenBy(y => y.FirstName), "id", "VisitorName");
return View(new AppointmentViewModel()
{
HostList = db.Hosts.OrderBy(x => x.Name).Select(y => new SelectListItem()
{
Value = y.id.ToString(),
Text = y.Name
}),
VisitorList = db.Visitors.OrderBy(x => x.LastName).ThenBy(y => y.FirstName).Select(z => new SelectListItem()
{
Value = z.id.ToString(),
Text = z.Title + " " + z.FirstName + " " + z.LastName
})
}
);
}
[HttpPost]
public JsonResult CreateVisitor(AppointmentViewModel model)
{
var visitor = new Visitor()
{
Title = model.VisitorTitle,
FirstName = model.VisitorFirstName,
LastName = model.VisitorSurname
};
db.Visitors.Add(visitor);
db.SaveChanges();
return Json(visitor.id);
}
public PartialViewResult Add()
{
return PartialView();
}
}
查看:
@model VisitorManager.Models.AppointmentViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>AppointmentViewModel</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.HostID, "HostID", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.HostID, Model.HostList, "- Please select -", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.HostID, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.VisitorID, "VisitorID", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.VisitorID, Model.VisitorList, "- Please select -", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.VisitorID, "", new { @class = "text-danger" })
</div>
<button type="button" id="addVisitor">Add new Visitor</button>
</div>
<div id="VisitorModal"></div>
<div class="form-group">
@Html.LabelFor(model => model.VisitTime, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.VisitTime, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.VisitTime, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$('#addVisitor').click(
function () {
$('#VisitorModal').load('@Url.Action("Add", "Appointment")');
}
);
</script>
部分视图:
@model VisitorManager.Models.AppointmentViewModel
<div class="form-group">
@Html.LabelFor(model => model.VisitorTitle, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.VisitorTitle, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.VisitorTitle, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.VisitorFirstName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.VisitorFirstName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.VisitorFirstName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.VisitorSurname, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.VisitorSurname, new { htmlAttributes = new { @class = "form-control", @id="surname" } })
@Html.ValidationMessageFor(model => model.VisitorSurname, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.VisitorCompany, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.VisitorCompany, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.VisitorCompany, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" id="visitorform" />
</div>
</div>
@section Scripts {
<script type="text/javascript">
$('#visitorform').submit(function () {
var data = $(this).serialize();
var url = '@Url.Action("CreateVisitor", "Appointment")';
var text = $('#surname').val(); // a value from the form that you want as the option text
$.post(url, data, function (response) {
if (response) {
$('#HostID').append($('<option></option>').val(response).text(text)).val(response);
} else {
// Oops
}
}).fail(function () {
// Oops
});
// ... close the modal
return false; // cancel the default submit
});
</script>}
我知道应该改进样式,并且应该以模态方式显示新的访问者表单,但我希望在我使逻辑正常工作后修复。
点击&#34;添加新访问者&#34;显示部分视图,包括将新访问者提交回控制器的按钮。单击&#34;创建&#34;部分视图中的按钮关闭视图,但表单数据不会提交回控制器。
关于为什么事件没有解雇的任何想法?
将新访问者添加到DropDownList后,我认为需要填写表单的其余部分并提交约会。
答案 0 :(得分:1)
您没有id="visitorform"
的第二个表单。部分中的元素需要包含在<form>
标记
@model VisitorManager.Models.AppointmentViewModel
<form id="visitorform">
<div class="form-group">
@Html.LabelFor(model => model.VisitorTitle, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.VisitorTitle, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.VisitorTitle, "", new { @class = "text-danger" })
</div>
</div>
.... // other elements for VisitorFirstName, VisitorSurname etc
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</form>
请注意,您需要从部分按钮中删除id="visitorform"
。
您还需要从主视图的<form>
标记中移动部分并将其移动到结尾(嵌套表单是无效的html,不受支持。
@model VisitorManager.Models.AppointmentViewModel
....
@using (Html.BeginForm())
{
.... // elements associated with AppointmentViewModel only
}
// Move the partial/modal here
<div id="VisitorModal"></div>
您还应该将部分脚本移动到主视图中(脚本应该只在主视图或布局中)脚本还需要使用事件委托(.on()
),因为表单是动态的加入
$('#VisitorModal').on('submit', '#visitorform', function () {
var data = $(this).serialize();
....
旁注:您之前的问题遗留了多余的ViewBag.HostID = new SelectList(..)
,应该从控制器方法中删除。