Главная Ларавел AJAX пагинация в Laravel-5. Динамическая подгрузка контента (результатов поиска по сайту).

Ларавел


AJAX пагинация в Laravel-5. Динамическая подгрузка контента (результатов поиска по сайту).

В данной статье я приведу пример динамической подгрузки результатов поиска по сайту. При этом контент (результат) будет получен в виде объекта пагинации, только вместо вывода стандартных кнопок с номерами страниц или стрелками "вперед" - "назад" и перехода на следующие страницы - строки будут добавляться в конец блока при его скролле вниз. Таким же образом можно реализовать не страницу результатов поиска, а, например, список постов и тд.

Для начала необходимо добавить форму поиска в любое удобное место на сайте, обычно это "шапка", но можно в любое удобное место:

<form action="/search" id="mainsearch" method="post" >
    {{ csrf_field() }}
    <div id="custom-search-input">
        <div class="input-group">
            <input type="text" name="searchfull" class="form-control"
                placeholder="поиск по сайту"/>
            <span class="btn">
				<button class="btn btn-danger" type="submit" form="mainsearch">
					<span class=" fa fa-search"></span>
                </button>
            </span>
        </div>
    </div>
</form>

Как видно, запрос будет отправлен методом POST на маршрут  /search. Но при добавлении нового контента будет использован метод GET  поэтому в файле routes/web.php добавляем маршрут any, этот маршрут обработает оба запроса :

Route::any('/search', 'HomeController@search')->name('search');

В своих примерах я буду использовать модель(таблицу) Personal, содержащую данные по пользователям (ФИО, email и тд.).

В контроллере, который будет обрабатывать данный запрос (в нашем случае HomeController) создадим функцию, которая будет обрабатывать поиск:

/**
     * Обработка поиска
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|string
     */
    public function search(Request $request){

        // логика поиска
        $lenght = 20;
        if ($request->page)$offset = ($request->page -1) * $lenght;
        else $offset = 0;
        $result = $request->searchfull;
        $search_to_page = [];
        // убираем символы, которые не будем искать
        $pattern = [
            '/\./',
            '/\,/',
            '/\+/',
            '/\-/',
            '/!/',
            '/\?/',
            '/\=/',
            '/\:/',
            '/\;/',
        ];

        $result_replase = preg_replace($pattern, '',$result_search);

        $result_replase = preg_replace('|[\s]+|s', ' ', $result_replase);//   '/[\s]{2,}/'
        //разбиваем запрос на слова
        $searches = explode(" ", $result_replase);
        //ищем результат по каждому слову в отдельности
        foreach ($searches as $search){
            if (iconv_strlen ($search) >= 3) {
                $search_personal = DB::table('personal')
                    ->where(['name', 'like', '%' . $search . '%'])
                    ->orWhere(['email', 'like', '%' . $search . '%'])
                    ->get();
                foreach ($search_personal as $personal) {
                    $search_result_personal[] = $personal->id;
                }
            }
        }
        if (isset($search_result_personal) && is_array($search_result_personal)) {
            $search_result_personal= array_unique($search_result_personal, SORT_NUMERIC);
        }
        else $search_result_personal= [];
        //формируем массив для вывода в view
        if ($search_result_personal){
            foreach ($search_result_personalas as $persona) {
                $search_to_page[] = [
                    'login' => $persona->name,
                    'email' => $persona->email,
                ];

            }
        }

        $count = count($search_to_page);
        //сам AJAX запрос
        if ($request->ajax()) {
            $offset = ($request->page - 1) * $lenght;
            $view = view('dataSearch', [
                'search' => $search_to_page,
                'offset' => $offset,
                'result' => htmlspecialchars(strip_tags($result)),
                'lenght' => $lenght,
                'ajax' => $request->page,
            ])->render();
            return response()->json(['html' => $view]);
        }
        return view ('search',[
            'offset' => $offset,
            'lenght' => $lenght,
            'result' => htmlspecialchars(strip_tags($result)),
            'search' => $search_to_page,
            'count' => $count,
        ])->render();
    }

В переменной $lenght указываем кол-во записей которые нужно получить и вывести за 1 раз, тут «20». Метод содержит проверку: если это AJAX - подключаем шаблон «search», который выводит только сами строки без другого контента и заголовков таблицы для добавления их в конец таблицы.
У меня данный шаблон выглядит так (файл resources/views/search.blade.php):

@extends('layouts.app')
@section('title', 'Результаты поиска')
@section('description', '')
@section('keywords', '')
@section('content')
    <div class="content">
        <div class="container">
            <div class="row">
                <h1> Результаты поиска </h1> <br>
					<div class="row">
						<div class="col-12">
							<div class="searched">
								<div class="fa fa-search"></div>
								<span class="yousearched"> Вы искали: </span> <span
										class="searchres"> {{$result}} </span>
								<div class="content_line"></div>
								<p class="quaery_twrap"><span class="quaery_text"> Под ваш запрос мы нашли: </span> <span
											class="quaery_res"> {{$count}} страниц </span></p>
								<div class="content_dotline"></div>
							</div>
						</div>
					</div>
					<div class="row">
						@if ($search)
							<div  id="search-data">
								@include('dataSearch')
							</div>
							<div class="ajax-load" style="display:none">
								<div class="you-class" style="width: 100%">
									<img src="url к картинке или можно заменить какой либо надписью" class="img_load" />
								</div>
							</div>
						@endif
					</div>
                </div>
            </div>
        </div>
    </div>
	<!-- Если количество найденных записей больше, чем количество $lenght то подключаем скрипт для навигации -->
    @if($count > $lenght)
        <script type="text/javascript">
            search = '{!!$result!!}';
        </script>
        <script src="{{ asset('js/search.js') }}"></script>
    @endif
@endsection

В данном шаблоне подключаем layout, делаем оформление страницы, всё что нужно для корректного отображения результатов поиска.

Так же подключаем здесь шаблон вывода результатов поиска «dataSearch», в данном случак  данный шаблон выглядит так (файл resources/views/dataSearch.blade.php):

@php
$search = array_slice ($search, $offset, $lenght);
$i = $offset + 1;
@endphp
@foreach ($search as $search_item)
    <div class="col-xs-12 quaery_page">
        <div class="row">
            <div class="qwrap">
                <div class="col-xs-1 float-left">
                    <div class="quaery_pnum"> {{$i}}.</div>
                </div>
                <div class="col-xs-11 quaery_textwrap">

                    <div class="textpage_shead">&nbsp;<a href="{{$search_item['link']}}">{{$search_item['title']}}</a></div>
                    {!! $search_item['short_text'] !!}
                </div>
            </div>
        </div>
        <div class="content_dotline"></div>
    </div>
@php
$i ++;
@endphp
@endforeach

Осталось только привести пример javascript (jquery) который мы подключили в шаблоне search.blade.php.
Файл public/js/search.js:

var page = 1;
$(window).scroll(function() {
    if($(window).scrollTop() + $(window).height()  >= $(document).height()) {
        page++;
        loadMoreData(page);
    }
});
function loadMoreData(page){
    $.ajax(
        {
            url: '?page=' + page,
            type: "get",
            method: 'GET',
            data: {searchfull:search},
            beforeSend: function()
            {
                $('.ajax-load').show();
            }
        })
        .done(function(data)
        {
            if(data.html == " "){
                $('.ajax-load').hide();
                $("#search-data").append('нет результатов');
                return;
            }
            $('.ajax-load').hide();
            $("#search-data").append(data.html);
        })
        .fail(function(jqXHR, ajaxOptions, thrownError)
        {
            $('.ajax-load').hide();
        });
}

Контент подгружается при скроллинге, при прокрутке страницы до конца вниз, подгружается следующая порция найденных позиций 

При этом, порция строк, которую вы указываете для получения (у меня 20), не должна полностью помещаться по высоте, т.е. у вас должна появиться полоска скролла в правой части блока. Таким образом пользователь будет видеть, что не все поместилось в видимой области блока, прокручивать его и таким образом вызывать js событие с подгрузкой нового контента.

На данном сайте реализован именно этот метод поиска.

 

 


Вы можете помочь развитию сайта отправив любую сумму

Комментарии

  1. adam
    21.06.2018 в 09:50

    It was very useful to learn.

  2. Виктор
    22.07.2018 в 03:32

    Спасибо попробовал на сайте, всё работает как часы.

Написать комментарий