Делаем простую сортировку. Гайд от неопытного новичка неопытным новичкам.
Задача: сделать фильтр, чтобы пользователь мог отсортировать товары(в моем случае товары из Mall, но на самом деле неважно какую модель хотите сортировать) по цене и по алфавиту.
Я еще прикрутил Ajax, эти моменты комментировать не буду, т.к. тут есть отличная статья обновления фрагментов Ajax, сам оттуда и брал инфу.
Сначала делаем форму с селектором, в option value мы просто передаем переменные в наш компонент.
<form method = "GET" >
<select name = "sorting">
<option value="">Все</option>
<option value="price_up">Сначала дешевые</option>
<option value="price_down">Сначала дорогие</option>
<option value="alpha">По алфавиту</option>
</select>
<button type="submit" data-request="onFilter" class="btn btn-primary">Применить</button>
</form>
Перейдем к компоненту, который мы создаем в нашем плагине. В нем я заострю внимание на двух моментах, первый:
public $products;
public function onRun()
{
$this->products = $this->filterProducts();
}
В $products мы поместим наши отсортированные объекты, в методе onRun мы вызываем метод filterProducts,который и определит наш $products.
Сам filterProducts:
public function filterProducts() {
$sort=Input: : get('sorting');
switch($sort) {
case 'price_up':
$products=Product: : orderBy('price', 'asc')->get();
break;
case 'price_down':
$products=Product: : orderBy('price', 'desc')->get();
break;
case 'name':
$products=Product: : orderBy('name')->get();
break;
default: $products=Product: : all();
}
return $products;
}
Input::get() — тут мы получаем значение нашего селектора из шаблона, а в качестве аргумента передаем имя селектора из шаблона <select name = "sorting">
Далее исходя из полученного значения переменной $sort через оператор switch выбираем подходящий для нас способ сортировке модели, подробнее про orderBy можно почитать в документации к laravel или october. Asc и desc — сортируют по возрастанию и убыванию.
Здесь я упростил свой код, предположив, что все необходимые поля для фильтрации у вас есть непосредственно в самой модели. Что, если цена товара указана в другой таблице? Я воспользовался innerjoin, и отрывок кода у меня выглядел так:
case 'price_up':
$products = Product::whereHas('categories',function($query) use ($categoryid){
$query->where('category_id',$categoryid);
})
->join('offline_mall_product_prices', 'product_id', 'offline_mall_products.id')
->select('offline_mall_products.*')
->orderBy('price')->get();
break;
Во первых, у меня тут идет сортировка по категориям, которые я так же передаю через ту же форму в шаблоне в переменную $categoryid, к нашим фильтрам это особо не имеет отношения, но решил не удалять, вдруг вам пригодиться 🙂 Тут важнее использование join:
первым аргументом мы передаем таблицу, в которой есть нужное нам поле для сортировки, вторым аргументом передаем поле с внешним ключом (то, которое содержит id нашего продукта, блога, чего угодно), третьим - первичный ключ нашей изначальной таблицы. В селекте указываем таблицу, значения которой хотим в итоге получить и спокойно сортируем по цене.
Нам осталось только получить сами объекты, не забываем подключить сам компонент на странице с формой и во фрагменте (partial), где будем формировать вывод товаров.
Во фрагменте все стандартно:
{% for product in FilterComponent.products %}
{{ product.name }}
{{ product.price() }}
{% endfor %}
FilterComponent — название моего компонента.
Если что-то забыл, или допустил ошибки — пишите, исправлю/добавлю.