how to hold file input value in react - javascript

suppose a page contains multi-stage form, in 1st stage of form contains input field for name and in second stage it contains input for file , onChange sets state values for name and file,but when we move back and forth like 1st stage to 2nd stage and sencond stage, we can hold value for input type name but how to hold value for input type file.
import React, { Component } from "react";
class App extends Component {
constructor(props) {
super(props);
this.state = {
pageone: true,
pagetwo: false,
pagethree: false,
pageonedata: "",
pagetwodata: "",
pagethreedata: ""
};
this.nextPage = this.nextPage.bind(this);
this.prevPage = this.prevPage.bind(this);
this.togglePage = this.togglePage.bind(this);
}
prevPage() {
if (this.state.pagetwo === true) {
this.setState({
pageone: !this.state.pageone,
pagetwo: !this.state.pagetwo
});
} else if (this.state.pagethree === true) {
this.setState({
pagethree: !this.state.pagethree,
pagetwo: !this.state.pagetwo
});
}
}
nextPage() {
if (this.state.pageone === true) {
this.setState({
pageone: !this.state.pageone,
pagetwo: !this.state.pagetwo
});
} else if (this.state.pagetwo === true) {
this.setState({
pagetwo: !this.state.pagetwo,
pagethree: !this.state.three
});
}
}
togglePage() {
this.setState({
pageone: !this.state.pageone,
pagetwo: !this.state.pagetwo
});
}
handleChange = e => {
this.setState({ ...this.state, [e.target.name]: e.target.value });
};
handleChange = e => {
this.setState({ ...this.state, [e.target.name]: e.target.files[0] });
};
render() {
return (
<div style={{ margin: "250px 500px" }}>
{this.state.pageone && (
<form>
<label>
<h4>page one</h4>
</label>
<input
type="text"
name="pageonedata"
value={this.state.pageonedata}
onChange={this.handleChange}
/>
</form>
)}
{this.state.pagetwo && (
<form>
<label>
<h4>page two</h4>
</label>
<input
type="file"
name="pagetwodata"
value={this.state.pagetwodata}
onChange={this.handleFile}
/>
</form>
)}
{this.state.pagethree && (
<form>
<label>
<h4>page three</h4>
</label>
<input
type="text"
name="pagethreedata"
value={this.state.pagethreedata}
onChange={this.handleChange}
/>
</form>
)}
<br />
<button
type="submit"
onClick={this.prevPage}
disabled={this.state.pageone ? true : false}
>
previous
</button>{" "}
<button
type="submit"
onClick={this.nextPage}
disabled={this.state.pagethree ? true : false}
>
next
</button>{" "}
<button
type="submit"
onClick={this.togglePage}
disabled={this.state.pagethree ? false : true}
>
finish
</button>
</div>
);
}
}
export default App;

You can't insert a file into an input element programmatically, only the user can do that, so the best way to keep the file in the input would be to set display:none; conditionally on the form instead of removing it from the DOM.
Example
class App extends Component {
// ...
handleFile = e => {
this.setState({ ...this.state, [e.target.name]: e.target.files[0] });
};
render() {
return (
{/* ... */}
<form style={{ display: this.state.pagetwo ? 'block' : 'none' }}>
<label>
<h4>page two</h4>
</label>
<input
type="file"
name="pagetwodata"
value={this.state.pagetwodata}
onChange={this.handleFile}
/>
</form>
{/* ... */}
);
}
}

You can now update the input files value using something like this example:
const fileInput = document.querySelector(`#your-input-file-id`);
const myFile = new File(['Hello World!'], 'myFile.txt', {
type: 'text/plain',
lastModified: new Date(),
});
const dataTransfer = new DataTransfer();
dataTransfer.items.add(myFile);
fileInput.files = dataTransfer.files;

Related

How to conditionally save the value of input tag?

I am trying to set value of input tag conditionally, I've two values for location state. One is coming from database and another one is coming from props. If user doesn't add his location, props value will be undefined. So, I wanted to do, something like if props value is present, then assign that value to input tag else keep location input tag as it is, i.e. value that is coming from database.
I tried with if else condition, If I don't give value of props, value of location tag is not remaining same, it is changing.
Anyone can please look into this?
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import "./stationprofile.css";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
import { getCS, updateCS } from "../fetchingData/api_calls";
class StationProfile extends Component {
constructor(props) {
super(props);
this.state = {
phone: "",
open: "",
close: "",
cost: "",
location: "",
edit: true,
error: "",
success: false
};
}
componentDidMount() {
const token = localStorage
.getItem("jwt")
getCS(token).then((data) => {
console.log(data);
this.setState((state) => ({
phone: data[0].cs_phone,
open: data[0].cs_openat,
close: data[0].cs_closeat,
cost: data[0].cs_cost,
location: data[0].cs_latitude + "," + data[0].cs_longitude,
}))
});
}
showSuccess = () => (
<div
className="alert alert-info"
style={{ display: this.state.success ? "" : "none" }}
>
Profile Updated
</div>
);
showError = () => (
<div
className="alert alert-danger"
style={{ display: this.state.error ? "" : "none" }}
>
{this.state.error}
</div>
);
handleChange = (name) => (event) => {
this.setState((state) => ({ [name]: event.target.value }));
};
clickHandler = (e) => {
this.setState({
edit: !this.state.edit
});
if (this.props.location === undefined){
this.setState({ location: this.state.location })
} else {this.setState({ location: this.props.location })};
console.log(this.props.location);
console.log(this.state.location);
};
clickSubmit = (e) => {
e.preventDefault();
// this.setState((state) => ({ location: this.state.location }));
const { phone, open, close, location, cost } = this.state;
console.log(location)
const token = localStorage
.getItem("jwt")
const lati = location[0];
const long = location[1];
updateCS({ phone, open, close, long, lati, cost }, token).then((data) => {
console.log(data);
if (
data.length == 16 ||
data == "YOU CAN ONLY ADD ONE CHARGING STATION." ||
data == "Charging Station Already Exist" ||
data == "YOU HAVE NO CHARGING STATION ADDED" ||
data == "Charging Station DOESNT Exist" ||
data == "Charging Station Already Exist" ||
data == ""
) {
this.setState({
error: data,
});
this.showError();
} else {
this.setState({
phone: phone,
open: open,
close: close,
location: location,
cost: cost,
success: true,
});
console.log("Station Updated");
}
// setTimeout(function(){ window.location.reload() }, 2000);
});
};
render() {
const buttonText = this.state.edit ? (
<Button variant="contained" color="primary">
Edit your profile
</Button>
) : (
<Button variant="contained" color="primary">
Back to profile
</Button>
);
return (
<div className="station__profile">
<div className="station__profiles">
<button onClick={this.clickHandler}>{buttonText}</button>
{this.state.edit ? (
<form className="station__container">
<h3>Station Profile</h3>
<div className="form-group">
<label>Phone Number</label>
<input
type="number"
className="form-control"
disabled="true"
placeholder={this.state.phone}
/>
</div>
<div className="form-group">
<label>Working Hours</label>
<input
type="number"
className="form-control"
disabled="true"
placeholder={this.state.open + " till " + this.state.close}
/>
</div>
<div className="form-group">
<label>Charges per Hour (in Rs)</label>
<input
type="number"
className="form-control"
disabled="true"
placeholder={this.state.cost}
/>
</div>
</form>
) : (
<form>
{this.showSuccess()}
{this.showError()}
<h3>Edit your station profile</h3>
<div className="form-group">
<label>Location</label>
<input
className="form-control"
placeholder="Location"
disabled="true"
value={this.state.location}
/>
<Button
className="station__setlocation station__location"
variant="contained"
color="primary"
>
<Link to="/map"> Set Your Location Manually</Link>
</Button>{" "}
</div>
<div className="form-group">
<label>Phone Number</label>
<input
type="number"
className="form-control"
placeholder="Enter phone number for station (optional)"
onChange={this.handleChange("phone")}
value={this.state.phone}
/>
</div>
<div className="form-group">
<label>Working Hours</label>
<div>
From:
<TextField
id="time"
ampm={false}
type="time"
defaultValue="00:00"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={this.handleChange("open")}
value={this.state.open}
/>
To:
<TextField
id="time"
ampm={false}
type="time"
defaultValue="00:00"
InputLabelProps={{
shrink: true,
}}
inputProps={{
step: 300, // 5 min
}}
onChange={this.handleChange("close")}
value={this.state.close}
/>
</div>
</div>
<div className="form-group">
<label>Charges per Hour (in Rs)</label>
<input
type="number"
className="form-control"
placeholder="Enter charges"
value={this.state.cost}
onChange={this.handleChange("cost")}
/>
</div>
<button
type="submit"
className="btn btn-primary btn-block"
onClick={this.clickSubmit}
>
Save changes
</button>
</form>
)}
</div>
</div>
);
}
}
const msp = (state) => ({
location: state.location,
});
export default connect(msp, null)(StationProfile);
If the location in props isn't strictly identical to undefined, your code will use it. If that's what's causing your error, does something like this work to choose the database's location?
const actualLocation = (this.props.location || this.state.location);
this.setState({ location: actualLocation });

Not able to type in input field

Hi I write a small component
export default class TextInput extends React.Component {
constructor(props) {
super(props);
this.onKeyPress = this.onKeyPress.bind(this);
this.state = { tags: [], value: "" };
}
onKeyPress(e) {
if (e.key === "Enter") {
this.setState({ tags: [...this.state.tags, e.target.value], value: "" });
}
}
render() {
return (
<div>
<div styleName="fieldset width-95">
<label>Tags</label>
<div>
<div>
{this.state.tags.map(tag => (
<span>{tag}</span>
))}
</div>
<input
type="text"
onKeyPress={this.onKeyPress}
value={this.state.value}
/>
</div>
</div>
</div>
);
}
}
after writing 1st time when I enter.it creates a tag but after that, I can't type anything in the input field. can anyone please explain how to enable typing so that I will be able to create another tag.
You also need an onChange handler as well to update state on user-input. Otherwise this.state.value will never update.
class TextInput extends React.Component {
constructor(props) {
super(props);
this.onKeyPress = this.onKeyPress.bind(this);
this.state = { tags: [], value: "" };
}
onKeyPress(e) {
if (e.key === "Enter") {
this.setState({ tags: [...this.state.tags, e.target.value], value: "" });
}
}
handleOnChange = e => {
this.setState({
value: e.target.value
});
};
render() {
return (
<div>
<div styleName="fieldset width-95">
<label>Tags</label>
<div>
<div>
{this.state.tags.map(tag => (
<span>{tag}</span>
))}
</div>
<input
type="text"
onChange={this.handleOnChange}
onKeyPress={this.onKeyPress}
value={this.state.value}
/>
</div>
</div>
</div>
);
}
}
See working sandbox: https://codesandbox.io/s/serene-https-t02h2
The problem is that you forgot to add an onClick event for the input, this will handle when you type something in it (You only need to update the state every time the onChange event is fire), like this (I've also made an update to a more ES6 syntax):
import React, { Component } from 'react';
export default class TextInput extends Component {
state = { tags: [], value: "" };
onKeyPress = e => {
if (e.key === "Enter") {
this.setState({ tags: [...this.state.tags, e.target.value], value: "" });
}
};
onClick = e => {
if (e && e.target && e.target.value) {
this.setState({ value: e.target.value });
}
};
render() {
const { tags, value } = this.state;
return (
<div>
<div styleName="fieldset width-95">
<label>Tags</label>
<div>
<div>
{tags.map(tag => (
<span>{tag}</span>
))}
</div>
<input
type="text"
onChange={this.onClick}
onKeyPress={this.onKeyPress}
value={value}
/>
</div>
</div>
</div>
);
}
}
You can try below code.And you remove value which you are set on state.And use onChange method.
import React, { Component } from 'react';
export default class TextInput extends React.Component {
constructor(props) {
super(props);
this.onKeyPress = this.onKeyPress.bind(this);
this.state = { tags: [] };
}
onKeyPress(e) {
if (e.key === "Enter") {
this.setState({ tags: [...this.state.tags, e.target.value], value:
e.target.value });
console.log("tag:",this.state.tags)
}
}
handleInputChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
render() {
return (
<div>
<div styleName="fieldset width-95">
<label>Tags</label>
<div>
<div>
{this.state.tags.map(tag => (
<span >{tag}</span>
))}
</div>
<input
type="text"
onKeyPress={this.onKeyPress}
name="demo"
value={this.state.value}
onChange={this.handleInputChange}
/>
</div>
</div>
</div>
);
}
}

i want to use 2 function in onChange

import React, { Component } from "react"; import { Link } from
"react-router-dom";
const emailRegx = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
export default class ChefInfo extends Component { constructor(props) { super(props); this.state = { eInput: "",
small: "" };
-
----------
---------
}
handleChange = e => {
this.setState({
eInput: e.target.value
});
};
emailTest = () => {
if (emailRegx.test(this.state.eInput) === false) {
this.setState({
small: "your email is inccorect"
});
} else {
this.setState({
small: ""
});
}
};
render() {
return (
<div className="big-parent">
<form>
<div className="input">
<label>
<strong>E-mail</strong>
</label>
<input
type="email"
className="input-filed"
onChange={() => { //here the problem
this.handleChange();
this.emailTest();
}}
/>
<small className="small">{this.state.small}</small>
</div>
</form>
<a href="#" className="btn btn-dark button">
<strong>READY</strong>
</a>
</div>
);
} }
Your handlechange use event object parameter.
So you should pass event object.
onChange={(e) => { //here the problem
this.handleChange(e);
this.emailTest();
}}
But in this case, you don't need to use two function.
This is enough.
handleChange = (e) => {
this.setState({
eInput : e.target.value,
small : emailRegx.test(e.target.value) ? '' : "your email is incorrect"
})
};
You can refactor you code such that it looks like this. This make your render/template code look cleaner.
handleEvent(event) {
this.handleChange(event);
this.emailTest();
}
.
.
.
<input
type="email"
className="input-filed"
onChange={this.handleEvent}
/>

Checking if input is empty on form validation, why is it always false?

I am trying to run a function on a Todo list that when a todo is added. A function will check the input box to check if its empty and if its empty, not do anything.
However, after using the function to check if the input is empty, it always returns False even when its empty. Where is the bug here?
The function name in question is "checkInput()" and it runs from the main submit button on the page
import React from "react";
import "./App.css";
import { isTemplateElement } from "#babel/types";
class TodoListt extends React.Component {
state = {};
constructor(props) {
super(props);
this.state = {
userInput: "",
list: [],
};
}
changeUserInput(input) {
this.setState({
userInput: input
})
}
addToList() {
const { list, userInput } = this.state;
this.setState({
list: [...list, {
text: userInput, key: Date.now(), done: false
}],
userInput: ''
})
}
handleChecked(e, index) {
console.log(e.target.checked);
const list = [...this.state.list];
list[index] = { ...list[index] };
list[index].done = e.target.checked;
this.setState({
list
})
}
checkInput() {
console.log(this.state.userInput);
userInput: '' ? console.log("True") : console.log("False")
}
render() {
return (
<div className="to-do-list-main">
<input
onChange={(e) => this.changeUserInput(e.target.value)}
value={this.state.userInput}
type="text"
/>
<button onClick={() => { this.checkInput(); { this.addToList(this.state.userInput) } }}>Add todo</button>
{this.state.list.map((list, index) => (
<div className="form">
<ul>
<li><input type="checkbox" onChange={(e) => this.handleChecked(e, index)} />
<span style={{ textDecoration: list.done ? 'line-through' : 'inherit' }}>
{list.text}
</span>
</li>
</ul>
</div>
))}
</div>
);
}
}
export default TodoListt;

enable button to submit only when all the fields are filled

I have a form which has 3 field. First two fields are email_from and email_subject and the last field is an editor. I have used draftjs for editor. If there is no editor i could enable and disable the submit button but due to the inclusion of the editor i did not know how can i enable the button only when all the fields are filled with no error.
Here is my code.
AdminEditor is the component which has draftjs editor
class EmailTemplate extends React.Component {
state = {
emailSubject: '',
emailFrom: ''
};
handleChange = event =>
this.setState({ [event.target.name]: event.target.value });
handleSubmit = event => {
event.preventDefault();
};
render() {
const { emailSubject, emailFrom } = this.state;
return (
<form onSubmit={this.handleSubmit}>
<FieldGroup
id="formControlsText"
name="emailSubject"
type="text"
label="Email Subject"
placeholder="Enter Email Form"
onChange={this.handleChange}
validationState={emailSubject ? 'success' : 'error'}
required
/>
<FieldGroup
id="formControlsText"
name="emailFrom"
type="email"
label="Email From"
placeholder="Enter Email From"
onChange={this.handleChange}
validationState={emailFrom ? 'success' : 'error'}
required
/>
<AdminEditor />
<Button type="submit">
Submit
</Button>
</form>
);
}
}
export default EmailTemplate;
class AdminEditor extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
isEmpty: true
};
}
onEditorStateChange = editorState => {
this.setState({
editorState
});
};
onEditorChange = editorContent => {
this.setState({
editorContent
});
};
handleChange = event =>
this.state.editorState.getCurrentContent().hasText()
? this.setState({ isEmpty: false })
: this.setState({ isEmpty: true });
render() {
const { editorState } = this.state;
return (
<div>
<Editor
editorState={this.state.editorState}
initialContentState={rawContentState}
toolbarClassName="home-toolbar"
wrapperClassName="home-wrapper"
editorClassName="home-editor"
onEditorStateChange={this.onEditorStateChange}
toolbar={{
textAlign: { inDropdown: true },
}}
onContentStateChange={this.onEditorChange}
placeholder="write text here..."
onChange={this.handleChange}
/>
</div>
);
}
}
export default AdminEditor;
Can anyone please help me?
There are many ways to do this, mostly based around passing some callbacks down into the controlled component which updates the state in the parent.
A simple way would be to pass a handler that sets a flag if the editor is empty or not:
class AdminEditor extends React.PureComponent {
...
handleChange = event =>
this.props.setEditorIsEmpty(
this.state.editorState.getCurrentContent().hasText()
);
Then in EmailTemplate:
setEditorIsEmpty(editorIsEmpty) {
this.setState({
editorIsEmpty
});
}
render() {
const { emailSubject, emailFrom } = this.state;
return (
<form onSubmit={this.handleSubmit}>
...
<AdminEditor
setEditorIsEmpty={this.setEditorIsEmpty}
/>
<Button
type="submit"
disabled={!emailSubject || !emailFrom || editorIsEmpty}>
Submit
</Button>
</form>
);
}

Categories

Resources