modal not working correctly in native base - react-native

I want when i click the button, opening the modal. But modal is not opening correctly. And it is not readable.
Here is in my modal code :
<Modal
isOpen={showModal}
>
<Modal.Content top="-60" maxWidth={400} height={300}>
<Modal.CloseButton />
<Modal.Header> bilgiler</Modal.Header>
<Modal.Body>
<Text>09.08.2001</Text>
{/* <Select
minWidth="200"
accessibilityLabel="Choose Service"
placeholder="Son ölçüm tarihi seçiniz.."
_selectedItem={{
bg: "teal.600",
endIcon: <CheckIcon size="5" />
}} mt={1}
>
</Select>*/}
<Text>Adi ve soyadi</Text>
</Modal.Body>
<Modal.Footer>
<Button.Group space={2}>
<Button variant="ghost" colorScheme="blueGray" onPress={() => setShowModal(false)} >
Çıkış
</Button>
<Button onPress={() => setShowModal(false)} >
Kaydet
</Button>
</Button.Group>
</Modal.Footer>
</Modal.Content>
</Modal>
and pressable code :
<Box flex="1" >
<Pressable left={290} top="-35" onPress={() => setShowModal(true)}>
<Image size={7} source={require('../assets/clock.png')} />
</Pressable>
</Box>
I try to change pressable but it not working

Try this
Create a component for Model to reuse or use can have it in screen itself.
Modal.js
const Mdal = ({ ...props }) => {
const { onInputChanged, showModal, onClose, header, inputTitle, ...p }
= props;
const [isOpen, setIsOpen] = useState(false);
return (
<Modal
isOpen={showModal}
onClose={onClose}
_backdrop={{
_dark: {
bg: "coolGray.800",
},
bg: "warmGray.50",
}}
>
<Modal.Content borderWidth={2} width="500" maxWidth="93%" maxH="600">
<Modal.CloseButton />
<Modal.Header flexDirection="row">{header}</Modal.Header>
<Modal.Body>
<Text>Your View</Text>
</Modal.Body>
<Modal.Footer background={COLOR.card_action_bg}>
<Button.Group space={2}>
<Button
colorScheme="warmGray"
onPress={() => {
onInputChanged("if any passing value");
}}
>
Save
</Button>
<Button
colorScheme="red"
onPress={() => {
onClose();
}}
>
Cancel
</Button>
</Button.Group>
</Modal.Footer>
</Modal.Content>
</Modal>
);
};
export default Mdal;
In the screen where you want modal :
import { Model } from "the path if it is as component"
const [showModal, setShowModal] = useState(false);
Place it inside your view
<Modal
onInputChanged={onInputChanged}
showModal={showModal}
onClose={() => setShowModal(false)}
header={"(" + ticketId + ") - " + action}
inputTitle={"Reason for transfer"}
/>
onInputChanged - is the function
const onInputChanged = (changedText) => {
//received selected value in changedText
}
change the state of showModal to true on your pressable view(onPress) ->
setShowModal(true);

Related

React Native - add specific clearButton on input field when the keyboard is open

I am trying to create a specific clear button to use on both ios and android devices. I have created a reusable component for the several fields I have. When I press the fields since the keyboard opens the X button shows in all fields not only the field I have pressed. In the code below emptyField is a value set in a parent component.
const [keyboardShow, setKeyboardShow] = useState<boolean>(false);
useEffect(() => {
const showKeyboard = Keyboard.addListener('keyboardDidShow', () => {
setKeyboardShow(true);
});
const hideKeyboard = Keyboard.addListener('keyboardDidHide', () => {
setKeyboardShow(false);
});
return () => {
showKeyboard.remove();
hideKeyboard.remove();
};
}, []);
<TouchableComponent>
<TextInput
key={currencyTypeId}
ref={forwardRef}
style={styles.input}
onChangeText={onChangeText}
value={inputValue}
editable={editable}
autoCorrect={false}
autoCompleteType='off'
returnKeyType={returnKeyType}
placeholder={placeholder}
placeholderTextColor={placeholderColor}
keyboardType={keyboardType}
/>
</TouchableComponent>
{inputValue.length > 0 && keyboardShow && (
<View style={styles.customButton}>
<TouchableOpacity onPress={emptyField}>
<CloseIcon width={12} height={12}/>
</TouchableOpacity>
</View>
)}
Seems 'keyboardDidShow' and 'keyboardDidHide' events triggered in each reusable component.
You can try another approach. Just use onBlur and onFocus events. It's isolated for each component:
<TouchableComponent>
<TextInput
onBlur={() => setIsFocused(false)}
onFocus={() => setIsFocused(true)}
key={currencyTypeId}
ref={forwardRef}
style={styles.input}
onChangeText={onChangeText}
value={inputValue}
editable={editable}
autoCorrect={false}
autoCompleteType="off"
returnKeyType={returnKeyType}
placeholder={placeholder}
placeholderTextColor={placeholderColor}
keyboardType={keyboardType}
/>
</TouchableComponent>
{inputValue.length > 0 && isFocused && (
<View style={styles.customButton}>
<TouchableOpacity onPress={() => {}}>
<CloseIcon width={12} height={12} />
</TouchableOpacity>
</View>
)}

KeyboardAvoidingView, ScrollView and Flatlist in a form

I have a form where I am using KeyboardAvoidingView and ScrollView so that when a user clicks on an input field the screen will scroll to that particular field
Within my form I have an input field that is searchable and I am using a FlatList to display the results for the user to choose from. Currently I am getting the error:
VirtualizedLists should never be nested inside plain ScrollViews
I've looked at many posts around this but am yet to find a solution (unless I've missed something):
1 - How to put FlatList inside of the ScrollView in React-native?
2 - FlatList inside ScrollView doesn't scroll
3 - How to make a FlatList scrollable inside of a ScrollView in react native?
This is what I have so far:
export const SignUpMember = ({navigation}) => {
const renderHeader = formikProps => {
return (
<>
<FormField
keyboardType={'default'}
fieldName={'firstName'}
label={'First Name'}
/>
<FormField
keyboardType={'default'}
fieldName={'lastName'}
label={'Last Name'}
/>
<FormField
onChangeText={text => {
formikProps.values.clubName = text;
searchItems(text);
}}
value={formikProps.values.clubName}
keyboardType={'default'}
fieldName={'clubName'}
label={'Club Name'}
placeholder={'Search Club By Name...'}
/>
</>
);
};
const renderFooter = formikProps => {
return (
<>
<FormField
keyboardType={'phone-pad'}
fieldName={'telephone'}
label={'Telephone'}
/>
<FormField
keyboardType={'email-address'}
fieldName={'email'}
label={'Email'}
/>
<FormField
keyboardType="default"
secureTextEntry={true}
fieldName={'password'}
label={'Password'}
type={'password'}
/>
<FormField
keyboardType="default"
secureTextEntry={true}
fieldName={'passwordConfirmation'}
label={'Confirm Password'}
type={'password'}
/>
<Button
mt="2"
bg="brand.blue"
type="submit"
onPress={formikProps.handleSubmit}>
Sign Up
</Button>
</>
);
};
return (
<KeyboardAvoidingView
keyboardVerticalOffset={headerHeight}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<ScrollView
_contentContainerStyle={styles.container}
nestedScrollEnabled={true}>
<Box p="1" py="8" w="90%" maxW="290">
<VStack space={3} mt="5">
<Formik
initialValues={initialFormValues}
onSubmit={values => handleFormSubmit(values)}
validationSchema={userValidationSchema}>
{formikProps => (
<View>
<FlatList
nestedScrollEnabled={true}
data={flatListData}
renderItem={({item}) => (
<Pressable
onPress={() => {
formikProps.values.clubName = item.name;
setFlatListData([]);
}}>
<Text style={styles.flatList}>{item.name}</Text>
</Pressable>
)}
keyExtractor={item => item.name}
ListHeaderComponent={renderHeader(formikProps)}
ListFooterComponent={renderFooter(formikProps)}
/>
</View>
)}
</Formik>
</VStack>
</Box>
</ScrollView>
</KeyboardAvoidingView>
);
};
export default SignUpMember;
How can I piece this together?

How to make alert on click of button

Is there a way to make Alert on click not using the alert method but Alert tag. Currently I tried using usestate but didn’t work
Hard to know what your problem is without seeing code but this is the general approach to show tag based components. Don't forget to revert the state value on dismissal.
const [showAlert, setShowAlert ] = useState(false);
return (
<>
{showAlert ?
<Alert {...otherPropsHere} />
: <View/> }
<Button title="Press Me" onPress={() => {setShowAlert(true)} />
</>
)
If the tag has a 'visible' prop then it would be more like this
const [showAlert, setShowAlert ] = useState(false);
return (
<>
<Alert visible={showAlert} {...otherPropsHere} />
<Button title="Press Me" onPress={() => {setShowAlert(true)} />
</>
)
If you need multiple alerts you could:
const [showAlertOne, setShowAlertOne ] = useState(false);
return (
<>
{showAlertOne ?
<Alert {...otherPropsHere} />
: <View/> }
{showAlertTwo ?
<Alert {...otherPropsHere} />
: <View/> }
<Button title="Show Alert One" onPress={() => {setShowAlertOne(true)} />
<Button title="Show Alert Two" onPress={() => {setShowAlertTwo(true)} />
</>
)
This isn’t the best way to do it but I think this should clear up the concept of what you are trying to do. A better way - if the alerts don’t show at the same time - is to have a single state object in which you store which alert you want to show. These could be an ENUM too to add a little safety.
This is the (partially) typed example with an enum and a wrapped component.
const myApp = () => {
enum AlertType = { One, Two, Three }
const [visibleAlert, setVisibleAlert ] = useState<AlertType | null>(null);
const VisibleAlert = (alertType:AlertType) => {
switch (visibleAlert) {
case AlertType.One:
return <Alert {otherPropsHere} />
break;
case AlertType.One:
return <Alert {otherPropsHere} />
break;
default:
return <View/>
break;
}
}>
return (
<>
<VisibleAlert alertType={visibleAlert} />
<Button title="Show Alert One" onPress={() => {setVisibleAlert(AlertType.One)} />
<Button title="Show Alert Two" onPress={() => {setVisibleAlert(AlertType.Two)} />
</>
)
}
Wrapping the modal in a component with its own state might be a good approach but let’s see what your issue is for sure first.

How to change state of react hook inside other component

Senario
I have a dialog, it look something like this, it have hook for showing this dialog, called showDialog , and dialog have a button with Onpress method
export default function DialogTesting(show: boolean) {
const [showDialog, doShow] = useState(show)
return (
<View>
{/* <Button
title="click"
onPress={() => {
setShow(true)
}}
>
<Text>Show dialog</Text>
</Button> */}
<Dialog
visible={showDialog}
title="Record New Progress"
style={DIALOG}
onClose={() => {
doShow(false)
}}
>
And a main sceen , it also have hook to show dialog, called show,
export const MedicalRecord = memo(function MedicalRecord() {
// const onPressViewAll = useCallback(() => {}, [])
const [show, setShow] = useState(false)
function hanndleDialog() {
setShow(!show)
}
return (
<SummaryViewContainer
count={5}
title={"dashboardScreen.medicalRecords.title"}
onPress={() => {
hanndleDialog()
}}
>
<View>
{show && (
<ProgressDialog
show={show}
callback={() => {
hanndleDialog()
}}
/>
)}
<RecordItem />
<RecordItem />
<RecordItem />
</View>
</SummaryViewContainer>
)
})
Problem
When i click the button in main screen, change hook show to true to show dialog, and use this hook state in dialog to set show in dialog to true to show that dialog, and in dialog, when i click button to close dialog, it disappear, but problem is, the state of show in main screen remain true, so i have to press twice to show dialog again
Question
How can i change hook status in main screen, or how can i press close button in dialog, the show hook in main screen return false, i tried to change state of mainscreen in dialog but it won't work
Here is a short video of problem
https://streamable.com/9mm26t
You should maintain just one copy of your state in the parent component itself. Then pass "show" and "setShow" as props to the child component.
Parent Component:
export const MedicalRecord = memo(function MedicalRecord() {
// const onPressViewAll = useCallback(() => {}, [])
const [show, setShow] = useState(false)
function hanndleDialog() {
setShow(!show)
}
return (
<SummaryViewContainer
count={5}
title={"dashboardScreen.medicalRecords.title"}
onPress={() => {
hanndleDialog()
}}
>
<View>
{show && (
<ProgressDialog
show={show}
setShow = {setShow}
/>
)}
<RecordItem />
<RecordItem />
<RecordItem />
</View>
</SummaryViewContainer>
)
})
Dialog Component:
export default function DialogTesting({show, setShow}) {
return (
<View>
{/* <Button
title="click"
onPress={() => {
setShow(true)
}}>
<Text>Show dialog</Text>
</Button> */}
<Dialog
visible={show}
title="Record New Progress"
style={DIALOG}
onClose={() => {
setShow(false)
}}
>
</View>
)
}
It looks like you have 2 versions of local state at each component. You need to keep 1 version of "show" at the top most parent where you care to control this variable and then pass it down as a prop to your child components. Then on your child components you need to expose a callback that the parent will pass down and the child will call to trigger what occurs when the button is clicked in the child component.

how to use react native elements radio button with redux form?

I am using react elements components in my react-native application.
import React,{ Component } from 'react';
import { Field,reduxForm } from 'redux-form';
import { Text,Input } from 'react-native-elements';
import { View,Button } from 'react-native';
import {Icon,CheckBox} from 'react-native-elements';
const renderField=({label,keyboardType,name,icon,iconType,input:{onChange,...restInput}}) => {
return(
<View style={{flexDirection:'row'}}>
<Input onChangeText={onChange} {...restInput} keyboardType={keyboardType} placeholder={label} inputContainerStyle={{borderWidth:2,borderColor:'lightgrey',borderRadius:20}} inputStyle={{color:'grey'}} leftIcon={<Icon size={25} type={iconType} name={icon} color="grey" />} errorStyle={{fontSize:15}} errorMessage="error" />
</View>
)
}
const checkBoxField=({label,keyboardType,name}) => {
var val=true;
return(
<View >
<View style={{flexDirection:'row',alignItems:'center',justifyContent:'center'}}>
<Text style={{fontSize:18}}>{label}</Text>
<CheckBox title='Male' checkedIcon='dot-circle-o' uncheckedIcon='circle-o' containerStyle={{backgroundColor:'transparent',borderWidth:0,padding:0}} textStyle={{fontSize:18}} />
<CheckBox title='Female' checkedIcon='dot-circle-o' uncheckedIcon='circle-o' containerStyle={{backgroundColor:'transparent',borderWidth:0,padding:0}} textStyle={{fontSize:18}} />
</View>
<View><Text style={{fontSize:15,color:'red'}}>error</Text></View>
</View>
)
}
const submit = values => {
console.log('submitting form', values)
}
const RegisterForm=props => {
const {handleSubmit}=props;
return(
<View style={{flex:1,flexDirection:'column',margin:20,justifyContent:'flex-start',alignItems:'center'}}>
<Field label="Username" component={renderField} name="username" icon="user" iconType="font-awesome" />
<Field label="Email" component={renderField} name="email" icon="email" iconType="zocial" />
<Field label="Gender" component={checkBoxField} name="gender" />
<Button title='SUBMIT' onPress={handleSubmit(submit)} />
</View>
)
}
const Register=reduxForm({
form:'register',
})(RegisterForm);
export default Register;
in the above code I am using redux form in my react-native application,by passing onChange() I can retrieve values of text input,but how can I retrieve the values of a radio button?currently the form contains text input values only,I need to add radio button values also. If the user select one value in the radio button I need to unselect other radio button how it will be possible?
You can use react-native-radio-input.
Its very simple to use.
import RadioGroup,{Radio} from "react-native-radio-input";
.
.
.
//Receive the checked value (ES6 syntax)
getChecked = (value) => {
// value = our checked value
alert(value)
}
<RadioGroup getChecked={this.getChecked}>
<Radio iconName={"lens"} label={"The first option"} value={"A"} />
<Radio iconName={"lens"} label={"The first option"} value={"B"} />
<Radio iconName={"lens"} label={"I need numbers"} value={1} />
<Radio label={"Is IconName Optional?"} value={"Yes"} />
<Radio label={"Show Sentence Value"} value={"This is a Sentence"} />
</RadioGroup>
.
.