Skip to content

Instantly share code, notes, and snippets.

@adamabernathy
Created January 12, 2017 21:36
Show Gist options
  • Select an option

  • Save adamabernathy/6ac71d56df86b9896de93e248147d29b to your computer and use it in GitHub Desktop.

Select an option

Save adamabernathy/6ac71d56df86b9896de93e248147d29b to your computer and use it in GitHub Desktop.
additive search problem
var Excel = React.createClass({
displayName: 'Excel',
__preSearchData: null,
_log: [],
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
};
},
componentDidMount: function () {
document.onkeydown = function (e) {
if (e.altKey && e.shiftKey && e.keyCode === 82) {
// ALT + SHIFT + R(eplay)
console.log("Boom");
this._replay();
}
else if (e.ctrlKey && e.keyCode === 90) {
console.log("Undoing...")
this._revertState();
}
}.bind(this);
},
_logSetState: function (newState) {
// want to remember the old state via a clone
this._log.push(JSON.parse(JSON.stringify(this._log.length === 0 ? this.state : newState)));
this.setState(newState);
},
_replay: function () {
if (this._log.length === 0) {
console.warn("No state to replay");
return;
}
var idx = -1;
var interval = setInterval(function () {
idx++;
if (idx === this._log.length - 1) {
// last element in array
clearInterval(interval);
}
this.setState(this._log[idx]);
}.bind(this), 1000);
},
_revertState: function () {
if (this._log.length === 0) {
console.warn("No state to replay");
return;
}
console.log(this._log);
console.log(this._log.length - 2);
this.setState(this._log[this._log.length - 1]);
},
_sort: function (e) {
var col = e.target.cellIndex;
var data = this.state.data.slice();
var descending = this.state.sortBy === col && !this.state.descending;
data.sort(function (a, b) {
return descending
? (a[col] < b[col] ? 1 : -1)
: (a[col] > b[col] ? 1 : -1)
});
this.setState({
data: data,
sortBy: col,
descending: descending
});
},
_showEditor: function (e) {
this.setState({
edit: {
row: parseInt(e.target.dataset.row, 10),
cell: e.target.cellIndex
}
})
},
_save: function (e) {
e.preventDefault(); // block default behavior
var input = e.target.firstChild;
var data = this.state.data.slice();
data[this.state.edit.row][this.state.edit.cell] = input.value
console.log({
row: this.state.edit.row,
cell: this.state.edit.cell,
value: input.value
});
this._logSetState({
edit: null,
data: data
});
},
_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();
console.log(needle)
if (!needle) {
// No search string
this.setState({ data: this.__preSearchData });
return;
}
var idx = e.target.dataset.idx; // what column to search
var searchData = this.__preSearchData.filter(function (row) {
return row[1].toString().toLowerCase().indexOf("tol") > -1 &&
row[idx].toString().toLowerCase().indexOf(needle) > -1
}); // bool
this.setState({ data: searchData });
},
_renderToolbar: function () {
return React.DOM.button({
onClick: this._toggleSearch,
className: "toolbar"
}, "Search");
},
_renderSearch: function () {
// Bail out
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,
// Generate the header
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)
)
),
// Generate the table body
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;
// Change the node type and allow for editing
if (_edit && _edit.row === rowIdx && _edit.cell === idx) {
content = React.DOM.form({ onSubmit: this._save },
React.DOM.input({
type: "text",
defaultValue: content
})
)
}
return React.DOM.td({
key: idx,
"data-row": rowIdx
}, content);
}, this) // row.map
)
);
}, this) // state.data.map
)
)
);
},
render: function () {
return (
React.DOM.div(
null,
this._renderToolbar(),
this._renderTable()
)
)
}
});
var headers = [
"Book", "Author", "Language", "Published", "Sales"
];
var data = [
["The Lord of the Rings", "J. R. R. Tolkien", "English", "1954–1955", "150 million"],
["Le Petit Prince (The Little Prince)", "Antoine de Saint-Exupéry", "French", "1943", "140 million"],
["Harry Potter and the Philosopher's Stone", "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"],
];
ReactDOM.render(
React.createElement(Excel, {
headers: headers,
initialData: data,
}),
document.getElementById("app")
);
@adamabernathy
Copy link
Author

I can get the filter to "filter" by hijacking LN 46, but I can't figure out how to get the values of all the other boxes. I could directly access them by a document.querySelectAll() but would that violate the state methodologies?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment