bamlab / react-native-formik Goto Github PK
View Code? Open in Web Editor NEWSet of helpers to make form awesome with React Native and Formik
License: MIT License
Set of helpers to make form awesome with React Native and Formik
License: MIT License
As per TS defination at index.d.ts, withNextInputAutoFocusForm
expects only one argument.
Though as per src we can pass another object to set option i.e.submitAfterLastInput: false
. This is also shown in Example here.
Hi,
i use a FlatList
inside a FieldArray
inside a component wrapped with withNextInputAutoFocusForm
inputs inside the FlatList
always have the done
button
inputs inside the FlatList
should display the next
button when this is not the last
FlatList
has a renderItem
prop but doesn't have the children
prop
so, getInputs
can find the inputs because it search children
prop
react-native-formik/src/withNextInputAutoFocus.js
Lines 11 to 19 in ab0a017
import { action } from '@storybook/addon-actions';
import { storiesOf } from '@storybook/react-native';
import { FieldArray, Formik } from 'formik';
import React from 'react';
import { FlatList, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { handleTextInput, withNextInputAutoFocusForm, withNextInputAutoFocusInput } from 'react-native-formik';
import { compose } from 'redux';
const TextField = compose(
handleTextInput,
withNextInputAutoFocusInput,
)(TextInput);
const NextInputAutoFocus = withNextInputAutoFocusForm(View);
const initialFormValues = { someList: ['first item', 'second item', 'third item'] };
storiesOf('fields', module).add('fieldArray', () => (
<Formik initialValues={initialFormValues} onSubmit={action('submit')}>
{({ handleSubmit }) => (
<NextInputAutoFocus>
<FieldArray name="someList">
{() => (
<FlatList
data={initialFormValues.someList}
renderItem={({ index }) => <TextField name={`someList[${index}]`} />}
keyExtractor={(_item, index) => index.toString()}
/>
)}
</FieldArray>
<TouchableOpacity onPress={handleSubmit}>
<Text>Submit</Text>
</TouchableOpacity>
</NextInputAutoFocus>
)}
</Formik>
));
It seems related to this issue #42 but i'm not sure this is the same problem
Thanks for this module : it's simple and usefull
I need to manage errors on a field :
withError
automatically define the prop error
from Yup for my children component.
However, if then in my form I define the props error
like error={hasAPIError()}
I don't have Yup's errors handle automatically. I need now to create a function that handle it for me like error={hasAPIError() || hasYupError()}
.
In our case we totally forget to do it because we thought that Yup's errors will always be handle and transfer to my children component.
Current withError
:
import { compose, mapProps } from "recompose";
import _ from "lodash";
import withFormik from "./withFormik";
const withError = compose(
withFormik,
mapProps(({ formik: { errors }, name, ...props }) => ({
error: _.get(errors, name),
...props,
name
}))
);
export default withError;
Change I propose :
import { compose, mapProps } from "recompose";
import _ from "lodash";
import withFormik from "./withFormik";
const withError = compose(
withFormik,
mapProps(({ formik: { errors }, name, error, ...props }) => ({
error: _.get(errors, name) || error, // Don't override errors that Formik handle for us
...props,
name
}))
);
export default withError;
What do you think about this update ?
The <Field />
component from Formik allows for field-level validation and currently this is a bit of a pain to do with react-native-formik. Are there any plans to support it out of the box?
Something broke for me going from v1.7.1 to v1.7.4:
Unable to resolve "@bam.tech/react-native-modalbox" from "node_modules/react-native-formik/src/withPickerValues/KeyboardModal.js"
Setting to strictly "react-native-formik": "1.7.1",
in package.json fixed it for me.
what happen with this error? I dont know what to do, I have remove node_modules and npm install again, it doesn't work. what should I do?
I'm basically using the demo Gist verbatim:
https://snack.expo.io/@almouro/react-native-formik-gist
When I type a single letter into any text field I get the error:
TypeError: undefined is not an object (evaluating '(i === 0 ? obj : resVal)[pathArray[i]]')
I tried removing validationSchema and I still got the error. Separately, I tried removing withNextInputAutoFocusForm and withNextInputAutoFocusInput, and still got the problem. It feels like a bug in handleTextInput. Maybe I'm doing something stupid in the syntax below.
From package.json
:
"formik": "^2.1.4",
"react-native-formik": "^1.7.8",
"react-native-material-textfield": "^0.16.1",
"recompose": "^0.30.0",
"yup": "^0.28.3"
Code:
import React from 'react';
import { Button, ScrollView, View } from 'react-native';
import { compose } from 'recompose';
import { Formik } from 'formik';
import * as Yup from 'yup';
import {
handleTextInput,
withNextInputAutoFocusForm,
withNextInputAutoFocusInput
} from 'react-native-formik';
import { OutlinedTextField } from 'react-native-material-textfield';
const MyInput = compose(
handleTextInput,
withNextInputAutoFocusInput
)(OutlinedTextField);
const Form = withNextInputAutoFocusForm(View);
const validationSchema = Yup.object().shape({
country: Yup.string()
.required('Required.')
.length(2, 'Must be 2 letter country code.'),
});
const RegistrationForm = props => (
<Formik
onSubmit={values => console.log(values)}
validationSchema={validationSchema}
>
{props => (
<Form>
<MyInput label="Country" name="country" type="name"/>
<MyInput label="Business name" name="name" type="name"/>
<MyInput label="Business website" name="website" type="email"/>
<MyInput label="Business phone number" name="phone" type="digits"/>
<MyInput label="Address line 1" name="addressLine1" type="name"/>
<MyInput label="Address line 2" name="addressLine2" type="name"/>
<MyInput label="City" name="city" type="name"/>
<MyInput label="State" name="state" type="name"/>
<MyInput label="Zip code" name="zip" type="digits"/>
<Button onPress={props.handleSubmit} title="SUBMIT" />
</Form>
)}
</Formik>
);
export default class MyScreen extends React.Component {
render() {
return (
<ScrollView style={{ padding: 30 }}>
<RegistrationForm/>
</ScrollView>
);
}
}
Hi ,
is there any way i can apply formik in react native for checkbox ?
i want to the checkbox to be required, any chance this is doable ?
thanks in advance
I'm using your example code "MyPicker" no matter what I try, the Picker does not show. I'm using iOS. My code, which is essentially your example. What has changed?
import React from "react";
import { Button, TextInput, Text, View } from "react-native";
import {Formik} from 'formik'
import {compose} from 'recompose'
import makeInput, {handleTextInput,
withNextInputAutoFocusForm,
withNextInputAutoFocusInput,
KeyboardModal,
withPickerValues
} from 'react-native-formik'
import { TextField } from "react-native-material-textfield";
import * as Yup from 'yup'
const FormikInput = compose(
handleTextInput,
withNextInputAutoFocusInput
)(TextField)
const MyPicker = compose(
makeInput,
withPickerValues
)(TextInput)
const InputsContainer = withNextInputAutoFocusForm(View)
const validationSchema = Yup.object().shape({
email: Yup.string()
.required()
.email("That's not a valid email"),
password: Yup.string()
.required()
.min(3, "That's too small"),
gender: Yup.string()
})
export default ThisForm => (
<Formik
onSubmit={values => {KeyboardModal.dismiss(); console.log(values)}}
validationSchema={validationSchema}
>
{props => {
return (
<InputsContainer style={{ padding: 10 }}>
<FormikInput label="email" name="email" type="email" />
<FormikInput label="password" name="password" type="password" />
<MyPicker
name="gender"
values={[{label: 'male', value: 'M'}, {label: 'female', value: 'F'}]}
/>
<Button onPress={props.handleSubmit} title="Submit" />
{/* <Text style={{fontSize: 20}}>{JSON.stringify(props, null, 2)}</Text> */}
</InputsContainer>
)
}}
</Formik>
)
Picker in here was quite good with a native feel and a clean API for both Android & iOS
We should import it in the same way we did with Picker
This error comes when typing into any text field -
TypeError: undefined is not an object (evaluating '(i === 0 ? obj : resVal)[pathArray[i]]')
This error occurs even with the example code in README.
It seems like work on react-native-formik stopped around the time the last stable version of Formik 1.x.x came out, which was 1.5.8, the package has not been updated for Formik v2
Right now it's working with [email protected], for anyone who wishes to use this package.
I see that the normal formik library supports nested forms...I simply need a way to send an object through the form with shape.
{ applicant_form: { user_id,
info_attributes: {
first_name,
last_name
}
}
}
I'd like to disable the automatic form submit which occurs on the last input withNextInputAutoFocus. It looks like withNextInputAutoFocus.js just establishes that the input is the last and then submits with no other alternative (lines 45-46). Am I missing something?
When using self-closing-tag components to generate text fields in a form, the withNextInputAutoFocusForm
does not register the generated textInputs and the expected behaviour does not work : pressing "OK" with a textInput focused submits the entire form.
const Form = withNextInputAutoFocusForm(View);
export class ReportForm extends PureComponent<PropsType, StateType> {
renderForm = ({ values, handleSubmit }: { values: any, handleSubmit: Function }) => {
return (
<Form>
<AircraftInformationSection />
</Form>
);
};
render() {
return (
<Formik
// ...
render={this.renderForm}
/>
);
}
}
export class AircraftInformationSection extends PureComponent<PropsType> {
render() {
return (
<View>
<TextInput
name="aircraftInformationSectionType"
// ...
/>
</View>
);
}
}
In this case, getInputs does not see any children in the props of <AircraftInformationSection />
Create a Provider/Consumer system with textFields subscribing to the form.
Add a prop to the form to specify the order of the fields to be focused.
My formik project worked great in react-native 0.62.2 , but doesn't render at all in 0.63.2
Hi, good job in this package. I wonder if I missed something in my code, please check this out?
https://snack.expo.io/HkFpyjdrm
Thanks
I'm not sure if it's expect behavior or not, but I tried out the advanced example and (at least on IOS) the keyboard closes and the fields reposition to the expanded state for a moment before the next field takes focus. The result is that the form jumps around when using the next button on the keyboard. This does not happen when tapping on the next field or any other field.
I wasted all day trying to get it to work with a custom input component and all the difference I could make is to either make the form submit by tapping Next button, or to defocus the field. Unlike the other issue here I don't even have any nesting. Unlike TextField and inbuilt native inputs it won't work in any way if I use a custom element that is seemingly compliant with the requirements set in readme. Here's the element wrapper:
export default class StyledInput extends React.Component {
constructor(props) {
super(props);
}
focus = () => this.setState({ focused: true });
render() {
return (
<TextField {...this.props} />
);
}
}
Here's how it used:
const Form = withNextInputAutoFocusForm(View);
const MyInput = withNextInputAutoFocusInput(StyledInput);
export default class Login extends Screen {
...
render() {
return (
<View >
<Formik
onSubmit={(values, actions) => this.formSubmit(values, actions)}
validationSchema={validationSchema}
initialValues={{
...
}}
render={formikProps => {
return (
<Form>
<MyInput
label='Blah'
autoFocus
name='login'
type='email'
/>
<MyInput
label='Password'
name='password'
type='password'
/>
</Form>
);
}}
/>
</View>
);
}
}
Am I doing something wrong or is it really broken?
using the provided example of:
const MyInput = compose(
handleTextInput,
withNextInputAutoFocusInput
)(TextField);
on a <MyInput name="multitest" multiline={true} />
it will go to the next input upon pressing enter instead of adding a new line to the multiline field.
I thought I could work around it by doing this:
const MyMultiInput = compose(
handleTextInput
)(TextField);
but unfortunately then the normal input above the "multitest" is done it skips the focus to the input below "multitest" that is another normal input.
Any thoughts on how to get around this besides making the multi fields the first or last fields in the form?
The picker no longer opens for me on IOS. It still works as expected on Android. I can see the KeyboardModal is called if it is IOS at line 47 of PickerModal.js when the Platform is IOS.
It appears that this issue is related to a wrapper I've placed around the App. In order to disable the Expo logger in terminal, I'm calling Logs.disableExpoCliLogging and then
const AppEntry = () => {
const App = require('./App').default;
return <App />;
};
registerRootComponent(AppEntry);
If I use the default entry node_modules/expo/AppEntry.js
the picker modal works on IOS.
When using the makeReactNativeField
, the initialValue
is no longer set (since v1.0.2).
I guess setFormikInitialValue
hoc is not setting the initial value even if it is set in its props.
const setFormikInitialValue = WrappedInput => {
return class WithFocusProp extends React.PureComponent {
constructor(props) {
super(props);
props.formik.setFieldValue(props.name, "");
}
...
Can the peer dependency be updated to also include formik version 2 or does it only work with version 1?
+-- UNMET PEER DEPENDENCY [email protected]
npm ERR! peer dep missing: formik@>= 0.11.x < 2, required by [email protected]
withFormik
by connectmaster
branch failed. 🚨I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.
You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.
Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.
Once all the errors are resolved, semantic-release will release your package the next time you push a commit the master
branch. You can also manually restart the failed CI job that runs semantic-release.
If you are not sure how to resolve this, here is some links that can help you:
If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.
semantic-release cannot push the version tag to the branch master
on remote Git repository.
Please refer to the authentication configuration documentation to configure the Git credentials on your CI environment.
Good luck with your project ✨
Your semantic-release bot 📦🚀
We could add something as simple as a <Text />
that shows JSON.stringinfy(formikContext, null, 2)
.
Very useful when trying to debug issues :)
If we give initial value as per the code in WithFormikControl the initila value from props always overrides the value got from getValue
const withFormikControl = compose( withErrorIfNeeded, connect, mapProps( ({ formik: { values, setFieldValue, setFieldTouched }, name, value, ...props }) => ({ value: get(values, name) === undefined ? value : get(values, name), setFieldValue: (value, ...args) => setFieldValue(name, value, ...args), setFieldTouched: (value, ...args) => setFieldTouched(name, value, ...args), name, ...props }) ) );
this should be the code
Hi, I'm really excited about this package. But the initialValues won't work with this lib. So, How to add initialValues?
At this point the majority of mobile app settings screens do not use a submit button, they submit the fields on blur. At present, this isn't possible because Formik uses blur for other purposes and blocks the usage of blur for submission. Since react-native-formik is meant to make Formik more friendly toward react-native, one of the configuration options should be individual inputs which submit on blur.
If my form state has a value, that is an array: [this] https://github.com/bamlab/react-native-formik/blob/master/src/makeReactNativeField.js#L9 fails
Say the form is like:
{
arrayValue: [
{ name: "Hello" }
]
}
Indeed you would set name=arrayValue.${i}.name
on the input and lodash is not getting by path
Ping @Gguigre if you want to add more details
In this example Formatting Inputs I'm confused by this line:
const formatPhoneNumber: string => string = (unformattedPhoneNumber) => ...;
Why the double function indirection? How exactly is that adding spaces? I'm guessing it's just a sample to say that if "value" prop is a function, it'll get called but store the value untransformed.
Would love some hints.
After upgrading to React Native 0.58, I experienced this error on Android:
BackAndroid is deprecated and has been removed from this package. Use BackHandler instead.
I tracked the issue down to @bam.tech/react-native-modalbox
:
'use strict';
var React = require('react');
var PropTypes = require('prop-types');
var {
View,
StyleSheet,
PanResponder,
Animated,
TouchableWithoutFeedback,
Dimensions,
Easing,
BackAndroid,
BackHandler,
Platform,
Modal,
Keyboard
} = require('react-native');
var createReactClass = require('create-react-class');
var BackButton = BackHandler || BackAndroid;
...
Removing BackAndroid
from this file seems to solve the problem.
Version 1.7.0 of react-native-modalbox
makes this fix.
You may want to publish a new version of @bam.tech/react-native-modalbox
that removes the deprecated BackAndroid
.
the issue is that the children is not updating when i dynamically add new input fields to formik,
example
<Formik>
<FormWrap>
<Input/>
{condition <Input/>}
</Formik>
<Button>
</FormWrap>
now when i finish typing in the second field the auto focus will jump to the first field which shouldn't happen,
what happen is that the children will allows be the first input, even after changing the condition to true
The library does not work for nested fields (for example user.username
) since the value is accessed directly from the object.
In makeReactNativeField.js
:
mapProps(({ formik: { setFieldValue, setFieldTouched, values }, name, ...props }) => ({
value: values[name],
// ...
}))
Same in withError.js
.
I think we could just add a selector function?
const getValue = (values, name) => {
if (!name.includes('.')) {
return values[name];
} else {
const nestedKeys = name.split('.');
selectedValue = values[nestedKeys[0]];
for (let i = 1; i < nestedKeys.length; i += 1) {
selectedValue = selectedValue[nestedKeys[i]];
}
return selectedValue;
}
}
And
mapProps(({ formik: { setFieldValue, setFieldTouched, values }, name, ...props }) => ({
value: getValue(values, name),
// ...
}))
I'll open a PR this week
when i try to type something in the input text this error appears
i'm using "formik": "^2.2.9", and "react-native-formik": "^1.7.8"
any solution plz
Hi, I love this code. Could provide a React Native adaptation for the MultiStepWizard example provided in the formik repository (https://github.com/jaredpalmer/formik/blob/master/examples/MultistepWizard.js) ?
Thanks in advance.
Is there nice and recommended way to scroll to first invalid form element using this lib, when form is submitted?
Thk's
Thanks for this awesome lib, it has been fun all the time to use it. I have a question though on how could i use withNextInputAutoFocus and my functional Hooks component. According to your docs, using withNextInputAutoFocus requires us to have a focus method, with a sole purpose to focus on the element.
The problem occurs when I'am using hooks. As we know that in functional component you can't have a method, on the other hand, because you want to use hooks you cannot use class. So I'am stuck in the middle of both. I really hope I can use Hooks and withNextInputAutoFocus together as I really enjoyed working with both.
It seems react-native-formik is not compatitble with the new version of formik.
My error:
TypeError: TypeError: Cannot read property 'setFieldValue' of undefined
This error is located at:
in mapProps(getContext(WithFocusProp)) (created by getContext(mapProps(getContext(WithFocusProp))))
in getContext(mapProps(getContext(WithFocusProp))) (created by mapProps(getContext(mapProps(getContext(WithFocusProp)))))
in mapProps(getContext(mapProps(getContext(WithFocusProp)))) (created by Styled(mapProps(getContext(mapProps(getContext(WithFocusProp))))))
in Styled(mapProps(getContext(mapProps(getContext(WithFocusProp)))))
When attempting to build a form dynamically using an array of Components, withNextInputAutoFocus
does not set the keyboard "enter" button to advance to the next field.
For example:
const config = [
{ label: "Email", name: "email", type: "email" },
{ label: "Password", name: "password", type: "password" },
{ label:"First Name", name: "firstName", type: "name" },
{ label: "Last Name", name: "lastName", type: "name" },
]
export default props => (
<Formik
onSubmit={values => console.log(values)}
validationSchema={validationSchema}
render={props => {
return (
<Form>
{
config.map( item =>
<MyInput label={item.label} name={item.name} type={item.type} />
)
}
<Button onPress={props.handleSubmit} title="SUBMIT" />
</Form>
);
}}
/>
);
The above code will render, but the autofocus feature does not work.
I can get all the values like email and password in console.log except selected value for picker
import React from 'react';
import { Text, View ,StyleSheet, Button, TextInput } from 'react-native';
import { TextField } from 'react-native-material-textfield';
import { compose } from 'recompose';
import { Formik } from 'formik';
import Yup from 'yup';
import makeInputGreatAgain, {
withNextInputAutoFocusForm,
withNextInputAutoFocusInput,
withPickerValues
} from 'react-native-formik';
export class MaterialTextInput extends React.PureComponent {
// Your custom input needs a focus function for `withNextInputAutoFocus` to work
focus() {
this.input.focus();
}
render() {
const { error, touched, ...props } = this.props;
//
const displayError = !!error && touched;
const errorColor = 'rgb(239, 51, 64)';
return (
<View>
<TextField
ref={input => (this.input = input)}
labelHeight={12}
baseColor={displayError ? errorColor : '#1976D2'}
tintColor="#2196F3"
textColor="#212121"
{...props}
/>
<Text
style={{
textAlign: 'right',
color: displayError ? errorColor : 'transparent',
height: 20,
}}
>
{error}
</Text>
</View>
);
}
}
const MyInput = compose(makeInputGreatAgain, withNextInputAutoFocusInput)(MaterialTextInput);
const Form = withNextInputAutoFocusForm(View);
const MyPicker = withPickerValues(TextInput);
const validationSchema = Yup.object().shape({
email: Yup.string()
.required('please! email?')
.email("well that's not an email"),
password: Yup.string()
.required()
.min(2, 'pretty sure this will be hacked'),
});
export default props => (
<Formik
onSubmit={values => console.log(values)}
validationSchema={validationSchema}
render={props => {
return (
<Form>
<MyInput label="Email" name="email" type="email" />
<MyInput label="Password" name="password" type="password" />
<MyInput label="First Name" name="firstName" type="name" />
<MyInput label="Last Name" name="lastName" type="name" />
<MyPicker
name="gender"
values={[{ label: 'male', value: 'Mr' }, { label: 'female', value: 'Mrs' }]}
/>
<Button onPress={props.handleSubmit} title="SUBMIT" />
</Form>
);
}}
/>
);
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.