一个出色的表格(React实现__ES5语法)

  本文主要是《React快速上手开发》一书中,第三章的内容代码整理,因为书中的代码零零散散,所以自己将整理了一下。

 

排序和编辑功能

<script>
	var header = ["Book", "Author", "Language", "Publishd", "Sales"];
	var data = [
		["The Lord of the Rings", "J. R. R.Tolkien", "English", "1954-1955", "150 million"],
		["Le Ptit Prince", "Antonie de Saint-Exupery", "French", "1943", "140 million"],
		["Harry Potter and the Philosopher", "J. K. Rowling", "English", "1997", "107 million"],
		["And Then There Were None", "Agatha Christie", "English", "1939", "100 million"],
		["Dream of the red chamber", "Cao Xueqin", "Chinese", "1754-1791", "100 million"],
		["The Hobbit", "J. R. R Tolkien", "English", "1937", "100 million"],
		["She A History of Adventure", "H. Rider Haggard", "English", "1887", "100 million"]
	];

	var Excel = React.createClass({
		displayName :"Excel",
		render :function() {
			return (
				React.DOM.table(null,
					React.DOM.thead(
						{onClick : this._sort},
						React.DOM.tr(
							null,
							this.state.headers.map(function(title, id){
								return React.DOM.th({key: id}, title);
							})
						)
					),
					React.DOM.tbody(
						{onDoubleClick:this._showEditor},
						this.state.data.map(function(row, rowIndex){
							return (
								React.DOM.tr(
									{key:rowIndex},
									row.map(function(field, cellIndex){
										var content = field;
										var edit = this.state.edit;
										if (edit && edit.row==rowIndex && edit.cell==cellIndex) {
											content = React.DOM.form(
												{onSubmit: this._save},
												React.DOM.input(
													{type : "text", defaultValue : content}
												)
											);
										}
										return React.DOM.td(
											{key:cellIndex, 'data-row':rowIndex}, 
											content
										);
									}, this)
								)
							);
						}, this)
					)
				)
			)
		},

		//点击表头,根据当前列排序
		_sort : function(ev){
			var column = ev.target.cellIndex;
			var data_bk = this.state.data.slice(); 
			data_bk.sort(function(a, b){
				return a[column] > b[column] ? 1 : -1;
			});
			this.setState({
				data : data_bk
			});
		},

		getInitialState :function (){
			return {
				headers : this.props.headers,
				data : this.props.initialData,
				descending : false,
				edit : null
			}
		},

		_showEditor : function(ev){
			this.setState({
				edit : {
					row: parseInt(ev.target.dataset.row, 10),
					cell : ev.target.cellIndex
				}
			});
		},

		_save : function(ev){
			ev.preventDefault();
			var input = ev.target.firstChild;
			var data = this.state.data.slice();
			data[this.state.edit.row][this.state.edit.cell] = input.value;
			this.setState({
				edit : null,
				data : data
			});
		}

	});

	ReactDOM.render(
		React.createElement(Excel, {headers : header, initialData : data}),
		document.getElementById("app")
	);
</script>

  

搜索功能

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>First Test React</title>
</head>
<body>
	<div id="app"></div>
</body>
<script src="react/build/react.js"></script>
<script src="react/build/react-dom.js"></script>
<script>
	var header = ["Book", "Author", "Language", "Publishd", "Sales"];
	var data = [
		["The Lord of the Rings", "J. R. R.Tolkien", "English", "1954-1955", "150 million"],
		["Le Ptit Prince", "Antonie de Saint-Exupery", "French", "1943", "140 million"],
		["Harry Potter and the Philosopher", "J. K. Rowling", "English", "1997", "107 million"],
		["And Then There Were None", "Agatha Christie", "English", "1939", "100 million"],
		["Dream of the red chamber", "Cao Xueqin", "Chinese", "1754-1791", "100 million"],
		["The Hobbit", "J. R. R Tolkien", "English", "1937", "100 million"],
		["She A History of Adventure", "H. Rider Haggard", "English", "1887", "100 million"]
	];

	var Excel = React.createClass({
		displayName :"Excel",
		_preSearchData : null,

		render :function() {
			return (
				React.DOM.div(
					null,
					this._renderToolbar(),  //渲染表头和搜索框
					this._renderTable()  //渲染表格内容
				)
			)
		},

		//点击表头,根据当前列排序
		_sort : function(ev){
			var column = ev.target.cellIndex;
			var data_bk = this.state.data.slice(); 
			data_bk.sort(function(a, b){
				return a[column] > b[column] ? 1 : -1;
			});
			this.setState({
				data : data_bk
			});
		},

		getInitialState :function (){
			return {
				headers : this.props.headers,
				data : this.props.initialData,
				descending : false,
				edit : null,
				search : false  //初始默认关闭搜索功能
			}
		},

		_showEditor : function(ev){
			this.setState({
				edit : {
					row: parseInt(ev.target.dataset.row, 10),
					cell : ev.target.cellIndex
				}
			});
		},

		_save : function(ev){
			ev.preventDefault();
			var input = ev.target.firstChild;
			var data = this.state.data.slice();
			data[this.state.edit.row][this.state.edit.cell] = input.value;
			this.setState({
				edit : null,
				data : data
			});
		},

		_renderToolbar : function() {
			return React.DOM.button(
				{
					onClick : this._toggleSearch,  //开启或者关闭搜索功能
					className : "toolbar"
				},
				"search"
			);
		},

		_renderTable : function() {
			return (
				React.DOM.table(null,
					React.DOM.thead(
						{onClick : this._sort},
						React.DOM.tr(
							null,
							this.state.headers.map(function(title, id){
								return React.DOM.th({key: id}, title);
							})
						)
					),
					React.DOM.tbody(
						{onDoubleClick:this._showEditor},
						this._renderSearch(),
						this.state.data.map(function(row, rowIndex){
							return (
								React.DOM.tr(
									{key:rowIndex},
									row.map(function(field, cellIndex){
										var content = field;
										var edit = this.state.edit;
										if (edit && edit.row==rowIndex && edit.cell==cellIndex) {
											content = React.DOM.form(
												{onSubmit: this._save},
												React.DOM.input(
													{type : "text", defaultValue : content}
												)
											);
										}
										return React.DOM.td(
											{key:cellIndex, 'data-row':rowIndex}, 
											content
										);
									}, this)
								)
							);
						}, this)
					)
				)
			)
		},

		_renderSearch : function() {
			if (!this.state.search) {
				return null;
			}
			return (
				React.DOM.tr(
					{onChange : this._search},
					this.props.headers.map(function(_ignore, idx){
						return React.DOM.td(
							{key : idx},
							React.DOM.input(
								{type : "text", "data-idx": idx}
							)
						)
					})
				)
			);
		},

		//调整搜索功能,如果是开启状态,则关闭它;否则打开搜索功能,通过设置state中的search
		_toggleSearch : function() {
			if (this.state.search) {
				this.setState({
					data : this._preSearchData,
					search : false
				});
				this._preSearchData = null;
			} else {
				this._preSearchData = this.state.data; //开启搜索时,将data先存入_preSearchData
				this.setState({
					search : true
				})
			}
		},

		_search : function (ev) {
			var needle = ev.target.value.toLowerCase();
			if (!needle) {  //搜索的字符串为空时,恢复原数据
				this.setState({data : this._preSearchData});
				return;
			}

			var idx = ev.target.dataset.idx;  //进行搜索的那一列
			var searchData = this._preSearchData.filter(function(row){
				return row[idx].toString().toLowerCase().indexOf(needle) > -1;
			});
			this.setState({
				data : searchData
			})
		}

	});

	ReactDOM.render(
		React.createElement(Excel, {headers : header, initialData : data}),
		document.getElementById("app")
	);
</script>
</html>
				

  

回放功能

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>First Test React</title>
</head>
<body>
	<div id="app"></div>
</body>
<script src="react/build/react.js"></script>
<script src="react/build/react-dom.js"></script>
<script>
	var header = ["Book", "Author", "Language", "Publishd", "Sales"];
	var data = [
		["The Lord of the Rings", "J. R. R.Tolkien", "English", "1954-1955", "150 million"],
		["Le Ptit Prince", "Antonie de Saint-Exupery", "French", "1943", "140 million"],
		["Harry Potter and the Philosopher", "J. K. Rowling", "English", "1997", "107 million"],
		["And Then There Were None", "Agatha Christie", "English", "1939", "100 million"],
		["Dream of the red chamber", "Cao Xueqin", "Chinese", "1754-1791", "100 million"],
		["The Hobbit", "J. R. R Tolkien", "English", "1937", "100 million"],
		["She A History of Adventure", "H. Rider Haggard", "English", "1887", "100 million"]
	];

	var Excel = React.createClass({
		displayName :"Excel",
		_preSearchData : null,  
		_log : [],

		render :function() {
			return (
				React.DOM.div(
					null,
					this._renderToolbar(),  //渲染表头和搜索框
					this._renderTable()  //渲染表格内容
				)
			)
		},

		//点击表头,根据当前列排序
		_sort : function(ev){
			var column = ev.target.cellIndex;
			var data_bk = this.state.data.slice(); 
			data_bk.sort(function(a, b){
				return a[column] > b[column] ? 1 : -1;
			});
			this.setState({
				data : data_bk
			});
		},

		getInitialState :function (){
			return {
				headers : this.props.headers,
				data : this.props.initialData,
				descending : false,
				edit : null,
				search : false  //初始默认关闭搜索功能
			}
		},

		_showEditor : function(ev){
			this.setState({
				edit : {
					row: parseInt(ev.target.dataset.row, 10),
					cell : ev.target.cellIndex
				}
			});
		},

		_save : function(ev){
			ev.preventDefault();
			var input = ev.target.firstChild;
			var data = this.state.data.slice();
			data[this.state.edit.row][this.state.edit.cell] = input.value;
			this.setState({
				edit : null,
				data : data
			});
		},

		_renderToolbar : function() {
			return React.DOM.button(
				{
					onClick : this._toggleSearch,  //开启或者关闭搜索功能
					className : "toolbar"
				},
				"search"
			);
		},

		_renderTable : function() {
			return (
				React.DOM.table(null,
					React.DOM.thead(
						{onClick : this._sort},
						React.DOM.tr(
							null,
							this.state.headers.map(function(title, id){
								return React.DOM.th({key: id}, title);
							})
						)
					),
					React.DOM.tbody(
						{onDoubleClick:this._showEditor},
						this._renderSearch(),
						this.state.data.map(function(row, rowIndex){
							return (
								React.DOM.tr(
									{key:rowIndex},
									row.map(function(field, cellIndex){
										var content = field;
										var edit = this.state.edit;
										if (edit && edit.row==rowIndex && edit.cell==cellIndex) {
											content = React.DOM.form(
												{onSubmit: this._save},
												React.DOM.input(
													{type : "text", defaultValue : content}
												)
											);
										}
										return React.DOM.td(
											{key:cellIndex, 'data-row':rowIndex}, 
											content
										);
									}, this)
								)
							);
						}, this)
					)
				)
			)
		},

		_renderSearch : function() {
			if (!this.state.search) {
				return null;
			}
			return (
				React.DOM.tr(
					{onChange : this._search},
					this.props.headers.map(function(_ignore, idx){
						return React.DOM.td(
							{key : idx},
							React.DOM.input(
								{type : "text", "data-idx": idx}
							)
						)
					})
				)
			);
		},

		//调整搜索功能,如果是开启状态,则关闭它;否则打开搜索功能,通过设置state中的search
		_toggleSearch : function() {
			if (this.state.search) {
				this.setState({
					data : this._preSearchData,
					search : false
				});
				this._preSearchData = null;
			} else {
				this._preSearchData = this.state.data; //开启搜索时,将data先存入_preSearchData
				this.setState({
					search : true
				})
			}
		},

		_search : function (ev) {
			var needle = ev.target.value.toLowerCase();
			if (!needle) {  //搜索的字符串为空时,恢复原数据
				this.setState({data : this._preSearchData});
				return;
			}

			var idx = ev.target.dataset.idx;  //进行搜索的那一列
			var searchData = this._preSearchData.filter(function(row){
				return row[idx].toString().toLowerCase().indexOf(needle) > -1;
			});
			this.setState({
				data : searchData
			})
		},

		_logSetState : function() {
			this._log.push(JSON.parse(JSON.stringify(
				this._log.length === 0 ? this.state : newState
			)));
			this.setState(newState)
		},

		componetDidMount : function() {
			document.onkeydown = function() {
				if (e.altKey && e.shiftKey && e.keyCode === 82) {
					this._replay();
				}
			}.bind(this);
		},

		_replay : function() {
			if (this._log.length === 0) {
				console.log("No state to replay yet");
				return;
			}
			var idx = -1;
			var interval = setInterval(function(){
				idx++;
				if (idx === this._log.length-1){
					clearInterval(interval);
				}
				this.setState(this._log[idx]);
			}.bind(this), 1000);
		}

	});

	ReactDOM.render(
		React.createElement(Excel, {headers : header, initialData : data}),
		document.getElementById("app")
	);
</script>
</html>
				

  

posted @ 2018-07-29 11:24  寻觅beyond  阅读(2610)  评论(0编辑  收藏  举报
返回顶部