You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:27:04