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>
Related
When I run the code the buttons don't work unless I take out onChange. I can add () to the end of my functions inside the on click but that makes them run on every key stroke. How do I fix this. It wont't let me post my question without more text so I am going to add some dummy text to post.
import React, { useState } from "react";
export default function Username(props) {
const [userName, setUsername] = useState('');
let userToken
const address = props.address;
function handleChange(event) {
setUsername(event.target.value);
}
function loginAccount() {
console.log('account created');
}
function createAccount() {
console.log('logged in');
}
function hi(){
console.log('hi');
}
while (userToken == null)
return (
<>
<div>
<p className = "account-Info" >address: {address}</p>
</div>
<div id="form">
<h2 className='user-Create' > Username </h2>
<form id='set-User'>
<input id='username' className="user-Create" type='text' value={userName} onChange={handleChange}
required minLength='3' maxLength='30' pattern="[a-zA-Z0-9_]+" title='only letters, numbers, and underscores.'/>
<button className='user-Create' onClick={loginAccount}>Create Account</button>
<button className='user-Create' onClick={createAccount}>Login</button>
<button className='user-Create' onClick={hi}>hi</button>
</form>
</div>
</>
);
while (userToken)
return(
<p>hello</p>
);
}
Set type="button" for each button inside your form
<button className='user-Create' type="button" onClick={loginAccount}>Create Account</button>
<button className='user-Create' type="button" onClick={createAccount}>Login</button>
<button className='user-Create' type="button" onClick={hi}>hi</button>
format like this
const FunctionName = (e) => {
console.log('account created');
I have an input and a button and it seems that it cannot detect the value of the input. I didn't use any form tag and I am wondering if that is the cause. What am I missing here? Many thanks in advance and greatly appreciated.
<div className="input-group mb-3">
<input type="text" className="form-control" placeholder="add a post"/>
<div class="input-group-append">
<button type="submit" class="btn btn-primary" onClick={(e) => {
makePost(e.target[0].value, item._id)}} type="button">Post</button>
</div>
</div>
e.target gives you the reference for the button, and no data of the form can be found there.
You have duplicate type property type="submit" and type="button", type=submit will submit the form, and type=button is just a button.
If you don't want to use React's state, which you probably should anyway. https://reactjs.org/docs/hooks-state.html, you can wrap your input elements in a form element and attach an onSubmit handler for the form. Change the button's type to submit (remember to add preventDefault(), so it won't "POST" the form automatically).
Then in your e.currentTarget you will have access to all the elements inside the form.
const Test = () => {
const onFormSubmit = (e) => {
e.preventDefault();
e.stopPropagation();
const formData = new FormData(e.currentTarget);
for (let [name, value] of formData.entries()) {
/* makePost function here or something */
console.log(name + ":" + value);
}
}
return (
<form onSubmit={onFormSubmit}>
<div className="input-group mb-3">
<input type="text" className="form-control" name={"id_maybe"} placeholder="add a post"/>
<div class="input-group-append">
<button type="submit" class="btn btn-primary">Post</button>
</div>
</div>
</form>
);
}
ReactDOM.render(<Test />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
I think this is what you're looking for
import React, { useState } from "react";
import "./style.css";
export default function App() {
const [value, setValue] = useState("");
const [posts, setPosts] = useState([]);
const onSubmit = () => {
posts.push(value);
setPosts([...posts]);
setValue("");
};
const handleInput = e => {
setValue(e.target.value);
};
return (
<div className="input-group mb-3">
<input
type="text"
className="form-control"
placeholder="add a post"
value={value}
onChange={handleInput}
/>
<div class="input-group-append">
<button class="btn btn-primary" onClick={onSubmit}>
Add Post
</button>
</div>
{posts.map(post => (
<div>{post}</div>
))}
</div>
);
}
e.target[0].value doesn't work. You cannot find the 0th element of e.target. Instead of doing that, you could try directly accesing value using e.target.value instead.
I don't think you're doing it the right way. With all due respect, your code is pretty sloppy. First of all, you have no <form> element. Second, you're doing this in a pretty weird way. Instead of using a separate function, you directly insert an arrow function into button.
You should also use State and add this in your constructor:
this.state = {
items: [],
text: ""
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
First of all, add an handleChange button here:
handleChange(event) {
this.setState({ text: event.target.value });
}
You can use something like this for your submit function:
handleSubmit(event) {
event.preventDefault();
const newItem = {
text: this.state.text,
id: performance.now()
};
this.setState(state => ({
items: state.items.concat(newItem),,
text: ""
}));
}
Change this in your render function:
<form>
<input type="text" className="form-control" onChange= {this.handleChange} value={this.state.text} placeholder="add a post"/>
<div class="input-group-append">
<button type="submit" class="btn btn-primary" onClick={this.handleSubmit}>Post</button>
</div>
</form>
You seem to be a newcomer to React, so why don't you read the React Tutorial?
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.
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