2013-01-08 19 views
6

私は、検索フィールドとして使用されるチェックボックス、ラジオボタン、およびテキストボックスのコレクションを持つフォームを持つMVC4ページを持っています。投稿時に選択が解析され、下位結果グリッドが新しい結果で更新されます。現在、すべてのフォーム値は返却時に消去され、新しい結果がグリッドに表示されます。グリッドのみがモデルの一部です。投稿後のフォーム値の保持

私はすべてのフォーム選択が投稿後に値を保持したいので、ユーザーは次の投稿/検索の選択を見る(そして変更する)ことができます。フォームには、ビューバッグが追加されています。

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "searchform" })) 
{ 
    @Html.ValidationSummary("Please correct the following errors") 

<div style="float:left;"> 

    <div style="float:left;"> 
    <label>Name:</label> 
    @Html.TextBox("name") 
    </div> 

    <div style="float:left; margin-left:15px"> 
    <label>Company:</label> 
    @Html.TextBox("company") 
    </div> 

    <div style="float:left; margin-left:65px"> 
    <label>Date Range:</label> 
    @Html.TextBox("dateStart", "", new { @class = "datefield", type = "date" }) 
    &nbsp;to&nbsp; 
    @Html.TextBox("dateEnd", "", new { @class = "datefield", type = "date" }) 
    </div> 

</div> 

<div style="clear: both;"> 
    Match Any Categories? <input type="radio" name="categoryMatchAll" value="false" checked="checked" />&nbsp;&nbsp;&nbsp; 
    Match All Categories? <input type="radio" name="categoryMatchAll" value="true" /> 
</div> 

<div style="float:left;"> 

    <div id="searchform-categories" style="float:left;"> 
     <div class="scroll_checkboxes"> 
      <label>Categories</label> 
      <ul> 
      @foreach (var x in ViewBag.Categories) 
      { 
        <li> 
         <input type="checkbox" name="categories" value="@x.Id"/> 

         @x.Name 

        </li> 
      } 
      </ul> 
     </div> 
    </div> 

    <div id="searchform-diversity" style="float:left; margin-left:30px">  
     <div class="search-selection" style="float:left;"> 
      <label>Minority Owned</label> 
      <ul> 
       @foreach (var x in ViewBag.Minorities) 
       { 
        <li> 
         @Html.RadioButton("minorities", (String)x.Id.ToString()) 
         @x.Name 
        </li> 
       } 
      </ul> 
     </div> 
     <div class="search-selection" style="float:left;"> 
      <label>Diversity Class</label> 
      <ul> 
      @foreach (var x in ViewBag.Classifications) 
      { 
       <li> 
        @Html.RadioButton("classifications", (String)x.Id.ToString()) 
        @x.Name 
       </li> 
      } 
     </ul> 
     </div>  
    </div> 

</div>  

<div style="clear: both;"> 
    <input type="submit" value="Search Profiles" /> 
    <input type="submit" value="Reset" /> 
    </div>  
} 

データグリッドは、私は、一般的であるが、バックビューに掲載のモデルを渡すかどう

@model IEnumerable<VendorProfileIntranet.Models.VendorProfile> 

<table id="VendorTable" width="100%" class="gradeA"> 
<thead> 
    <tr> 
    <th> 
     @Html.DisplayNameFor(model => model.Name) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.CompanyName) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.City) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.State) 
    </th> 
    <th> 
     @Html.DisplayNameFor(model => model.DateCreated) 
    </th> 
    <th>Actions</th> 
    </tr> 
</thead> 
<tbody> 

@foreach (var item in Model) 
{ 
<tr> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.Name) 
    </td> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.CompanyName) 
    </td> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.City) 
    </td> 
    <td> 
     @Html.DisplayFor(modelItem => item.State) 
    </td> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.DateCreated) 
    </td> 
    <td class="list-field"> 
     @Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) | 
     @Html.ActionLink("View", "View", new { id = item.ProfileID }) | 
     @Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" }) 
    </td> 
</tr> 

} 

</tbody> 
<tfoot> 
    <tr> 
     <td>&nbsp;</td> 
    </tr> 
</tfoot> 

答えて

1

ここで私はこの問題を一般的に解決しています。マイノートは純粋に私の意見です(宗教?)MVCプロジェクトのクラスの名前を明確にして目的を明確にします。拡張可能な、それを維持するためのインタフェースの

カップル:、私はまた、あなたができるようになる方法でそれらをクラスあなたのコントローラの今

// I like suffixing classes that I only use for MVC with Model 
public PersonSearchCriteriaModel 
{ 
    public string Name {get; set;} 
    public string Company {get; set;} 
    public string DateStart {get; set;} 
    public string DateEnd {get; set;} 
} 

// I like suffixing classes that I used passed to a View/Partial View 
// with ViewModel  
public class PersonSearchViewModel : IPersonSearchResultsView, 
            IPersonSearchCriteriaView 
{ 
    public IEnumerable<EFPerson> PersonSearchResults { get; set; } 
    public PersonSearchCriteriaModel PersonSearchModel { get; set; } 
} 

// be specific about what type of results, both in the name of the 
// interface and the property needed, you don't want to have overlapping 
// properies on your classes, I like suffixing interfaces that are specific 
// to a View or Partial View with View 
public interface IPersonSearchResultsView 
{ 
    IEnumerable<EFPerson> PersonSearchResults { get; } 
} 

public interface IPersonSearchCriteriaView 
{ 
    PersonSearchCriteriaModel PersonSearchModel { get; } 
} 

がカップルを設定します将来のAjax

public PersonController : Controller 
{ 
    public ActionResult Search() 
    { 
    var model = new PersonSearchViewModel(); 
    // make sure we don't get a null reference exceptions 
    model.PersonSearchModel = new PersonSearchCriteriaModel(); 
    model.PersonSearchResults = new List<EFPerson>(); 
    return this.View(model); 
    } 

    [HttpPost] 
    public ActionResult Search(PersonSearchViewModel model) 
    { 
    model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel); 

    return this.View(model) 
    } 

    // You could use this for Ajax 
    public ActionResult Results(PersonSearchViewModel model) 
    { 
    model.PersonSearchResults = this.GetPersonResults(model.PersonSearchModel); 

    return this.Partial("Partial-SearchResults", model) 
    } 

    private GetPersonResults(PersonSearchCriteriaModel criteria) 
    { 
    return DbContext.GetPersonResults(criteria) 
    } 
} 

ビューをいくつか作成します。

/Views/Person/Partial-SearchCriteria.cshtml

@model IPersonSearchCriteriaView 

// the new part is for htmlAttributes, used by Ajax later 
@using (Html.BeginForm(..., new { id="searchCriteria" })) 
{ 
    // Here is were the magic is, if you use the @Html.*For(m=>) 
    // Methods, they will create names that match the model 
    // and you can back back to the same model on Get/Post 

    <label>Name:</label> 
    @Html.TextBoxFor(m => Model.PersonSearchModel.Name) 

    // or let mvc create a working label automagically 

    @Html.EditorFor(m => Model.PersonSearchModel.Name) 

    // or let mvc create the entire form.. 

    @Html.EditorFor(m => Model.PersonSearchModel) 
} 

@model IPersonSearchResultsView 

@foreach (var person in Model.PersonSearchResults) 
{ 
    <tr> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => person.Name) 
    </td> 

    // etc 
    </tr> 
} 

/Views/Person/Partial-SearchResults.cshtmlそして最後にビュー:

/Views/Person/Search。CSHTML

今Ajaxは(単純化して、私の正確に正しいことではない)簡単かなりクレイジーである可能
@model PersonSearchViewModel 

@Html.Partial("Partial-SearchCriteria", Model) 

// easily change the order of these 

<div id="searchResults"> 
@Html.Partial("Partial-SearchResults", Model); 
</div> 

$.Ajax({ 
    url: '/Person/Results', 
    data: $('#searchCriteria').serialize(), 
    success: function(jsonResult) 
    { 
    $('#searchResults').innerHtml(jsonResult); 
    }); 
+0

thx、私はあなたの解決策を試みます。 – SQLGrinder

1

としてモデルにバインドされています。この方法では、値はクリアされません。

あなたのコードは次のようになります。そうでない場合はModelはnullになるとプロパティがコールされたときに例外がスローされます、最初にフォームを取得するとき、あなたは新しいModelを作成する必要があります

<div style="float:left;"> 

    <div style="float:left;"> 
    <label>Name:</label> 
    @Html.TextBox("name", Model.Name) 
    </div> 

<div style="float:left; margin-left:15px"> 
<label>Company:</label> 
@Html.TextBox("company", Model.Company) 
</div> 

<div style="float:left; margin-left:65px"> 
<label>Date Range:</label> 
@Html.TextBox("dateStart", Model.DateStart, new { @class = "datefield", type = "date" }) 
&nbsp;to&nbsp; 
@Html.TextBox("dateEnd", Model.DateEnd, new { @class = "datefield", type = "date" }) 
</div> 

をそれ。

ここではサンプルモデル

public class SearchModel 
{ 

    public SearchModel() 
    { 
     Results = new List<Result>(); 
    } 

    public string Name {get; set;} 

    public string Company {get; set;} 

    public string DateStart {get; set;} 

    public string DateEnd {get; set;} 

    public List<Result> Results {get; set;} 
} 


@foreach (var item in Model.Results) 
{ 
<tr> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.Name) 
    </td> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.CompanyName) 
    </td> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.City) 
    </td> 
    <td> 
     @Html.DisplayFor(modelItem => item.State) 
    </td> 
    <td class="list-field"> 
     @Html.DisplayFor(modelItem => item.DateCreated) 
    </td> 
    <td class="list-field"> 
     @Html.ActionLink("Edit", "Edit", new { id = item.ProfileID }) | 
     @Html.ActionLink("View", "View", new { id = item.ProfileID }) | 
     @Html.ActionLink("Delete", "Delete", new { id = item.ProfileID }, new { onclick = " return DeleteConfirm()" }) 
    </td> 
</tr> 

} 

は、MVCのビューのためのモデルを作成する上linkです。

+0

私が理解しているのは、モデルが1つしかなく、すでにデータグリッドに取り込まれているということです。そのため、あなたが提案しているものを組み込む方法がわかりません。 (上記の更新を参照) – SQLGrinder

+0

@Vicはい、それは本当ですが、モデルは単なるクラスです。あなたはクラス内に何かを持つことができます。 –

+0

@VicをGETすると、結果は空になります。行は表示されません。検索が完了すると、結果と検索条件が表示されます。 –

1

あなたはMVCでHTMLを使用している場合は、その後、hereから溶液2をチェックvalue="@Request["txtNumber1"]"がうまく働きました私のために、

<input type="text" id="txtNumber1" name="txtNumber1" value="@Request["txtNumber1"]"/> 

希望は助けてくれます。

+0

なぜ投票が下りますか?将来的にはより良い答えを加えるために説明してください。 – stom