搜索结果分页 Laravel 5.3

23

分页搜索结果

我刚开始使用 Laravel,试图制作一个带有正确分页的搜索功能。该函数在第一页可以正常工作,但是在第二页就不行了。我认为它没有将结果传递给下一页,但我找不到答案。


这是我的 IndexController 中的搜索功能:

public function search()
{
    $q = Input::get('search');

    # going to next page is not working yet
    $product = Product::where('naam', 'LIKE', '%' . $q . '%')
        ->orWhere('beschrijving', 'LIKE', '%' . $q . '%')
        ->paginate(6);

    return view('pages.index', compact('product'));
}

这是我的路线:

Route::post('search{page?}', 'IndexController@search');

这是第二页的网址:

/search?page=2

这是我展示我的分页方式的方法:

{{ $product->appends(Request::get('page'))->links()}}

错误:

MethodNotAllowedHttpException in RouteCollection.php line 218:

请求出现错误。

路由:

Route::get('search/{page?}', 'IndexController@search');

错误:

MethodNotAllowedHttpException in RouteCollection.php line 218:
in RouteCollection.php line 218
at RouteCollection->methodNotAllowed(array('GET', 'HEAD')) in RouteCollection.php line 205
at RouteCollection->getRouteForMethods(object(Request), array('GET', 'HEAD')) in RouteCollection.php line 158
at RouteCollection->match(object(Request)) in Router.php line 780
at Router->findRoute(object(Request)) in Router.php line 610
at Router->dispatchToRoute(object(Request)) in Router.php line 596
at Router->dispatch(object(Request)) in Kernel.php line 267
at Kernel->Illuminate\Foundation\Http\{closure}(object(Request)) in Pipeline.php line 53
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 46
at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 137
at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 33
at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 104
at Pipeline->then(object(Closure)) in Kernel.php line 149
at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 116
at Kernel->handle(object(Request)) in index.php line 53

希望我的问题清楚,并且格式正确。谢谢你们的帮助(对不起我的英语不好)


答案:

我最终采用了此帖子中的答案,并结合帖子的一些帮助。

我为初始搜索使用了一个POST函数,为后续页面使用了GET函数。这是可能的,因为现在我将我的搜索给了URL。


编辑:

  • 添加了初始错误。
  • 添加了Route::get错误
  • 添加了答案

请问您能否提供完整的错误堆栈跟踪信息? - Skysplit
我在思考,我能否通过一个POST路由来修复初始搜索,并通过第二个GET路由来获取下一页?我认为我需要将“?page=#”作为路由缓存。 - Casper Spruit
11个回答

49

如果您想在下一页应用过滤器,应像这样将它们添加到分页器中:

$product = Product::where('naam', 'LIKE', '%' . $q . '%')
        ->orWhere('beschrijving', 'LIKE', '%' . $q . '%')
        ->paginate(6);
$product->appends(['search' => $q]);

将您的路由从POST更改为GET:

Route::get('search', 'IndexController@search');

直到中午我的大脑才能正常运转。这确实是正确的答案。对于这个问题,也不应该是Route::get('search/{page?}')吗? - Skysplit
2
@Skysplit 坦白地说,{page?} 应该完全从 URL 中删除。 - Andrej
是的,你说得对。如果添加页面解析器会很有用。 - Skysplit
这个可以用来跳转到第二页,但是要提交我的搜索需要一个POST请求。有什么解决办法吗? - Casper Spruit
1
@casperspruit 我不确定为什么你需要使用 POST 进行搜索。通常情况下,当您想要更改应用程序状态/数据时才会使用 POST。搜索不会改变任何内容,因此您可以使用 GET。如果您真的想使用 POST,那么您必须覆盖分页器视图并在其中使用 post 方法。 - Skysplit
显示剩余9条评论

17

一个快速的方式(Laravel 5.7)

$product->appends(Request::all())->links();

3
Route::get('product', function () {
    $product= App\product::paginate(15);

    $product->setPath('custom/url');

});

视图:

{{ $product->appends(['search' => Request::get('page')])->links() }}

2
$searchdata =  \Request::get( 'inputTextFieldname' ); \make as global
$searchresult = Modelname::where ( 'blogpost_title', 'LIKE', '%' .$searchdata . '%' )->paginate(2);
return view( 'search', compact('searchresult') );

在您的视图页面中。
{{$searchresult->appends(Request::only('inputTextFieldname'))->links()}}

使您的路线达到get方法
Route::get('/search', ['as' => 'search', 'uses' => 'searchController@index']);

this will be done, thanks,


2

我猜你想要改变像这样的URL页面:search/1search/2?首先,你的路由应该是Route ::post('search/{page?}')

我不确定仅进行此更改是否有效,但如果无效,你需要像这样解决页面:

public function search(\Illuminate\Http\Request $request, $page = 1)
{
    $q = $request->get('search');

    \Illuminate\Pagination\Paginator::currentPageResolver(function () use ($page) {
        return $page;
    });

    # going to next page is not working yet
    $product = Product::where('naam', 'LIKE', '%' . $q . '%')
        ->orWhere('beschrijving', 'LIKE', '%' . $q . '%')
        ->paginate(6);

    return view('pages.index', compact('product'));
}

编辑:我的URL类似于search?page=2,分页默认处理,那我该如何更改呢?您的函数与我的一样会出现相同的错误:“RouteCollection.php第218行中的MethodNotAllowedHttpException” - Casper Spruit

2

解决这个问题的简单方法是在您的UsersController.php中添加->withQueryString()->paginate(6)

public function search()
{
$q = Input::get('search');

# going to next page is not working yet
$product = Product::where('naam', 'LIKE', '%' . $q . '%')
    ->orWhere('beschrijving', 'LIKE', '%' . $q . '%')
    ->paginate(6)->withQueryString();

return view('pages.index', compact('product'));
}

在视图文件中。
{{$product->links()}}

请编辑您的问题,解释在这种情况下withQueryString()的作用是什么。 - miken32
嗨,Miken, withQueryString() 函数适用于 Laravel 7 和 8。 它将使 URL 请求 ?page=2, 正如您在官方文档 https://laravel.com/docs/8.x/pagination#appending-query-string-values 中所看到的。 - Sachin Saini
正如我所说,[编辑]您的问题以解释这一点。 - miken32

2
在我的情况下,我已经安装了Laravel 5.7。
$perPage = $request->per_page ?? 10;

$data['items'] = User::where('name', 'like', '%'. $request->search . '%')
                         ->paginate($perPage)
                         ->appends(['search' => $request->search, 'per_page' => $request->per_page]);

    return view('users.index', $data);

我的视图文件代码如下:
对于每页选择下拉菜单和搜索区域:
<form role="form" class="form-inline" method="get" action='{{ url('/user') }}'>
 <div class="row">
  <div class="col-sm-6">
   <div class="dataTables_length">
     <label>Show
     <select name="per_page"
       onchange="this.form.submit()"
       class="form-control input-sm">
      <option value=""></option>
      <option value="10" {{ $items->perPage() == 10 ? 'selected' : '' }}>10
      </option>
      <option value="25" {{ $items->perPage() == 25 ? 'selected' : '' }}>25
      </option>
      <option value="50" {{ $items->perPage() == 50 ? 'selected' : '' }}>50
      </option>
     </select>
     entries
     </label>
    </div>
   </div>

<div class="col-sm-6">
 <div class="dataTables_filter pull-right">
  <div class="form-group">
   <label>Search: &nbsp;
   <input type="search" name="search" class="form-control input-sm"
   placeholder="Name" value="{{ request()->search }}">
   </label>
  </div>
 </div>
</div>

我的分页生成器代码
{{ $items->appends(['search' => request()->search, 'per_page' => request()->per_page])->links() }}

1
分页功能,你应该创建一个简单的表单:

<form action="{{URL::to('/search')}}" method="post">
    <input type="hidden" name="query"/>
    <select name="pages">
    @for($p = 1; $p < $products->lastPage(); $p++ )
        <option value="{{ $p }}">{{ $p }}</option>
    @endfor
    </select>
</form>

分页方法在这里:
$results->count()
$results->currentPage()
$results->firstItem()
$results->hasMorePages()
$results->lastItem()
$results->lastPage() (Not available when using simplePaginate)
$results->nextPageUrl()
$results->perPage()
$results->previousPageUrl()
$results->total() (Not available when using simplePaginate)
$results->url($page)

谢谢,但我认为这不是最干净的方法,尽管这些信息现在对我有所帮助。 - Casper Spruit

1
如果您正在使用 GET 方法的搜索表单,则使用以下内容来保留搜索结果中的分页功能。
 public function filter(Request $request)
    {        
        $filter = $request->only('name_operator','name_value','email_operator','email_value', 'phone_operator','phone_value',   'gender_value', 'age_operator','age_value');
        $contacts = $this->repo->getFilteredList(array_filter($filter));
        $contacts->appends($filter)->links(); //Continue pagination with results
        return view('dashboard::index', compact('contacts'))->withInput($request->all());
    }

-1

在路由中使用any而不是post

Route::any('search', 'IndexController@search');


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接