Razor MVC中Dropdownlist选中变更时获取值并动态添加输入项
问题描述
我有一个Tblproduct类,其中包含GetTypes()方法返回SelectListItem列表用于绑定下拉框,代码如下:
public partial class Tblproduct: AuditableEntity { [DisplayName("Product Type")] public int? ProductTypeId { get; set; } public static List<SelectListItem> GetTypes() { List<SelectListItem> datas = new List<SelectListItem>(); datas.Insert(0, new SelectListItem() { Value="",Text=""}); datas.Insert(1, new SelectListItem() { Value= InventoryCatalogueID.ToString(), Text="Inventory Catalogue"}); datas.Insert(1, new SelectListItem() { Value= ServiceCatalogueID.ToString(), Text="Service Catalogue"}); datas.Insert(1, new SelectListItem() { Value= ServiceCatalogueID.ToString(), Text= "Sub-Assembly" }); datas.Insert(1, new SelectListItem() { Value= ServiceCatalogueID.ToString(), Text= "Raw Material" }); datas.Insert(1, new SelectListItem() { Value= ServiceCatalogueID.ToString(), Text= "Finish Good" }); datas.Insert(1, new SelectListItem() { Value= ServiceCatalogueID.ToString(), Text= "Service Catalogue" }); return datas; } }
对应的ViewModel代码:
public ProductVM(Tblproduct _model = null, bool isreadonly = false):base(_model, isreadonly,"ControllerName") { types = Tblproduct.GetTypes(); } public List<SelectListItem> types { get; set; }
已通过View中的select2成功绑定下拉框:
<select2 asp-for="model.ProductTypeId" asp-items="@Model.types"/>
现在需要根据选中的类型添加对应输入项,尝试过用auto-post-back获取选中值,但下拉框总会自动选中第一个选项。期望实现类似如下逻辑:
@if(Model.types = 'Finish Good'){ // 添加新的输入框或下拉框 }
想问如何获取下拉框的SelectedIndex或SelectedText变化来实现需求?
解决方案
方案一:前端JavaScript无刷新处理(推荐)
无需回发页面,直接监听select2的选择事件动态显示/隐藏输入项,步骤如下:
- 在View中给动态区域添加类型标记:
<select2 id="productTypeSelect" asp-for="model.ProductTypeId" asp-items="@Model.types"/> <!-- 动态输入区域 --> <div id="dynamicInputs"> <!-- 成品对应的输入项 --> <div data-type="Finish Good" class="hidden-input"> <label>成品规格</label> <input asp-for="model.FinishGoodSpec" /> </div> <!-- 原材料对应的输入项 --> <div data-type="Raw Material" class="hidden-input"> <label>原材料批次</label> <input asp-for="model.RawMaterialBatch" /> </div> <!-- 其他类型对应区域可按需添加 --> </div> <style> .hidden-input { display: none; } </style>
- 添加JavaScript监听选择事件:
$(document).ready(function() { // 初始化时根据当前选中值显示对应区域 showMatchedInput(); // 监听select2选择事件 $('#productTypeSelect').on('select2:select', function(e) { showMatchedInput(); }); function showMatchedInput() { // 隐藏所有动态区域 $('.hidden-input').hide(); // 获取选中的文本 var selectedText = $('#productTypeSelect option:selected').text().trim(); // 显示对应类型的区域 $('div[data-type="' + selectedText + '"]').show(); } });
方案二:修复后端PostBack后的选中问题
如果必须使用回发方式,需先修正GetTypes()的Value重复问题(当前多个选项Value相同,导致绑定失效),再保留选中状态:
- 修正
Tblproduct.GetTypes(),给每个类型分配唯一Value:
public static List<SelectListItem> GetTypes() { List<SelectListItem> datas = new List<SelectListItem>(); datas.Insert(0, new SelectListItem() { Value="",Text=""}); // 给每个类型分配唯一标识,可根据实际业务调整值 datas.Add(new SelectListItem() { Value= "1", Text="Inventory Catalogue"}); datas.Add(new SelectListItem() { Value= "2", Text="Service Catalogue"}); datas.Add(new SelectListItem() { Value= "3", Text= "Sub-Assembly" }); datas.Add(new SelectListItem() { Value= "4", Text= "Raw Material" }); datas.Add(new SelectListItem() { Value= "5", Text= "Finish Good" }); return datas; }
- 在ViewModel中添加属性记录选中的类型文本:
public ProductVM(Tblproduct _model = null, bool isreadonly = false):base(_model, isreadonly,"ControllerName") { types = Tblproduct.GetTypes(); // 获取当前选中的类型文本 SelectedTypeText = types.FirstOrDefault(t => t.Value == _model?.ProductTypeId?.ToString())?.Text; } public string SelectedTypeText { get; set; } public List<SelectListItem> types { get; set; }
- 在View中开启auto-post-back并根据选中值显示输入项:
<select2 asp-for="model.ProductTypeId" asp-items="@Model.types" asp-post-back="true"/> @if(Model.SelectedTypeText == "Finish Good"){ <div> <label>成品规格</label> <input asp-for="model.FinishGoodSpec" /> </div> } @if(Model.SelectedTypeText == "Raw Material"){ <div> <label>原材料批次</label> <input asp-for="model.RawMaterialBatch" /> </div> }
内容的提问来源于stack exchange,提问作者tryingtocode
相关产品推荐
相关产品推荐

