在我的MVC5控制器中,我在我的ViewModel中填写两个列表,如下所示:
public async Task<ActionResult> Create()
{
var db = new ApplicationDbContext();
var model = new RegisterViewModel()
{
RegionsList = db.Regions.ToList().Select(x => new SelectListItem()
{
Selected = false,
Text = x.Name,
Value = x.Name
}),
CompanyList = db.Companies.ToList().Select(x => new SelectListItem()
{
Selected = false,
Text = x.Name,
Value = x.CompanyId.ToString()
})
};
return View(model);
}
然后,在我的视图中,我将公司显示为DropDownList,将Regions显示为一组复选框:
<div class="form-group">
@Html.LabelFor(model => model.CompanyList, new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(c => c.SelectedCompanyId, Model.CompanyList, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.Label("Assign the user to one or more regions", new { @class = "control-label col-md-2" })
<span class=" col-md-10">
@foreach (var item in Model.RegionsList)
{
<input type="checkbox" name="SelectedRegionNames" value="@item.Value" checked="@item.Selected" class="checkbox-inline" />
@Html.Label(item.Value, new { @class = "control-label" })
}
</span>
</div>
这样可行,但由于所有公司的所有地区都显示出来,所以它有点混乱。我想隐藏一组复选框,直到公司被选中,然后隐藏公司下拉列表并显示region.CompanyId ==所选区域的区域列表。
有人可以教我如何做到这一点吗?
答案 0 :(得分:3)
如果您想进行服务器端过滤,那么您的操作顺序可能如下所示:
在第一步中,您所做的一切都不再显示任何区域。所以你在视图模型中不需要它们:
var model = new RegisterViewModel()
{
CompanyList = db.Companies.ToList().Select(x => new SelectListItem()
{
Selected = false,
Text = x.Name,
Value = x.CompanyId.ToString()
})
};
return View(model);
但是你需要一种方法来识别将客户端包含它们的HTML元素。 id
值适用于此:
<span id="regionsSelection" class="col-md-10"></span>
在第二步中,您将change
处理程序附加到拥有公司的select
元素。当然,您需要一种方法来识别该元素。例如,如果它的name
属性为SelectedCompanyId
,那么这应该有效:
$('select[name="SelectedCompanyId"]').change(function () {
});
第三步将涉及在change
处理程序内部进行AJAX调用。但在我们能够做到这一点之前,我们需要一个服务器端控制器动作来根据选定的公司获取区域。我主要猜测你的对象模型细节,但结构将是这样的:
public ActionResult GetRegions(int companyId)
{
var db = new ApplicationDbContext();
var regions = db.Regions.Where(r => r.Companies.Any(c => c.Id == companyId));
return Json(regions);
}
我们的想法是获取与提供的公司ID相关联的区域,并将它们作为JSON数组返回。然后,您可以从change
处理程序中的客户端代码调用该操作。像这样:
$.ajax({
url: '@Url.Action("GetRegions", "MyController")',
type: 'POST',
dataType: 'json',
data: { companyId : $('select[name="SelectedCompanyId"]').val()
}).done(function(response) {
// "response" has the returned data, use it here
}).fail(function(response) {
// There was an error, handle it here
});
那个(或类似的东西)应该从服务器获取区域。 (请注意,我在这里使用了一些服务器端代码来定义URL。)
然后第四步在AJAX调用的done
处理程序中进行,您可以使用响应中的数据创建HTML元素。再一次,我将主要猜测对象的结构。您可能希望在浏览器的调试工具中手动检查实际的JSON响应,以确保它符合您的预期。
如果response
成功地成为区域集合,那么使用它可能看起来像这样:
$('#regionSelection').html('');
for (var i = 0; i < response.length; i++) {
$('#regionSelection').append('<input type="checkbox" name="SelectedRegionNames" value="' + response[i].Name + '" checked="false" class="checkbox-inline" />');
$('#regionSelection').append('<label class="control-label">' + response[i].Name + '</label>');
}
正如您所看到的,首先我清空span
的当前内容(删除之前添加到其中的任何区域复选框。然后我所做的就是将HTML元素附加到手动span
,问题中的代码在初始页面渲染过程中附加它们。
我无法100%保证这是一个满足您需求的复制/粘贴解决方案,因为我不太了解您的模型结构或您的UX或用例来实现此功能。但是,从动态获取服务器中的对象列表以驱动客户端UI,这可以解决问题。
答案 1 :(得分:0)
您有两种选择:
在服务器上过滤(发回表单并返回正确的项目)
在客户端上过滤(第一次发送所有内容并显示/隐藏项目)
可以使用适当的ViewModel完成替代方案:
public class FilteredRegions
{
public FilteredRegions()
{
Regions = new List<Region>();
}
public int SelectedCompanyID { get; set; }
public IEnumerable<SelectListItem> CompanyList { get; set; }
public int SelectedRegionID { get; set; }
public virtual ICollection<Topic> Regions { get; set; }
}
备选方案二(我强烈推荐,基于假设你的地区少于1000个)
将每个区域放在视图中,并在其上添加一个很好的数据属性:
<div class="form-group">
@Html.Label("Assign the user to one or more regions", new { @class = "control-label col-md-2" })
<span class=" col-md-10">
@foreach (var item in Model.RegionsList)
{
<input type="checkbox" name="SelectedRegionNames" value="@item.Value" checked="@item.Selected" class="checkbox-inline hide" data-company="@item.CompanyId" />
@Html.Label(item.Value, new { @class = "control-label" })
}
</span>
</div>
然后将事件句柄附加到下拉菜单,执行以下操作:(未测试)
$('#dropdown').change(function() {
var companyID = $(this).value;
$('input[data-company]').hide();
$('input[data-company="' + companyID + '"]').show();
})
即。当公司选择发生变化时,隐藏所有复选框并显示所有正确的复选框。 你需要jquery代码片段。