Browse Source

Video 8: Filter Items in the React Native List View.

Frederic G. MARAND 7 years ago
parent
commit
03f29d961d
2 changed files with 74 additions and 6 deletions
  1. 22 4
      app.js
  2. 52 2
      footer.js

+ 22 - 4
app.js

@@ -33,6 +33,15 @@ const styles = StyleSheet.create({
   }
 });
 
+const filterItems = (filter, items) => {
+  return items.filter((item) => {
+    if ((filter === 'ACTIVE' && item.complete) || (filter === 'COMPLETED' && !item.complete)) {
+      return false;
+    }
+    return true;
+  });
+};
+
 class App extends Component {
   constructor(props) {
     super(props);
@@ -42,10 +51,12 @@ class App extends Component {
     this.state = {
       allComplete: false,
       dataSource: ds.cloneWithRows([]),
+      filter: "ALL",
       items: [],
       value: ""
     };
     this.handleAddItem = this.handleAddItem.bind(this);
+    this.handleFilter = this.handleFilter.bind(this);
     this.handleRemoveItem = this.handleRemoveItem.bind(this);
     this.handleToggleAllComplete = this.handleToggleAllComplete.bind(this);
     this.handleToggleComplete = this.handleToggleComplete.bind(this);
@@ -67,9 +78,13 @@ class App extends Component {
     this.setSource(newItems, newItems, { value: "" });
   }
 
+  handleFilter(filter) {
+    this.setSource(this.state.items, filterItems(filter, this.state.items), { filter });
+  }
+
   handleRemoveItem(key) {
     const newItems = this.state.items.filter((item) => item.key !== key);
-    this.setSource(newItems, newItems);
+    this.setSource(newItems, filterItems(this.state.filter, newItems));
   }
 
   handleToggleAllComplete() {
@@ -79,7 +94,7 @@ class App extends Component {
       complete
     }));
     // console.table(newItems);
-    this.setSource(newItems, newItems, { allComplete: complete });
+    this.setSource(newItems, filterItems(this.state.filter, newItems), { allComplete: complete });
   }
 
   handleToggleComplete(key, complete) {
@@ -92,7 +107,7 @@ class App extends Component {
         complete
       };
     });
-    this.setSource(newItems, newItems);
+    this.setSource(newItems, filterItems(this.state.filter, newItems));
   }
 
   render() {
@@ -128,7 +143,10 @@ class App extends Component {
             style={styles.list}
           />
         </View>
-        <Footer />
+        <Footer
+          filter={this.state.filter}
+          onFilter={this.handleFilter}
+        />
       </View>
     );
   }

+ 52 - 2
footer.js

@@ -1,12 +1,62 @@
 import React, { Component } from 'react';
-import { View, Text, StyleSheet } from 'react-native';
+import {
+  StyleSheet,
+  Text,
+  TouchableOpacity,
+  View
+} from 'react-native';
+
+const styles = StyleSheet.create({
+  container: {
+    alignItems: "center",
+    flexDirection: "row",
+    justifyContent: "space-between",
+    padding: 16
+  },
+  filter: {
+    borderColor: "transparent",
+    borderRadius: 5,
+    borderWidth: 1,
+    padding: 8
+  },
+  filters: {
+    flexDirection: "row"
+  },
+  selected: {
+    borderColor: "rgba(175, 47, 47, 0.2)"
+  }
+});
 
 class Footer extends Component {
   render() {
+    const { filter } = this.props;
     return (
-      <View />
+      <View style={styles.container}>
+        <View style={styles.filters}>
+          <TouchableOpacity
+            onPress={() => this.props.onFilter('ALL')}
+            style={[styles.filter, filter === 'ALL' && styles.selected]}>
+            <Text>All</Text>
+          </TouchableOpacity>
+          <TouchableOpacity
+            onPress={() => this.props.onFilter('ACTIVE')}
+            style={[styles.filter, filter === 'ACTIVE' && styles.selected]}>
+            <Text>Active</Text>
+          </TouchableOpacity>
+          <TouchableOpacity
+            onPress={() => this.props.onFilter('COMPLETED')}
+            style={[styles.filter, filter === 'COMPLETED' && styles.selected]}>
+            <Text>Completed</Text>
+          </TouchableOpacity>
+        </View>
+      </View>
     );
   }
 }
 
+Footer.propTypes = {
+  filter: React.PropTypes.string,
+  onFilter: React.PropTypes.func
+};
+
 export default Footer;