Skip to content

Commit b2183fb

Browse files
committed
add custom filter and built-in filter to chapter 4. fix pubspec.yamls to point to release, not git head
1 parent ceb9af1 commit b2183fb

10 files changed

Lines changed: 114 additions & 50 deletions

File tree

Chapter_01/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: angular_dart_demo
22
version: 0.0.1
33
dependencies:
4-
angular:
5-
git: https://github.com/angular/angular.dart.git
4+
angular: 0.0.2
5+
# git: https://github.com/angular/angular.dart.git
66
# git: https://github.com/mhevery/angular.dart.git
77

88
browser: any

Chapter_02/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: angular_dart_demo
22
version: 0.0.1
33
dependencies:
4-
angular:
5-
git: https://github.com/angular/angular.dart.git
4+
angular: 0.0.2
5+
# git: https://github.com/angular/angular.dart.git
66
# git: https://github.com/mhevery/angular.dart.git
77

88
browser: any

Chapter_03/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
name: angular_dart_demo
22
version: 0.0.1
33
dependencies:
4-
angular:
5-
git: https://github.com/angular/angular.dart.git
4+
angular: 0.0.2
5+
# git: https://github.com/angular/angular.dart.git
66
# git: https://github.com/mhevery/angular.dart.git
77

88
browser: any

Chapter_04/categories.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
"Appetizers",
3+
"Salads",
4+
"Soups",
5+
"Main Dishes",
6+
"Side Dishes",
7+
"Desserts"
8+
]

Chapter_04/index.html

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,54 @@
99
<div recipe-book>
1010
<h3>Recipe List</h3>
1111

12-
<label for="recipe-filter">Filter recipe list</label>
13-
<input id="recipe-filter" type="text"
14-
ng-model="searchFilter"></input>
15-
16-
<ul>
17-
<li class="pointer"
18-
ng-repeat="recipe in ctrl.recipes | searchfilter:searchFilter">
19-
<rating max="5" rating="recipe.rating"></rating>
20-
<span class="extra-space"
21-
ng-click="ctrl.selectRecipe(recipe)">{{recipe.name}}</span>
22-
</li>
23-
</ul>
24-
25-
<h3>Recipe Details</h3>
26-
<div ng-if="ctrl.selectedRecipe != null">
27-
<div><strong>Name: </strong>{{ctrl.selectedRecipe.name}}</div>
28-
<div><strong>Category: </strong>{{ctrl.selectedRecipe.category}}</div>
29-
<div><strong>Rating: </strong>
30-
<rating max="5" rating="ctrl.selectedRecipe.rating"></rating>
12+
<div id="filters">
13+
<div>
14+
<label for="name-filter">Filter recipes by name</label>
15+
<input id="name-filter" type="text"
16+
ng-model="ctrl.nameFilter"
17+
value=" "></input>
3118
</div>
3219
<div>
33-
<ul>
34-
<li ng-repeat="ingredient in ctrl.selectedRecipe.ingredients">
35-
{{ingredient}}
36-
</li>
37-
</ul>
20+
<label for="category-filter">Filter recipes by category</label>
21+
<span ng-repeat="category in ctrl.categories">
22+
<input type="checkbox" id="category-filter"
23+
ng-model="ctrl.categoryFilterMap[category]">{{category}}
24+
</span>
25+
</div>
26+
<input type="button" value="clear filters" ng-click="ctrl.clearFilters()">
27+
</div>
28+
29+
<div id="recipe-list">
30+
<ul>
31+
<li class="pointer"
32+
ng-repeat="recipe in ctrl.recipes | filter:{name:ctrl.nameFilter} | categoryfilter:ctrl.categoryFilterMap">
33+
<rating max-rating="5" rating="recipe.rating"></rating>
34+
<span class="extra-space"
35+
ng-click="ctrl.selectRecipe(recipe)">{{recipe.name}}</span>
36+
</li>
37+
</ul>
38+
</div>
39+
40+
<div id="recipe-details">
41+
<h3>Recipe Details</h3>
42+
<div ng-if="ctrl.selectedRecipe != null">
43+
<div><strong>Name: </strong>{{ctrl.selectedRecipe.name}}</div>
44+
<div><strong>Category: </strong>{{ctrl.selectedRecipe.category}}</div>
45+
<div><strong>Rating: </strong>
46+
<rating max-rating="5" rating="ctrl.selectedRecipe.rating"></rating>
47+
</div>
48+
<div>
49+
<ul>
50+
<li ng-repeat="ingredient in ctrl.selectedRecipe.ingredients">
51+
{{ingredient}}
52+
</li>
53+
</ul>
54+
</div>
55+
<div><strong>Directions: </strong>{{ctrl.selectedRecipe.directions}}</div>
3856
</div>
39-
<div><strong>Directions: </strong>{{ctrl.selectedRecipe.directions}}</div>
4057
</div>
41-
</div>
58+
59+
</div>
4260

4361
<script type="application/dart" src="main.dart"></script>
4462
<script src="packages/browser/dart.js"></script>

Chapter_04/main.dart

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ import 'package:di/di.dart';
33
import 'rating_component.dart';
44
import 'recipe.dart';
55

6-
@NgFilter(name: 'searchfilter')
7-
class SearchFilter {
8-
call(value, filterString) {
9-
if (value is List && filterString != null) {
10-
return value.where((i) => i.name.contains(filterString)).toList();
6+
@NgFilter(name: 'categoryfilter')
7+
class CategoryFilter {
8+
call(recipeList, filterMap) {
9+
if (recipeList is List && filterMap != null && filterMap is Map) {
10+
// If there is nothing checked, treat it as everything is checked.
11+
bool nothingChecked = filterMap.values.every((isChecked) => !isChecked);
12+
if (nothingChecked) {
13+
return recipeList.toList();
14+
}
15+
return recipeList.where((i) => filterMap[i.category] == true).toList();
1116
}
12-
return value.toList();
1317
}
1418
}
1519

@@ -18,12 +22,22 @@ class SearchFilter {
1822
publishAs: 'ctrl')
1923
class RecipeBookController {
2024

25+
static const String LOADING_MESSAGE = "Loading recipe book...";
26+
static const String ERROR_MESSAGE = """Sorry! The cook stepped out of the
27+
kitchen and took the recipe book with him!""";
28+
2129
Http _http;
2230

23-
List categories = ["Appetizers", "Salads", "Soups", "Main Dishes",
24-
"Side Dishes", "Desserts"];
31+
String loadingMessage = "Loading recipe book...";
32+
33+
// Data objects that are loaded from the server side via json
34+
List categories = [];
2535
List<Recipe> recipes = [];
2636

37+
// Filter box
38+
Map<String, bool> categoryFilterMap = {};
39+
String nameFilter = "";
40+
2741
RecipeBookController(Http this._http) {
2842
_loadData();
2943
}
@@ -34,21 +48,40 @@ class RecipeBookController {
3448
selectedRecipe = recipe;
3549
}
3650

51+
void clearFilters() {
52+
categoryFilterMap.keys.forEach((f) => categoryFilterMap[f] = false);
53+
nameFilter = "";
54+
}
55+
3756
void _loadData() {
3857
_http.get('/angular.dart.tutorial/Chapter_04/recipes.json')
3958
.then((HttpResponse response) {
4059
for (Map recipe in response.data) {
41-
recipes.add(new Recipe.fromJson(recipe));
60+
recipes.add(new Recipe.fromJsonMap(recipe));
4261
}
62+
},
63+
onError: (Object obj) {
64+
loadingMessage = ERROR_MESSAGE;
4365
});
66+
67+
_http.get('/angular.dart.tutorial/Chapter_04/categories.json')
68+
.then((HttpResponse response) {
69+
for (String category in response.data) {
70+
categories.add(category);
71+
categoryFilterMap[category] = false;
72+
}
73+
},
74+
onError: (Object obj) {
75+
loadingMessage = ERROR_MESSAGE;
76+
});
4477
}
4578
}
4679

4780
main() {
4881
var module = new AngularModule()
4982
..type(RecipeBookController)
5083
..type(RatingComponent)
51-
..type(SearchFilter);
84+
..type(CategoryFilter);
5285

53-
bootstrapAngular([module]);
86+
ngBootstrap(module: module);
5487
}

Chapter_04/pubspec.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name: angular_dart_demo
22
version: 0.0.1
33
dependencies:
4-
angular:
4+
angular:
5+
# 0.0.2
56
git: https://github.com/angular/angular.dart.git
67
# git: https://github.com/mhevery/angular.dart.git
78

Chapter_04/rating_component.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import 'package:angular/angular.dart';
2626
* 'rating' : '=.rating'
2727
* NEW:
2828
* 'max-rating' : '@maxRating',
29-
* 'rating' : '=rating'
29+
* 'rating' : '<=>rating'
3030
*
3131
* The compnoent's public fields are available for data binding from the
3232
* component's view. Similarly, the component's public methods can be
@@ -38,8 +38,8 @@ import 'package:angular/angular.dart';
3838
cssUrl: 'rating_component.css',
3939
publishAs: 'ctrl',
4040
map: const {
41-
'max' : '@.max',
42-
'rating' : '=.rating'
41+
'max-rating' : '@maxRating',
42+
'rating' : '<=>rating'
4343
}
4444
)
4545
class RatingComponent {
@@ -52,7 +52,7 @@ class RatingComponent {
5252

5353
int rating;
5454

55-
set max(String value) {
55+
set maxRating(String value) {
5656
stars = [];
5757
var count = value == null ? 5 : int.parse(value);
5858
for(var i=1; i <= count; i++) {

Chapter_04/recipe.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Recipe {
1212
Recipe(this.name, this.category, this.ingredients, this.directions,
1313
this.rating);
1414

15-
String toJson() {
15+
String toJsonString() {
1616
Map data = {
1717
"name" : name,
1818
"category" : category,
@@ -23,7 +23,7 @@ class Recipe {
2323
return JSON.encode(data);
2424
}
2525

26-
factory Recipe.fromJson(Map json) {
26+
factory Recipe.fromJsonMap(Map json) {
2727
return new Recipe(json['name'], json['category'], json['ingredients'],
2828
json['directions'], json['rating']);
2929
}

Chapter_04/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@
88

99
[ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
1010
display: none !important;
11+
}
12+
13+
ul {
14+
list-style-type: none;
1115
}

0 commit comments

Comments
 (0)