如何在react-native中避免这种行为?

时间:2017-02-17 11:31:33

标签: javascript reactjs react-native

我目前正在使用react-native中的掩码进行输入,但是我想避免输入非数字字符。我做了,但是我想避免以下行为:

enter image description here

'use strict';

import React, { Component, PropTypes } from 'react';
import { styles, cleanStyle, dirtyStyle } from './styles';

import { colors } from '../../config/styles';

import {
  Animated,
  Easing,
  Platform,
  StyleSheet,
  Text,
  TextInput,
  View,
  Keyboard,
} from 'react-native';

const textPropTypes = Text.propTypes || View.propTypes;
const textInputPropTypes = TextInput.propTypes || textPropTypes;
const propTypes = {
  ...textInputPropTypes,
  inputStyle: textInputPropTypes.style,
  labelStyle: textPropTypes.style,
  disabled: PropTypes.bool,
  style: View.propTypes.style,
};

const SMInput  = React.createClass({
  propTypes,

  getDefaultProps() {
    return {
      editable: true,
      onlyNumbers: false,
      underlineColorAndroid: 'transparent'
    };
  },

  getInitialState() {

    Keyboard.addListener('keyboardDidChangeFrame', () => {
      console.log('keyboardDidChangeFrame');
    });
    const state = {
      text: (this.props.value) ? this.props.value.toString() : '',
      dirty: !!this.props.value,
      borderColor: new Animated.Value(0),
      labelColor: new Animated.Value(0),
      maxLength: this.props.maxLength,
      placeHolder: '',
    };

    const style = state.dirty ? dirtyStyle : cleanStyle;
    state.labelStyle = {
      fontSize: new Animated.Value(style.fontSize),
      top: new Animated.Value(style.top),
      position: new Animated.Value(style.position),
    }

    return state;
  },

  _animate(dirty) {
    const animateTime = 150;
    const nextStyle = dirty ? dirtyStyle : cleanStyle;
    const labelStyle = this.state.labelStyle;
    const anims = Object.keys(nextStyle).map(prop => {
      return Animated.timing(
        labelStyle[prop],
        {
          toValue: nextStyle[prop],
          duration: animateTime,
        },
        Easing.ease
      )
    });

    setTimeout(() => {
      if (this.props.placeholder && dirty) {
        this.setState({
          placeHolder: this.props.placeholder
        });
      }
    }, 120);

    anims.push(
      Animated.timing (
        this.state.borderColor, {
          toValue: dirty ? 1 : 0,
          duration: animateTime,
        }
      )
    );

    anims.push(
      Animated.timing (
        this.state.labelColor, {
          toValue: dirty ? 1 : 0,
          duration: animateTime,
        }
      )
    );

    Animated.parallel(anims).start();
  },

  _onFocus() {
    this._animate(true);
    this.setState({ dirty: true });
    if (this.props.onFocus) {
      this.props.onFocus(arguments);
    }
  },

  _onBlur() {
    if (!this.state.text) {
      this._animate(false);
      this.setState({ dirty: false });
    }

    if (this.props.onBlur) {
      this.props.onBlur(arguments);
    }

    if (this.props.placeholder) {
      this.setState({
        placeHolder: ''
      });
    }
  },

  onChangeText(text) {
    this.setMask(text);
    if (this.props.onChangeText) {
      this.props.onChangeText(text);
    }
  },

  setMask(text) {

  //function mask(inputName, mask) {
      var mask = '00/00/0000';

      this.setState({
        maxLength: mask.length
      });

      var value = text;

      var literalPattern = /[0\*]/;
      var numberPattern = /[0-9]/;
      var newValue = '';

      for (var vId = 0, mId = 0 ; mId < mask.length ; ) {
        if (mId >= value.length) {
          break;
        }

        // Number expected but got a different value, store only the valid portion
        if (mask[mId] == '0' && value[vId].match(numberPattern) == null) {
          break;
        }

        // Found a literal
        while (mask[mId].match(literalPattern) == null) {
          if (value[vId] == mask[mId]) {
            break;
          }

        newValue += mask[mId++];
      }

      newValue += value[vId++];
      mId++;
    }
    this.setState({
      text: newValue
    })

  },

  updateText(event) {
    const text = event.nativeEvent.text;
    this.setState({ text })

    if (this.props.onEndEditing) {
      this.props.onEndEditing(event);
    }
  },

  _renderLabel() {
    const labelColor = this.state.labelColor.interpolate({
      inputRange: [ 0, 1 ],
      outputRange: [ colors.darkPurple50, colors.purple100 ]
    });

    return (
      <View style={ styles.wrapper }>
        <Animated.Text
          ref='label'
          style={ [this.state.labelStyle, styles.label, this.props.labelStyle, { color: labelColor } ] }
        >
          {this.props.children}
        </Animated.Text>
      </View>
    )
  },

  render() {

    const borderColor = this.state.borderColor.interpolate({
      inputRange: [ 0, 1 ],
      outputRange: [ colors.gray80, colors.purple100 ]
    });

    const props = {
      autoCapitalize: this.props.autoCapitalize,
      autoCorrect: this.props.autoCorrect,
      autoFocus: this.props.autoFocus,
      bufferDelay: this.props.bufferDelay,
      clearButtonMode: this.props.clearButtonMode,
      clearTextOnFocus: this.props.clearTextOnFocus,
      controlled: this.props.controlled,
      editable: this.props.editable,
      enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically,
      keyboardType: this.props.keyboardType,
      multiline: this.props.multiline,
      onBlur: this._onBlur,
      onChange: this.props.onChange,
      onChangeText: this.onChangeText,
      onEndEditing: this.updateText,
      onFocus: this._onFocus,
      onSubmitEditing: this.props.onSubmitEditing,
      password: this.props.password,
      returnKeyType: this.props.returnKeyType,
      selectTextOnFocus: this.props.selectTextOnFocus,
      selectionState: this.props.selectionState,
      style: [styles.input],
      maxLength: this.state.maxLength,
      underlineColorAndroid: this.props.underlineColorAndroid, // android TextInput will show the default bottom border
      onKeyPress: this.props.onKeyPress,
      spellCheck: this.props.spellCheck,
      mask: this.props.mask,
      placeholder: this.state.placeHolder,
      placeholderTextColor: colors.darkPurple50,
      value: this.state.text,
    };

    const elementStyles = [styles.element];

    if (this.props.inputStyle) {
      props.style.push(this.props.inputStyle);
    }

    if (this.props.style) {
      elementStyles.push(this.props.style);
    }

    if (!this.props.editable) {
      elementStyles.push(styles.elementNotEditable);
      props.style.push(styles.inputNotEditable);
    }

    return (
      <Animated.View style={ [elementStyles, { borderColor: borderColor }] }>
        { this._renderLabel() }
        <TextInput
          { ...props }
        >
        </TextInput>
      </Animated.View>
    );
  },
});

SMInput.propTypes = {
  disabled: PropTypes.bool,
  style: Text.propTypes.style,
};

export default SMInput;

0 个答案:

没有答案