2013-01-08 13 views
6

Ich habe eine MVC4-Seite mit einem Formular mit einer Sammlung von Kontrollkästchen, Optionsfeldern und Textfeldern, die als Suchfelder verwendet werden. Beim Post werden die Auswahlen geparst und das untere Ergebnisraster wird mit neuen Ergebnissen aktualisiert. Im Moment werden alle Formularwerte bei der Rückkehr gelöscht und die neuen Ergebnisse werden im Raster angezeigt - nur das Raster ist Teil des Modells.Formularwerte nach der Veröffentlichung beibehalten (nicht Teil des Modells)

Ich möchte, dass alle Formularauswahlen ihre Werte nach dem Post behalten, damit der Benutzer die Auswahl für den nächsten Post/Suche sehen (und ändern) kann. Das Formular ist mit Viewbags gefüllt.

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

das Datenraster als

an das Modell gebunden
@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> 

Antwort

1

Also hier ist, wie ich normalerweise dieses Problem lösen. Meine Notizen sind nur meine Meinung (religiös?) Über das Benennen von Klassen in einem MVC-Projekt, um ihren Zweck klar zu machen.

Paar von Schnittstellen es erweiterbar zu halten:

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

Paar von Klassen

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

Jetzt für Ihre Controller, ich werde sie so einrichten, dass Sie auch erlauben würde, zu tun Ajax in der Zukunft.

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

Erstellen Sie ein paar Teilansichten Ihrer Ansichten.

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

und schließlich die Ansicht:

/Ansichten/Person/Suche.cshtml

@model PersonSearchViewModel 

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

// easily change the order of these 

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

Jetzt Ermöglichen Ajax ist ziemlich verrückt einfach (vereinfacht und meine nicht genau rechts):

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

thx für all das, ich werde versuchen, Ihre Lösung. – SQLGrinder

1

Was ich in der Regel tun, ist die gepostete Modell zurück in die Ansicht übergeben. Auf diese Weise werden die Werte nicht gelöscht.

Ihr Code würde wie folgt aussehen:

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

Wenn zunächst die Form bekommen, werden Sie einen neuen Model erstellen müssen, da sonst die Model null sein wird, und eine Ausnahme auslösen, wenn Eigenschaften aufgerufen werden es.

Beispielmodell

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> 

} 

Hier ist ein link auf Modelle für eine Ansicht in MVC zu schaffen.

+0

Mein Verständnis ist, dass Sie nur ein Modell haben können, und das ist bereits durch das Datenraster genommen, so dass ich nicht sicher bin, wie man das einbezieht, was Sie vorschlagen. (siehe oben) – SQLGrinder

+0

@Vic Ja, das stimmt, aber ein Model ist einfach eine Klasse. Sie können alles in der Klasse haben. –

+0

@Vic auf dem GET, die Ergebnisse werden leer sein - keine Zeilen angezeigt werden. Wenn die Suche abgeschlossen ist, werden die Ergebnisse und die Suchkriterien angezeigt. –

1

, wenn Sie HTML in Mvc verwenden dann Lösung überprüfen 2 von here, value="@Request["txtNumber1"]" hat gut funktioniert für mich,

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

hoffe hilft jemand.

+0

Warum unten abstimmen? Bitte erläutern Sie, um in Zukunft bessere Antworten zu geben. – stom

Verwandte Themen