2013-01-08 93 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項目中命名類以保持其目的。

夫婦的接口,以保持它的可擴展:

// 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; } 
} 

// 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; } 
} 

現在你的控制器,我會設置它們的方式,也將讓你做情侶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) 
} 

/Views/Person/Partial-SearchResults.cshtml

@model IPersonSearchResultsView 

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

    // etc 
    </tr> 
} 

最後認爲:

/Views/Person/Search。CSHTML

@model PersonSearchViewModel 

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

// easily change the order of these 

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

現在支持Ajax是很瘋狂很容易(簡體和我的不完全正確):

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

thx爲提供所有,我會嘗試你的解決方案。 – SQLGrinder

1

我通常做的是通過張貼示範回視圖。這樣值不會被清除。

您的代碼將是這個樣子:

<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> 

當最初獲得的形式,你必須創建一個新的Model,否則Model將是無效並拋出一個異常時,性能要求它。

標本模型

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

我的理解是,你只能有一個模型,這已經被數據網格佔用,所以我不知道如何合併你的建議。 (見上面更新) – 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