ReactExample: add "smart lists"

This commit is contained in:
Scott Kyle 2015-10-27 03:08:18 -07:00
parent 6fc2110991
commit ab33d47a94
4 changed files with 87 additions and 20 deletions

View File

@ -46,6 +46,9 @@ module.exports = React.StyleSheet.create({
flex: 1,
lineHeight: 30,
},
listItemTextSpecial: {
fontStyle: 'italic',
},
listItemDelete: {
paddingLeft: 12,
paddingRight: 12,

View File

@ -30,14 +30,21 @@ class TodoApp extends React.Component {
}
render() {
let extraItems = [
{name: 'Complete', items: realm.objects('Todo', 'done = true')},
{name: 'Incomplete', items: realm.objects('Todo', 'done = false')},
];
let route = {
title: 'My Todo Lists',
component: TodoListView,
passProps: {
ref: 'listView',
items: this.todoLists,
extraItems: extraItems,
onPressItem: (list) => this._onPressTodoList(list),
},
backButtonTitle: 'Lists',
rightButtonTitle: 'Add',
onRightButtonPress: () => this._addNewTodoList(),
};
@ -64,17 +71,27 @@ class TodoApp extends React.Component {
}
_onPressTodoList(list) {
this.refs.nav.push({
let items = list.items;
let route = {
title: list.name,
component: TodoListView,
passProps: {
ref: 'listItemView',
items: list.items,
items: items,
rowClass: TodoItem,
},
rightButtonTitle: 'Add',
onRightButtonPress: () => this._addNewTodoItem(list),
});
};
// Check if the items are mutable (i.e. List rather than Results).
if (items.push) {
Object.assign(route, {
rightButtonTitle: 'Add',
onRightButtonPress: () => this._addNewTodoItem(list),
});
}
this.refs.nav.push(route);
}
_setEditingRow(rowIndex) {

View File

@ -58,14 +58,14 @@ class TodoListItem extends React.Component {
return this.props.editing ? null : this.renderDelete();
}
renderText() {
renderText(extraStyle) {
if (this.props.editing) {
return (
<TextInput
ref="input"
value={this.text}
placeholder="Call Mom"
style={styles.listItemInput}
style={[styles.listItemInput, extraStyle]}
onChangeText={this._onChangeText}
onEndEditing={this.props.onEndEditing}
enablesReturnKeyAutomatically={true} />
@ -73,7 +73,7 @@ class TodoListItem extends React.Component {
} else {
return (
<Text
style={styles.listItemText}
style={[styles.listItemText, extraStyle]}
onPress={this.props.onPress}
suppressHighlighting={true}>
{this.text}

View File

@ -12,6 +12,7 @@ class TodoListView extends React.Component {
super(props);
this.dataSource = new ListView.DataSource({
sectionHeaderHasChanged: () => false,
rowHasChanged: (row1, row2) => row1 !== row2
});
@ -34,8 +35,14 @@ class TodoListView extends React.Component {
render() {
// Clone the items into a new Array to prevent unexpected errors from changes in length.
let items = Array.from(this.props.items);
let dataSource = this.dataSource.cloneWithRows(items);
let sections = [Array.from(this.props.items)];
let extraItems = this.props.extraItems;
if (extraItems && extraItems.length) {
sections.push(extraItems);
}
let dataSource = this.dataSource.cloneWithRowsAndSections(sections);
return (
<View style={styles.container}>
@ -49,32 +56,41 @@ class TodoListView extends React.Component {
}
renderRow(item, sectionIndex, rowIndex) {
let RowClass = this.props.rowClass || TodoListItem;
let RowClass;
let editing = false;
if (sectionIndex == 0) {
RowClass = this.props.rowClass || TodoListItem;
editing = this.state.editingRow == rowIndex;
} else if (sectionIndex == 1) {
RowClass = TodoListExtraItem;
}
return (
<RowClass
item={item}
editing={this.state.editingRow == rowIndex}
onPress={() => this._onPressRow(item, rowIndex)}
onPressDelete={() => this._onPressDeleteRow(item, rowIndex)}
editing={editing}
onPress={() => this._onPressRow(item, sectionIndex, rowIndex)}
onPressDelete={() => this._onPressDeleteRow(item)}
onEndEditing={() => this._onEndEditingRow(item, rowIndex)} />
);
}
_onPressRow(item, rowIndex) {
_onPressRow(item, sectionIndex, rowIndex) {
let onPressItem = this.props.onPressItem;
if (onPressItem) {
onPressItem(item, rowIndex);
onPressItem(item);
return;
}
// If no handler was provided, then default to editing the row.
this.setState({editingRow: rowIndex});
if (sectionIndex == 0) {
this.setState({editingRow: rowIndex});
}
}
_onPressDeleteRow(item) {
realm.write(() => realm.delete(item));
this._deleteItem(item);
this.forceUpdate();
}
@ -86,12 +102,43 @@ class TodoListView extends React.Component {
}
}
_deleteItem(item) {
let items = item.items;
realm.write(() => {
// If the item is a TodoList, then delete all of its items.
if (items && items.length) {
realm.delete(items);
}
realm.delete(item);
});
}
_deleteItemIfEmpty(item) {
// The item could be a TodoList or a Todo.
if (!item.name && !item.text) {
realm.write(() => realm.delete(item));
this._deleteItem(item);
}
}
}
class TodoListExtraItem extends TodoListItem {
renderText() {
return super.renderText(styles.listItemTextSpecial);
}
renderLeftSide() {
return (
<View style={styles.listItemLeftSide}>
<Text>{this.props.item.items.length}</Text>
</View>
);
}
renderRightSide() {
return null;
}
}
module.exports = TodoListView;