NumberEditView.js 7.07 KB
import React, {Component} from 'react';
import {Text, TextInput, View,} from 'react-native';
// 金额大写处理
import {convertCurrency} from "../utils/utils";
// 默认高度
const defaultHeight = (70);
// 默认标题高度
const titleViewHeight = (24);
// 默认纵向内边距
const VPading = (6);
// 默认金额大写区域高度
const DescHeight = (30);

/*
数字输入框组件
该组件可匹配以下几种数据格式
    金额输入框(type:'MONEY')
    数字输入框(type:'NUMBER')
    省份证输入框(type:'IDCARD')
 */
export default class NumberEditView extends Component {
    // 构造方法
    constructor(props) {
        super(props);
        this.state = {
            value: '',// 输入值
        };
        // 传入参数
        this.attrData = this.props.attrData;
        // 支持的类型
        this.type = this.props.type;
        // 用于带出输入内容的callback回调
        this.onChangeText = this.props.onChangeText;
        // 键盘格式
        this.inputType = this.props.inputType || 'numeric';
        // json解析后的传入参数
        this.extendData = (this.attrData.data && this.attrData.data.length > 0) ? JSON.parse(this.attrData.data) : {};
    }

    // 生命周期-组件将要展示
    componentWillMount() {
        // 设置默认值
        if (this.attrData.value && this.attrData.value.length > 0) {
            this.setState({
                value: this.attrData.value
            })
        }
    }

    // 绘制UI
    render() {
        /*
        name:标题
        code:代码编号
        type:控件类型(    金额输入框(type:'MONEY')
                         数字输入框(type:'NUMBER')
                         省份证输入框(type:'IDCARD'))
        uom:金额单位
        description:描述
        isRequired:是否必须
        isPreview:是否预览
        */
        let {name, code, type, uom, description, isRequired, isPreview} = this.attrData;
        /*
        placeholder:输入提示文字
        showChinese:是否显示大写金额
        precision:精度
        */
        let {placeholder, showChinese, precision} = this.extendData;
        let displayUom = ''
        if (!!uom) {
            displayUom = '(' + uom + ')';
        }
        let calcHeight = defaultHeight;
        if (showChinese) {
            // 如果显示金额中文大写,需要给个额外用于大写区域的高度
            calcHeight += DescHeight
        }
        return (
            // 最外层的样式区域
            <View style={{
                // 宽度
                width: '100%',
                backgroundColor: 'white',
                paddingTop: VPading,
                paddingLeft: 10,
                paddingRight: 15,
                height: calcHeight
            }}>
                {/*标题显示区域*/}
                <View style={{
                    flexDirection: 'row',
                    height: titleViewHeight,
                    justifyContent: 'flex-start',
                    alignItems: 'center'
                }}>
                    {/*是否必须UI设定*/}
                    {isRequired && <Text style={{color: "#FF3030"}}>* </Text>}
                    {!isRequired && <Text style={{color: "#fff"}}>* </Text>}
                    {/*标题设定(如果有金额单位指定,一并显示)*/}
                    <Text style={{fontSize: 16, color: 'rgba(0, 0, 0, 1)'}}>{name || ""}{displayUom}</Text>
                </View>
                <View style={{flexDirection: 'row', alignItems: 'center'}}>
                    {/*输入框*/}
                    <TextInput
                        style={{
                            fontSize: 14,
                            color: 'black',
                            height: 30,
                            width: '100%',
                            marginLeft: 10,
                            backgroundColor: '#fff',
                            textAlign: 'left',
                            marginTop: 4,
                            marginBottom: 4,
                            padding: 0
                        }}
                        // 身份证输入18位限制
                        maxLength={type === 'IDCARD' ? 18 : (precision || 16)}
                        //是否多行
                        multiline={false}
                        keyboardType={this.inputType}
                        //输入框内容发生变化的触发回调
                        onChangeText={text => {
                            if (type === 'IDCARD') {
                                // 身份证直接赋值
                                this.attrData.value = text;
                                this.setState({
                                    value: text,
                                })
                                if (this.onChangeText) {
                                    this.onChangeText(text, this.attrData.code)
                                }
                            } else {
                                // 计算精度
                                this.calculatePrecision(text, precision, type);
                            }
                        }}
                        //显示的值
                        value={this.state.inputValue}
                        //默认值
                        defaultValue={this.state.value}
                        //提示文字颜色
                        placeholderTextColor={'#999'}
                        //提示文字
                        placeholder={placeholder || '请输入'}
                        //去除android输入框下面的横线,和ios保持一致
                        underlineColorAndroid="transparent"
                    />
                </View>
                {/*金额大写显示区域*/}
                {showChinese &&
                <View style={{
                    height: DescHeight,
                    paddingBottom: VPading,
                    flexDirection: 'row',
                    alignItems: 'center',
                    backgroundColor: '#fff',
                    marginLeft: 10,
                    marginRight: 15
                }}>
                    <Text style={{fontSize: 14, color: 'rgba(0, 0, 0, 1)'}}>大写</Text>
                    <Text style={{fontSize: 16, color: 'rgba(0, 0, 0, 1)', marginLeft: 6, marginRight: 4}}>
                        {!!this.state.inputValue ? convertCurrency(this.state.inputValue) : ''}</Text>
                </View>
                }
            </View>
        )
    }

    // 金额精度计算
    calculatePrecision(text, precision, type) {
        let newText = '';
        if (precision === undefined || precision === null || parseInt(precision) === 0) {
            // 取整数
            newText = text.replace(/[^\d]+/, '');
            this.setState({inputValue: newText})
        } else {
            // 取小数点
            this.setState({inputValue: text})
            newText = parseFloat(text).toFixed(parseInt(precision))
        }
        if (this.onChangeText) {
            this.onChangeText(newText, type)
        }
        this.attrData.value = newText;
    }
}