使用 Razor Page Partial 创建动态 html table 日期

Create dynamic html table of dates using Razor Page Partial

我正在开发 .NET Core 3.1 Razor 页面应用程序。

请求

我需要创建一个页面,允许用户 select 一个日期,将 X 天添加到该日期,然后生成一个 table 包含那些能够添加的日期每个日期的值。

接近

我有一个页面允许用户 select 一个开始日期(使用日期选择器)和一个数字(来自下拉列表)代表要添加到开始日期。

一旦用户点击设置按钮,就会对我的页面模型中的获取处理程序进行 JQuery 和 Ajax (GET) 调用:

JQuery/Ajax

<script type='text/javascript'>
$(document).ready(function () {
    //alert("Ready!");

    $("#load").click(function () {
        //alert("button");
        var startDate = $("#StartDate").val();
        var duration = $('#Duration').val();
        var turl = '/SPC/Index?handler=CarPartial&StartDate=' + startDate + '&Duration=' + duration;        
            $('#spc_data_table').load(turl);
        
    });

});

CSHTML

<div class="row">
 <div id="spc_data_table" class="col-md-12">


 </div>
</div>

页面模型

[BindProperty]
public IList<SpcTable> data { get; set; }

public class SpcTable
{
    public int id { get; set; }
    public string tableDate { get; set; }
    public string tableValue { get; set; }
}

public PartialViewResult OnGetCarPartial(string StartDate, string Duration)
    {
        data = new List<SpcTable>();
        var EndDate = Convert.ToDateTime(StartDate).AddDays(Convert.ToDouble(Duration) - 1);
        int count = 0;

        for (var date = Convert.ToDateTime(StartDate); date <= EndDate; date = date.AddDays(1))
        {
            data.Add(new SpcTable { id = count, tableDate = date.ToShortDateString(), tableValue = null });
            count++;
        }

        return Partial("_SpcTable", data);
    }

部分

<script type='text/javascript'>
$(document).ready(function () {

    $('#submit').on('click', function (evt) {
        evt.preventDefault();
        $.post('', $('form').serialize(), function () {
            alert('Posted using jQuery');
        });
    });

});
<table class="table">
    <tr>
        <td></td>
        <td>Date</td>
        <td>Value</td>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                <input type="hidden" name="data.Index" value="@item.id" />
                <input type="hidden" name="data[@item.id].id" value="@item.id" />
                @item.id
            </td>
            <td><input name="data[@item.id].tableDate" value="@item.tableDate" class="form-control form-control-sm" readonly/></td>
            <td><input name="data[@item.id].tableValue" value="@item.tableValue" class="form-control form-control-sm" /></td>

        </tr>
    }

</table>

<div class="form-group row">
    <button class="btn btn-primary" id="submit">Submit</button>
</div>

然后以 HTML table 的形式返回部分页面,它将包含每个日期的一行。然后用户在每个日期旁边添加一个值,然后通过另一个 JQuery/Ajax 调用 (POST)

提交表单

但是,如果用户想要增加或减少 table 中的天数,他们会 select 从下拉列表中选择不同的数字并重新加载部分,但是,他们将根据 table 内的初始日期输入的所有初始值都将丢失。

我的问题

  1. 是否有更好的方法来创建我的请求?
  2. 如果没有,有没有办法让 table 值保留在部分中,即使它已重新加载?

谢谢。

当您为tableDate设置tableValue时,您可以添加一个onchange事件来监控tableValue是否改变。然后将值添加到列表并将其作为 json 字符串传递给后端。在后端,你可以反序列化这个 json 并与新的 tableDate 进行比较,将值添加到现有的 tableDate.

这是一个工作演示:

查看:

@page
@model IndexModel
<form>
    <input id="StartDate" type="date" />
    <select id="Duration">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
    </select>
    <input type="button" id="load" value="set" />
    <div class="row">
        <div id="spc_data_table" class="col-md-12">
   
        </div>
    </div>
</form>

视图中的 JS:

@section Scripts
{
<script>
    var obj = {};
    $(document).ready(function () {
        $("#load").click(function () {
            var startDate = $("#StartDate").val();
            var duration = $('#Duration').val();
            var turl = '?handler=CarPartial&StartDate=' + startDate + '&Duration=' + duration;
            if (jQuery.isEmptyObject(obj)) {
                $('#spc_data_table').load(turl);
            }
            else {
                turl = turl + "&json=" + JSON.stringify(obj);
                $('#spc_data_table').load(turl);
                obj = {};   
            }
        });

    });
    function saveValue(objectValue) {
        var value = objectValue.value;
        var keyName = $(objectValue).closest("td").prev("td").find("input").val()
        obj[keyName] = value;
    }
</script>
}

局部视图:

<table class="table">
    <tr>
        <td></td>
        <td>Date</td>
        <td>Value</td>
    </tr>  
    @foreach (var item in Model)
    {
        <tr>
            <td>
                <input type="hidden" name="data.Index" value="@item.id" />
                <input type="hidden" name="data[@item.id].id" value="@item.id" />
                @item.id
            </td>
            <td><input name="data[@item.id].tableDate" value="@item.tableDate" class="form-control form-control-sm" readonly /></td> 
                         //add this event....
            <td><input onchange="saveValue(this);" name="data[@item.id].tableValue" value="@item.tableValue" class="form-control form-control-sm" /></td>

        </tr>
    }

</table>

页面模型:

public class IndexModel : PageModel
{
    public IActionResult OnGet()
    {

        return Page();
    }

    [BindProperty]
    public IList<SpcTable> data { get; set; }

    public class SpcTable
    {
        public int id { get; set; }
        public string tableDate { get; set; }
        public string tableValue { get; set; }
    }
    public PartialViewResult OnGetCarPartial(string StartDate, string Duration, string json)
    {

        data = new List<SpcTable>();
        var EndDate = Convert.ToDateTime(StartDate).AddDays(Convert.ToDouble(Duration) - 1);
        int count = 0;

        for (var date = Convert.ToDateTime(StartDate); date <= EndDate; date = date.AddDays(1))
        {
            data.Add(new SpcTable { id = count, tableDate = date.ToShortDateString(), tableValue = null });
            count++;
        }
        //judge if the set tableValue for tableDate in frontend
        if (!string.IsNullOrEmpty(json))
        {
            //deserialize to the model
            var model = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json);
            foreach (var item in model)
            {
                foreach (var date in data)
                {
                    //if you set value for tableDate
                    //and the tableDate still exist after filtering
                    if (item.Key == date.tableDate)
                    {
                        //set the value for this tableDate
                        date.tableValue = item.Value;
                    }
                }
            }
        }
        return Partial("_SpcTable", data);
    }

}

注:

如果您进行了第二次操作,onchange 事件将被触发。也就是说,当你填写一个input时,需要选择一个select或者填写另一个input或者点击页面白色space来触发onclick事件