我有2个文本框
我要禁用该按钮,直到用户输入有效的电子邮件和密码。因此,在onChange方法中,我从form.getValue()
检索值,该值触发验证,如文档中所述。如果值为null
,我会将按钮的已禁用状态更改为true
其他false
。我只想在输入失去焦点或提交而不是每次getValue()
来电时显示错误。
只要触发onChange
,表单就会在所有字段中显示错误,因为我调用了form.getValue()
。我想仅在用户移动到下一个文本框时显示错误(焦点从当前文本框中丢失)或者用户点击提交。当用户刚刚开始在文本框中输入时,我不想用错误消息来纠缠他。
重现的步骤
代码
// @flow
import React, { PureComponent } from 'react';
import { View, Text, Platform, TouchableHighlight } from 'react-native';
import t from 'tcomb-form-native';
import { resetTo } from 'src/lib/navigation';
import { SIGNED_IN } from 'src/routes/constants';
import { getErrorMessage } from 'src/lib/auth-helpers';
import { FullScreenBGImage } from 'src/components';
import { text, background } from 'src/styles/';
import LoginBG from '../../../assets/images/login-bg.jpg';
import styles from './style';
type Props = {
loggedIn: boolean,
navigation: Object,
login: (string, string) => void,
user: Object,
};
type States = {
isDisabled: boolean,
value: ?Object,
};
const Email = t.refinement(t.String, email => {
const reg = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/;
return reg.test(email);
});
const { Form } = t.form;
// here we define our domain model
const LoginForm = t.struct({
email: Email,
password: t.String,
});
const textboxStyle = {
color: text.color2,
backgroundColor: background.color1,
fontSize: 17,
height: 50,
paddingVertical: Platform.OS === 'ios' ? 7 : 0,
paddingHorizontal: 16,
borderWidth: 1,
marginBottom: 5,
};
const formStylesheet = {
...Form.stylesheet,
textbox: {
normal: {
...textboxStyle,
},
error: {
...textboxStyle,
},
},
errorBlock: {
color: text.error,
},
};
const formOptions = {
auto: 'placeholders',
fields: {
email: { error: 'Enter valid email' },
password: {
error: 'Enter valid password'
password: true,
secureTextEntry: true,
},
},
stylesheet: formStylesheet,
};
class Login extends PureComponent<Props, States> {
loginForm: ?Object;
onFormChange: () => void;
static navigationOptions = {
header: null,
};
constructor(props: Props) {
super(props);
this.loginForm = {};
this.state = {
value: null,
isDisabled: true,
};
this.handleSubmit = this.handleSubmit.bind(this);
this.onFormChange = this.onFormChange.bind(this);
}
/**
* ComponentWillReceiveProps.
*
* Redirect if user is logged in
*/
componentWillReceiveProps(nextProps: Props) {
if (nextProps.loggedIn !== this.props.loggedIn && nextProps.loggedIn) {
resetTo(SIGNED_IN, nextProps.navigation);
}
}
handleSubmit = () => {
// use that ref to get the form value
const value = this.loginForm ? this.loginForm.getValue() : null;
if (value) {
this.props.login(value.email, value.password);
}
}
onFormChange() {
const value = this.loginForm ? this.loginForm.getValue() : null;
if (value) {
this.setState({
value,
isDisabled: false,
});
}
}
render() {
const errorMessage = getErrorMessage(this.props.user);
const error = errorMessage
? <View><Text style={styles.errorMessage}>{errorMessage}</Text></View>
: null;
return (
<View style={styles.container}>
<FullScreenBGImage imageSrc={LoginBG} styles={styles.bgImage}>
<View style={styles.logo}>
<Text style={styles.logoLabel}>VERUS</Text>
</View>
<View style={styles.loginForm}>
{error}
<Form
ref={c => { this.loginForm = c; }}
type={LoginForm}
value={this.state.value}
onChange={this.onFormChange}
options={formOptions} // pass the options via props
/>
<TouchableHighlight
style={styles.button}
onPress={this.handleSubmit}
underlayColor="#99d9f4"
disabled={this.state.isDisabled}
>
<Text style={styles.buttonText}>Sign In</Text>
</TouchableHighlight>
</View>
</FullScreenBGImage>
</View>
);
}
}
export default Login;
版本
tcomb-form-native v0.6.11
答案 0 :(得分:0)
嘿通过该方法将始终首先验证表单,因此您只需更改onChange的方法并使用this.refs.loginForm.refs.input.refs.email.state.value
之类的内容获取所需的电子邮件字段的值,其中email是您的字段的名称和loginForm表单的引用名称。然后,您可以使用自己的正则表达式测试值以更改按钮的状态;)
一些给我这个想法的文档: 这里:https://github.com/gcanti/tcomb-form/issues/370
和https://github.com/gcanti/tcomb-form/blob/master/GUIDE.md#accessing-fields