I have a react application in which I use a google Recaptcha in the Login component. I don't want users to log in without checking the "I'm not a robot" Recaptcha. I am using a state but I am not as successful as the state never changes, how can I do? I have the code below.
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
captcha: false,
}
}
callBack = () => {
console.log("something inside re captcha");
}
verifyBack = (response) => {
if (response) {
this.setState({
captcha: true,
});
}
}
onSubmit = () => {
// checking if captcha state is true to log in but not successful.
// log in only after checking the I'm not a robot box (assuming username/password matches).
}
render() {
return (
<div>
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required />
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" required />
<button type="submit" onClick={this.onSubmit}>Login </button>
<label>
<input type="checkbox" checked="checked" name="remember" /> Remember me
</label>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" class="cancelbtn">Cancel</button>
<span class="psw">Forgot password?</span>
</div>
<div className="row invisible-recaptch">
<ReCAPTCHA
sitekey="6Lf8zsgUAAAAAHV1_VcrNDHfWuYAXw1tUSLnexQg"
render="explicit"
onloadCallback={this.callBack}
verifyCallback={this.verifyBack}
/>
</div>
</div>
);
}}
Based on your code,
I think you need to bind your verifyBack function in constructor.
constructor(props) {
super(props);
...
this.verifyBack = this.verifyBack.bind(this);
}
Your problem will solve.Inside verifyBack function u do not have
access of this so that setState is not working.bind the function with
this will help u to do this.
Related
I try it but not working
import React from "react";
import "./App.css";
import { useForm } from "react-hook-form";
import classNames from "classnames";
import { useState } from "react";
function App() {
const { register, handleSubmit,formState: { errors } } = useForm();
// console.log(errors);
const onSubmit = data => console.log(JSON.stringify(data));
const postData = async (e)=>{
e.preventDefault();
const res = await fetch("https://test1-5022f-default-rtdb.firebaseio.com/reactformData.json",
{
method:"POST",
header:{
"content-type":"application/json",
},
Here what I pass in body?
body:JSON.stringify(data)
}
)
};
There are many fields in my form but here I show some
return (
<div>
<div className="container">
<div className="form-group my-3 ">
<form name="Registration_form" id="Form" action="" method="POST" onSubmit={handleSubmit(onSubmit)}>
<div className="form-group my-3">
<label htmlFor="name">Name:</label>
<input
type="text"
name="Name"
id="Name"
className={classNames("form-control",{"is-invalid":errors.Name,})}
autoComplete="off"
{...register('Name',
{ required: true,
maxLength: 15,
pattern: /^[A-Za-z]+$/
})
}
/>
<span id="name" className="text-danger fw-bold">{errors.Name?.type === "required" && "This field is required"}</span>
<span id="name" className="text-danger fw-bold">{errors.Name?.type ==="maxLength" && "Length Should be less then 15"}</span>
<span id="name" className="text-danger fw-bold">{errors.Name?.type === "pattern" && "Digits are not allow"}</span>
</div>
</div>
<div className="form-group my-3">
<label htmlFor="email">Email: </label>
<input
type="text"
name="email"
id="email"
className={classNames("form-control",{"is-invalid":errors.email,})}
placeholder="email#example.com"
autoComplete="off"
{...register('email',
{
required: true,
pattern:/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/,
})
}
/>
<span id="mail" className="text-danger fw-bold">{errors.email?.type === "required" && "Email is required"}</span>
<span id="mail" className="text-danger fw-bold">{errors.email?.type === "pattern" &&"Invalid format"}</span>
</div>
<input type="submit" id="submit" value="submit" onClick={postData} className="btn btn-success my-3" />
</form>
That is code which I try but it not working anybody review it and give your valuable comments and suggestions
Basically I want form validation using react hook form,its done but when I stuck in passing data to fire base data base
when I use, useState then its override because react hook form already store it but how to pass it to data base with out useState??
Through react hook form
You should remove your onClick from the submit button and handle your form submission from the onSubmit event on the form. Send your form data to your firebase endpoint, from your onSubmit function like so.
<input type="submit" id="submit" value="submit" onClick={postData} <-- Remove this
className="btn btn-success my-3" />
...
const onSubmit = (data) => {
// All your form fields will the converted to json object (data)
// and will be handled by hooks form
console.log(data);
// send data to firebase API
const responseRaw = fetch(
"https://your-firebase-url",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}
);
const response = responseRaw.json();
};
In an example of a Vue wizard form I tried to add form validation with Joi. How do I set this up logically? The goal is to controll the fields before moving to the second and last page with the next() method. Because of the simplicity of this wizard form, I don't want to change to VueFormWizard. To increase the code I erased a lot of fields etc..
<template>
<div>
<div v-if="errorMessage" class="alert alert-danger" role="alert">
{{errorMessage}}
</div>
<form>
<div v-if="step ===1 ">
<div class="form-group">
<label for="title">Title</label>
<input v-model="example.title"
type="text"
class="form-control"
id="title" />
</div>
<button #click.prevent="next()">Next step</button>
</div>
<div v-if="step === 2">
<div class="form-group">
<label for="userName">Email.</label>
<input v-model="example.userName"
type="email"
class="form-control"
id="userName" />
</div>
<button #click.prevent="prev()">Go back</button>
<button #click.prevent="createExample" type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</template>
<script>
import Joi from 'joi'
const schema = Joi.object().keys({
title: Joi.string().alphanum().min(2).max(40).required(),
userName: Joi.string().email(),
})
export default {
data: () => ({
step: 1,
errorMessage: false,
example: {
title: '',
userName: ''
}
}),
watch: {
example: {
handler () {
this.errorMessage = ''
},
deep: true
}
},
methods: {
prev () {
this.step--
},
next () {
this.step++
if (this.validUser()) {
return false
}
},
createExample () {
// Post request
},
validUser () {
const result = Joi.validate(this.huismap, schema)
return true
if (result.error.message.includes('title')) {
this.errorMessage = 'Vul een titel in van min 2 karakters'
return false
}
}
}
</script>
You can make use of browser validation if you set it up like this:
<form #submit.prevent="submitMyForm">
<input v-model="form.title" required minlength="4" maxlength="20" />
<button type="submit">Submit</button>
</form>
Now your browser will prevent you from submitting the form if title is empty, if the length is less than 4 or greater than 20.
This solution can do a lot of stuff, even regex checking:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation#Validating_against_a_regular_expression
However this is limited to a small set of checks and is not supported by older browsers. If you need very specific validation you'd have to use a custom solution, which is described here https://v2.vuejs.org/v2/cookbook/form-validation.html.
I am trying to create a frontend for a Spring Boot application and I chose React but I do not have much experience with React or JavaScript.
So I have a form that I am trying to use to send a post request but when I press the submit button, nothing seems to happen. I assume its my onSubmit handler that's the problem but I don't know what is wrong with it. When I send the POST request manually it works fine so I don't think it's the REST API thats causing an issue.
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
import { Link } from 'react-router-dom';
class Create extends Component {
constructor() {
super();
this.state = {
name: '',
email: '',
title: '',
description: ''
};
}
onChange = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
onSubmit = (e) => {
e.preventDefault();
const { name, email, title, description } = this.state;
axios.post('/create', { name, email, title, description })
.then((result) => {
this.props.history.push("/")
});
}
render() {
const { name, email, title, description } = this.state;
return (
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
Send Message
</h3>
</div>
<div class="panel-body">
<h4><Link to="/"><span class="glyphicon glyphicon-th-list" aria-hidden="true"></span> Message List</Link></h4>
<form onSubmit={this.onSubmit}>
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" name="name" onChange={this.onChange}/>
</div>
<div class="form-group">
<label for="email">Email:</label>
<input type="text" class="form-control" name="email" onChange={this.onChange}/>
</div>
<div class="form-group">
<label for="title">Title:</label>
<input type="text" class="form-control" name="title" onChange={this.onChange}/>
</div>
<div class="form-group">
<label for="description">Description:</label>
<input type="text" class="form-control" name="description" onChange={this.onChange}/>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
</div>
);
}
}
export default Create;
The first rule of React is, You do not update state property directly (or React wouldn't know that the state has changed).
It's not easy to tell how React would behave if you do so.
So instead of setting the state value directly,
onChange = (e) => {
const state = this.state
state[e.target.name] = e.target.value;
this.setState(state);
}
Change it like this and try to submit again.
onChange = (e) => {
const state = this.state
this.setState({[e.target.name]: e.target.value});
}
When I render an input element within my component if i set the element "value" it become read-only but if i set the value on "defaultValue" it will never update again when i re-update my state.
Here is my code :
import React from "react";
export default class EditForm extends React.Component {
editTransaction(event) {
var transaction = this.props.transaction;
event.preventDefault();
var NewTransaction = {
transactions_data: {
amount: this.refs.amount.value
}
}
this.props.editTransaction(NewTransaction, transaction.id);
}
closeForm() {
this.props.closeForm();
}
render() {
var {amount}=this.props.transaction;
return (
<div>
<br/>
<h4>Edit Transaction</h4>
<div className="btn btn-danger pull-right" onClick={this.closeForm.bind(this)}>close</div>
<div className="clearfix"></div>
<form onSubmit={this.editTransaction.bind(this)}>
<div>
<label for="amount">Amount</label>
<input value={amount} onChange={(value) => this.onChange(value)} className="form-control"
id="amount" name="amount" type="number"
ref="amount"/>
</div>
<br/>
<br/>
<input className="btn btn-info" type="submit" value="submit"/>
</form>
</div>
);
}
}
and then i found out if i make an error out of this by adding
onChange={(value) => this.onChange(value)} on my input element, it works properly ( it updating while the props or state is updating, and i can re-type the value), but i think this is not a proper solution, because it cause errors on my browser console. It is because "this.onChange" function does not exist.
How can this problem be solved?
The reason your input doesn't work is because you need to define the onChange function which actually sets the state with the updated value. You can probably do it inline since it only needs on statement like
<input type="text" value={this.state.inputVal} onChange={(e) => {this.setState({inputVal: e.target.value})}} />
However I would recommend you to use an onChange method as you can handle multiple inputs together with it and it looks cleaner
class EditForm extends React.Component {
constructor() {
super();
this.state = {
}
}
onChange(e) {
this.setState({[e.target.name]: e.target.value})
}
editTransaction(event) {
var transaction = this.props.transaction;
event.preventDefault();
var NewTransaction = {
transactions_data: {
amount: this.refs.amount.value
}
}
this.props.editTransaction(NewTransaction, transaction.id);
}
closeForm() {
this.props.closeForm();
}
render() {
return (
<div>
<br/>
<h4>Edit Transaction</h4>
<div className="btn btn-danger pull-right" onClick={this.closeForm.bind(this)}>close</div>
<div className="clearfix"></div>
<form onSubmit={this.editTransaction.bind(this)}>
<div>
<label for="amount">Amount</label>
<input value={this.state.amount} onChange={(value) => this.onChange(value)} className="form-control"
id="amount" name="amount" type="number"
ref="amount"/>
<input value={this.state.amount1} onChange={(value) => this.onChange(value)} className="form-control"
id="amount1" name="amount1" type="number"
ref="amount"/>
</div>
<br/>
<br/>
<input className="btn btn-info" type="submit" value="submit"/>
</form>
</div>
);
}
}
ReactDOM.render(<EditForm/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.0.2/react-dom.min.js"></script>
<div id="app"></div>
You need to define an onChange method, if you are using redux that could be an action that updates your component state via a reducer. An easier method using simple state with es6 is shown below. Furthermore, you are getting the value from the input field via ref which is discouraged by Facebook. This should also give you an error because you are trying to control and uncontrolled component.
Here's a link to the form documentation for further reading.
class Foo extends React.Component {
constructor(props) {
super(props);
this.state = ({
inputVal: '',
});
}
onChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
}
handleSubmit = (event) => {
event.preventDefault();
console.log(this.state.inputVal);
}
render() {
return (
<div>
<input type="text" value={this.state.inputVal} onChange={this.onChange} />
</div>
);
}
}
I was tinkering with this and found a really simple solution:
class App extends Component {
constructor(props) {
super(props)
this.enterText = this.enterText.bind(this)
this.state = {
userNameText: 'user name',
pswdText: 'pswd',
textEntry: false
}
}
async enterText() {
if (!this.state.textEntry) {
await this.clearText()
this.setState({textEntry: true})
}
}
clearText() {
this.setState({
userNameText: '',
pswdText: ''
})
}
render() {
return (
<div className="App">
<div className="App-header">
<h1 className="App-title">
Welcome
</h1>
</div>
<div className="login-fields">
<LoginFields userNameText={this.state.userNameText} pswdText={this.state.pswdText} onFocus={this.enterText} />
</div>
</div>
)
}
}
So, upon initial render(), the state of the fields are whatever is hard coded in the constructor. When the user clicks in either the name or pswd box (these could easily be separated), both are cleared with clearText() and then both are set to null with allowText(). Once set to null, the user input text is accepted.
Make sure the LoginFields component has this in the input:
onFocus={this.props.onFocus}
When you set the value on an input in React, its value will never change (unless you specify an onChange handler)
<input type="text" name="address" value="Europe" />
The end result of this element is a textbox with the value Europe that cannot be changed, so effectively, it's a read-only textbox.
Instead, when you want to provide a default value for your input field, you should use the defaultValue attribute as follows:
<input type="text" name="address" defaultValue="Europe" />
So just replace the value attribute with defaultValue
I am currently hacking around with a small front-end react project that is hitting Soundcloud's API. Very basic as of right now, I'm just taking in some user input and querying the api endpoint for related songs. For some strange reason I cannot get the enter key to submit my form and thus fire my this.handleSubmit() method. The only way I can get it to fire is to click the button my enter functionality seems to be broken. I searched around and can't find what I'm overlooking, any assistance is greatly appreciated!
import React from 'react';
import Styles from '../styles/index.js'
class SearchBar extends React.Component {
constructor(props) {
super(props);
this.initPlayer(this.props.song)
};
initPlayer(song){
SC.oEmbed(song, { auto_play: true }).then(function(song) {
document.getElementById('player').innerHTML = song.html;
});
}
handleSubmit(e){
e.preventDefault();
let term = document.getElementById('search').value
SC.get('/tracks', {
q: term
})
.then( (tracks) => {
const song = tracks[0].permalink_url;
if (tracks.length < 1) {
alert('not found!');
}
SC.oEmbed(song, { auto_play: true }).then(function(song) {
document.getElementById('player').innerHTML = song.html;
});
document.getElementById('search').value = '';
});
}
render() {
return (
<div>
<div className="col-lg-12">
<div style={Styles.playerStyle} id="player"></div>
<label htmlFor="search">Artist:</label>
<input type="text" className="form-control" id="search" />
<div className="text-center">
<form onSubmit={this.handleSubmit}>
<button type='submit' style={Styles.buttonStyle} className="btn btn-primary">Submit</button>
</form>
</div>
<div id="player"></div>
<br />
</div>
</div>
);
}
}
export default SearchBar;
form can only be submitted by enter-key when it is focus and has input|button(type="submit"). So just move input into your form.
<form onSubmit={this.handleSubmit}>
<input type="text" className="form-control" id="search" />
<button type='submit' style={Styles.buttonStyle} className="btn btn-primary">Submit</button>
</form>