I'd like to generate some HTML to show sucessfull form submission. I can't seem to do it within the handleSubmit Method.
class BookingForm extends Component{
...
handleChange(event) {
const target = event.target;
const value = target.value;
const name = target.name;
console.log(name + ' '+value);
this.setState({
[name]: value
});
}
Submit method that I'd like to render html:
handleSubmit(event) {
console.log(this.state.lessonTime)
event.preventDefault();
this.setState({'success':true})
return(
<h1>Success</h1>
);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<TimeList defaultTime={this.state.defaultTime}
handleChange={this.handleChange}/>
<br/>
<DateList defaultDate={this.state.defaultDate}
handleChange={this.handleChange}/>
<br/>
<NumberOfLessons defaultNOL={this.state.defaultLessons}
handleChange={this.handleChange}/>
<br/>
<input type="submit" value="Book Lesson" />
</form>
<br/>
</div>
);
}
}
Any ideas on how I can get the success heading to show once submit has been clicked on.
Thanks
I think a better way to handle this is to use state to control the rendering of "success" heading. You can add the following line of code to the place you want to add the header:
{this.state.success && <div> Successful </div> }
I think the reason the html tag returned by handleSubmit in your function doesn't show up is because although it returns the tag, it doesn't know where to put it. If you want to make it work, you'll need to use methods like createElement and appendChild but that's not the way react should work.
If you want your <h1> element to render instead of form on successful completion do this in your render function:
render() {
return (
<div>
{this.state.success?(
<h1>Success</h1>
):(
<form onSubmit={this.handleSubmit}>
<TimeList defaultTime={this.state.defaultTime}
handleChange={this.handleChange}/>
<br/>
<DateList defaultDate={this.state.defaultDate}
handleChange={this.handleChange}/>
<br/>
<NumberOfLessons defaultNOL={this.state.defaultLessons}
handleChange={this.handleChange}/>
<br/>
<input type="submit" value="Book Lesson" />
</form>
<br/>)}
</div>
);
}
Related
I am sending a POST request to an endpoint in react using axios and if my returned response is successfull I am setting some state.
Here is my code:
axios.post('/some/endpoint', {mydata})
.then(res => {
console.log(res.data);
if(res.data.success)
{
setMsg('successful');
setActive('alert alert-success fade-out');
}
else
{
setMsg('Oops! An error occured!');
setActive('alert alert-danger');
}
})
After the first API request, everything is fine, I get the message and it fades out, Although If I try to send another request, It doesn't appear again and start to fade out, Why isn't the setMsg and setActive calls firing?
Heres the render:
return (
<>
<Modal open={open} onClose={onCloseModal} center closeIcon={closeIcon} modalId="response-modal">
<div className="qr-modal-header-stock">
<h5>Enter fulfillment stock</h5>
<p>{title}</p>
<p>Fulfilment Center: {fulfilmentCenterName}</p>
<p>Existing stock: {stock}</p>
<p className={active} style={{opacity:0}}>{msg}</p> <-- this appears firstly but not the second time when I submit the form, why?
<form onSubmit={handleSubmit}>
<input type="hidden" name="ean" value={data} />
<input type="hidden" name="product_stock" value={newStock} />
<input type="number" class="form-control" onChange={e => setNewStock(parseInt(e.target.value) + parseInt(stock))}/> <br />
<input type="submit" class="btn btn-primary form-control" id="submit-fulfilment-center" value="Save"/>
</form>
<br />
<p>New stock: {isNaN(newStock) ? 0 : newStock}</p>
<button className="btn btn-primary" onClick={onCloseModal}>Scan another ean</button>
</div>
</Modal>
</ >
);
You should use "useState" hook and watch "Msg" and "Active" states for changes.
useState(()=>{
// do somthing here
},[Msg,Active])
using this will re-render the page every time the value of "Msg" or "Active" changes.
Notice : Do Not set states and watch them in the same useState hook , this will will cause an infinite rendring loop
I'm trying to submit a form with a form action. However the submit takes quite a long time, so I'm trying to show a loading message while the form is submitting, telling the user to wait on the screen and they'll be redirected afterwards. The problem is, when I show the loading screen, the form submit no longer works. I've narrowed it down due to the fact that the submit button that triggered the event no longer exists, thus it won't submit. Is there a way to show the loading screen and ensure the submit action goes through?
handleSubmit = () => {
...
this.setState({isLoading: true});
...
this.formRef.current.submit();
}
<form ref={this.formRef} action="https://www.google.com" method="post">
{isLoading ? (
this.renderLoading()
) : (
<>
<input type="text">input</input>
<button type="submit" onClick={this.handleSubmit}>button<button>
</>
</form>
I have tried the below solution and it works successfully, however, I don't want the button to be shown in the loading screen.
handleSubmit = () => {
...
this.setState({isLoading: true});
...
this.formRef.current.submit();
}
<form ref={this.formRef} action="https://www.google.com" method="post">
{isLoading ? (
this.renderLoading()
) : (
<>
<input type="text">input</input>
</>
<button type="submit" onClick={this.handleSubmit}>button<button>
</form>
Is there a way to make this work without showing the button in the loading screen?
Hide the controls rather than killing them:
handleSubmit = () => {
...
this.setState({isLoading: true});
...
this.formRef.current.submit();
}
<form ref={this.formRef} action="https://www.google.com" method="post">
<>
{ isLoading && this.renderLoading() }
<input type="text" className={isLoading ? 'hidden' : ''}>input</input>
<button type="submit" onClick={this.handleSubmit} className={isLoading ? 'hidden' : ''}>button<button>
</>
</form>
css for hidden class is display: none
So iv been stuck for quite some time now, i need to make my delete button work on every row and make inputs spit info to my table.
My question is : Is it even possible to do it? (I just started to learn react/js literally today).
The final product should look like "to do list" but when i open it it automatically has values from api that i can delete and add new.
My code:
export default class FetchRandomUser extends React.Component {
state = {
loading: true,
people: []
};
async componentDidMount() {
const url = "https://swapi.dev/api/people/";
const response = await fetch(url);
const data = await response.json();
const pirmadata = data;
this.setState({ people: pirmadata.results, loading: false });
console.log(pirmadata)
}
render() {
if (this.state.loading) {
return <div>loading...</div>;
}
if (!this.state.people.length) {
return <div>didn't get a person</div>;
}
return (
<div className="listas">
{this.state.people.map(person => (
<tr className="taras" key={person.name + person.age}>
<th className="name">{person.name}</th>
<th className="birth">{person.birth_year}</th>
<th className="genders">{person.gender}</th>
<th><button type="submit" className="delete">Delete</button></th>
</tr>
))}
</div>
);
}
}
My form is made on different .js file and basically is a function which holds this form:
<div className="forma">
<form>
<input type="text" placeholder="Enter name :"></input>
<input type="text" placeholder="Enter birth date :"></input>
<input type="text" placeholder="Enter gender :"></input>
<button type="submit">Submit entry!</button>
</form>
</div>
Add a click handler for the Delete button that is the onSubmit handler of the form element. That way when you click it, it will call the form's handler function.
Pass the handlerFunc to the component with the th elements as a prop to be able to use it as the following:
function YourComponent({ handler }){
return <th><button onClick={handler} className="delete">Delete</button></th>);
}
Form onSubmit handler:
<form onSubmit={handlerFunc}>
<input type="text" placeholder="Enter name :"></input>
<input type="text" placeholder="Enter birth date :"></input>
<input type="text" placeholder="Enter gender :"></input>
<button type="submit">Submit entry!</button>
</form>
<YourComponent handler={handlerFunc} />
I have a stateless react component that is a little pop up. It takes some data from the user, and passes that back to its parent, where it executes the work.
What is the best way for this component to have a handleSubmit() function, that takes the user input, and sends it back to the parent?
import React, { Component } from "react";
import "../../../node_modules/bulma/css/bulma.css";
const Transfer = (props, token, web3) => {
return (
<div className="modal is-active">
<div className="modal-background" onClick={props.onClick} />
<div className="modal-card">
<section className="modal-card-body">
<div className="content">
<h1 className="title"> Transfer Tokens </h1>
<p className="has-text-danger">
Requires that you are the owner of the token you are transferring
</p>
<p className="subtitle">How it works</p>
<p className="">
Enter the ID of the token you want to transfer, the address to
whom its going to, and thats it!
</p>
//problem area
<form onSubmit={props.onClickSubmit}>
<label htmlFor="text">Address to recieve token</label>
<input
name="Address"
className="input is-info "
required="true"
/>
<label htmlFor="number">Token ID</label>
<input
className="input is-info"
name="Token ID"
type="number"
required="true"
/>
<a className="button is-pulled-right">Submit</a>
</form>
</div>
</section>
<footer className="modal-card-foot is-clearfix">
<a className="button" onClick={props.onClick}>
Cancel
</a>
</footer>
</div>
</div>
);
};
export default Transfer;
I pass in as a prop, onClickSubmit, in my parent component, and that contains the logic for what I'm trying to do.
Very new to stateless react components
It will be difficult to accomplish what you want with a stateless component since you cannot use either refs or state in a stateless component. You can think of a stateless component as a pure function that returns a piece of UI depending on the props you give it.
You could instead use a stateful component and e.g. store the input values in state and call the onClickSubmit prop function with this state when the user submits the form.
If you want to build stateless forms component, I send you a lib that I'm working on:
react-distributed-forms
This allow you to build your Transfer Component this way, (pay attention to use Input instead of input and Button instead of button):
import React, { Component } from "react";
import "../../../node_modules/bulma/css/bulma.css";
import { Input, Button } from "react-distributed-forms";
const Transfer = (props, token, web3) => {
return (
<div className="modal is-active">
<div className="myForm">
<label htmlFor="text">Address to receive token</label>
<Input name="Address" className="input is-info " required="true" />
<label htmlFor="number">Token ID</label>
<Input
className="input is-info"
name="Token ID"
type="number"
required="true"
/>
<Button name="submit" className="button is-pulled-right">
Cancel
</Button>
</div>
</div>
);
};
export default Transfer;
And then in your parent Component, wherever it is in the hierarchy, you simply do:
<Form onSubmit={({ name }) => { console.log(name); }} onFieldChange={({ name, value} ) => { console.log(name, value); }}>
...whatever
<Transfer />
...whatever
</Form>
onFieldChange will receive every input change.
onSubmit will receive the attribute "name" on the Button when you click it.
react-distributed-forms use React context API, so you don't have to pass directly props, it just works. Is built for really dynamic forms...
I have component that renders jsx like this
<section>
<div>
<input type="text" class="hide" />
<button id={item.uniqueID}>show input</button>
</div>
<div>
<input type="text" class="hide" />
<button id={item.uniqueID}>show input</button>
</div>
<div>
<input type="text" class="hide" />
<button id={item.uniqueID}>show input</button>
</div>
</section>
I want this behavior, when I click the button in the first div, the input in the first div will show. Similarly, I click the button in the third div the input in third div will show.
How you do that in react?
If it were me I would make a new component out of:
show input
Lets call it <InputToggler/>
and then it would have a state of inputHidden for its own input and use classes to determine if it should show or not and the button would have an onclick handler to toggle the state of hidden or shown. Here is a pen showing exactly that
http://codepen.io/finalfreq/pen/VKPXoN
class InputToggler extends React.Component {
constructor() {
super();
this.state = {
inputHidden: true
}
}
toggleInput = () => {
this.setState({
inputHidden: !this.state.inputHidden
})
};
render() {
const inputClass = this.state.inputHidden ? 'hide' : '';
const buttonLabel = this.state.inputHidden ? 'show input' : 'hide input'
return (
<span>
<input type="text" className={inputClass} />
<button onClick={this.toggleInput} id={this.props.item.uniqueID}>
{buttonLabel}
</button>
</span>
)
}
}
This is the concept not the exact code.
Each button should have onClick with callback to a function ex. toggleShow
<button id={item.uniqueID} onClick={this.toggleShow.bind(this)}>show input</button>
toggleShow do something like:
toggleShow(e){
var item = e.target.id;
this.setState({inputClassName1: "hide"})
at the same time the input field classname should refer to the state
Note that I omitted the fact that you have multiple objects, you may want to handle their references in arrays.