簡體   English   中英

Model 在表單中綁定可編輯的表格字段(Razor 頁面)

[英]Model Binding editable table fields within a form (Razor Pages)

我的 Asp.Net 6 - Razor 頁面應用程序在表單中有一個可編輯的表格。

我正在嘗試將可編輯的表字段綁定到 model 但不確定如何執行此操作,因為td字段不能與asp-for標記幫助程序一起使用。

我希望能夠從頁面模型的OnPost()方法中的表中檢索已編輯的值。

這些是我要從中檢索值的兩個可編輯表列的 ID:

  • 對於id="importColumn" ,當用戶單擊一個單元格時,該列的單元格值會使用 Javascript on-click 處理程序從勾號更改為叉號。

  • 對於id="modifiedColumnNames" ,用戶修改此列中任何單元格的值。

.cshtml 表格:

<form method="post" asp-antiforgery="true">
   <table id="columnsToImportTable" class="display roundedCorners" width="100%">
      <thead>
         <tr>
            <th class="centreText">Column Name</th>
            <th class="centreText">Import Column</th>
            <th class="centreText">Database Column Name</th>
         </tr>
      </thead>
      <tbody>
         @for (var i = 0; i < Model.newLayer.ColumnNames.Count(); i++)
         {
         <tr>
            <td class="greyOutBackground centreText defaultCursor">@Model.newLayer.ColumnNames[i]</td>
            <td id="importColumn" class="greyOutBackground centreText pointerCursor green tick true">&#10004;
               <input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="true">
            </td>
            <td id="modifiedColumnNames">
               <div contenteditable>@Model.newLayer.ColumnNames[i]</div>
               <input type="hidden" asp-for="@Model.newLayer.ColumnNames[i]">
            </td>
         </tr>
         }
      </tbody>
   </table>
   <div>
      <input id="importButton" type="submit" value="Import">
   </div>
</form>

Javascript/Jquery 點擊處理程序:

$('#columnsToImportTable td.tick').click(function(e) {
    e.stopPropagation();
    e.preventDefault();
    var $this = $(this);

    if ($this.hasClass('true')) {
        $this.html('<td id="importColumn" class="greyOutBackground centreText pointerCursor red tick false centreElement">&#10006;<input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="false"></td>');
    } else {
        $this.html('<td id="importColumn" class="greyOutBackground centreText pointerCursor green tick true centreElement">&#10004;<input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="true"></td>');
    }

    $this.toggleClass('true');
});

Model:

public class NewLayer
    {
        public List<string> ColumnNames { get; set; } = new List<string>();
        public List<string> ColumnDataTypes { get; set; } = new List<string>();
        public List<string> LayerNames { get; set; } = new List<string>();
        public List<string> ImportColumn { get; set; } = new List<string>();
        public string SelectedLayer { get; set; } = null!;
        public string SelectedNameField { get; set; } = null!;
    }

頁面 Model:

public class IndexModel: PageModel {
  private FileProcessor _FileProcessor = new FileProcessor();
  private AppContext _context;

  [BindProperty(SupportsGet = true)]
  public NewLayer newLayer {get;set;}

  public IndexModel(AppContext context) {
    _context = context;
    newLayer = new NewLayer();
  }

  public void OnGet() {
    var filePath = "[FilePath]";

      var ColumnNamesAndDatatypes = _FileProcessor.GetColumnNamesAndTypes(filePath);

      for (var i = 0; i < ColumnNamesAndDatatypes.Count(); i++) {
        newLayer.ColumnNames.Add(ColumnNamesAndDatatypes[i].ColumnName);
        newLayer.ColumnDataTypes.Add(ColumnNamesAndDatatypes[i].DataType);
        newLayer.ImportColumn.Add("true");
      }

      newLayer.LayerNames = _context.Layers.Select(l => l.LayerName).ToList();
  }

  public void OnPost(NewLayer newLayer) {
    var test = this.newLayer;
  }
}

由於您使用Model Binding方法提交表單並將數據從客戶端傳輸到后端,因此我們應該根據視圖model和索引來設置隱藏字段的名稱屬性。

對於importColumn列,當用戶單擊單元格時,可以使用clone()方法獲取importColumn隱藏字段,然后更改其 value 屬性,最后將其添加到新的td元素中。

對於modifiedColumnNames列,當用戶修改值時,需要將 contenteditable 的 div 內容復制到隱藏字段。 您可以使用 div 的input事件。

您可以參考以下代碼:

Html 元素:為 modifiedColumnNames 隱藏字段添加 class。

<form method="post" asp-antiforgery="true">
   <table id="columnsToImportTable" class="display roundedCorners" width="100%">
      <thead>
         <tr>
            <th class="centreText">Column Name</th>
            <th class="centreText">Import Column</th>
            <th class="centreText">Database Column Name</th>
         </tr>
      </thead>
      <tbody>
         @for (var i = 0; i < Model.newLayer.ColumnNames.Count(); i++)
         {
         <tr>
            <td class="greyOutBackground centreText defaultCursor">@Model.newLayer.ColumnNames[i]</td>
            <td id="importColumn" class="greyOutBackground centreText pointerCursor green tick true">&#10004;
               <input type="hidden" asp-for="@Model.newLayer.ImportColumn[i]" value="true">
            </td>
            <td id="modifiedColumnNames">
               <div class="editdiv" contenteditable>@Model.newLayer.ColumnNames[i]</div>
               <input type="hidden" asp-for="@Model.newLayer.ColumnNames[i]">
            </td>
         </tr>
         }
      </tbody>
   </table>
   <div>
      <input id="importButton" type="submit" value="Import">
   </div>
</form>

JS代碼:

<script>
    $(function(){
        $('#columnsToImportTable td.tick').click(function(e) {
            e.stopPropagation();
            e.preventDefault();
            var $this = $(this);
            // get the ImportColumn hidden field.
            var hiddentag = $(this).find("input[type='hidden']").clone();
            if ($this.hasClass('true')) {
                //change the hidend field' value 
                $(hiddentag).attr("value","false");
                //get the html 
                var newtag = $(hiddentag)[0].outerHTML;
                $this.html('<td id="importColumn" class="greyOutBackground centreText pointerCursor red tick false centreElement">&#10006;' + newtag + '</td>');
            } else {
                $(hiddentag).attr("value","true");
                var newtag = $(hiddentag)[0].outerHTML;
                $this.html('<td id="importColumn" class="greyOutBackground centreText pointerCursor green tick true centreElement">&#10004;' + newtag + '</td>');
            }
            $this.toggleClass('true');
        });
        //
        $(".editdiv").each(function(index, item){
            $(item).on('propertychange input', function (e) {
                $(this).next("input[type='hidden']").val($(this).text());
            });
        });
    });
</script>

索引.cshtml.cs:

public class IndexModel : PageModel
{
    //private FileProcessor _FileProcessor = new FileProcessor();
    //private AppContext _context;

    [BindProperty(SupportsGet = true)]
    public NewLayer newLayer { get; set; }

    public IndexModel()
    { 
        newLayer = new NewLayer();
    }

    public void OnGet()
    { 
        for (var i = 0; i < 3; i++)
        {
            newLayer.ColumnNames.Add("Name " + i.ToString());
            newLayer.ColumnDataTypes.Add("DataType " + i.ToString());
            newLayer.ImportColumn.Add("true");
        }

        newLayer.LayerNames = new List<string>() { "L1", "L2" };
    }

    public void OnPost(NewLayer newLayer)
    {
        var test = this.newLayer;
    }
}

結果是這樣的:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM