Add Field validation to TextInputDialog

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
pull/21833/head
Michael Telatynski 2020-03-13 17:32:02 +00:00
parent 4de0e21a4b
commit ee1659625c
3 changed files with 81 additions and 11 deletions

View File

@ -18,6 +18,7 @@ import React, {createRef} from 'react';
import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import Field from "../elements/Field";
export default createReactClass({
displayName: 'TextInputDialog',
@ -33,6 +34,7 @@ export default createReactClass({
focus: PropTypes.bool,
onFinished: PropTypes.func.isRequired,
hasCancel: PropTypes.bool,
validator: PropTypes.func, // result of withValidation
},
getDefaultProps: function() {
@ -45,25 +47,57 @@ export default createReactClass({
};
},
getInitialState: function() {
return {
value: this.props.value,
valid: false,
};
},
UNSAFE_componentWillMount: function() {
this._textinput = createRef();
this._field = createRef();
},
componentDidMount: function() {
if (this.props.focus) {
// Set the cursor at the end of the text input
this._textinput.current.value = this.props.value;
// this._field.current.value = this.props.value;
this._field.current.focus();
}
},
onOk: function() {
this.props.onFinished(true, this._textinput.current.value);
onOk: async function(ev) {
ev.preventDefault();
if (this.props.validator) {
await this._field.current.validate({ allowEmpty: false });
if (!this._field.current.state.valid) {
this._field.current.focus();
this._field.current.validate({ allowEmpty: false, focused: true });
return;
}
}
this.props.onFinished(true, this.state.value);
},
onCancel: function() {
this.props.onFinished(false);
},
onChange: function(ev) {
this.setState({
value: ev.target.value,
});
},
onValidate: async function(fieldState) {
const result = await this.props.validator(fieldState);
this.setState({
valid: result.valid,
});
return result;
},
render: function() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
@ -77,14 +111,17 @@ export default createReactClass({
<label htmlFor="textinput"> { this.props.description } </label>
</div>
<div>
<input
id="textinput"
ref={this._textinput}
<Field
id="mx_TextInputDialog_field"
className="mx_TextInputDialog_input"
defaultValue={this.props.value}
autoFocus={this.props.focus}
placeholder={this.props.placeholder}
size="64" />
ref={this._field}
type="text"
label={this.props.placeholder}
value={this.state.value}
onChange={this.onChange}
onValidate={this.props.validator ? this.onValidate : undefined}
size="64"
/>
</div>
</div>
</form>

View File

@ -35,6 +35,7 @@ import {useSettingValue} from "../../../hooks/useSettings";
import * as sdk from "../../../index";
import Modal from "../../../Modal";
import SettingsStore from "../../../settings/SettingsStore";
import withValidation from "../elements/Validation";
export const ALL_ROOMS = Symbol("ALL_ROOMS");
@ -47,6 +48,34 @@ const inPlaceOf = (elementRect) => ({
chevronFace: "none",
});
const validServer = withValidation({
rules: [
{
key: "required",
test: async ({ value }) => !!value,
invalid: () => _t("Enter a server address"),
}, {
key: "available",
final: true,
test: async ({ value }) => {
try {
const opts = {
limit: 1,
server: value,
};
// check if we can successfully load this server's room directory
await MatrixClientPeg.get().publicRooms(opts);
return true;
} catch (e) {
return false;
}
},
valid: () => _t("Looks good"),
invalid: () => _t("Can't find this server or its room list"),
},
],
});
// This dropdown sources homeservers from three places:
// + your currently connected homeserver
// + homeservers in config.json["roomDirectory"]
@ -188,6 +217,7 @@ const NetworkDropdown = ({onOptionChange, protocols = {}, selectedServerName, se
button: _t("Add"),
hasCancel: false,
placeholder: _t("Server address"),
validator: validServer,
});
const [ok, newServer] = await finished;

View File

@ -1437,6 +1437,9 @@
"And %(count)s more...|other": "And %(count)s more...",
"ex. @bob:example.com": "ex. @bob:example.com",
"Add User": "Add User",
"Enter a server address": "Enter a server address",
"Looks good": "Looks good",
"Can't find this server or its room list": "Can't find this server or its room list",
"All rooms": "All rooms",
"Your server": "Your server",
"Are you sure you want to remove <b>%(serverName)s</b>": "Are you sure you want to remove <b>%(serverName)s</b>",