Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title>Таблица</title>
- <meta charset="UTF-8">
- <link rel="stylesheet" type="text/css" href="style.css">
- </head>
- <body>
- <div id="app">
- </div>
- <script src="react/build/react.js"></script>
- <script src="react/build/react-dom.js"></script>
- <script>
- var Excel = React.createClass({
- displayName: 'Excel',
- propTypes: {
- headers: React.PropTypes.arrayOf(
- React.PropTypes.string
- ),
- initialData: React.PropTypes.arrayOf(
- React.PropTypes.arrayOf(
- React.PropTypes.string
- )
- ),
- },
- getInitialState: function() {
- return {
- data: this.props.initialData,
- sortby: null,
- descending: false,
- edit: null, // [row index, cell index],
- search: false,
- };
- },
- _sort: function(e) {
- var column = e.target.cellIndex;
- var data = this.state.data.slice();
- var descending = this.state.sortby === column && !this.state.descending;
- data.sort(function(a, b) {
- return descending
- ? (a[column] < b[column] ? 1 : -1)
- : (a[column] > b[column] ? 1 : -1);
- });
- this.setState({
- data: data,
- sortby: column,
- descending: descending,
- });
- },
- _showEditor: function(e) {
- this.setState({edit: {
- row: parseInt(e.target.dataset.row, 10),
- cell: e.target.cellIndex,
- }});
- },
- _save: function(e) {
- e.preventDefault();
- var input = e.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,
- });
- },
- _preSearchData: null,
- _toggleSearch: function() {
- if (this.state.search) {
- this.setState({
- data: this._preSearchData,
- search: false,
- });
- this._preSearchData = null;
- } else {
- this._preSearchData = this.state.data;
- this.setState({
- search: true,
- });
- }
- },
- _search: function(e) {
- var needle = e.target.value.toLowerCase();
- if (!needle) {
- this.setState({data: this._preSearchData});
- return;
- }
- var idx = e.target.dataset.idx;
- var searchdata = this._preSearchData.filter(function(row) {
- return row[idx].toString().toLowerCase().indexOf(needle) > -1;
- });
- this.setState({data: searchdata});
- },
- _download: function(format, ev) {
- var contents = format === 'json'
- ? JSON.stringify(this.state.data)
- : this.state.data.reduce(function(result, row) {
- return result
- + row.reduce(function(rowresult, cell, idx) {
- return rowresult
- + '"'
- + cell.replace(/"/g, '""')
- + '"'
- + (idx < row.length - 1 ? ',' : '');
- }, '')
- + "\n";
- }, '');
- var URL = window.URL || window.webkitURL;
- var blob = new Blob([contents], {type: 'text/' + format});
- ev.target.href = URL.createObjectURL(blob);
- ev.target.download = 'data.' + format;
- },
- render: function() {
- return (
- React.DOM.div(null,
- this._renderToolbar(),
- this._renderTable()
- )
- );
- },
- _renderToolbar: function() {
- return React.DOM.div({className: 'toolbar'},
- React.DOM.button({
- onClick: this._toggleSearch,
- }, 'Поиск'),
- React.DOM.a({
- onClick: this._download.bind(this, 'json'),
- href: 'data.json',
- }, 'Экспорт таблицы в JSON'),
- React.DOM.a({
- onClick: this._download.bind(this, 'csv'),
- href: 'data.csv',
- }, 'Экспорт таблицы в CSV')
- );
- },
- _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,
- })
- );
- })
- )
- );
- },
- _renderTable: function() {
- return (
- React.DOM.table(null,
- React.DOM.thead({onClick: this._sort},
- React.DOM.tr(null,
- this.props.headers.map(function(title, idx) {
- if (this.state.sortby === idx) {
- title += this.state.descending ? ' \u2191' : ' \u2193';
- }
- return React.DOM.th({key: idx}, title);
- }, this)
- )
- ),
- React.DOM.tbody({onDoubleClick: this._showEditor},
- this._renderSearch(),
- this.state.data.map(function(row, rowidx) {
- return (
- React.DOM.tr({key: rowidx},
- row.map(function(cell, idx) {
- var content = cell;
- var edit = this.state.edit;
- if (edit && edit.row === rowidx && edit.cell === idx) {
- content = React.DOM.form({onSubmit: this._save},
- React.DOM.input({
- type: 'text',
- defaultValue: cell,
- })
- );
- }
- return React.DOM.td({
- key: idx,
- 'data-row': rowidx,
- }, content);
- }, this)
- )
- );
- }, this)
- )
- )
- );
- }
- });
- var headers = [
- "Название", "Автор", "Язык", "Дата публикации", "Продажи"
- ];
- var data = [
- ["Властелин колец", "Р. Р. Толкин", "Английский", "1954-1955", "150 миллионов"],
- ["Принц Ле Пети (Маленький принц)", "Антуан де Сент-Экзюпери", "Французский", "1943", "140 миллионов"],
- ["Гарри Поттер и философский камень", "Дж. К. Роулинг", "Английский", "1997", "107 миллионов"],
- ["И тогда их не было", "Агата Кристи", "Английский", "1939", "100 миллионов"],
- ["Мечта о Красной палате", "Цао Сюэцин", "Китайский", "1754-1791", "100 миллионов"],
- ["Хоббит", "Р. Р. Толкиен", "Английский", "1937", "100 миллионов"],
- ["Она: история приключений", "Х. Райдер Хаггард", "Английский", "1887", "100 миллионов"],
- ];
- var Ex = ReactDOM.render(
- React.createElement(Excel, {
- headers: headers,
- initialData: data,
- }),
- document.getElementById("app")
- );
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment