2016-10-11 17 views
0

私はjQueryを使用して動的に行を追加しているかみそりビューページにフォームを持っています。動的に作成されたフィールドを配列にバインドして、配列を1つずつ参照してデータベースのテーブルに挿入できるようにしたい。問題は、フィールドが配列ではなく個々のフィールドとして "FormCollection"に表示されることです。asp.net mvcでフォーム提出時に動的に作成されたフィールドを配列にバインドする方法は?

ビューページの添付画像を参照してください:新しい行を追加する enter image description here

jQueryのスクリプト:

$(function() { 
    var tableRowNum = 1; 
    $("#add-work-row").click(function() { 
     tableRowNum++; 
     var tableRow = "<tr>"; 
     tableRow += "<td><input name='works[" + (tableRowNum - 1) + "].workCover' type='checkbox' class='text' /></td>"; 
     tableRow += "<td><input name='works[" + (tableRowNum - 1) + "].workTitle' type='text' class='text work-title caps' /></td>"; 
     tableRow += "<td><input name='works[" + (tableRowNum - 1) + "].workComposers' type='text' class='text work-composer caps' /></td>"; 
     tableRow += "<td><input name='works[" + (tableRowNum - 1) + "].workPerformances' type='text' class='text work-performances' /></td>"; 
     tableRow += "<td><input name='works[" + (tableRowNum - 1) + "].workDuration' type='text' class='text work-duration input-duration' /></td>"; 
     tableRow += "<td><a href='#' class='delete-row'></a></td>"; 
     tableRow += "</tr>"; 
     $("#worksTable").append(tableRow); 
     return false; 
    }); 
}); 

コントローラのアクションは次のとおりです。新しいを追加するための

public ActionResult CreateReport(FormCollection form) 
{ 
    // works is null? 
    var works = form["works"];   
    foreach (var work in works) 
    { 
     // Do something     
    } 
    return null; 
} 
+2

'FormCollection'を使用しないMVCでは、モデルにバインドします。また、新しい行やバインドする必要のあるモデルをどのように生成するかを示していません。 –

+0

'FormCollection'の代わりに' IEnumerable 'を使います。ここで' YourViewModel'はテーブルの行を表します。モデルバインディングに関するPhil Haackの記事を参照してください。http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ – erdinger

+0

@StephenMuecke、私は行を追加するjqueryスクリプトを追加しましたテーブルに。おそらく、プロパティworks []を持つモデルを作成してバインドすることができます。しかし、別のSOの答えでは、フィールドを "works [0] .fieldName"という名前にすると、 "works"という名前の配列にバインドされます。このコンセプトはここでは機能しませんでした。 – TejSoft

答えて

0

スクリプト行は次のようになります。

入力フィールド名に接頭辞worksがあることに注意してください。これは、MVCコントローラのアクションで使用されます。

また、worksPerformedCollectionは、 "Works Performed"セクションの行を含むviewmodelのプロパティの名前と同じです。

index(具体的には、works.worksPerformedCollection.index)は、1行あたりの入力をグループ化するために使用されます。 tableRowNumが連続している場合は必要ありませんが、そうでない場合は必要です。行を削除するUIの機能があるため、行番号が順番に並んでいない可能性があります。あなたは以下のクラスを持っているサーバー側で

「パフォーマンス詳細」セクションの入力フィールドが works.performanceDateworks.performerNameとして指名されなければならない
$(function() { 
    var tableRowNum = 1; 
    $("#add-work-row").click(function() { 
     tableRowNum++; 
     var tableRow = "<tr>"; 
     // Index value for grouping (non-sequential) rows. 
     tableRow += "<td><input type='hidden' name='works.worksPerformedCollection.index' value=" + (tableRowNum - 1) + " /></td>"; 
     // Checkbox. 
     tableRow += "<td><input name='works.worksPerformedCollection[" + (tableRowNum - 1) + "].workCover' type='checkbox' class='text' value='true' />"; 
     tableRow += "<input type='hidden' name='works.worksPerformedCollection["+ (tableRowNum - 1) +"].workCover' value='false' /></td>"; 

     tableRow += "<td><input name='works.worksPerformedCollection[" + (tableRowNum - 1) + "].workTitle' type='text' class='text work-title caps' /></td>"; 
     tableRow += "<td><input name='works.worksPerformedCollection[" + (tableRowNum - 1) + "].workComposers' type='text' class='text work-composer caps' /></td>"; 
     tableRow += "<td><input name='works.worksPerformedCollection[" + (tableRowNum - 1) + "].performances' type='text' class='text work-performances' /></td>"; 
     tableRow += "<td><input name='works.worksPerformedCollection[" + (tableRowNum - 1) + "].duration' type='text' class='text work-duration input-duration' /></td>"; 
     tableRow += "<td><a href='#' class='delete-row'></a></td>"; 
     tableRow += "</tr>"; 
     $("#worksTable").append(tableRow); 
     return false; 
    }); 
}); 

など

public class PerformanceViewModel 
{ 
    [Required] 
    public DateTime PerformanceDate { get; set; } 

    [Required] 
    public string PerformerName { get; set; } 

    // ... 

    public IEnumerable<WorksPerformedViewModel> WorksPerformedCollection { get; set; } 
} 

public class WorksPerformedViewModel 
{ 
    public bool WorkCover { get; set; } 
    public string WorkTitle { get; set; } 
    public string WorkComposers { get; set; } 
    public int? Performances { get; set; } 
    public TimeSpan? Duration { get; set; } 
} 

これはMVCコントローラにあります。

[HttpPost] 
public ActionResult CreateReport(PerformanceViewModel works) 
{ 
    // ... 
} 

コントローラのアクションがworksとしてのviewmodelを受け入れることに注意してください - これは、クライアント側の入力フィールドに名前を付けるときに使用したのと同じ接頭辞です。

関連する問題