2015-09-12 17 views
12

Sto provando a impaginare i risultati (ogni 25 righe) utilizzando Select2 4.0, ma non so come ottenerlo. Qualcuno sa come farlo?Selezionare2 v4 come impaginare i risultati utilizzando AJAX

Se l'utente raggiunge la fine delle 25 righe e se ci sono più righe vorrei caricarlo e mostrarlo.

Ecco il mio modello HTML

<div class="form-group"> 
    {!! Form::select('breed_id', $breeds, null, ['class' => 'form-control', 'id' =>'breed_id']) !!} 
</div> 

E qui è la JavaScript per Select2.

$("#breed_id").select2({ 
    placeholder: 'Breed...', 
    width: '350px', 
    allowClear: true, 
    ajax: { 
     url: '', 
     dataType: 'json', 
     data: function(params) { 
      return { 
       term: params.term 
      } 
     }, 
     processResults: function (data, page) { 
      return { 
       results: data 
      }; 
     }, 
     cache: true 
    } 
}); 

E questo è il codice che ho per il mio controller

if ($request->ajax()) 
{ 
    $breeds = Breed::where('name', 'LIKE', '%' . Input::get("term"). '%')->orderBy('name')->take(25)->get(['id',DB::raw('name as text')]); 

    return response()->json($breeds); 
} 

Anche quando ho cercato di mettere params.page si dice "non definito".

risposta

24

Select2 supporta l'impaginazione quando si utilizzano i dati remoti tramite la chiave pagination che esce da processResults.

Per scrolling infinito, l'oggetto pagination si prevede di avere una proprietà more che è un valore booleano (true o false). Questo indicherà a Select2 se dovrebbe caricare più risultati quando raggiunge il fondo o se ha raggiunto la fine dei risultati.

{ 
    results: [array, of, results], 
    pagination: { 
    more: true 
    } 
} 

Nel tuo caso, hai la possibilità di modellare i risultati. In questo modo è possibile modificare la risposta JSON in modo che corrisponda al formato previsto, il che significa che non sarà nemmeno necessario utilizzare processResults.

Select2 può passare il numero di pagina come page se si modifica la funzione ajax.data per restituirla.

data: function(params) { 
    return { 
     term: params.term || "", 
     page: params.page || 1 
    } 
}, 

E quindi sarà possibile ottenere la pagina utilizzando Input::get('page'). E puoi calcolare il numero totale di risultati da saltare usando (page - 1) * resultCount, dove resultCount è 25 nel tuo caso. Ciò ti consentirà di modificare la tua query per combinare LIMIT e OFFSET per ottenere solo i risultati di cui hai bisogno.

$page = Input::get('page'); 
$resultCount = 25; 

$offset = ($page - 1) * $resultCount; 

Ed è possibile utilizzare la seguente query per generare una query LIMIT/OFFSET (sulla base degli this Stack Overflow question.

$breeds = Breed::where('name', 'LIKE', '%' . Input::get("term"). '%')->orderBy('name')->skip($offset)->take($resultCount)->get(['id',DB::raw('name as text')]); 

Così ora $breeds conterrà solo i risultati richiesti. L'unica cosa che resta da fare è per modellare la risposta in modo che corrisponda a quanto previsto da Select2.Puoi determinare se ci sono più pagine controllando il numero totale di risultati e vedendo se hai superato il limite

$count = Breed::count(); 
$endCount = $offset + $resultCount; 
$morePages = $endCount > $count; 

Quindi ora $morePages dovrebbe essere un valore booleano, che è esattamente ciò che Select2 sta cercando in pagination.more. Ora devi solo modellare la risposta in modo che corrisponda al formato che ho menzionato prima.

$results = array(
    "results" => $breeds, 
    "pagination" => array(
    "more" => $morePages 
) 
); 

E poi il rendering che

return response()->json($results); 

Mettendo tutto insieme, si ottiene questo per JavaScript

$("#breed_id").select2({ 
    placeholder: 'Breed...', 
    width: '350px', 
    allowClear: true, 
    ajax: { 
     url: '', 
     dataType: 'json', 
     data: function(params) { 
      return { 
       term: params.term || '', 
       page: params.page || 1 
      } 
     }, 
     cache: true 
    } 
}); 

E quanto segue per il controller

if ($request->ajax()) 
{ 
    $page = Input::get('page'); 
    $resultCount = 25; 

    $offset = ($page - 1) * $resultCount; 

    $breeds = Breed::where('name', 'LIKE', '%' . Input::get("term"). '%')->orderBy('name')->skip($offset)->take($resultCount)->get(['id',DB::raw('name as text')]); 

    $count = Breed::count(); 
    $endCount = $offset + $resultCount; 
    $morePages = $endCount > $count; 

    $results = array(
     "results" => $breeds, 
     "pagination" => array(
     "more" => $morePages 
    ) 
    ); 

    return response()->json($results); 
} 
+2

Wooow sei davvero rock !! Ho solo dovuto cambiare 2 cose ... $ morePages = $ count> $ endCount; e anche il conteggio deve essere in base all'input $ count = Count (Breed :: where ('name', 'LIKE', '%'. Input :: get ("term"). '%') -> orderBy ('nome') -> get (['id', DB :: raw ('nome come testo')])); Grazie mille! – Diego

+0

grazie .. molto grazie ..! –

Problemi correlati