向表单添加动态列表元素和客户端验证

问题描述 投票:0回答:1

我想将类类型 Food 的元素添加到表单中。当用户单击某个按钮时,应显示包含两个元素的行:

  • 一个下拉列表来选择食物类型
  • 金额的输入元素。 当表单发布到后端时,动态添加的元素需要绑定到名为 FoodItems 的 List 属性。
public class Food {
    public int SelectedFoodItemId {get; set;}
    public int Amount {get; set;}
}

我的 Razor 页面有以下内容:

[Bind Property]
public InputModel Input {get; set;}

public class InputModel{
    public List<Food> FoodItems {get; set;}
    public List<SelectListItem> FoodItemsSelectList {get; set;}
    
    // Other properties to be displayed left out for brevity
}

我应该如何向页面添加新元素并启用客户端验证(使用默认的 JQuery 验证和 Unobtrusive Validation),以便添加的元素正确绑定到后端的列表(FoodItems)?

我尝试使用javascript来实现这一点,我有一个变量计数器来跟踪向用户显示了多少元素(食物数据行)并使用它和Ajax调用控制器(必须将MVC添加到程序中) ) 获取 FoodItemsSelectList(填充下拉列表)的 Json 数据的操作方法通过操作 Id 和 Name 字段生成新的 Food 数据行,以便后端模型绑定和客户端重新启用正常工作。它有效,但我觉得这需要大量工作,并且有一种更简单的方法可以做到这一点。

asp.net-core asp.net-core-mvc razor-pages unobtrusive-validation
1个回答
0
投票

我应该如何向页面添加新元素并启用客户端 侧面验证(使用默认的 JQuery 验证和 Unobtrusive 验证)以添加的元素正确绑定到的方式 后端列出(FoodItems)?

嗯,根据您的场景和描述,这可以通过多种方式完成。最简单的方法之一是使用 javascript

addEventListener
以及表单提交。

当您点击“提交”按钮时,应该有一个函数可以使用 JavaScript 使用原始 html 字符串插值创建动态。在该函数中,您还可以设置验证功能。

让我们看看如何实现这一目标。

为了模拟您的场景,我使用了以下方式:

Razor.cs 页面:

public class FoodModel : PageModel
{
    [BindProperty]
    public InputModel Input { get; set; }

    public class InputModel
    {
        public List<Food> FoodItems { get; set; }
        public List<SelectListItem> FoodOptions { get; set; }
    }

    public class Food
    {
        public int SelectedFoodItemId { get; set; }
        public int Amount { get; set; }
    }

    public void OnGet()
    {
        
        var foodOptions = new List<SelectListItem>
        {
            new SelectListItem { Value = "1", Text = "Option 1" },
            new SelectListItem { Value = "2", Text = "Option 2" },
            new SelectListItem { Value = "3", Text = "Option 3" }
            
        };

        Input = new InputModel
        {
            FoodItems = new List<Food>(),
            FoodOptions = foodOptions
        };
    }

    public IActionResult OnPost(IFormCollection formData)
    {
       

        var dynamicFormDataDictionary = new Dictionary<string, object>();

        foreach (var item in formData)
        {

            dynamicFormDataDictionary.Add(item.Key, item.Value);
            dynamicFormDataDictionary.Remove("__RequestVerificationToken");
        }

        return Page();
    }
}

Razor.cshtml 页面:

@page
@model RazorPageDemoApp.Pages.FoodModel

<form method="post">
    <div id="foodItemsContainer">
        
    </div>
    <br />
    <button type="button" id="addFoodRow" class="btn btn-primary">Add Food Row</button>

    <button type="submit" class="btn btn-success">Submit</button>
</form>

@section Scripts {
    <script>
        document.addEventListener("DOMContentLoaded", function () {
            const addFoodRowButton = document.getElementById("addFoodRow");
            const foodItemsContainer = document.getElementById("foodItemsContainer");
            let counter = 0;

            addFoodRowButton.addEventListener("click", function () {
                counter++;

                const rowHtml = `
                            <div class="food-row">
                                <select name="Input.FoodItems[${counter}].SelectedFoodItemId" class="food-dropdown" required>
                                   @foreach (var option in Model.Input.FoodOptions)
                                        {
                                            <option value="@option.Value">@option.Text</option>
                                        }
                                </select>
                                <input type="number" name="Input.FoodItems[${counter}].Amount" class="food-amount" required />
                                <div class="invalid-feedback">This field is required.</div>
                            </div>
                        `;

                foodItemsContainer.insertAdjacentHTML("beforeend", rowHtml);
            });

            // Validation for dynamically added elements
            document.querySelector('form').addEventListener('submit', function (event) {
                if (foodItemsContainer.children.length === 0) {
                    event.preventDefault();
                    alert("You haven't added any data.");
                } else {
                    const invalidFields = this.querySelectorAll(':invalid');
                    if (invalidFields.length > 0) {
                        event.preventDefault();
                        invalidFields.forEach(function (field) {
                            field.classList.add('is-invalid');
                        });
                    }
                }
            });
        });
    </script>
}

输出:

注意:如果您想了解其他方法,请在新帖子中分享您的问题并提供更具体的详细信息。另外,你可以看看这个官方文档

© www.soinside.com 2019 - 2024. All rights reserved.