如何在Razor页面点击搜索按钮后新增一组重复输入控件?
解决方案
1. 前端视图修改(cshtml)
调整表单结构,添加动态字段容器和隐藏模板,同时修改JS逻辑实现填充数据后自动新增输入区域:
@page @model Surplus.Pages.FormItems.NewSurplusFormPageModel <!DOCTYPE html> <html> <head> <title>Surplus Form</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-..." crossorigin="anonymous"> </head> <body> <center><h1>@Model.WelcomeMessage</h1></center> <div class="container"> <form method="post" id="surplusForm"> <!-- 初始输入区域 --> <div class="mb-3"> <input type="text" class="form-control" id="assetTag" asp-for="AssetTag" placeholder="Enter CPS Tag Number" /> </div> <div class="mb-3"> <select class="form-control" id="building" asp-for="Building" placeholder="Select Building"> <option value="">Select Building</option> @foreach (var buildingOption in Model.BuildingOptions) { <option value="@buildingOption">@buildingOption</option> } </select> </div> <div class="mb-3"> <input type="text" class="form-control" id="description" asp-for="Description" placeholder="Enter Item Name" /> </div> <div class="mb-3"> <select class="form-control" id="reason" asp-for="Reason" placeholder="Select Reason"> <option value="">Select Reason</option> @foreach (var reasonOption in Model.ReasonOptions) { <option value="@reasonOption.CodeID">@reasonOption.ReasonDescription</option> } </select> </div> <div class="mb-3"> <button type="button" id="searchButton" class="btn btn-primary form-control">Search</button> </div> <!-- 动态字段容器:存放新增的输入区域 --> <div id="dynamicFieldsContainer" class="mb-4"></div> <!-- 隐藏的动态字段模板 --> <div id="fieldTemplate" class="border p-3 mb-3 d-none"> <div class="mb-3"> <input type="text" class="form-control asset-tag-input" name="Items[__index__].AssetTag" placeholder="Enter CPS Tag Number" /> </div> <div class="mb-3"> <select class="form-control building-select" name="Items[__index__].Building" placeholder="Select Building"> <option value="">Select Building</option> @foreach (var buildingOption in Model.BuildingOptions) { <option value="@buildingOption">@buildingOption</option> } </select> </div> <div class="mb-3"> <input type="text" class="form-control description-input" name="Items[__index__].Description" placeholder="Enter Item Name" /> </div> <div class="mb-3"> <button type="button" class="btn btn-primary form-control search-btn">Search</button> </div> </div> <button type="submit" class="btn btn-primary form-control">Submit</button> </form> </div> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $(document).ready(function () { let fieldIndex = 0; // 初始搜索按钮逻辑 $('#searchButton').on('click', function () { const assetTag = $('#assetTag').val().trim(); if (!assetTag) return; $.ajax({ url: '?handler=InputFields', data: { assetTag: assetTag }, method: 'GET', success: function (result) { if (result) { // 填充当前输入字段 $('#building').val(result.Building); $('#description').val(result.Description); // 新增一组输入区域 addNewFieldGroup(); } }, error: function (xhr, status, error) { console.error(error); } }); }); // 动态添加输入区域的函数 function addNewFieldGroup() { const template = $('#fieldTemplate').clone(); template.removeClass('d-none'); // 替换模板中的索引占位符,确保表单绑定正常 const newHtml = template.html().replace(/__index__/g, fieldIndex); template.html(newHtml); $('#dynamicFieldsContainer').append(template); fieldIndex++; // 给新的搜索按钮绑定事件 template.find('.search-btn').on('click', function () { const $group = $(this).closest('.border.p-3'); const assetTag = $group.find('.asset-tag-input').val().trim(); if (!assetTag) return; $.ajax({ url: '?handler=InputFields', data: { assetTag: assetTag }, method: 'GET', success: function (result) { if (result) { $group.find('.building-select').val(result.Building); $group.find('.description-input').val(result.Description); // 继续新增输入区域 addNewFieldGroup(); } }, error: function (xhr, status, error) { console.error(error); } }); }); } }); </script> </body> </html>
2. 后端PageModel调整
修改页面模型,支持多条目表单绑定,并完善搜索接口逻辑:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; namespace Surplus.Pages.FormItems { // 定义单条资产的模型 public class SurplusItem { public string AssetTag { get; set; } public string Building { get; set; } public string Description { get; set; } } // 假设的原因选项模型 public class ReasonOption { public string CodeID { get; set; } public string ReasonDescription { get; set; } } // 页面主模型 public class NewSurplusFormPageModel : PageModel { private readonly YourDbContext _dbContext; public NewSurplusFormPageModel(YourDbContext dbContext) { _dbContext = dbContext; } public string WelcomeMessage { get; set; } = "Surplus Form"; public List<string> BuildingOptions { get; set; } public List<ReasonOption> ReasonOptions { get; set; } // 初始表单字段绑定 [BindProperty] public string AssetTag { get; set; } [BindProperty] public string Building { get; set; } [BindProperty] public string Description { get; set; } [BindProperty] public string Reason { get; set; } // 动态添加的多条目绑定 [BindProperty] public List<SurplusItem> Items { get; set; } = new List<SurplusItem>(); public void OnGet() { // 从数据库加载选项数据 BuildingOptions = _dbContext.Buildings.Select(b => b.Name).ToList(); ReasonOptions = _dbContext.ReasonOptions.ToList(); } // 搜索标签号的接口 public IActionResult OnGetInputFields(string assetTag) { // 查询数据库匹配的资产信息 var asset = _dbContext.Assets.FirstOrDefault(a => a.AssetTag == assetTag); if (asset != null) { return new JsonResult(new { Building = asset.Building, Description = asset.Description }); } return new JsonResult(null); } // 表单提交处理 public IActionResult OnPost() { if (!ModelState.IsValid) { // 重新加载选项,返回页面 BuildingOptions = _dbContext.Buildings.Select(b => b.Name).ToList(); ReasonOptions = _dbContext.ReasonOptions.ToList(); return Page(); } // 这里处理表单提交逻辑,包括初始字段和Items列表 // 示例:保存到数据库 // var mainItem = new Asset { ... }; // _dbContext.Assets.Add(mainItem); // foreach(var item in Items) { ... } // _dbContext.SaveChanges(); return RedirectToPage("/Success"); } } // 假设的数据库上下文,需根据实际情况调整 public class YourDbContext : DbContext { public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) { } public DbSet<Asset> Assets { get; set; } public DbSet<Building> Buildings { get; set; } public DbSet<ReasonOption> ReasonOptions { get; set; } } // 假设的资产模型 public class Asset { public string AssetTag { get; set; } public string Building { get; set; } public string Description { get; set; } } // 假设的建筑模型 public class Building { public string Name { get; set; } } }
关键说明
- 动态表单绑定:通过
Items[__index__].PropertyName的命名格式,Razor Pages可以自动将多个动态字段绑定到List<SurplusItem>集合中 - 模板复用:使用隐藏的模板div,通过克隆并替换索引占位符来快速生成新的输入区域
- 搜索逻辑复用:将搜索逻辑封装成函数,确保初始按钮和新增按钮的行为一致
- 数据库查询:确保
OnGetInputFields方法中正确实现标签号到资产信息的查询逻辑,需根据实际数据库表结构调整
内容的提问来源于stack exchange,提问作者djjailbreak
相关产品推荐
相关产品推荐

