Handles Enter key to submit dialogs.

If there is no focused node inside the dialog we focus any of the available buttons, submit button is first.
pull/76/merge jitsi-meet_2141
damencho 8 years ago committed by hristoterezov
parent bf7415e6b5
commit 8e3dfcf0d0
  1. 139
      react/features/base/dialog/components/StatelessDialog.web.js

@ -7,6 +7,18 @@ import { translate } from '../../i18n';
import { DIALOG_PROP_TYPES } from '../constants';
/**
* The ID to be used for the cancel button if enabled.
* @type {string}
*/
const CANCEL_BUTTON_ID = 'modal-dialog-cancel-button';
/**
* The ID to be used for the ok button if enabled.
* @type {string}
*/
const OK_BUTTON_ID = 'modal-dialog-ok-button';
/**
* Web dialog that uses atlaskit modal-dialog to display dialogs.
*/
@ -63,7 +75,34 @@ class StatelessDialog extends Component {
// Bind event handlers so they are only bound once for every instance.
this._onCancel = this._onCancel.bind(this);
this._onDialogDismissed = this._onDialogDismissed.bind(this);
this._onKeyDown = this._onKeyDown.bind(this);
this._onSubmit = this._onSubmit.bind(this);
this._setDialogElement = this._setDialogElement.bind(this);
}
/**
* React Component method that executes once component is mounted.
*
* @inheritdoc
*/
componentDidMount() {
this._updateButtonFocus();
}
/**
* React Component method that executes once component is updated.
*
* @param {Object} prevProps - The previous properties, before the update.
* @returns {void}
*/
componentDidUpdate(prevProps) {
// if there is an update in any of the buttons enable/disable props
// update the focus if needed
if (prevProps.okDisabled !== this.props.okDisabled
|| prevProps.cancelDisabled !== this.props.cancelDisabled
|| prevProps.submitDisabled !== this.props.submitDisabled) {
this._updateButtonFocus();
}
}
/**
@ -74,21 +113,25 @@ class StatelessDialog extends Component {
*/
render() {
return (
<ModalDialog
footer = { this._renderFooter() }
header = { this._renderHeader() }
isOpen = { true }
onDialogDismissed = { this._onDialogDismissed }
width = { this.props.width || 'medium' }>
<div>
<form
className = 'modal-dialog-form'
id = 'modal-dialog-form'
onSubmit = { this._onSubmit }>
{ this.props.children }
</form>
</div>
</ModalDialog>
<div
onKeyDown = { this._onKeyDown }
ref = { this._setDialogElement }>
<ModalDialog
footer = { this._renderFooter() }
header = { this._renderHeader() }
isOpen = { true }
onDialogDismissed = { this._onDialogDismissed }
width = { this.props.width || 'medium' }>
<div>
<form
className = 'modal-dialog-form'
id = 'modal-dialog-form'
onSubmit = { this._onSubmit }>
{ this.props.children }
</form>
</div>
</ModalDialog>
</div>
);
}
@ -139,7 +182,7 @@ class StatelessDialog extends Component {
return (
<AKButton
appearance = 'subtle'
id = 'modal-dialog-cancel-button'
id = { CANCEL_BUTTON_ID }
onClick = { this._onCancel }>
{ this.props.t(this.props.cancelTitleKey || 'dialog.Cancel') }
</AKButton>
@ -196,13 +239,75 @@ class StatelessDialog extends Component {
<AKButton
appearance = 'primary'
form = 'modal-dialog-form'
id = 'modal-dialog-ok-button'
id = { OK_BUTTON_ID }
isDisabled = { this.props.okDisabled }
onClick = { this._onSubmit }>
{ this.props.t(this.props.okTitleKey || 'dialog.Ok') }
</AKButton>
);
}
/**
* Sets the instance variable for the div containing the component's dialog
* element so it can be accessed directly.
*
* @param {Object} element - The DOM element for the component's dialog.
* @private
* @returns {void}
*/
_setDialogElement(element) {
this._dialogElement = element;
}
/**
* Handles 'Enter' key in the dialog to submit/hide dialog depending on
* the available buttons and their disabled state.
*
* @param {Object} event - the key event.
* @private
* @returns {void}
*/
_onKeyDown(event) {
if (event.key === 'Enter') {
if (this.props.submitDisabled && !this.props.cancelDisabled) {
this._onCancel();
} else if (!this.props.okDisabled) {
this._onSubmit();
}
}
}
/**
* Updates focused button, if we have a reference to the dialog element.
* Focus on available button if there is no focus already.
*
* @private
* @returns {void}
*/
_updateButtonFocus() {
if (this._dialogElement) {
// if we have a focused element inside the dialog, skip changing
// the focus
if (this._dialogElement.contains(document.activeElement)) {
return;
}
let buttonToFocus;
if (this.props.submitDisabled) {
buttonToFocus = this._dialogElement
.querySelector(`[id=${CANCEL_BUTTON_ID}]`);
} else if (!this.props.okDisabled) {
buttonToFocus = this._dialogElement
.querySelector(`[id=${OK_BUTTON_ID}]`);
}
if (buttonToFocus) {
buttonToFocus.focus();
}
}
}
}
export default translate(StatelessDialog);

Loading…
Cancel
Save