SelectForm.js 7.02 KB
Newer Older
1
import React, { useState, useEffect } from 'react';
2
import { StyleSheet, TouchableOpacity, TouchableWithoutFeedback, View, Text, Modal, FlatList } from 'react-native';
3
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
4

5
const INIT_SUBCATEGORY = {
6
    id: 1,
7
8
9
    value: '',
    foreign_id: 0,
}
10

11
12
13
14
15
16
17
18
19
const SelectForm = ({
    inputTitle,
    placeholder,
    data,
    selectedData,
    onValueChange,
    subData,
    selectedSubData,
    onSubValueChange,
20
    onUpdateDataPress,
21
22
}) => {
    const [option, setOption] = useState([])
23
24
    const [subOption, setSubOption] = useState([])

25
    const [selectedOption, setSelectedOption] = useState({})
26
27
28
29
30
31

    const [subOptionShow, setSubOptionShow] = useState(false)
    const [modalOpen, setModalOpen] = useState(false)

    const onPressSelectBox = () => { setModalOpen(true) }

32
    const modalClose = () => { setModalOpen(false); }
33
34

    const onPressOption = (item) => {
35
36
37
        if (item.id === 0) {
            return null
        }
38
39
        if (subOption !== undefined) {
            if (subOptionShow) {
40
41
                onValueChange(selectedOption)
                onSubValueChange(item)
42
43
                modalClose()
            } else {
44
                setSelectedOption(item)
45
46
47
                setSubOptionByOptionId(item)
            }
        } else {
48
            onValueChange(item)
49
50
51
52
53
            modalClose()
        }
    }

    const setSubOptionByOptionId = (item) => {
54
        const newOption = subData.filter((subItem) => {
55
56
57
58
            if (subItem.foreign_id === item.id)
                return true;
        })
        if (newOption.length === 0) {
59
60
61
            onValueChange(item)
            onSubValueChange(INIT_SUBCATEGORY)
            modalClose()
62
        } else {
63
            newOption.unshift({id: 1, value: '기타'})
Choi Ga Young's avatar
Choi Ga Young committed
64
            if (newOption.length % 3 == 0) { //여기 ===해야하지않나?
65
66
67
68
69
70
71
72
73
                setSubOption(newOption)
                setSubOptionShow(true)
            } else {
                for (let i = 0; i < (newOption.length % 3); i++) {
                    newOption.push(INIT_SUBCATEGORY)
                }
                setSubOption(newOption)
                setSubOptionShow(true)
            }
74
75
        }
    }
76
    
77
78
79
80
81
82
83
84
85
    const renderOptionItem = ({ item }) => (
        <TouchableOpacity onPress={() => onPressOption(item)} style={style.option}>
            <Text style={style.optionText} >
                {item.value}
            </Text>
        </TouchableOpacity>
    );

    useEffect(() => {
86
87
        setOption(data)
        setSubOption(subData)
88
89
90
        setSubOptionShow(false)
    }, [modalOpen])

91
    return (
92
93
94
        <View>
            <View style={style.container}>
                <View style={style.inputTitleArea}>
95
                    <Text style={style.inputTitle}>{inputTitle}</Text>
96
97
98
99
                </View>
                <View style={style.selectBox}>
                    <TouchableWithoutFeedback onPress={onPressSelectBox}>
                        <Text style={style.textStyle}>
100
101
                            {selectedData.value ?
                                selectedSubData?.value ?
Soo Hyun Kim's avatar
Soo Hyun Kim committed
102
                                    selectedData.value + ' > ' + selectedSubData.value
103
104
                                    : selectedData.value
                                : placeholder}
105
106
107
                        </Text>
                    </TouchableWithoutFeedback>
                </View>
108
            </View>
109
110
111
112
113
114
115

            <Modal
                transparent
                swipeDirection="down"
                animationType="slide"
                visible={modalOpen}
                onRequestClose={modalClose}
116
            >
117
118
                <View style={style.selectModalContainer}>
                    <TouchableWithoutFeedback onPress={modalClose}>
119
                        <View style={{ flex: 1 }} />
120
121
122
123
124
125
                    </TouchableWithoutFeedback>
                    <View style={style.selectModal}>
                        <View style={style.modalHeader}>
                            {subOptionShow ?
                                <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }} >
                                    <MaterialCommunityIcons name='arrow-left' size={35} color='white' onPress={() => { setSubOptionShow(false); }} />
126
                                    <Text style={style.modalHeaderText}>{selectedOption.value}</Text>
127
128
                                </View>
                                :
129
                                <Text style={style.modalHeaderText}>{inputTitle}</Text>}
130
                            <View style={{ flexDirection: "row" }}>
131
                                <MaterialCommunityIcons name='playlist-edit' size={35} color='white' onPress={() => { modalClose(); setTimeout(() => { onUpdateDataPress() }, 500) }} />
132
133
134
                                <MaterialCommunityIcons name='close' size={35} color='white' onPress={modalClose} />
                            </View>
                        </View>
135
                        <View style={[style.modalBody]}>
136
137
138
139
140
141
142
143
144
145
                            <FlatList
                                data={subOptionShow ? subOption : option}
                                renderItem={renderOptionItem}
                                numColumns={3}
                                keyExtractor={item => item.id.toString()}
                            />
                        </View>
                    </View>
                </View>
            </Modal>
146
147
148
149
        </View>
    );
};

150
const style = StyleSheet.create({
151
    container: {
152
        height: 50,
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
        flexDirection: 'row',
        alignItems: "center",
        marginHorizontal: 10,
        marginVertical: 3,
        borderWidth: 1.5,
        borderStyle: "solid",
        borderColor: "#1467ff",
        borderRadius: 5,
        backgroundColor: "#f5f5f5",
    },
    inputTitleArea: {
        flex: 1,
    },
    inputTitle: {
        alignSelf: "center",
        color: "#1467ff",
        fontSize: 20,
Soo Hyun Kim's avatar
Soo Hyun Kim committed
170
        fontFamily: 'GowunDodum-Regular',
171
172
173
174
175
    },
    selectStyle: {
        flex: 3,
        fontSize: 20,
    },
176
177
178
179
180
    selectBox: {
        flex: 3,
    },
    textStyle: {
        fontSize: 20,
Soo Hyun Kim's avatar
Soo Hyun Kim committed
181
        fontFamily: 'GowunDodum-Regular',
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    },
    selectModalContainer: {
        flex: 1,
        justifyContent: 'flex-end',
    },
    selectModal: {
        flex: 1,
    },
    modalHeader: {
        flex: 1,
        backgroundColor: '#4f4f4f',
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'space-between',
    },
    modalHeaderText: {
        color: 'white',
Soo Hyun Kim's avatar
Soo Hyun Kim committed
199
        fontFamily: 'GowunDodum-Regular',
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
        marginLeft: 25,
        fontSize: 20,
    },
    modalBody: {
        flex: 5,
        flexDirection: 'row',
        backgroundColor: '#f0f0f0',
    },
    option: {
        flex: 1,
        height: 50,
        borderWidth: 0.8,
        borderStyle: 'solid',
        borderColor: '#575757',
        backgroundColor: '#adadad',
        justifyContent: 'center',
        alignItems: 'center',
    },
    optionText: {
Soo Hyun Kim's avatar
Soo Hyun Kim committed
219
        fontFamily: 'GowunDodum-Regular',
220
221
        fontSize: 20,
    }
222
223
224
})

export default SelectForm