Closed cybercoder closed 4 years ago
Hello @cybercoder -
The <ProgressStep />
component should be the parent that wraps the content you wan't displayed inside of each step. In this case, try placing the Formik component inside of the desired <ProgressStep />
tag.
Hello @cybercoder -
The
<ProgressStep />
component should be the parent that wraps the content you wan't displayed inside of each step. In this case, try placing the Formik component inside of the desired<ProgressStep />
tag.
If Formik
being the child, then we need context api to handle enable/disable Next/Prev buttons. So i made some patches in your component and it's working for me.
@cybercoder Ok awesome! That's great to hear. Feel free to open a PR with any changes if you think they'd benefit other users of the library.
@cybercoder How can i do this validation?
@cybercoder How can i do this validation?
just pass all props to lower component. i can't understand what you mean of validation
.
@cybercoder Ok awesome! That's great to hear. Feel free to open a PR with any changes if you think they'd benefit other users of the library.
I did made the patch in previous version, I have no idea how i can make a PR with the patch in the new version. So i send you the patch file.
Here is how i did handle formik:
This is the Wizard component:
<View style={{flex: 1, marginHorizontal: 10}}>
{/* <TouchableOpacity onPress={() => SampleInit().then(setData({...data}))}>
<Text>Init Sample</Text>
</TouchableOpacity> */}
<ProgressSteps
stepNumStyle={styles.stepNumStyle}
progressBarColor="#009688"
activeStepIconBorderColor="#009688"
activeLabelColor="#009688"
disabledStepIconColor="gray"
labelColor="gray"
completedStepIconColor="#009688"
completedProgressBarColor="#009688"
labelFontFamily={
Platform.OS === 'android'
? 'iran_sans_mobile_fa_num'
: 'IRANSansMobileFaNum'
}>
<Step1 data={data} label="step1" />
<Step2 data={data} label="step2" />
<Step3 data={data} label="step3" />
<Step4 data={data} label="step4" navigation={navigation} />
</ProgressSteps>
</View>
And a example step using formik
, yup
and redux
is like this:
import React, {useState} from 'react';
import {View} from 'react-native';
import {Input} from '../../../../../../components';
import {useSelector, useDispatch} from 'react-redux';
import {updateCargo} from '../../../../../../redux/actions';
import {ProgressStep} from 'react-native-progress-steps';
import {Formik} from 'formik';
import * as Yup from 'yup';
import Modal from 'react-native-modal';
import SelectType from './selectType';
import SelectTonne from './selectTonne';
import SelectPackaging from './selectPackaging';
import SelectLoadingType from './selectLoadingType';
import styles from '../../../../../../styles';
const validationSchema = Yup.object().shape({
type: Yup.object().typeError('نوعمحمولهراتعیینفرمایید.'),
quantity: Yup.number()
.required('لطفا وزن نسبی محموله را وارد فرمایید.')
.positive('وزن منفی؟')
.typeError('عددواردفرمایید!'),
packaging: Yup.object().typeError('نوعبستهبندیراتعیینفرمایید.'),
load: Yup.object().typeError('حالتبارگیریراتعیینفرمایید.'),
value: Yup.number()
.transform((o, v) => v && parseFloat(v.replace(/,/g, '')))
.required('لطفا ارزش نسبی محموله را وارد فرمایید.')
.positive('ارزش منفی؟')
.typeError('عددواردفرمایید!'),
});
const tonneList = [...Array(25).keys()];
export default (props) => {
const dispatch = useDispatch();
let {cargo} = useSelector((state) => state.order);
let {loadTypes, packagingTypes, cargoTypes} = props.data;
let [typeModalIsVisible, showTypeModal] = useState(false);
let [isTonneModalVisible, showTonneModal] = useState(false);
let [packagingModalIsVisible, showPackagingModal] = useState(false);
let [loadingTypeModalIsVisible, showLoadingTypeModal] = useState(false);
let [workerCount, setWorkerCount] = useState(0);
let initialData = cargo
? {...cargo}
: {
type: null,
load: null, //loadTypes.find((l) => l.title === 'عادی'),
quantity: null,
packaging: null,
value: null,
};
return (
<Formik
initialValues={initialData}
validationSchema={validationSchema}
validateOnMount={validationSchema.isValidSync(initialData)}
onSubmit={(values) => {
if (JSON.stringify(values) !== JSON.stringify(cargo)) {
dispatch(updateCargo(values));
}
}}>
{({handleChange, values, handleSubmit, errors}) => (
<ProgressStep
{...props}
label="مشخصات محموله"
nextBtnText="ادامه"
onNext={handleSubmit}
nextBtnDisabled={!validationSchema.isValidSync(values)}
nextBtnStyle={styles.nextBtnStyle}
nextBtnTextStyle={styles.nextBtnTextStyle}>
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingBottom: 10,
}}>
<Input
name="type"
image="truck"
placeholder="نوع محموله شما چیست؟"
editable={false}
value={values.type?.title}
onPress={() => showTypeModal(true)}
// error={errors.type}
/>
<Input
image="truck"
placeholder="وزن محموله شما چقدر است؟"
editable={false}
name="quantity"
value={
values.quantity ? values.quantity.toString() + ' تن' : null
}
onPress={() => showTonneModal(true)}
// error={errors.quantity}
/>
<Input
image="truck"
placeholder="نوع بسته بندی محموله شما چیست؟"
editable={false}
value={values.packaging?.title}
onPress={() => showPackagingModal(true)}
/>
<Input
image="truck"
name="value"
maxLength={13}
onChangeText={handleChange('value')}
keyboardType="number-pad"
value={
values.value
? values.value
.replace(/,/g, '')
.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
: null
}
placeholder="ارزش محموله شما چند تومان است؟"
editable={true}
onPress={() => {}}
// error={errors.value}
/>
<Input
image="truck"
placeholder="حالت بارگیری محموله چیست؟"
editable={false}
value={values?.load?.title}
onPress={() => showLoadingTypeModal(true)}
/>
</View>
<Modal
isVisible={typeModalIsVisible}
style={styles.fullScreenModal}
animationOutTiming={300}
backdropTransitionOutTiming={0}
useNativeDriver={true}
backdropOpacity={0.3}
onBackButtonPress={() => showTypeModal(false)}
onBackdropPress={() => showTypeModal(false)}>
<SelectType
data={cargoTypes.docs}
onSave={(typeData) => {
values.type = typeData;
showTypeModal(false);
}}
/>
</Modal>
<Modal
isVisible={isTonneModalVisible}
style={styles.fullScreenModal}
animationOutTiming={300}
backdropTransitionOutTiming={0}
useNativeDriver={true}
backdropOpacity={0.3}
onBackButtonPress={() => showTonneModal(false)}
onBackdropPress={() => showTonneModal(false)}
onSwipeComplete={() => showTonneModal(false)}
swipeDirection={['up', 'left', 'right', 'down']}>
<SelectTonne
data={tonneList}
onSave={(quantity) => {
values.quantity = quantity;
showTonneModal(false);
}}
/>
</Modal>
<Modal
isVisible={packagingModalIsVisible}
style={styles.fullScreenModal}
animationOutTiming={300}
backdropTransitionOutTiming={0}
useNativeDriver={true}
backdropOpacity={0.3}
onBackButtonPress={() => showPackagingModal(false)}
onBackdropPress={() => showPackagingModal(false)}
onSwipeComplete={() => showPackagingModal(false)}
swipeDirection={['up', 'left', 'right', 'down']}>
<SelectPackaging
data={packagingTypes}
onSave={(packaging) => {
values.packaging = packaging;
showPackagingModal(false);
}}
/>
</Modal>
<Modal
isVisible={loadingTypeModalIsVisible}
style={styles.fullScreenModal}
animationOutTiming={300}
backdropTransitionOutTiming={0}
useNativeDriver={true}
backdropOpacity={0.3}
onBackButtonPress={() => showLoadingTypeModal(false)}
onBackdropPress={() => showLoadingTypeModal(false)}
onSwipeComplete={() => showLoadingTypeModal(false)}
swipeDirection={['up', 'left', 'right', 'down']}>
<SelectLoadingType
data={loadTypes}
onSave={(load) => {
values.load = load;
showLoadingTypeModal(false);
}}
/>
</Modal>
</ProgressStep>
)}
</Formik>
);
};
Theres formik
mistakes by me where must use setValue
to handle fields value updates but i did them directly, which not related to this topic.
wrapping progress step with
formik
is impossible.