一个出色的表格(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>
如需转载,请注明文章出处,谢谢!!!