从TForm.getValue()

时间:2018-03-12 14:41:18

标签: javascript reactjs react-native tcomb-form-native

我有2个文本框

  • 电子邮件
  • 密码

我要禁用该按钮,直到用户输入有效的电子邮件和密码。因此,在onChange方法中,我从form.getValue()检索值,该值触发验证,如文档中所述。如果值为null,我会将按钮的已禁用状态更改为true其他false。我只想在输入失去焦点或提交而不是每次getValue()来电时显示错误。

只要触发onChange,表单就会在所有字段中显示错误,因为我调用了form.getValue()。我想仅在用户移动到下一个文本框时显示错误(焦点从当前文本框中丢失)或者用户点击提交。当用户刚刚开始在文本框中输入时,我不想用错误消息来纠缠他。

重现的步骤

  • 使用创建2个表单字段(带有优化的电子邮件和密码) 包含错误消息的选项
  • 检索onChange方法中的值
  • 您将开始看到错误消息。

代码

// @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

1 个答案:

答案 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