diff --git a/server/camlistored/ui/index.js b/server/camlistored/ui/index.js index 4ca9da180..5b976c31f 100644 --- a/server/camlistored/ui/index.js +++ b/server/camlistored/ui/index.js @@ -140,6 +140,7 @@ cam.IndexPage = React.createClass({ getInitialState: function() { return { backwardPiggy: false, + keyNavEnabled: true, currentURL: null, // currentSearch exists in Index just to wire together the searchbox of Header, and the Map // aspect, so the Map aspect can add the zoom level to the predicate in the search box. @@ -243,7 +244,7 @@ cam.IndexPage = React.createClass({ cam.MapAspect.getAspect.bind(null, this.props.config, this.props.availWidth, this.props.availHeight - this.HEADER_HEIGHT_, this.updateSearchBarOnMap_, this.setPendingQuery_, this.childSearchSession_), - cam.PermanodeDetail.getAspect.bind(null, this.props.serverConnection, this.props.timer), + cam.PermanodeDetail.getAspect.bind(null, this.props.serverConnection, this.props.timer, this.toggleKeyNavigation_), cam.BlobDetail.getAspect.bind(null, this.getDetailURL_, this.props.serverConnection), ].map(getAspect).filter(goog.functions.identity); @@ -900,7 +901,16 @@ cam.IndexPage = React.createClass({ } }, + toggleKeyNavigation_: function(enabled) { + this.setState({ + keyNavEnabled: enabled, + }); + }, + handleKeyUp_: function(e) { + if (!this.state.keyNavEnabled) { + return; + } var isEsc = (e.keyCode == 27); var isRight = (e.keyCode == 39); var isLeft = (e.keyCode == 37); diff --git a/server/camlistored/ui/permanode_detail.js b/server/camlistored/ui/permanode_detail.js index 2f75ae08b..804461a7d 100644 --- a/server/camlistored/ui/permanode_detail.js +++ b/server/camlistored/ui/permanode_detail.js @@ -31,6 +31,7 @@ cam.PermanodeDetail = React.createClass({ timer: React.PropTypes.shape({ setTimeout: React.PropTypes.func.isRequired, }).isRequired, + toggleKeyNav: React.PropTypes.func.isRequired, }, getInitialState: function() { @@ -46,9 +47,11 @@ cam.PermanodeDetail = React.createClass({ componentWillReceiveProps: function(nextProps) { // this.props == nextProps is for the very first load. if (this.props == nextProps || this.props.meta.blobRef != nextProps.meta.blobRef) { - this.setState({rows: this.getInitialRows_(nextProps.meta)}); + this.setState({ + rows: this.getInitialRows_(nextProps.meta), + newRow: {}, + }); } - this.setState({newRow: {}}); }, componentWillMount: function() { @@ -116,7 +119,10 @@ cam.PermanodeDetail = React.createClass({ ); }; - return React.DOM.table(null, + return React.DOM.table({ + onFocus: this.handleTableFocus_.bind(null), + onBlur: this.handleTableBlur_.bind(null), + }, React.DOM.tbody(null, React.DOM.tr( {key: 'header'}, @@ -140,7 +146,7 @@ cam.PermanodeDetail = React.createClass({ row: r, }); }, this) - ) + ), ); }, @@ -149,6 +155,14 @@ cam.PermanodeDetail = React.createClass({ this.forceUpdate(); }, + handleTableBlur_: function() { + this.props.toggleKeyNav(true); + }, + + handleTableFocus_: function() { + this.props.toggleKeyNav(false); + }, + handleDelete_: function(row) { this.setState({ rows: this.state.rows.filter(function(r) { return r != row; }), @@ -295,7 +309,7 @@ cam.PermanodeDetail.AttributeRow = React.createClass({ }, }); -cam.PermanodeDetail.getAspect = function(serverConnection, timer, blobref, targetSearchSession) { +cam.PermanodeDetail.getAspect = function(serverConnection, timer, toggleKeyNav, blobref, targetSearchSession) { if (!targetSearchSession) { return null; } @@ -313,6 +327,7 @@ cam.PermanodeDetail.getAspect = function(serverConnection, timer, blobref, targe meta: pm, serverConnection: serverConnection, timer: timer, + toggleKeyNav: toggleKeyNav, }); }, };