nexxai's avatar
Level 37

Large list of collection items (names) - is there a way to skip to a letter?

We have a large database of names, and we'd like to allow our users to jump to a particular letter in a view. We currently just use basic pagination but that's becoming untenable as the list of names is constantly growing, and by a lot.

Is there a way where we can keep pagination (if not, that's OK), but have the ability for our users to skip to a particular letter in the list?

Current lookup code:

    $people = Person::where('approved', 1)
        ->orderBy('first_name')
        ->paginate(30);

Current (simplified) display code:

@foreach ($people as $person)

    <tr><td>{{ $person->name }}</td></tr>

@endforeach

$people->links()

I think I could probably do a groupBy, but the unintended side effect of using a groupBy is that it would either be one gigantic page split up into letter-specific names, or having a single page for each letter which will still look unbalanced if you have letters with a ton of names vs. letters with few or no names.

Thoughts?

0 likes
7 replies
Cronix's avatar
$people = Person::where('approved', 1)
        ->orderBy('first_name');

// Conditionally add a "like" where clause
if ($request->has('q')) {
    $people->where('first_name', 'LIKE', $request->q . '%');
}

$people->paginate(30);

where "q" is an optional request parameter for the first letter of the name to limit the search.

nexxai's avatar
Level 37

@Cronix So I tried that but now I'm getting:

Call to undefined method Illuminate\Database\Query\Builder::links()

even on the original request (with no query parameters). Is that because the query has been split up and it's gone from a collection to a query builder?

nexxai's avatar
Level 37

@jlrdw I'm not sure what you mean - I meant that I tested both with and without query parameters, just to rule out whether or not they were causing the problem.

Can you show me the examples you're referring to so that I can see if there's anything useful in them?

Thanks

Sanctuary's avatar

@jlrdw No need to have an annoying tone about it. I've noticed that across all your recent posts. The Laracasts forum is here precisely for this kind of stuff—for people to ask questions on things they're struggling on or are curious about. If you're gonna be an ass, sometimes it's best to not reply at all. :)

@nexxai What Cronix posted would filter for people's name starting with whatever value $request->q gives you. Hopefully that's what you're looking for, but if not, let us know. However, for it to work, you would need to reassign the $users variable. Based on the example above:

public function index(Request $request) {
    $users = User::orderBy('name');

    if ($request->has('name')) {
        $users->where('name', 'LIKE', "{$request->name}%");
    }

    $users = $users->paginate(5);

    return view('some-view', compact('users'));
}
2 likes
Snapey's avatar
Snapey
Best Answer
Level 122

if the numbers of names are less than, say 10,000 then you could use datatables.net and do filtering of the table client side?

1 like
jlrdw's avatar
echo '<td>' . $dogs->appends($pagelinks)->links('custompager') . '</td>';
// $pagelinks something like ['adpt' => 0] or ['color' => 'brown']  or ['myletter' => 'c'] or whatever.

But again it has been answered prior with examples, sorry.

Please or to participate in this conversation.