Giter VIP home page Giter VIP logo

react-native-formik's Issues

withNextInputAutoFocus doesn't work with FlatList

Hi,

i use a FlatList inside a FieldArray inside a component wrapped with withNextInputAutoFocusForm

Current behavior

inputs inside the FlatList always have the done button

Expected behavior

inputs inside the FlatList should display the next button when this is not the last

Technical detail

FlatList has a renderItem prop but doesn't have the children prop

so, getInputs can find the inputs because it search children prop

const getInputs = children =>
React.Children.toArray(children).reduce((partialInputs, child) => {
if (child && child.props && child.props.children) {
return partialInputs.concat(getInputs(child.props.children));
}
if (child && child.props && !!child.props.name)
return partialInputs.concat(child);
return partialInputs;
}, []);

Demo

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

[withError] Don't override formik error when error props is defined.

Problem

I need to manage errors on a field :

  • One with Yup (validationSchema);
  • One with a call to an API;

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.

Solution

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 ?

Ability to perform field-level validations?

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?

dependency issues

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.

Focus next input with custom button

I have UI that has iOS keyboard navigation options to focus next/previous input. I am unable to focus the inputs using the button.
image

Can anyone help me with any method available to focus the input?

TypeError: undefined is not an object (evaluating '(i === 0 ? obj : resVal)[pathArray[i]]')

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>
    );
  }
}

using checkbox

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

Picker does not appear

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>
)

react-native-formik throws an error and doesn't work AT ALL with Formik v2

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.

Nested Form Walkthrough

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
                }
        }
}

Disable form submit on last input

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?

withNextInputAutoFocus does not work with nested components

Description

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.

Steps to reproduce / example

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 />

Ideas of technical solution

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.

KeyboardSpacer collapses momentarily when transitioning between fields

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.

withNextInputAutoFocus doen't work with custom components at all

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?

withNextInputAutoFocusInput goes to next input on new line for a multiline input

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?

withPickerValues stopped working on IOS

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.

Initial value not set

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, "");
    }

...

Support Formik 1.0.1+

  • We need to replace withFormik by connect
  • do we want to handle retrocompatibility? or submit a 2.0 with a breaking change?

The automated release is failing 🚨

🚨 The automated release from the master 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.


The push permission to the Git repository is required.

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 📦🚀

Add a Debugging component

We could add something as simple as a <Text /> that shows JSON.stringinfy(formikContext, null, 2).
Very useful when trying to debug issues :)

Custom input with initial value is not working

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

How to add initialValues?

Hi, I'm really excited about this package. But the initialValues won't work with this lib. So, How to add initialValues?

Submission on blur for each individual input should be an optional configuration

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.

Confused by formatting inputs example on home page

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.

BackAndroid error when using React Native 0.58

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.

WithNextInputAutoFocusInput Formik children is not updating

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

Handle nested fields

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.

Suggested solution

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

Using React Hooks & withNextInputAutoFocus together

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.

Incompatibility with formik v1

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)))))

withNextInputAutoFocus does not work with arrays of (dynamic) components.

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.

Picker doesnt pass the value to props

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>
            );
        }}
    />
);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.