You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何用Typeahead.js实现姓名双向匹配的自动补全搜索

Hey there! Let's refine your setup to make sure your autocomplete works seamlessly for both name orders, plus your existing mobile search. Here's a step-by-step fix:

1. Improve Controller Logic

Your current code handles single-term searches well, but it misses the combined name order scenarios. Let's adjust the query to account for both "Firstname Lastname" and "Lastname Firstname" when two terms are entered:

public function autocomplete(Request $request)
{
    $query = $request->input('query');
    $searchTerms = preg_split('/\s+/', trim($query), -1, PREG_SPLIT_NO_EMPTY);

    $usersQuery = Profile::query();

    if (count($searchTerms) === 2) {
        // Handle both name combinations when two terms are provided
        [$firstTerm, $secondTerm] = $searchTerms;
        
        $usersQuery->where(function ($q) use ($firstTerm, $secondTerm) {
            // Match "Firstname Lastname"
            $q->where('firstname', 'like', "%{$firstTerm}%")
              ->where('lastname', 'like', "%{$secondTerm}%")
              // OR match "Lastname Firstname"
              ->orWhere(function ($subQ) use ($firstTerm, $secondTerm) {
                  $subQ->where('firstname', 'like', "%{$secondTerm}%")
                       ->where('lastname', 'like', "%{$firstTerm}%");
              });
        });
    } else {
        // For single terms (or more than 2), match any field as before
        foreach ($searchTerms as $term) {
            $usersQuery->where(function ($q) use ($term) {
                $q->orWhere('firstname', 'like', "%{$term}%")
                  ->orWhere('lastname', 'like', "%{$term}%")
                  ->orWhere('mobile', 'like', "%{$term}%");
            });
        }
    }

    // Format results to play nicely with Typeahead (include full name for display)
    $results = $usersQuery->get(['firstname', 'lastname', 'mobile'])->map(function ($profile) {
        return [
            'value' => "{$profile->firstname} {$profile->lastname}",
            'firstname' => $profile->firstname,
            'lastname' => $profile->lastname,
            'mobile' => $profile->mobile
        ];
    });

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

Key Changes:

  • Two-term handling: We explicitly check for two search terms and use nested where() clauses to match both name orders (prevents the OR condition from leaking into other search logic).
  • Result formatting: We map the database results to include a value field—this is what Typeahead uses for default display, making it easy to show the full user name.

2. Frontend Typeahead.js Setup

Now let's set up the frontend to consume this endpoint. Make sure you've included jQuery and Typeahead.js first, then initialize the plugin:

<!-- Load dependencies -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>

<!-- Your search input -->
<input type="text" id="user-search" placeholder="Search by name or mobile...">

<script>
$(document).ready(function() {
    $('#user-search').typeahead({
        hint: true,
        highlight: true,
        minLength: 1 // Start searching after 1 character
    }, {
        name: 'users',
        source: function(query, syncResults, asyncResults) {
            // Fetch results from your Laravel endpoint
            $.ajax({
                url: '/autocomplete', // Update this to match your route
                method: 'GET',
                data: { query: query },
                success: function(data) {
                    asyncResults(data);
                },
                error: function() {
                    asyncResults([]); // Fallback to empty if something breaks
                }
            });
        },
        display: 'value', // Use the full name as the default display text
        templates: {
            // Customize how suggestions look in the dropdown
            suggestion: function(profile) {
                return `
                    <div class="suggestion-item">
                        <strong>${profile.value}</strong>
                        <br>
                        <small>Mobile: ${profile.mobile}</small>
                    </div>
                `;
            }
        }
    });
});
</script>

3. Route Configuration

Don't forget to add the route in routes/web.php (or routes/api.php if you're using an API route):

// Web route example
Route::get('/autocomplete', [YourController::class, 'autocomplete']);

// API route example (if using API middleware)
Route::get('/autocomplete', [YourController::class, 'autocomplete'])->middleware('api');

4. Quick Optimizations

  • Database Indexes: Add indexes to your firstname, lastname, and mobile columns in the profiles table to speed up the LIKE queries.
  • Limit Results: If you have thousands of users, add ->limit(10) to the query to return only top matches (prevents slow loads and cluttered dropdowns).
  • Full-Text Search: For larger datasets, consider Laravel's built-in full-text search or Laravel Scout with Algolia/Meilisearch for faster, more accurate results.

内容的提问来源于stack exchange,提问作者Falgun Atara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:17:58