【问题标题】:How to disable submit button if the required fields are empty in tcomb-form-native?如果 tcomb-form-native 中的必填字段为空,如何禁用提交按钮?
【发布时间】:2017-03-28 07:19:50
【问题描述】:

我正在使用 tcomb-form-native 并且能够在单击登录按钮时禁用错误消息。同样在单击登录按钮时,我将其路由到下一页,即主页。如果必填字段为空,我想禁用登录按钮并启用它并在两个字段都填满时重定向到主页。下面是我试过的代码。

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  Image,
  View,
  Button,
  StyleSheet,
  TextInput,
  Linking,
  Alert,
  Navigator
} from 'react-native';
import t from 'tcomb-form-native';

const Form = t.form.Form;

// here we are: define your domain model
const Email = t.subtype(t.Str, (email) => {
  const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return reg.test(email);
});

const LoginFields = t.struct({
  username: Email,  // a required string
  password: t.String, // a required string
});

const options = {
  fields: {
    password: {
      type: 'password',
      placeholder: 'Password',
      error: 'Password cannot be empty'
    },
    username: {
      placeholder: 'e.g: abc@gmail.com',
      error: 'Insert a valid email'
    }
  }
}; // optional rendering options (see documentation)


export default class Login extends Component {
  _onSubmit() {
    const value = this.refs.form.getValue();
     if (value) { // if validation fails, value will be null
       console.log(value);
        // value here is an instance of LoginFields
     }

     this.props.navigator.push({
       id: 'Home'
     });
  }
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.header}>
        </View>
        <View style={styles.content}>
          <Text style={styles.contentHeader}>
            Pateast Login
          </Text>
          <View style={styles.loginFormContent}>
            <Form
              ref="form"
              type={LoginFields}
              options={options}
            />
              <Text style={{color: 'blue', marginBottom: 10}}
                onPress={() => Linking.openURL('https://www.google.co.in')}>
                Forgot Password?
              </Text>
              <Button
                  onPress={this._onSubmit.bind(this)}
                  title="Login"
                  color="#008080"
                  accessibilityLabel="Ok, Great!"
                />
            </View>
        </View>
        <View style={styles.footer}>
        </View>
      </View>


    );
  }
}

const styles = StyleSheet.create(
  {
    container: {
      flex: 1
    },
    contentHeader: {
      fontFamily: 'sans-serif-condensed',
      fontWeight: 'bold',
      fontSize: 40,
      alignSelf: 'center',
      marginBottom: 30
    },
    header : {
      flex: 0.5,
      backgroundColor: '#008080'
    },
    content: {
      flex: 10,
      backgroundColor: '#f8f8ff',
      justifyContent: 'center'
    },
    loginFormContent: {
      marginHorizontal: 20
    },
    footer: {
      flex: 0.5,
      backgroundColor: '#008080'
    },
    loginText: {
      fontSize: 20,
      marginBottom: 10
    },
    inputFields: {
      fontSize: 20,
      borderStyle: 'solid',
      borderColor: '#000000',
      borderRadius: 30,
      marginBottom: 10
    }
  }
)

【问题讨论】:

  • 提交按钮是一个独立的组件,它与tcomb表单无关,使用Button的disabledprops来实现你的需要。

标签: react-native tcomb-form-native


【解决方案1】:

disabled 属性的初始状态应该是 true 试试这个

import React, { Component } from 'react';
import {
  AppRegistry,
  Text,
  Image,
  View,
  Button,
  StyleSheet,
  TextInput,
  Linking,
  Alert,
  Navigator
} from 'react-native';
import t from 'tcomb-form-native';

const Form = t.form.Form;

// here we are: define your domain model
const Email = t.subtype(t.Str, (email) => {
  const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return reg.test(email);
});

const LoginFields = t.struct({
  username: Email,  // a required string
  password: t.String, // a required string
});

const options = {
  fields: {
    password: {
      type: 'password',
      placeholder: 'Password',
      error: 'Password cannot be empty'
    },
    username: {
      placeholder: 'e.g: abc@gmail.com',
      error: 'Insert a valid email'
    }
  }
}; // optional rendering options (see documentation)


export default class Login extends Component {
  constructor(props) {
    super(props);
    this.state = {
      buttonState: true,
      value: {}
    }
  }

  _onSubmit() {
    const value = this.refs.form.getValue();
     if (value) { // if validation fails, value will be null
       console.log(value);
        // value here is an instance of LoginFields
     }

     this.props.navigator.push({
       id: 'Home'
     });
  }

  onChange = () => {
    const value = this.refs.form.getValue();
    if(value) {
      this.setState({
        value,
        buttonState: false
      });
    }
  }
  render() {
    return (
      <View style={styles.container}>
        <View style={styles.header}>
        </View>
        <View style={styles.content}>
          <Text style={styles.contentHeader}>
            Pateast Login
          </Text>
          <View style={styles.loginFormContent}>
            <Form
              ref="form"
              type={LoginFields}
              options={options}
              value={this.state.value}
              onChange={this.onChange}
            />
              <Text style={{color: 'blue', marginBottom: 10}}
                onPress={() => Linking.openURL('https://www.google.co.in')}>
                Forgot Password?
              </Text>
              <Button
                  onPress={this._onSubmit.bind(this)}
                  title="Login"
                  color="#008080"
                  disabled={this.state.buttonState}
                  accessibilityLabel="Ok, Great!"
                />
            </View>
        </View>
        <View style={styles.footer}>
        </View>
      </View>


    );
  }
}

const styles = StyleSheet.create(
  {
    container: {
      flex: 1
    },
    contentHeader: {
      // fontFamily: 'sans-serif-condensed',
      fontWeight: 'bold',
      fontSize: 40,
      alignSelf: 'center',
      marginBottom: 30
    },
    header : {
      flex: 0.5,
      backgroundColor: '#008080'
    },
    content: {
      flex: 10,
      backgroundColor: '#f8f8ff',
      justifyContent: 'center'
    },
    loginFormContent: {
      marginHorizontal: 20
    },
    footer: {
      flex: 0.5,
      backgroundColor: '#008080'
    },
    loginText: {
      fontSize: 20,
      marginBottom: 10
    },
    inputFields: {
      fontSize: 20,
      borderStyle: 'solid',
      borderColor: '#000000',
      borderRadius: 30,
      marginBottom: 10
    }
  }
)

【讨论】:

    【解决方案2】:

    你可以这样做

    import React, { Component } from 'react';
    import {
      AppRegistry,
      Text,
      Image,
      View,
      Button,
      StyleSheet,
      TextInput,
      Linking,
      Alert,
      Navigator
    } from 'react-native';
    import t from 'tcomb-form-native';
    
    const Form = t.form.Form;
    
    // here we are: define your domain model
    const Email = t.subtype(t.Str, (email) => {
      const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
      return reg.test(email);
    });
    
    const LoginFields = t.struct({
      username: Email,  // a required string
      password: t.String, // a required string
    });
    
    const options = {
      fields: {
        password: {
          type: 'password',
          placeholder: 'Password',
          error: 'Password cannot be empty'
        },
        username: {
          placeholder: 'e.g: abc@gmail.com',
          error: 'Insert a valid email'
        }
      }
    }; // optional rendering options (see documentation)
    
    
    export default class Login extends Component {
      constructor(props){
       super(props);
       this.state = {
         enabledButton: false,
         formValue: {
           email: '',
           password: '', // you need to check this well and update it when value changes
         },
       };
      }
    
       onChange(obj) {
        const value = this.refs.form.getValue();
        if (value) {
         this.setState({
          enabledButton: true,
         });
        } else {
         this.setState({
          enabledButton: false,
        });
       }
      }
      _onSubmit() {
        const value = this.refs.form.getValue();
         if (value) { // if validation fails, value will be null
           console.log(value);
            // value here is an instance of LoginFields
         }
    
         this.props.navigator.push({
           id: 'Home'
         });
      }
      render() {
        return (
          <View style={styles.container}>
            <View style={styles.header}>
            </View>
            <View style={styles.content}>
              <Text style={styles.contentHeader}>
                Pateast Login
              </Text>
              <View style={styles.loginFormContent}>
                <Form
                  ref="form"
                  type={LoginFields}
                  options={options}
                  onChange={this.onChange.bind(this)}
                  value={this.state.formValue}
                />
                  <Text style={{color: 'blue', marginBottom: 10}}
                    onPress={() => Linking.openURL('https://www.google.co.in')}>
                    Forgot Password?
                  </Text>
                  <Button
                      onPress={this._onSubmit.bind(this)}
                      title="Login"
                      color="#008080"
                      accessibilityLabel="Ok, Great!"
                      disabled={this.state.enabledButton}
                    />
                </View>
            </View>
            <View style={styles.footer}>
            </View>
          </View>
    
    
        );
      }
    }
    
    const styles = StyleSheet.create(
      {
        container: {
          flex: 1
        },
        contentHeader: {
          fontFamily: 'sans-serif-condensed',
          fontWeight: 'bold',
          fontSize: 40,
          alignSelf: 'center',
          marginBottom: 30
        },
        header : {
          flex: 0.5,
          backgroundColor: '#008080'
        },
        content: {
          flex: 10,
          backgroundColor: '#f8f8ff',
          justifyContent: 'center'
        },
        loginFormContent: {
          marginHorizontal: 20
        },
        footer: {
          flex: 0.5,
          backgroundColor: '#008080'
        },
        loginText: {
          fontSize: 20,
          marginBottom: 10
        },
        inputFields: {
          fontSize: 20,
          borderStyle: 'solid',
          borderColor: '#000000',
          borderRadius: 30,
          marginBottom: 10
        }
      }
    )
    

    【讨论】:

    • 我在第 51 行(onChange 函数)附近遇到了意外的令牌错误。请让我知道我在哪里做错了。
    • 它不允许我写任何东西并且按钮仍然处于启用状态。 :(
    • 因为您需要为 form 设置值,请检查我更新的答案,但这不是您需要更新更改值的完整解决方案
    猜你喜欢
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多