2012-04-07 5 views
13

Ho implementato una WebGrid. L'ordinamento, il paging e il filtraggio non funzionano insieme. Funzionano quando li usi da solo. Quando si combinano i tre, allo stesso tempo, il filtro non funziona.Il filtro si perde in WebGrid + Paging + Ordinamento + Filtro in .NET 4.0

Il sintomo:
Filtra il set di risultati, quindi ordina.

o

Filtro gruppo di risultati, quindi andare alla pagina successiva.

In entrambi i casi, il filtro viene perso. Ma fa pagina e ordina.

Nel codice sottostante: Quando il metodo di azione viene chiamato tramite un ordinamento o impaginazione, i valori nulli vengono visualizzati per ciascuno dei parametri del filtro.

Quando il metodo di azione viene chiamato tramite il filtro, i parametri del filtro vengono visualizzati.

Questo mi dice che quando si avvia un ordinamento o un'impaginazione che non invia il modulo.

public ActionResult MyPage(int? page, int? rowsPerPage, 
       string sort, string sortdir, 
       string orderNumber, string person, string product) 

Mi sono guardato intorno su SO e altrove. Ci sono un sacco di esempi e persone che chiedono come fare l'uno o l'altro o tutti e tre. Ma ho visto solo one with my issue, quindi lo sto postando qui. (La sua era irrisolto così)

ho la mia pagina implementato come segue:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" })) 
{ 
    <div class="right"> 
     <select id="rowsPerPage" name="rowsPerPage"> 
      <option>15</option> 
      <option>25</option> 
      <option>50</option> 
      <option>75</option> 
      <option>100</option> 
     </select> 
    </div> 

    <div class="table"> 
     <div class="tableRow"> 
      <div class="tableCell"> 
       Order Number 
      </div> 
      <div class="tableCell"> 
       Person 
      </div> 
      <div class="tableCell"> 
       Product 
      </div> 
     </div> 
     <div class="tableRow"> 
      <div class="tableCell"> 
       <input type="text" id="orderNumber" name="orderNumber" /> 
      </div> 
      <div class="tableCell"> 
       <input type="text" id="person" name="person" /> 
      </div> 
      <div class="tableCell"> 
       <input type="text" id="product" name="product" /> 
      </div>   
      <div class="tableCell"> 
       <input type="submit" class="button" value="Search" /> 
      </div> 
     </div> 
    </div> 

<br/> 

<div id="myGrid"> 
    @Html.Partial("_MyPage", Model) 
</div> 

} 

La griglia è implementato come una vista parziale in questo modo:

<script type="text/javascript"> 
    $(document).ready(function() { 
     resetUI(); 
    }); 
</script> 

@{ 
    var grid = new WebGrid(canPage: true, rowsPerPage: Model.rowsPerPage, canSort: true, ajaxUpdateContainerId: "grid", ajaxUpdateCallback: "resetUI"); 
    grid.Bind(Model.rows, rowCount: Model.TotalRecords, autoSortAndPage: false); 
    @grid.GetHtml(
     tableStyle: "fancyTable", 
     headerStyle: "header", 
     footerStyle: "footer", 
     rowStyle: "row", 
     alternatingRowStyle: "alt", 
     mode: WebGridPagerModes.Numeric | WebGridPagerModes.NextPrevious, 
     nextText: "Next", 
     previousText: "Previous", 
     htmlAttributes: new { id = "grid" }, 
     columns: grid.Columns(
      grid.Column("OrderDate", "Order Date", format: @<text>@((item.OrderDate != null) && (item.OrderDate.ToString("MM/dd/yyyy") != "01/01/0001") ? item.OrderDate.ToString("MM/dd/yyyy") : "")</text>), 
      grid.Column("OrderNumber", "Order Number"), 
      grid.Column("Field1, "Field 1"), 
      grid.Column("Field2", "Field 2"), 
      grid.Column("Person", "Person"), 
      grid.Column("Product", "Product"), 
      grid.Column(format: (item) => Html.ActionLink("View", "Details", new { id = item.orderNumber })) 
      ) 
     ); 
} 
+0

Hai trovato la soluzione per questo? – RredCat

+0

Si noti che asp.net mvc creerà elementi di input nascosti aggiuntivi per le checkbox e che il WebGrid sembra reinterpretare questi 2 elementi se presenti in querystring in un singolo elemento con 2 valori, che possono causare problemi di analisi in Razor se un modello è associato a una casella di controllo tramite checkboxfor. Ho dovuto usare jQuery per cancellare questi campi nascosti sul lato client. –

risposta

22

Quando si costruisce l'impaginazione e ordinare collegamenti, l'helper WebGrid tiene conto di tutti i parametri della stringa di query presenti nell'url corrente. Ignora i valori POSTed e route. E dal momento che i tuoi POST di ricerca, i valori che sono stati inseriti dall'utente in questo modulo non sono presenti nella stringa di query, quindi non fanno parte della paginazione e dei collegamenti di ordinamento e quando fai clic su uno di questi link i valori sono perduto. Questo è di design.

Così un modo per risolvere che è quello di sostituire il vostro AjaxForm:

@using (Ajax.BeginForm("MyPage", null, new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myGrid" }, new { id = "filter" })) 

con un modulo HTML standard utilizzando il verbo GET:

@using (Html.BeginForm("MyPage", null, FormMethod.Get)) 

o un modulo AJAX utilizzando il verbo GET:

Ora, quando l'utente vuole filtrare qualcosa e preme il pulsante Cerca invia i valori inseriti nel modulo di ricerca finirà nella stringa di query e durante il rendering l'helper WebGrid li utilizzerà per generare i suoi collegamenti Ordina e Pagina e, naturalmente, quando si fa clic su tali collegamenti i valori verranno inviati al server.

Se si desidera un maggiore controllo su questo, è possibile considerare controlli di rete più avanzati come MvcContrib.Grid o Telerik Grid for ASP.NET MVC.

+0

Funzionerà anche con 'Ajax.BeginForm' con GET usando' new AjaxOptions {HttpMethod = "Get", ... ' – nemesv

+0

No, non penso che funzionerà (anche se non l'ho provato e potrei essere in errore). Quando esegui una richiesta AJAX (indipendentemente dal fatto che sia GET o POST) non stai modificando l'url corrente. –

+0

Funzionerà anche con AJAX (l'ho testato :)), 'WebGrid' utilizza internamente il' Request.QueryString' per passare i valori al cercapersone e ai collegamenti di ordinamento che vengono popolati anche nelle richieste AJAX. – nemesv

1

Inviare il modulo per l'URL che punta il link paging:

<script type="text/javascript"> 
    $(function() { 
     $('th a, tfoot a').click(function() { 
      $('form').attr('action', $(this).attr('href')).submit(); 
      return false; 
     }); 
    }); 
</script> 

Questo doesnot aiutami, ma potrebbe aiutare a

1

Basta creare un GET per il metodo di azione, ogni volta che una specie o di ricerca spara dalla griglia colpisce il metodo GET insieme a molti parametri (puoi vedere puntando il numero di paging o ordinare l'intestazione della griglia usando gli strumenti di sviluppo web del tuo browser), lì puoi filtrare il tuo set di dati e poi passare il modello alla vista:

[HttpGet] 
public ActionResult MyPage() 

Ogni volta che si esegue Sort o Paging, questo metodo viene colpito, quindi è possibile eseguire il filtraggio, è possibile aggiungere alcuni flag statici che possono essere assegnati a seconda di cosa si desidera filtrare.