Как реализовать поиск c фильтрами в Laravel?

236
30 декабря 2017, 04:51

На главную страницу сайта выгружаются данные, к примеру, квартиры (фото, описание, площадь, стоимость и т.д.). Также есть простая форма поиска, в которой 4 поля: min-area, max-area, min-price, max-price. Я думаю уже все догадались, что это за поля. А также есть один chechbox. Подскажите пожалуйста, как реализовать поиск с данной формы? Прошу объяснить на пальцах..Можно без ajax-запросов. Для меня важно чтобы по нажатию на кнопку "Найти", пользователя редиректило на главную страницу сайта, где уже были бы выведены необходимые данные. Всем большое спасибо за помощь, грамотный и подробный ответ обязательно оценю)

Answer 1

я постараюсь расписать цепочку максимально просто и схематично, с одним параметром

Шаблон (файл вида) resources/views/index.blade.php

    {{ @if(empty($searchResults)) }}
    <p>результатов нет</p>
    {{ @else }}
    <!-- блок для итерации результатов поиска -->
    {{ @endif; }}
    <form action='{{ route('index') }}' method='POST'>
            <input name='price'>
            <input name='area'>
    </form>

Контроллер app/Http/Controllers/Controller.php

    public function index(Request $request, YouModel $model)
    {
            $searchResults = $model->getResult($request->post('price', 0.0), $request->post('area', 0.0));
            return view('index', ['searchResults' => $searchResults]);
    }

Модель /app/Models/YouModel.php

    public function getResult(float $price = 0.0, float $area = 0.0)
    {
            $query = [];
            if ($price) {
                  $query = $query + ['price' => $price];
            }
             if ($area) {
                  $query = $query + ['area' => $area];
            }               
            if (empty($query)) {
                  return self::all();
            }
            return $this->where($query)->get();
    }

routes/web.php

    Route::any('/', 'Controller@index')->name('index');
Answer 2

Делал похожую штуку, см пример.

public function index(Request $request)
{   
    $users = new User;
    // Для сохранения запросов по которым ищем/фильтруем
    $queries = [];
    // Фильтры
    // Первое значение, название параметра, второе - поле в базе данных
    $filters = [
        'status' => 'status_code',
        'register' => 'registered_at',
        'fio' => 'full_name',
        'mobile' => 'mobile_phone',
        'email' => 'email',
        'user_status' => 'status_code'
    ];
    /*
     * Форичаем все фильтры и проверяем наш реквест
     * Для поиска отрабатывают кейсы, для всего остального - дефолт.
     */
    foreach ($filters as $filter => $name) {
        if ($request->has($filter)) {
            switch ($filter) {
                case 'fio':
                    $users = $users->byFio($request[$filter]);
                    break;
                case 'mobile':
                    $users = $users->byMobile($request[$filter]);
                    break;
                case 'email':
                    $users = $users->byEmail($request[$filter]);
                    break;
                case 'register':
                    $users = $users->byRegisterDate($this->getDate($request->register));
                    break;
                default:
                    $users = $users->where($name, $request[$filter]);
                    break;
            }
            /*
             * Добавляем запросы в массив
             * далее просто аппендим в коллекцию
             */
            $queries[$filter] = $request[$filter];
        }
    }
    $users  = $users->orderBy('id', 'DESC')
            ->paginate(20)
            ->appends($queries);
    return view('admin.users.index', compact('users'));
}

В шаблоне

<form action="{{route('users.index')}}" class="form-inline" method="GET"> 
    <div class="form-group"> 
        <label for="fio" class="control-label">По ФИО:</label> 
        <input name="fio" id="fio" class="form-control"> 
    </div> 
    <div class="form-group"> 
        <label for="mobile" class="control-label">По номеру телефона:</label> 
        <input name="mobile" id="mobile" class="form-control"> 
    </div> 
    <div class="form-group"> 
        <label for="email" class="control-label">По email:</label> 
        <input name="email" id="email" class="form-control"> 
    </div> 
    <input type="submit"> 
 
</form> 
<div style="margin-top:10px;"> 
    <a href ='?user_status=1'>Неактивные</a> | 
    <a href ='?user_status=2'>Активные</a> | 
    <a href ='?register=today'>Добавлены сегодня </a> 
</div>

READ ALSO
Как заменить конструкцию query_posts на get_posts?

Как заменить конструкцию query_posts на get_posts?

На сайте wordpress есть конструкция с query_posts

173
Как сделать на сайте индексируемые табы с отдельным урл?

Как сделать на сайте индексируемые табы с отдельным урл?

Есть интернет-магазин, на карточке товара есть описание и дрв табах

209
Построить дерево php (массив + объекты)

Построить дерево php (массив + объекты)

Добрый вечер всем! Подскажите пожалуйста, несколько часов уже пытаюсь бороться с рекурсией, не могу понять как сделать правильный массивЕсть...

238
Последовательная выборка из БД

Последовательная выборка из БД

БД содержит две таблицы: street_54646:

206