先上圖,不囉嗦。
這邊還只有UI的功能而已,補上三支code!
還有包裝component進去。
import React, { PropTypes } from 'react';
import Book from './Book';
import BookInputWidget from './BookInputWidget';
const propTypes = {
updateBooks: PropTypes.func.isRequired,
books: PropTypes.array.isRequired,
};
class ReadingListWidget extends React.Component {
constructor(props){
super(props);
this.onBookDelete = this.onBookDelete.bind(this)
this.onBookModify = this.onBookModify.bind(this)
this.onConfirmModify = this.onConfirmModify.bind(this)
this.onCancelModify = this.onCancelModify.bind(this)
this.state = {
books: props.books,
modifyList: []
}
}
onBookDelete(id){
console.log(id);
let books = this.state.books.filter((book, i) => {
console.log(book);
return book.id!=id;
});
this.setState({books})
}
onBookModify(id){
console.log(id);
let modifyList = this.state.modifyList;
if(modifyList.indexOf(id)==-1){
modifyList.push(id);
}
this.setState({modifyList});
}
onCancelModify(id){
let modifyList = this.state.modifyList.filter((modifiedID) => {
return modifiedID!=id;
});
this.setState({modifyList});
}
onConfirmModify(id){
let modifyList = this.state.modifyList.filter((modifiedID) => {
return modifiedID!=id;
});
this.setState({modifyList});
}
render() {
const { books, modifyList } = this.state;
const bookComponents = books.map((book, index) => {
if(modifyList.indexOf(book.id)==-1){
return(
<Book { ...book}
key={index}
onDelete = {this.onBookDelete}
onModify = {this.onBookModify}
/>
);
}else{
return(
<BookInputWidget { ...book}
key={index}
onConfirm = {this.onConfirmModify}
onCancel = {this.onCancelModify}
/>
);
}
});
return (
<div className="container">
<h3>
Reading List
</h3>
<div className="row">
<div className="col-md-1">{''}</div>
<div className="col-md-2">閱讀狀態</div>
<div className="col-md-3">書名</div>
<div className="col-md-2">作者</div>
<div className="col-md-4">
</div>
</div>
{bookComponents}
<hr />
<BookInputWidget />
<hr />
</div>
);
}
}
ReadingListWidget.propTypes = propTypes;
export default ReadingListWidget;
import React, { PropTypes } from 'react';
const propTypes = {
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
status: PropTypes.string.isRequired,
author_id: PropTypes.number.isRequired,
author_name: PropTypes.string.isRequired,
onDelete: PropTypes.func.isRequired,
onModify: PropTypes.func.isRequired
}
class Book extends React.Component {
constructor(props){
super(props);
this.onCheckboxChange = this.onCheckboxChange.bind(this);
this.onModifyClick = this.onModifyClick.bind(this);
this.onDeleteClick = this.onDeleteClick.bind(this);
this.state = {
status: props.status
}
}
onCheckboxChange(e){
let target = e.target;
target.indeterminate = true;
switch(this.state.status){
case "unread":
target.checked = false;
target.indeterminate = true;
this.setState({status: 'reading'});
break;
case "reading":
target.checked = true;
target.indeterminate = false;
this.setState({status: 'finished'});
break;
case "finished":
target.checked = false;
target.indeterminate = false;
this.setState({status: 'unread'});
break;
}
}
onDeleteClick(e){
let {id, onDelete} = this.props;
onDelete(id);
}
onModifyClick(e){
let {id, onModify} = this.props;
onModify(id);
}
render() {
const {id, name, author_name} = this.props;
const {status} = this.state;
return (
<div className="row">
<div className="col-md-1">{id}</div>
<div className="col-md-2">
<input type="checkbox" name={"status"} onChange={this.onCheckboxChange} />
<label>{status}</label>
</div>
<div className="col-md-3">{name}</div>
<div className="col-md-2">{author_name}</div>
<div className="col-md-4">
<button type="button" className="btn btn-outline-success" onClick={this.onModifyClick}>Modify</button>
<button type="button" className="btn btn-outline-danger" onClick={this.onDeleteClick}>Delete</button>
</div>
</div>
);
}
}
Book.propTypes = propTypes;
export default Book;
import React, { PropTypes } from 'react';
const propTypes = {
id: PropTypes.number,
name: PropTypes.string,
status: PropTypes.string,
author_id: PropTypes.number,
author_name: PropTypes.string,
onCreate: PropTypes.func,
onCancel: PropTypes.func,
onConfirm: PropTypes.func
}
const defaultProps = {
id: 0,
name: '',
status: 'unread',
author_id: 0,
author_name: '',
onCreate: function(){},
onCancel: function(){},
onConfirm: function(){}
}
class BookInputWidget extends React.Component {
constructor(props){
super(props);
this.onCheckboxChange = this.onCheckboxChange.bind(this);
this.onConfirmClick = this.onConfirmClick.bind(this);
this.onCancelClick = this.onCancelClick.bind(this);
this.onCreateClick = this.onCreateClick.bind(this);
console.log(props)
this.state = {
name: props.name || '',
status: props.status || 'unread',
author_name: props.author_name || ''
}
}
onCheckboxChange(e){
let target = e.target;
target.indeterminate = true;
switch(this.state.status){
case "unread":
target.checked = false;
target.indeterminate = true;
this.setState({status: 'reading'});
break;
case "reading":
target.checked = true;
target.indeterminate = false;
this.setState({status: 'finished'});
break;
case "finished":
target.checked = false;
target.indeterminate = false;
this.setState({status: 'unread'});
break;
}
}
onCreateClick(e){
let {id, onCreate} = this.props;
onCreate(id);
}
onCancelClick(e){
let {id, onCancel} = this.props;
onCancel(id);
}
onConfirmClick(e){
let {id, onConfirm} = this.props;
onConfirm(id);
}
render() {
const {id} = this.props;
const {name, status, author_name} = this.state;
let buttons=null
if(id==0){
buttons=<span className="create-book">
<button type="button" className="btn btn-primary" onClick={this.onCreateClick}>Create</button>
</span>
}else{
buttons=<span className="create-book">
<button type="button" className="btn btn-success" onClick={this.onConfirmClick}>Confirm</button>
<button type="button" className="btn btn-secondary" onClick={this.onCancelClick}>Cancel</button>
</span>
}
return (
<div className="row">
<div className="col-md-1">{''}</div>
<div className="col-md-2">
<input type="checkbox" name={"status"} onChange={this.onCheckboxChange} />
<label>{status}</label>
</div>
<div className="col-md-3">
<input type="text" name="name" value={name}/>
</div>
<div className="col-md-2"><input type="text" name="author_name" value={author_name} /></div>
<div className="col-md-4">
{buttons}
</div>
</div>
);
}
}
BookInputWidget.propTypes = propTypes;
BookInputWidget.defaultProps = defaultProps;
export default BookInputWidget;
如此一來分工就滿清楚的了,ReadingListWidget專門Reload資訊,Book專門show出資訊,然後BookInputWidget負責修改或新增book資訊。
明天要打包JSON,寫AJAX,串接後端rails服務了!!
我會在犧牲掉兩天deploy...如果篇數不夠的話QQ