web-dev-qa-db-fra.com

Laravel Multiple Pagination en une seule page

J'ai des problèmes avec ma pagination ... J'ai deux tables avec des données d'une base de données et je les ai paginées avec Laravel Paginator.

Maintenant, le problème, c’est que lorsque vous accédez, par exemple, à la page 2, elle ajoute? Page = 2, mais le premier tableau passe donc à la page 2.

Y a-t-il un moyen d'obtenir quelque chose comme ça?

page_table1={number}&page_table2={number}

de sorte que vous n'appliquez pas le changement de page sur d'autres tables.

31
Melvin Koopmans

Malheureusement, je ne peux pas tester ce code pour le moment, mais en parcourant la documentation et le code (en Illuminate/Pagination/Environment), je suppose que vous pourriez obtenir quelque chose comme ceci:

# use default 'page' for this
$collection1 = Model::paginate(20);

# use custom 'other_page' for this
$collection2 = Model2::paginate(20);
$collection2->setPageName('other_page');

La méthode setPageName() n'est pas documentée dans la documentation, mais il s'agit d'une méthode publique aux côtés de celles indiquées dans la documentation. Elle devrait donc fonctionner correctement. Pour référence, il s’agit de la déclaration (l. 171-180 dans vendor/laravel/framework/src/Illuminate/Pagination/Environment.php):

/**
 * Set the input page parameter name used by the paginator.
 *
 * @param  string  $pageName
 * @return void
 */
public function setPageName($pageName)
{
    $this->pageName = $pageName;
}

Maintenant, prenez en compte le fait que vous aurez une autre chaîne de requête ajoutée à l'URL, vous devez donc indiquer à la pagination de l'examiner. Utilisez la méthode appends() :

$collection1->appends(array_except(Request::query(), 'page'))->links();

$collection2->appends(array_except(Request::query(), 'other_page'))->links();

Autrement dit, indiquez à chaque présentateur de construire l'URL avec toutes les chaînes de la requête (le tableau résultant de Request::query()sans l'index actuel utilisé par le paginateur, sinon vous obtiendrez une valeur double). array_except() est un assistant de tableau intégré dans Laravel qui renvoie le tableau donné (1er paramètre) purgé de l'index transmis (2e paramètre).

Je vais essayer de tester ce code dès que possible, mais cela devrait fonctionner. Faites le moi savoir en tout cas!

18
Damien Pirsy
$publishedArticles = Article::paginate(10, ['*'], 'published');
$unpublishedArticles = Article::paginate(10, ['*'], 'unpublished');

Le troisième argument est utilisé comme suit:

laravel/public/articles? publié = 3

laravel/public/articles? non publié = 1

31
anonym

C'est une solution facile que j'ai trouvée sur Laravel 4.

Manette

Changez le nom de la page avant de faire la pagination:

Paginator::setPageName('page_a');
$collection_A = ModelA::paginate(10);

Paginator::setPageName('page_b');
$collection_B = ModelB::paginate(10);

Vue

Faites de même: changez le nom de la page avant d’imprimer les liens

Paginator::setPageName('page_a');
$collection_A->links();

Paginator::setPageName('page_b');
$collection_B->links();

Si vous ne voulez perdre aucun état de page pendant que vous naviguez vers une autre page, ajoutez aux liens la page actuelle de toutes les collections:

Paginator::setPageName('page_a');
$collection_A->appends('page_b', Input::get('page_b',1))->links();

Paginator::setPageName('page_b');
$collection_B->appends('page_a', Input::get('page_a',1))->links();
26
daVe

dans laravel 5.3 (maibe travaillant dans une autre version de laravel 5), j’utilise comme ceci:

    $produk = Produk::paginate(5, ['*'], 'produk');
    $region = Region::paginate(5, ['*'], 'region');

et dans le modèle de lame, ajoutent des liens de courants d’autrui pour maintenir la position:

    {{$produk->appends(['region' => $region->currentPage()])->links()}}    
    {{$region->appends(['produk' => $produk->currentPage()])->links()}}    
9
mosleim

Dans Laravel 5.2, déclarez le nom de la page lorsque vous utilisez paginate().

Voici un exemple qui fonctionne avec plusieurs paginateurs sur une page.

  • Assurez-vous de spécifier un $pageName différent pour les autres modèles.

Voir la méthode \Illuminate\Database\Eloquent\Builder::paginate()

/**
 * Get things by ownerId
 *
 * @param integer $ownerId The owner ID.
 *
 * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator Returns a pagination instance.
 */
public function getThings($ownerId)
{
    $builder = \App\Models\Things::where('ownerId', '=', (integer) abs($ownerId));

    // dd([
    //     '__METHOD__' => __METHOD__,
    //     '__FILE__' => __FILE__,
    //     '__LINE__' => __LINE__,
    //     '$ownerId' => $ownerId,
    //     'sql' => $builder->toSql(),
    //     '$builder' => $builder,
    //     'paginate' => $builder->paginate($perPage = null, $columns = ['*'], $pageName = 'p', $page = null),
    // ]);

    return $builder->paginate($perPage = null, $columns = ['*'], $pageName = 'p', $page = null);
}

Note: $pageName = 'p'

5

Laravel 5.7

Model->paginate(10, ['*'], 'paramName');

10 = Max items per page

['*'] = colums

paramName = pagination param name

Illuminate\Database\Eloquent\Builder

3
Rubens

Utilisation:

$var1 = DB1::orderBy('...')->paginate(5, ['*'], '1pagination');

$var2 = DB2::orderBy('...')->paginate(5, ['*'], '2pagination');

Pour Laravel 5.2

1
LauroRafael

La réponse de anonym peut être très pratique dans les vues associées à des modèles. testé dans laravel-5.4:

Supposons que nous ayons une vue pour le show.blade.php_ du contrôleur de clientèle et que nous lui passions le modèle Customer en utilisant:

`` `

return view(['customer' => \App\Customer::find($customerId)]);

`` `.... Chaque client a de nombreux produits, et plusieurs emplacements et nous souhaitons lister avec pagination ses produits et ses emplacements, nous pouvons simplement le faire dans la vue comme:

@foreach($customer->products()->paginate(10,['*'],'productsPage') as $product)
HTML list
@endforeach
{!! $customer->products()->paginate(10,['*'],'productsPage')->links() !!}

@foreach($customer->locations()->paginate(10,['*'],'locationsPage') as $location)
HTML list
@endforeach
{!! $customer->locations()->paginate(10,['*'],'locationsPage')->links() !!}
0
SaidbakR

Il me semble que vous devez mettre à jour l'outil de pagination afin qu'il ait un paramètre supplémentaire qui identifie le tableau car il n'est pas assez intelligent pour savoir qu'il pourrait avoir 2 instances de lui-même sur la même page. DOH!

Plutôt que d'avoir à définir la page en cours pour toutes les tables via une URL, vous souhaitez idéalement stocker le numéro de page actif dans la session par identifiant de table ALORS, votre script doit uniquement se soucier des instructions et ne pas s'assurer qu'il porte les numéros de page existants. également.

Voici un concept vraiment brouillon ....

// The page would be $tableId + "," + $pageNum
// Passed as a value of "page"
$goTo = "$tableId,$pageNum";
?page=$goTo

Ensuite, quand il arrive à la partie qui obtient vos données de table, il ferait quelque chose comme

if(!empty($_GET["page"])){
    list($tableId,$pageNum) = explode(",",$_GET["page"]);

    // Store table's active page number
    $_SESSION["_tableBrowser"][$tableId] = $pageNum;


    // Your table reader would then look at the session for the active page number
    // and not what is in $_GET
}
0
Adam