renathy
(Renate Vidruska)
1
Hi!
I wonder, what is the best way to create web store product list filters?
I do have a product list using CListView (it is not customized, but simply CListView widget).
I need to filter this product list by category, brand, gender and some other properties (about 6 properties).
SiteController/ProductsAction is action which displays product list. Now it has only one variable $brands:
actionProducts($brands=null) and if $brands != null I am adding it to CDbCondition.
But I wonder, what is the best way to create a long filter?
Where to store all those filter values? If these are GET variables, how properly create URL?
xahgmah
(Xahgmah)
2
You can use in your product model something like this
public static function getFilterResults($filters = array())
{
$joinArr = array();
$criteria = new CDbCriteria;
if ($filters) {
if (isset($filters['category'])) {
//example for MANY2MANY relation
$joinArr[] = "INNER JOIN `" . self::item2CategoryTableName() . "` as `i2c` ON (`t`.`item_id` = `i2c`.`r_item_id`)";
$criteria->addInCondition('i2c.r_category_id', $filters['category']);
}
//example for BELONGS TO relation
if (isset($filters['brand'])) {
$criteria->addInCondition('t.brand_id', $filters['brand']);
}
if (isset($filters['filter'])) {
$joinArr[] = "INNER JOIN `" . self::item2FilterTableName() . "` as `i2f` ON (`t`.`item_id` = `i2f`.`item_id`)";
$criteria->addInCondition('i2f.value_id', $filters['filter']);
}
//example for price
if (isset($filters['priceRange'])) {
$criteria->addBetweenCondition('t.price', $filters['priceRange']['0'], $filters['priceRange']['1']);
}
if (isset($filters['search'])) {
if (count($filters['search']) > 0)
$criteria->compare("`t`.`item_id`", $filters['search']);
else
$criteria->compare("`t`.`item_id`", -1);
}
}
$criteria->join = implode(" ", $joinArr);
return self::getDataProvider($criteria, 12);
}
public static function getDataProvider($criteria2, $pageSize, $defaultOrder = 't.viewed_cnt DESC')
{
$criteria = new CDbCriteria;
$criteria->group = "t.item_id";
$criteria->addCondition("t.amount != " . self::AVAILABLE_SOLD);
$sort = new CSort();
$sort->sortVar = 'sort';
$sort->defaultOrder = $defaultOrder;
$sort->attributes = array(
'price' => array(
'label' => "Price",
'asc' => 't.price ASC',
'desc' => 't.price DESC',
),
'newest' => array(
'label' => "Newest",
'asc' => 't.create_datetime ASC',
'desc' => 't.create_datetime DESC',
),
);
if ($criteria2 instanceof CDbCriteria) {
$criteria2->mergeWith($criteria);
}
$dataProvider = new CActiveDataProvider("Item", array(
'pagination' => array(
'pageSize' => $pageSize,
),
'sort' => $sort,
'criteria' => $criteria2,
)
);
return $dataProvider;
}
And send values ids for filtering to this method as array;
It can be session, $_GET, etc.
Example site with this filters - 300watches2 dot chdev dot com dot ua (site is not finished)