React mui button input file not opening local machin file directory - reactjs

I am trying to implement a button as an input field of file type, I have tried to wrap the input field with the button, and hide it. But, this is not working since nothing happens when I click on the button. I don't get the dialog to choose the files from the local machine. This is my component:
class MediaPlaceholder extends Component {
constructor(props){
super(props)
this.state = {
file: null
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
file: URL.createObjectURL(event.target.files[0])
})
}
render() {
const {classes} = this.props;
return (
<Paper className={classes.media}>
<div>
<label htmlFor="upload-file">
<Button onClick={event => this.handleChange(event)}>
Add media...
<input
accept="image/*"
className={classes.input}
id="upload-file"
type="file"
/>
</Button>
</label>
</div>
</Paper>
);
}
}
I saw in few places that this is the suggested solution, so I am wondering why is it not working?

From the Material-UI docs/example https://material-ui.com/components/buttons/#contained-buttons :
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
/>
<label htmlFor="contained-button-file">
<Button variant="contained" component="span" className={classes.button}>
Upload
</Button>
</label>
So you could try :
class MediaPlaceholder extends Component {
constructor(props){
super(props)
this.state = {
file: null
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
file: URL.createObjectURL(event.target.files[0])
})
}
render() {
const {classes} = this.props;
return (
<Paper className={classes.media}>
<div>
<input
accept="image/*"
className={classes.input}
id="upload-file"
type="file"
/>
<label htmlFor="upload-file">
<Button onClick={this.handleChange.bind(this)}>
Add media...
</Button>
</label>
</div>
</Paper>
);
}
}

Related

Show images in a Reactjs page only when a variable has a particular value

I have the following simple code that has a small radio button selection and it shows two images at the bottom of the form. I would like this code to show NO images when it loads and, depending on the selection being made in the radio button choice, just show the single image that represents the selection. Basically a virtual if this.state.programmingmodel === 'event-driven' then <HoverImage src={longrunning} hoverSrc={longrunninghover} /> (and same thing for eventdriven).
I have tried to play with adding an onSubmitForm syntax to the <HoverImage> section(s) but it didn't really work out. I don't think I need to create another "event" because I want to re-use the onSubmit event.
import React, { Component } from "react";
import "./index.css"
import HoverImage from "react-hover-image";
import longrunning from './longrunning.jpg';
import longrunninghover from './longrunninghover.jpg';
import eventdriven from './eventdriven.jpg';
import eventdrivenhover from './eventdrivenhover.jpg';
class App extends Component {
constructor() {
super();
this.state = {
programmingmodel: "long-running"
};
}
onValChange = (event) => {
this.setState({
[event.target.name]: event.target.value,
});
};
onCheckValChange = (e) => {
this.setState({ [e.target.name]: e.target.checked });
};
onSubmitForm = (event) => {
event.preventDefault();
console.log("state", this.state);
};
render() {
return (
<div className="App">
<h1>Containers product selection </h1>
<form onSubmit={this.onSubmitForm}>
<br/>
<b> Programming model </b>
<br/>
<label>
<input
type="radio"
name="programmingmodel"
value="long-running"
checked={this.state.programmingmodel === 'long-running'}
onChange={this.onValChange}
/>
<span>Long-running </span>
</label>
<label>
<input
type="radio"
name="programmingmodel"
value="event-driven"
checked={this.state.programmingmodel === 'event-driven'}
onChange={this.onValChange}
/>
<span>Event-driven </span>
</label>
<br/>
<button type="submit">Submit</button>
<br/>
</form>
<br/>
<HoverImage src={longrunning} hoverSrc={longrunninghover} />
<br/>
<HoverImage src={eventdriven} hoverSrc={eventdrivenhover} />
</div>
);
}
}
export default App;
You only have to check for the status of your state and decide which component to render. I've removed the form, and some unused code, as it's not needed.
like this:
class App extends React.Component {
constructor() {
super();
this.state = {
programmingmodel: "long-running"
};
}
onValChange = (event) => {
this.setState({
[event.target.name]: event.target.value
});
};
onCheckValChange = (e) => {
this.setState({ [e.target.name]: e.target.checked });
};
render() {
return (
<div className="App">
<h1>Containers product selection </h1>
<b> Programming model </b>
<br />
<label>
<input
type="radio"
name="programmingmodel"
value="long-running"
checked={this.state.programmingmodel === "long-running"}
onChange={this.onValChange}
/>
<span>Long-running </span>
</label>
<label>
<input
type="radio"
name="programmingmodel"
value="event-driven"
checked={this.state.programmingmodel === "event-driven"}
onChange={this.onValChange}
/>
<span>Event-driven </span>
</label>
{this.state.programmingmodel === "long-running" ? (
<HoverImage src={longrunning} hoverSrc={longrunninghover} />
) : (
<HoverImage src={eventdriven} hoverSrc={eventdrivenhover} />
)}
</div>
);
}
}
Regarding the loading state, I would do it on the parent component and wouldn't mix the logics.

Not able to update form data in React

I am using react to accept input from the user. And when the user submits I want to get rid of the form and display the user input data.
I am not able to see the user input data on my result page. I have uploaded the screenshots and the code below.
class Form extends React.Component {
constructor(props){
super(props)
this.state = {isFormOn: true, isResult: false , firstname: "", lastname: ""};
this.handleClick = this.handleClick.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleClick(){
this.setState(state => ({
isFormOn: !state.isFormOn,
isResult: !state.isResult
}));
}
handleChange({ event }) {
this.setState({
[event.target.name]: event.target.value
});
}
render(){
return(
<div>
{ this.state.isFormOn && (
<div>
First name :
<input type="text" name="firstname" onChange={this.handleChange} /><br />
Last name :
<input type="text" name="lastname" onChange={this.handleChange} /><br />
<br />
<button onClick={this.handleClick}>
{this.state.isFormOn ? 'ON' : 'OFF'}
</button>
</div>
)}
{ this.state.isResult && (
<div>
<h4>The name entered is : {this.state.firstname} {this.state.lastname} </h4>
<button onClick={this.handleClick}>
{this.state.isFormOn ? 'ON' : 'OFF'}
</button>
</div>
)}
</div>
);
}
}
ReactDOM.render(
<Form />,
document.getElementById('root')
);
Render form to accept user input
Result of the user entered information
Your event handler (handleChange) is destructuring the event object, and trying to extract a property called event from it, which doesn't exist.
You need to use the event object directly instead:
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}

Browser not previewing image that was previously uploaded

I have a component in React that is responsible for image preview. I also have an option for removing the image. I have noticed that if I have uploaded an image, and then removed it, that I can't preview it if I want to upload it again. Why is that happening?
This is my component:
class MediaPlaceholder extends Component {
constructor(props) {
super(props)
this.state = {
fileUrl: null
}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({
fileUrl: URL.createObjectURL(event.target.files[0])
})
}
removeImage() {
this.setState((prevState) => {
URL.revokeObjectURL(prevState.fileUrl);
return {fileUrl: null};
});
}
render() {
const {classes} = this.props;
const {fileUrl} = this.state;
return (
<Paper className={classes.media}>
{fileUrl &&
<div className={classes.imageWrapper}>
<IconButton aria-label="Clear" className={classes.iconButton} onClick={() => this.removeImage()}>
<ClearIcon/>
</IconButton>
<img src={fileUrl} className={classes.image}/>
</div>
}
<input
accept="image/*"
className={classes.input}
id="upload-file"
type="file"
onChange={(event) => this.handleChange(event)}
/>
<label htmlFor="upload-file">
<Button component="span">
Add media...
</Button>
</label>
</Paper>
);
}
}

React form with <Popup> alert message instead of alert()

I am trying to create a contact form in React. It sends the email. Everything is working fine. What I would like to achieve is to replace the alert('') with a better looking < Popup> message using react Popup package.
Here is the code:
import React, { Component } from 'react';
import '../css/Contact.css';
import axios from 'axios';
import Popup from "reactjs-popup";
class Contact extends Component {
constructor(props) {
super(props);
this.state = {
name: '',
email: '',
message: '',
isValid: false
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.validationCheck = this.validationCheck.bind(this);
}
handleChange = (event) => {
const name = event.target.id;
const value = event.target.value;
this.setState ({ [name] : value});
}
validationCheck () {
if((this.state.name.length)>3 &&
(this.state.message.length)>5 &&
(this.state.email.length)>7 &&
(this.state.email.includes("#")) &&
(this.state.email.includes(".")) &&
((this.state.name || this.state.message || this.state.message)!=0)
)
{
this.setState({ isValid: true});
this.forceUpdate();
};
}
async handleSubmit (event) {
this.validationCheck();
this.forceUpdate();
if ((this.state.isValid) === true) {
event.preventDefault();
const { name, email, message } = this.state;
const form = await axios.post('/api/form', {
name,
email,
message
});
alert('thank you for your message');
event.target.reset();
}
else {
event.preventDefault();
alert('you might have entered something wrong');
}
}
render() {
return (
<div className="contact">
<h1>Contact Me</h1>
<form id="form" onSubmit={this.handleSubmit}>
<div>
<label htmlFor="Name" className="badge badge-secondary">Name</label>
<input
onChange={this.handleChange} id="name" className="form-control" placeholder="Enter your name here."/>
</div>
<div>
<label htmlFor="Email" className="badge badge-secondary">Email address</label>
<input
onChange={this.handleChange}
id="email"
className="form-control"
placeholder="Enter your e-mail address here." />
</div>
<div className="">
<label htmlFor="Message" className="badge badge-secondary">Message</label>
<textarea
onChange={this.handleChange} rows="4"
className="form-control" id="message" placeholder="Enter your message here."></textarea>
</div>
<button
type="submit"
form="form"
className="btn btn-secondary btn-lg button"
id="submit"
value="Submit"> Send! </button>
</form>
<hr />
<button type="button" className="btn btn-outline-info" onClick={this.props.scrollToTop}>
Scroll me back to the top!</button>
</div>
);
}
}
export default Contact;
I have tried to replace 'alert('thank you for your message');' with return(< Popup>); but that is clearly not a way forward.
Here's a way how you can exactly use a reactjs-popup:
import React from "react";
import Popup from "reactjs-popup";
export default () => (
<Popup trigger={<button> Trigger</button>} position="right center">
<div>Popup content here !!</div>
</Popup>
);
All you need to do is put a trigger for it and it'll work
For help: https://react-popup.netlify.com/

I cannot close the modal and dimmer in semantic - using react

I'm trying to get a modal to close in react, using semantic modal. For some reason, I can get the form to close, but the dimmer remains. I need help.
I have tried $('.ui.modal').modal('hide dimmer') and many number of other things.
Modal is here:
export default class AddCamerModal extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<Modal
id="add-camera-form"
trigger={<Button id="color-0093ee border-color-0093ee"
basic
icon="video-camera"
size="large"></Button>}
>
<Header icon='cube' content='New Object' />
<Modal.Content>
<AddCameraForm />
</Modal.Content>
</Modal>
)
}
Form is here:
export default class AddCameraForm extends React.Component {
constructor(props) {
super(props);
}
closeModal() {
$('.modal').modal('hide');
}
render() {
return (
<Form size="large">
<Form.Group widths="equal">
<Form.Field label='Name' control='input' placeholder='Name' name="name" id="name" required />
</Form.Group>
<Form.Group>
<Button type='submit' className="submit" onClick={this.handleSave}>Save</Button>
<Button type='deny' className="deny" onClick={this.closeModal}>Cancel</Button>
</Form.Group>
</Form>
)
}
}
You should pass 'open' prop false to your modal. You can do it via state or via props. For example:
export default class AddCamerModal extends React.Component {
constructor(props) {
super(props);
this.closeModal=this.closeModal.bind(this)
state={ isOpen: true }
}
closeModal() {
this.setState({isOpen: !this.state.isOpen});
}
render() {
return (
<Modal
open={this.props.open}
id="add-camera-form"
trigger={<Button id="color-0093ee border-color-0093ee"
basic
icon="video-camera"
size="large"></Button>}
>
<Header icon='cube' content='New Object' />
<Modal.Content>
<AddCameraForm closeModal={this.closeModal} />
</Modal.Content>
</Modal>
)
}
}
export default class AddCameraForm extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Form size="large">
<Form.Group widths="equal">
<Form.Field label='Name' control='input' placeholder='Name' name="name" id="name" required />
</Form.Group>
<Form.Group>
<Button type='submit' className="submit" onClick={this.handleSave}>Save</Button>
<Button type='deny' className="deny" onClick={this.props.closeModal}>Cancel</Button>
</Form.Group>
</Form>
</div>
)
}
}
Maybe try this...
export default class AddCamerModal extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
}
render() {
return (
<Modal
id="add-camera-form"
open={this.state.open}
onClose={e => this.setState({ open: false })}
trigger={
<Button
id="color-0093ee border-color-0093ee"
basic
icon="video-camera"
size="large"
onClick={e => this.setState({ open: true })}
/>
}
>
<Header icon="cube" content="New Object" />
<Modal.Content>
<AddCameraForm />
</Modal.Content>
</Modal>
);
}
}
Okay, I want to post this just in case someone gets stuck in the same rabbit hole I was in. I had to set the open attribute in the modal, then pass that down to my AddCameraForm through the closeModal prop.
Here's the AddCameraModal:
export default class AddCameraModal extends React.Component {
constructor(props) {
super(props);
this.openModal=this.openModal.bind(this);
this.closeModal=this.closeModal.bind(this);
this.state = { isOpen: false }
}
openModal() {
this.setState({isOpen: true})
}
closeModal() {
this.setState({isOpen: false});
}
render() {
return (
<Modal
open={this.state.isOpen}
id="add-camera-form"
trigger={
<Button id="color-0093ee border-color-0093ee"
basic
icon="video-camera"
size="large" onClick={this.openModal}>
</Button>
}
>
<Header icon='cube' content='New Object' />
<Modal.Content>
<AddCameraForm closeModal={this.closeModal} openModal={this.openModal} />
</Modal.Content>
</Modal>
)
}
}
And here's the button's code from my AddCameraForm class:
<Button type='deny' className="cancel" onClick={this.props.closeModal}>Cancel</Button>

Resources