我能够在我的index.cshtml页面上的表单上最初将视图模型传递给编辑器模板页面。在索引页面上,我有一个提交按钮,将表单结果(编辑器模板中的单选按钮组)发布回控制器,在HttpPost方法中,它将此模型传递给部分视图,该视图显示在模式弹出窗口中。所有这一切都显示了所选的表单元素,但它禁用了用户的单选按钮。用户可以从此处返回(关闭窗口)或确认表单结果。当用户单击确认按钮时,它应该将viewmodel传递回控制器到另一个HttpPost方法,然后该方法将处理表单结果并返回最终的确认视图。但是当我尝试将视图模型从模态弹出窗口传递回控制器时,它不会保留绑定。我试图确保所有内容都通过Hidden输入绑定,但我必须在某处丢失某些内容。也许我会以错误的方式解决这个问题。我只需要基本保持viewmodel绑定从初始帖子,并能够在用户从模态弹出窗口确认选择后处理。什么是最好的方法来实现这一点,而不必在那里进行会话黑客?
索引
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "ballotForm" }))
{
@Html.AntiForgeryToken()
@(Html.EditorFor(m => m.BallotViewModel, new ViewDataDictionary(ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = "BallotViewModel"
}
}))
<table class="col-sm-12">
<tr>
<td class="pull-right">
<button type="submit" class="btn btn-primary" data-target="#modal-container" data-toggle="modal">Vote Management Ballot</button>
</td>
</tr>
</table>
}
控制器 - 初始发布到模态弹出窗口
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(HomeViewModel bModel)
{
if (ModelState.IsValid)
{
//set property to identity view
bModel.BallotViewModel[0].IsVoteConfirmationView = true;
return PartialView("ViewVoteConfirmation", bModel);
}
}
控制器 - 从模态弹出窗口确认提交后发布
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ConfirmVote(HomeViewModel cModel)
{
//Process form results here but model is null
//Go to Thank You View
return View();
}
ViewVoteConfirmation:
@model Ballot.WebUI.Models.HomeViewModel
<div class="row">
@(Html.EditorFor(m => m.BallotViewModel, new ViewDataDictionary(ViewData) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "BallotViewModel" } }))
</div>
@using (Html.BeginForm("ConfirmVote", "Home", FormMethod.Post, new { id = "ballotConfirmVoteForm" }))
{
@Html.AntiForgeryToken()
<div class="row">
@Html.EditorFor(m => m.BallotViewModel[0].Proposals, "Proposals", new ViewDataDictionary(ViewData)
{
TemplateInfo = new TemplateInfo
{
HtmlFieldPrefix = "Proposals"
}
})
</div>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<button type="button" class="btn btn-default"
data-dismiss="modal">
Cancel
</button>
<button type="submit" id="approve-btn"
class="btn btn-danger">
Confirm
</button>
</div>
</div>
}
ProposalViewModel:
public class ProposalViewModel
{
public int ProposalItemID { get; set; }
public string ProposalItemTitle { get; set; }
public string Option0_Name { get; set; }
public string Option1_Name { get; set; }
public string Option2_Name { get; set; }
public string Option3_Name { get; set; }
public string PercOfShare { get { return "% of Share"; }}
public bool IsHeader { get; set; }
public int TagOrder { get; set; }
public int SelectedVoteOption { get; set; }
public bool IsVoteConfirmationView { get; set; }
public bool IsCumulative { get; set; }
public int SharePercentage { get; set; }
public List<VoteOptionViewModel> lVoteOptions { get; set; }
}
提案:
@model List<Ballot.WebUI.Models.ProposalViewModel>
@for (int i = 0; i < Model.Count; i++)
{
@Html.HiddenFor(m => m[i].ProposalItemID)
@Html.HiddenFor(m => m[i].ProposalItemTitle)
@Html.HiddenFor(m => m[i].Option0_Name)
@Html.HiddenFor(m => m[i].Option1_Name)
@Html.HiddenFor(m => m[i].Option2_Name)
@Html.HiddenFor(m => m[i].Option3_Name)
@Html.HiddenFor(m => m[i].PercOfShare)
@Html.HiddenFor(m => m[i].IsHeader)
@Html.HiddenFor(m => m[i].TagOrder)
@Html.HiddenFor(m => m[i].SelectedVoteOption)
@Html.HiddenFor(m => m[i].IsVoteConfirmationView)
@Html.HiddenFor(m => m[i].IsCumulative)
@Html.HiddenFor(m => m[i].lVoteOptions)
@Html.HiddenFor(m => m[i].SharePercentage)
}
用于更改SharePercentage标签值的jquery脚本
$(function () {
//When 'For' is Selected
$('[class$=PercOfShareFor]').on('click', function (e) {
if ($(this).is(':checked')) {
var forMatches1 = 0;
$('[class$=PercOfShareFor]').each(function (i, val) {
if ($(this).is(':checked')) {
//check how many 'For' Vote Options are selected
forMatches1++;
//select the Share Percentage value label in the same row, and change the class to ForSelected (used as selector)
$(this).closest('td').next('td').next('td').find('.SharePercentage')
.removeClass("SharePercentage")
.addClass("SharePercentageForSelected");
//if the Share Percentage class (used as selector) was previously WithholdSelected then change to ForSelected
$(this).closest('td').next('td').next('td').find('.SharePercentageWithholdSelected')
.removeClass("SharePercentageWithholdSelected")
.addClass("SharePercentageForSelected");
}
});
//divide total 'For' Selections by number of Director Proposals
var forPercent1 = 100 / forMatches1;
//format the percentage to display 2 decimal places if not a whole number
var forPercent2 = Math.round(forPercent1 * 100) / 100;
//Update 'For' Percentages
$('[class$=SharePercentageForSelected]').text(forPercent2);
}
});
//When 'Withhold' is Selected after initially selecting 'For'
$('[class$=PercOfShareWithhold]').on('click', function (e) {
if ($(this).is(':checked')) {
var forMatches = 0;
$('[class$=PercOfShareFor]').each(function (i, val) {
if ($(this).is(':checked')) {
//check how many 'For' Vote Options are still selected
forMatches++;
}
});
var withholdMatches = 0;
$('[class$=PercOfShareWithhold]').each(function (i, val) {
if ($(this).is(':checked')) {
//check how many 'Withhold' Vote Options are still selected
withholdMatches++;
//set the class to WithholdSelected
$(this).closest('td').next('td').find('.SharePercentageForSelected')
.removeClass("SharePercentageForSelected")
.addClass("SharePercentageWithholdSelected")
.text("0"); //Set 'Withhold' Percentage back to 0
}
});
//divide total 'For' Selections by number of Director Proposals
var forPercent1 = 100 / forMatches;
//format the percentage to display 2 decimal places if not a whole number
var forPercent2 = Math.round(forPercent1 * 100) / 100;
//Update 'For' Percentages
$('[class$=SharePercentageForSelected]').text(forPercent2);
}
});
});
答案 0 :(得分:0)
你不能通过表格帖子做你想做的事情。浏览器将Post作为完整的HTML页面返回(即使您说它是部分服务器端)。您将需要使用某种形式的JavaScript来完成它,或者您需要使您的确认页面成为实际页面而不是模态弹出窗口。
基本前提是你需要通过javascript捕获提交(或按钮点击)然后显示模态。您可以使用第一个操作的结果填充模态,但您需要通过ajax而不是标准表单帖子提交表单。然后根据他们在模态中的选择,你可以提交或不提交表格。
已有多种资源可供您使用。这是一个展示如何display a confirmation for a delete action的人。然后你可以改变那个javascript,通过ajax加载你的第一个动作的结果,就像这篇关于加载MVC partial views using AJAX或者关于使用jQuery dialog for CRUD operations的关于加载{{3}}的文章一样,这个文章很可能。
答案 1 :(得分:0)
模型绑定修复是为BallotViewModel的EditorTemplate添加一个隐藏字段,这样当选择单选按钮时,标签不仅会更改值,而且隐藏字段也会更改值。
编辑模板
@ Html.HiddenFor(m =&gt; Model.Proposals [i] .SharePercentage,new {@class =&#34; hdnSharePercentage&#34;}) @ Html.LabelFor(m =&gt; Model.Proposals [i] .lVoteOptions [j] .SharePercentage,Model.Proposals [i] .lVoteOptions [j] .SharePercentage,new {@class =&#34; SharePercentage&#34; })
的jQuery $(本).closest(&#39; TD&#39;)。下一个(&#39; TD&#39;)。下一个(&#39; TD&#39;)。找到(&#39; .hdnSharePercentageWithholdSelected&# 39) .removeClass(&#34; hdnSharePercentageWithholdSelected&#34) .addClass(&#34; hdnSharePercentageForSelected&#34);