Reputation: 1098
I have a list lets's say 'ProductList'
I have a filter bar with tiltes 'Color' and 'Shape' with toggle buttons Red, green, square and round.
Color: Red Green
Shape: Square Round
1st category - Color
If I click red, the 'ProductList' must be filtered for Red color.
firstFilteredList = ProductList.where((p) => p.color == "red");
Now if I click green, the 'ProductList' must be filtered for Red and Green color.
firstFilteredList = ProductList.where((p) => p.color == "red" || p.color == "green");
2st category - Shape
Now if I click square, the 'firstFilteredList' must be filtered for square shape.
secondFilteredList = firstFilteredList.where((p) => p.shape == "square");
Now if I click round, the 'firstFilteredList' must be filtered for square and round shape.
secondFilteredList = firstFilteredList.where((p) => p.shape == "square" || p.shape == "round");
I need to remove those filters if the button is toggled off.
I've just mentioned two filter categories - Color and shape, for the sake of simplicity. There may be 6-7 filter categories. So, the solution has to be scalable.
Can someone help me solve this?
Edit: ProductList is a element of CategorizedProduct. I have to return List.
class CategorizedProduct {
String id;
String title;
List<Product> product;
String selectedVariant;
}
class Product {
String color;
String id;
bool shapeRectangle;
bool shapeRound;
bool shapeSquare;
}
Upvotes: 2
Views: 5177
Reputation: 5086
You can put your queries in a list than perform contains()
.
Here is a Dart example that does it.
enum ProductColor { RED, GREEN, BLUE }
enum Weight { HEAVY, NORMAL, LIGHT }
enum Shape { SQUARE, ROUND, TRIANGLE }
class Product {
final String name;
final ProductColor color;
final Weight weight;
final Shape shape;
Product(this.name, this.color, this.weight, this.shape);
@override
String toString() {
return '$name $color $weight $shape';
}
}
class Query {
final List<ProductColor> color;
final List<Weight> weight;
final List<Shape> shape;
Query({this.color, this.weight, this.shape});
}
List<Product> filter(List<Product> products, Query query) {
return products
.where((product) =>
(query.color == null || query.color.contains(product.color)) &&
(query.weight == null || query.weight.contains(product.weight)) &&
(query.shape == null || query.shape.contains(product.shape)))
.toList();
}
void main() {
List<Product> _productList = [
Product("P1", ProductColor.BLUE, Weight.HEAVY, Shape.TRIANGLE),
Product("P2", ProductColor.GREEN, Weight.NORMAL, Shape.ROUND),
Product("P3", ProductColor.RED, Weight.LIGHT, Shape.ROUND),
Product("P4", ProductColor.GREEN, Weight.NORMAL, Shape.SQUARE),
];
Query _query = Query(color: [ProductColor.GREEN], shape: [Shape.ROUND]);
List<Product> results = filter(_productList, _query);
results.forEach(print);
}
Upvotes: 8
Reputation: 2425
You want to use a onPressed()
for your filter selections, with a boolean for on or off (filter selected or not). Something like this:
//red color filter button
...
onPressed(
redFilter = !redFilter; //on if off, off if on...
)
Then you can use a list of boolean
bool redFilter = false;
bool greenFilter = false;
bool squareFilter = false;
bool roundFilter = false;
List<bool> filters = [redFilter, greenFilter, squareFilter, roundFilter];
Upvotes: 0