paul.morrissey
27 Nov 2017, 3:15 PM
I have a Login component that contains a "submit" button. The button that gets created in the DOM is of type "button" not "submit" and pressing the Enter key does not call the button's handler. Below is the code for the component. Am I coding this wrong?
import * as React from 'react';
import { connect } from "react-redux";
import {
Container,
Button,
FormPanel,
FieldSet,
TextField,
PasswordField,
Toolbar,
Label,
Spacer
} from '@extjs/ext-react';
import actions from '../../actions';
import AppState from '../../types/state';
import { NestedStringMap } from '../../types/common';
import { pick } from '../../utils/utils';
interface LoginActions {
loginUserNameChanged: typeof actions.loginUserNameChanged;
loginUserPasswordChanged: typeof actions.loginUserPasswordChanged;
resetLoginForm: typeof actions.resetLoginForm;
authenticate: typeof actions.authenticate;
}
interface LoginProps {
loginUserName: string;
loginUserPassword: string;
loginFormValid: boolean;
loginFailed: boolean;
resources: NestedStringMap;
}
class LoginMainView extends React.Component<LoginActions & LoginProps, {}> {
onLoginUser = () => {
this.props.authenticate(this.props.loginUserName, this.props.loginUserPassword);
}
onResetLoginForm = () => {
this.props.resetLoginForm({});
}
render() {
return (
<Container
shadow
layout={{
type: 'vbox',
align: 'center',
pack: 'center'
}}
>
<FormPanel
shadow
width={600}
height={300}
align='center'
padding="20"
>
<FieldSet>
<Container layout="hbox">
<Spacer />
<Label
html={this.props.resources.loginTitle as string}
style={{
fontSize: "1.5em",
fontWeight: "bold"
}}
margin={5}
/>
<Spacer />
</Container>
<TextField
labelAlign="placeholder"
label={this.props.resources.userNameLabel as string}
value={this.props.loginUserName}
onChange={(me, loginUserName) => this.props.loginUserNameChanged({ loginUserName })}
/>
<PasswordField
labelAlign="placeholder"
label={this.props.resources.userPasswordLabel as string}
revealable
value={this.props.loginUserPassword}
onChange={(me, loginUserPassword) => this.props.loginUserPasswordChanged({ loginUserPassword })}
/>
<Container
layout="center"
padding={10}
hidden={!(this.props.loginFailed)}
style={{
color: 'red'
}}
>
{this.props.resources.failed}
</Container>
</FieldSet>
<Toolbar
docked="bottom"
layout={{
type: 'hbox',
pack: 'center'
}}
>
<Button
type="submit"
text={this.props.resources.loginUserAction as string}
margin="0 10 0 0"
disabled={!(this.props.loginFormValid)}
handler={() => this.onLoginUser()}
/>
<Button
text={this.props.resources.resetValuesAction as string}
handler={() => this.onResetLoginForm()}
/>
</Toolbar>
</FormPanel>
</Container>
);
}
}
function mapStateToProps(state: AppState): LoginProps {
const { nameCurrentValue, passwordCurrentValue, failed } = state.loginState;
return {
loginUserName: nameCurrentValue,
loginUserPassword: passwordCurrentValue,
loginFormValid: !!(nameCurrentValue && passwordCurrentValue),
loginFailed: failed,
resources: state.resources.login as NestedStringMap
};
}
const loginActions: LoginActions = pick(
actions,
'loginUserNameChanged',
'loginUserPasswordChanged',
'resetLoginForm',
'authenticate'
);
const connectModule = connect<LoginProps, LoginActions>(
mapStateToProps,
loginActions
)(LoginMainView);
export default connectModule;
import * as React from 'react';
import { connect } from "react-redux";
import {
Container,
Button,
FormPanel,
FieldSet,
TextField,
PasswordField,
Toolbar,
Label,
Spacer
} from '@extjs/ext-react';
import actions from '../../actions';
import AppState from '../../types/state';
import { NestedStringMap } from '../../types/common';
import { pick } from '../../utils/utils';
interface LoginActions {
loginUserNameChanged: typeof actions.loginUserNameChanged;
loginUserPasswordChanged: typeof actions.loginUserPasswordChanged;
resetLoginForm: typeof actions.resetLoginForm;
authenticate: typeof actions.authenticate;
}
interface LoginProps {
loginUserName: string;
loginUserPassword: string;
loginFormValid: boolean;
loginFailed: boolean;
resources: NestedStringMap;
}
class LoginMainView extends React.Component<LoginActions & LoginProps, {}> {
onLoginUser = () => {
this.props.authenticate(this.props.loginUserName, this.props.loginUserPassword);
}
onResetLoginForm = () => {
this.props.resetLoginForm({});
}
render() {
return (
<Container
shadow
layout={{
type: 'vbox',
align: 'center',
pack: 'center'
}}
>
<FormPanel
shadow
width={600}
height={300}
align='center'
padding="20"
>
<FieldSet>
<Container layout="hbox">
<Spacer />
<Label
html={this.props.resources.loginTitle as string}
style={{
fontSize: "1.5em",
fontWeight: "bold"
}}
margin={5}
/>
<Spacer />
</Container>
<TextField
labelAlign="placeholder"
label={this.props.resources.userNameLabel as string}
value={this.props.loginUserName}
onChange={(me, loginUserName) => this.props.loginUserNameChanged({ loginUserName })}
/>
<PasswordField
labelAlign="placeholder"
label={this.props.resources.userPasswordLabel as string}
revealable
value={this.props.loginUserPassword}
onChange={(me, loginUserPassword) => this.props.loginUserPasswordChanged({ loginUserPassword })}
/>
<Container
layout="center"
padding={10}
hidden={!(this.props.loginFailed)}
style={{
color: 'red'
}}
>
{this.props.resources.failed}
</Container>
</FieldSet>
<Toolbar
docked="bottom"
layout={{
type: 'hbox',
pack: 'center'
}}
>
<Button
type="submit"
text={this.props.resources.loginUserAction as string}
margin="0 10 0 0"
disabled={!(this.props.loginFormValid)}
handler={() => this.onLoginUser()}
/>
<Button
text={this.props.resources.resetValuesAction as string}
handler={() => this.onResetLoginForm()}
/>
</Toolbar>
</FormPanel>
</Container>
);
}
}
function mapStateToProps(state: AppState): LoginProps {
const { nameCurrentValue, passwordCurrentValue, failed } = state.loginState;
return {
loginUserName: nameCurrentValue,
loginUserPassword: passwordCurrentValue,
loginFormValid: !!(nameCurrentValue && passwordCurrentValue),
loginFailed: failed,
resources: state.resources.login as NestedStringMap
};
}
const loginActions: LoginActions = pick(
actions,
'loginUserNameChanged',
'loginUserPasswordChanged',
'resetLoginForm',
'authenticate'
);
const connectModule = connect<LoginProps, LoginActions>(
mapStateToProps,
loginActions
)(LoginMainView);
export default connectModule;