JPT
JPT

Reputation: 131

How to preserve the value of a form value which is set in code

I have a react based website which is essentially a user authenticate front end. One of our forms is a registration form, on which we are trying to add CAPTCHA functionality. Now the problem is that we have to use our in-house CAPCHA routines which i cannot change (well not without a mountain of redtape and weeks of delays).

So i have the scenario where i have a form (we use Formik) and in the form i have to embed a hidden text box and a div which the JS of our CAPTCHA system uses buy overriding the div and by placing some values in the hidden boxes which is then used to call an API later on in the flow. The CAPTCHA JS also plumbs itself into the onSubmit of the form.

Anyway, my problem is that the hidden field is being set by the JS routines, and so is not covered by the binding mechanisms of react. So if i change one of the normal fields or submit the form then the hidden text boxes value is set to "" - presumably because its value is set back to what the form thinks it should be - how can i avoid this? when the form is submitted i need to access both the normal fields and this hidden fields.

Some sample code which may make it clearer:

render() {
    const { apiError } = this.props;

    return (
        <div>
            <Formik
                initialValues={{
                    firstName: '',
                    lastName: '',
                    email: '',
                    password: '',
                    confirmPassword: '',
                    newsletter: false,
                    legal: false
                }}
                validate={this.validate}
                onSubmit={this.handleSubmit}
            >
                {({
                    errors,
                    touched,
                    values,
                    isSubmitting,
                    handleSubmit,
                    setStatus,
                    status = { submitedWithEmptyInputs: false, submited: false },
                }) => (
                    <div>
                        <div>
                            {apiError &&
                                status.submited &&
                                apiError === 409 && (
                                    <GenericError>Email address exists</GenericError>
                                )}
                            {apiError &&
                                status.submited &&
                                apiError !== 409 && (
                                    <GenericError>
                                        Sorry we couldn't process your request. Please check all
                                        inputs.
                                    </GenericError>
                                )}
                        </div>
                        <Form onSubmit={handleSubmit} noValidate>
                            <InputField
                                label="First Name"
                                type="text"
                                id="firstName"
                                name="firstName"
                                value={values.firstName}
                                error={values.firstName && errors.firstName}
                            >
                                {status.submitedWithEmptyInputs &&
                                    errors.firstName && (
                                        <ErrorMessage className="error">
                                            {errors.firstName}
                                        </ErrorMessage>
                                    )}
                                {status.submitedWithEmptyInputs &&
                                    errors.firstName && (
                                        <ErrorIcon className="error">
                                            <Icon icon={ICONS.ERROR} size="20px" />
                                        </ErrorIcon>
                                    )}
                            </InputField>
                            ....
                            ....


                            <div id="challenger" />
                            <input type="hidden" name="cid" id="cid" value="" />


                                <Button
                                    text="Create your ID"
                                    primary
                                    width="100%"
                                    type="submit"
                                    id="submit"
                                    loading={this.props.registering}
                                    disabled={isSubmitting}
                                    onClick={() => {
                                        if (
                                            !values.firstName ||
                                            !values.lastName ||
                                            !values.email ||
                                            !values.password ||
                                            !values.confirmPassword ||
                                            !values.legal
                                        ) {
                                            setStatus({ submitedWithEmptyInputs: true });
                                        }
                                    }}
                                />
                            </FormActions>
                        </Form>

Upvotes: 0

Views: 3114

Answers (1)

Joshua Underwood
Joshua Underwood

Reputation: 927

As crude as this might be, you have an id for your challenger input, so in your form change handler (or submitter) use vanilla javascript to grab and store its value and then set it back. e.g.

onChange(event) { 
    let challengeValue = document.getElementById('cid').value;
    // do some change handling stuff which includes a setState probably, right?
    this.setState({ someKey: someValue }, () => {
        //This is the callback for setState, lets apply the value back to cid
        document.getElementById('cid').value = challengeValue;
    });
}

Upvotes: 1

Related Questions