CheckboxView.js 12.2 KB
import React, {Component} from 'react';
import {Image, Modal, ScrollView, StyleSheet, Text, TouchableOpacity, View,} from 'react-native';
import {isJSONString} from "../utils/utils";
// 选中的图标
const checkedImg = require("../img/selectActive.png");
// 未选中的图标
const unCheckedImg = require("../img/select.png");
// 默认高度
const defaultHeight = (70);
// 默认标题高度
const titleViewHeight = (24);
// 默认纵向内边距
const VPading = (6);

/*
单选/多选框组件(type:'SELECT'/'CHECKBOX')
 */
export default class CheckboxView extends Component {
    // 构造方法
    constructor(props) {
        super(props);
        this.state = {
            // 选择的值
            checkedValue: '',
            // 是否以模态展示
            showModal: false,
            options: [],
            // 选项
            checkedData: {},
            //checkedDataList: []
        };
        // 传入参数
        this.attrData = this.props.attrData;
        // json解析后的传入参数
        this.extendData = (this.attrData.data && this.attrData.data.length > 0) ? JSON.parse(this.attrData.data) : {};
        // 用于带出选择值的callback回调
        this.callback = this.props.callback;
    }

    // 生命周期-组件将要展示
    componentWillMount() {
        let checkedText = "";
        // 设置默认值
        if (this.attrData.value && this.attrData.value.length > 0) {
            if (isJSONString(this.attrData.value)) {
                // 多选
                let checkedValues = JSON.parse(this.attrData.value);
                let checkedCount = 0;
                checkedValues.map(item => {
                    if (checkedCount === 0) {
                        checkedText = item.value;
                        //resultText = item.value;
                    } else {
                        checkedText = checkedText + "\n" + item.value;
                        //resultText = checkedText + "," + item.value;
                    }
                    checkedCount++;
                });
            } else {
                // 单选
                checkedText = this.attrData.value;
            }
        }
        this.setState({
            checkedValue: checkedText,
            options: this.extendData.options
        }, () => this.confirmChecked());
    }

    // 触发显示模态样式的选择框
    showCheckboxModal() {
        this.setState({
            showModal: true,
        });
    }

    /**
     * 模态框取消操作
     */
    closeModal() {
        this.setState({
            showModal: false,
        });
    }

    /**
     * 确定选择
     */
    confirmChecked() {
        this.closeModal();

        let checkedText = "";
        if (this.state.options && this.state.options.length > 0) {
            let resultArray = [];
            let checkedCount = 0;
            this.state.options.map((item, index) => {
                if (item.checked) {
                    if (checkedCount === 0) {
                        checkedText = item.value;
                        //resultText = item.value;
                    } else {
                        // 多选的情况,用"\n"拼接
                        checkedText = checkedText + "\n" + item.value;
                        //resultText = checkedText + "," + item.value;
                    }
                    resultArray.push(item.value);
                    checkedCount++;
                }
            });
            this.attrData.value = JSON.stringify(resultArray);
        } else {
            this.attrData.value = "";
        }
        this.setState({
            checkedValue: checkedText
        })
        if (this.callback) {
            this.callback(this.attrData.value);
        }
    }

    // 绘制UI
    render() {
        /*
        name:标题
        code:代码编号
        type:控件类型(SELECT/CHECKBOX)
        description:描述
        isRequired:是否必须
        isPreview:是否预览
        */
        let {name, code, type, description, isRequired, isPreview} = this.attrData;
        // 提示文字
        let {placeholder} = this.extendData;

        return (
            // 最外层的样式区域
            <View style={{
                width: '100%',
                minHeight: defaultHeight,
                paddingTop: VPading,
                paddingLeft: 10,
                paddingRight: 15,
                backgroundColor: '#fff'
            }}>
                {/*用于触发显示模态样式的选择框*/}
                <TouchableOpacity
                    style={{
                        flexDirection: 'row',
                        width: '100%',
                        backgroundColor: '#fff',
                        alignItems: 'center'
                    }}
                    activeOpacity={0.8}
                    onPress={() => this.showCheckboxModal()}
                >
                    <View style={{flex: 1}}>
                        {/*标题显示区域*/}
                        <View style={{
                            flexDirection: 'row',
                            height: titleViewHeight,
                            backgroundColor: '#fff',
                            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 || ""}</Text>
                        </View>
                        <View style={{
                            width: "100%",
                            minHeight: 30,
                            marginLeft: 10,
                            marginTop: 4,
                            marginBottom: 4,
                            justifyContent: 'center',
                            backgroundColor: 'white'
                        }}>
                            <Text
                                style={{
                                    fontSize: 14,
                                    color: (!!this.state.checkedValue && this.state.checkedValue.length > 0) ? 'black' : '#999',
                                    textAlign: 'left',
                                }}>{this.state.checkedValue || placeholder || '请选择'}
                            </Text>
                        </View>
                    </View>
                    <Image style={{width: 16, height: 16}} source={require('../img/bread.png')} resizeMode={'contain'}/>
                </TouchableOpacity>
                {/*模态样式选择框定义*/}
                <Modal animationType={"fade"} transparent={true} visible={this.state.showModal}
                       onRequestClose={() => this.closeModal()}>
                    {/** 目录弹窗 */}
                    <View style={{flex: 1}}>
                        <TouchableOpacity style={styles.modalBg} activeOpacity={1} onPress={() => this.closeModal()}/>
                        {/** 实体内容 */}
                        <View style={styles.contentBg}>
                            {/** 标题栏 */}
                            <View style={styles.titleBar}>
                                <TouchableOpacity
                                    style={{paddingLeft: 15, paddingRight: 5}}
                                    activeOpacity={0.8}
                                    onPress={() => this.closeModal()}
                                >
                                    <Image style={{width: 14, height: 14}}
                                           source={require('../img/loadBack.png')}/>
                                </TouchableOpacity>
                                <Text style={styles.modelTitle}>{name + "选择"}</Text>
                                {type !== 'SELECT' &&
                                <TouchableOpacity
                                    style={{
                                        justifyContent: "center",
                                        alignItems: "center",
                                        borderRadius: 20,
                                        paddingVertical: 3,
                                        paddingHorizontal: 8,
                                        backgroundColor: global.homeColor
                                    }}
                                    activeOpacity={0.8}
                                    onPress={() => this.confirmChecked()}
                                >
                                    <Text style={{fontSize: 14, color: 'white'}}>确定</Text>
                                </TouchableOpacity>
                                }
                            </View>
                            <View style={{width: '100%', height: 1, backgroundColor: 'rgba(245,245,245,1)'}}/>
                            {/** 内容 */}
                            <ScrollView style={{flex: 1}} horizontal={false} showsVerticalScrollIndicator={false}>
                                {this.state.options && this.state.options.map((value, index) => this.renderCheckboxItem(value, index))}
                            </ScrollView>
                        </View>
                    </View>
                </Modal>
            </View>
        )
    }

    // 选择条目UI绘制
    renderCheckboxItem(item, index) {
        return (
            <TouchableOpacity
                key={index}
                style={{flexDirection: 'row', flex: 1, alignItems: 'center'}}
                activeOpacity={0.8}
                onPress={() => {
                    if (this.attrData.type === 'CHECKBOX') {
                        // 多选
                        //let tempArr = this.state.checkedDataList;
                        if (item.checked) {
                            item.checked = false;
                            //tempArr = tempArr.filter(data => data.value !== item.value);
                        } else {
                            item.checked = true;
                            //tempArr.push(item);
                        }
                        // 刷新列表
                        this.setState({})
                    } else if (this.attrData.type === 'SELECT') {
                        this.closeModal();
                        this.state.options.map((t, k) => {
                            t.checked = k === index;
                        });
                        this.setState({
                            checkedData: item,
                            checkedValue: item.value
                        });
                        this.attrData.value = item.value;
                        if (this.callback) {
                            this.callback(this.attrData.value);
                        }
                    }
                }}
            >
                <Image
                    source={item.checked ? checkedImg : unCheckedImg}
                    style={styles.checkedBox}
                />
                <View style={{flex: 1}}>
                    <Text style={{fontSize: 16, color: 'rgba(0, 0, 0 , 1)', paddingVertical: 10}}>{item.value}</Text>
                    <View style={{width: '100%', height: 1, backgroundColor: 'rgba(245,245,245,1)'}}/>
                </View>
            </TouchableOpacity>
        )
    }
}

const styles = StyleSheet.create({
    modalBg: {
        backgroundColor: 'rgba(0,0,0,.5)',
        width: '100%',
        height: '100%',
        display: 'flex',
        position: 'absolute'
    },
    contentBg: {
        width: '100%',
        height: 300,
        backgroundColor: "rgba(255, 255, 255, 1)",
        position: 'absolute',
        bottom: 0,
        borderTopLeftRadius: 8,
        borderTopRightRadius: 8
    },
    titleBar: {
        flexDirection: "row",
        justifyContent: "flex-start",
        alignItems: "center",
        marginTop: 15,
        marginBottom: 10,
        marginRight: 15
    },
    modelTitle: {
        flex: 1,
        color: "rgba(0, 0, 0, 1)",
        fontSize: 16,
        textAlign: "center",
        justifyContent: "center"
    },
    checkedBox: {
        width: 20,
        height: 20,
        marginLeft: 8,
        marginRight: 8
    },
});