How to read and upload a file in reactjs using custom button - javascript

I want to upload and read a file locally, but I want to do that using a custom button not using HTML input.
<input type="file" id="my_file_input" />
I found this way but I don't want to use this shape or this button, I wanted to use a material UI Raised Button to do this functionality to match the other site Button.
I also tried the following way but it didn't work because as i clicked the button nothing happened.
<input type="file" id="my_file_input" style={{display:"none"}}/>
<label htmlFor="my_file_input">
<RaisedButton
label="Import from Excel"
labelColor="#FFFFFF"
backgroundColor="#01579b"
/>
</label>
I thought I should do the uploading/reading file functionality manually in the onClick function of the RaisedButton but I didn't find a way to do that.
So is there any other solution for this problem in react?

I hope this code will help you.
We can solve it in two ways.
1-)
HTML
<div>
<input type="file" hidden ref={this.inputReference} onChange={this.fileUploadInputChange} />
<button className="ui button" onClick={this.fileUploadAction}>
Image Upload
</button>
{this.state.fileUploadState}
</div>
REACT CONSTRUCTOR
constructor(props) {
super(props);
this.state={fileUploadState:""}
this.inputReference = React.createRef();
}
ONCLICK FUNCTION
fileUploadAction = () =>this.inputReference.current.click();
fileUploadInputChange = (e) =>this.setState({fileUploadState:e.target.value});
2-)
HTML
<div>
<input id="fileButton" type="file" hidden />
<button onClick={this.fileUploadButton}>
Image Upload
</button>
{this.state.fileUploadState}
</div>
React State
this.state = {fileUploadState:""}
React Function
fileUploadButton = () => {
document.getElementById('fileButton').click();
document.getElementById('fileButton').onchange = () =>{
this.setState({
fileUploadState:document.getElementById('fileButton').value
});
}
}

I wanted to provide an update for using refs with functional components. Here is a quick example:
Import React, {useRef} from 'React'
const myComponent = () => {
const fileInputRef=useRef();
const handleChange(event) = () =>{
// do something with event data
}
return(
<>
<button onClick={()=>fileInputRef.current.click()}>
Custom File Input Button
</button>
<input onChange={handleChange} multiple={false} ref={fileInputRef} type='file'hidden/>
</>
)
}

please read API of React Material https://material-ui.com/demos/buttons/
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const styles = theme => ({
button: {
margin: theme.spacing.unit,
},
input: {
display: 'none',
},
});
function ContainedButtons(props) {
const { classes } = props;
return (
<div>
<input
accept="image/*"
className={classes.input}
id="contained-button-file"
multiple
type="file"
/>
<label htmlFor="contained-button-file">
<Button variant="raised" component="span" className={classes.button}>
Upload
</Button>
</label>
</div>
);
}
ContainedButtons.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(ContainedButtons);

As the doc says, you just need to add:
component="span"
To the button component.

Related

Custom PopUp modal component not showing when clicked in React

I am trying to show a custom PopUp component on the screen when a user clicks on the Info icon but nothing is rendering in the UI when clicked.
I'm not exactly certain where I'm going wrong if anyone could provide some guidance?
Here is my Card component with PopUp inside the return:
import React, { useState } from 'react';
import { Card } from 'react-bootstrap';
import InfoIcon from '#material-ui/icons/Info';
import PopUp from './PopUp';
const WelcomeCard = (props) => {
const [show, setShow] = useState(false);
const togglePop = () => {
setShow(true);
};
return (
<Card className='m-3 p-2 welcome-card rounded'>
<Card.Body>
<Card.Text className='mt-4'>{props.text}</Card.Text>
<Card.Title>{props.title}</Card.Title>
<button>{props.button}</button>
{show && <PopUp toggle={togglePop} />}
<InfoIcon className='info-icon' onClick={togglePop} />
</Card.Body>
</Card>
);
};
export default WelcomeCard;
And my actual PopUp component itself:
import React from 'react';
const PopUp = (props) => {
const handleClick = () => {
props.toggle();
};
return (
<div className='modal'>
<div className='modal_content'>
<span className='close' onClick={handleClick}>
×
</span>
<form>
<h3>Register!</h3>
<label>
Name:
<input type='text' name='name' />
</label>
<br />
<input type='submit' />
</form>
</div>
</div>
);
};
export default PopUp;
Would really appreciate some help on this one to understand it better, thanks in advance!

Cannot read property 'suppressHydrationWarning' of null

I'm a react beginner, currently learning NextJS.
I've created a simple component in CreateSubject.js:
import React from 'react';
export default function CreateSubject(props) {
return (
<div>
<div className="field">
<label className="label">Name</label>
<div className="control">
<input
ref="input"
className="input"
type="text"
/>
</div>
</div>
<div className="field is-grouped is-grouped-right">
<p className="control">
<a
className="button is-primary"
onClick={props.onClick}
>
Validate
</a>
</p>
<p className="control">
<a className="button is-light">
Cancel
</a>
</p>
</div>
</div>
)
};
This code is NOT working, I got the following error:
Uncaught TypeError: Cannot read property 'suppressHydrationWarning' of null
If I change this function into a Component:
import React from 'react';
export default class CreateSubject extends React.Component {
render() {
return (
<div>
<div className="field">
...
it's working well. What is wrong with the first code?
For more information, I'm using NextJS, and CreateSubject is called like that:
import React from 'react';
import Navbar from './Navbar';
import Modal from './Modal';
import CreateSubject from './forms/CreateSubject';
let displayShowModal = false;
const createSubject = () => {
alert('okkkk')
};
export default () => (
<div>
<Modal display={displayShowModal} title="Creating subject">
<CreateSubject onClick={createSubject}/>
</Modal>
<Navbar/>
</div>
);
The issue was due to the input field having a ref attribute. Removing the ref attribute that wasn't that useful anyway fixed the issue.
The problem was that you used a functional component and we should use useRef for it: https://reactjs.org/docs/refs-and-the-dom.html#refs-and-function-components. Also, be cautious when you pass ref attribute to your element. Often people pass name of the ref as a string instead of using {}.
In your case it should be:
import React, {useRef} from 'react';
export default function CreateSubject(props) {
const anyName = useRef(null);
...
<input
ref={anyName} // not ref="anyName"
className="input"
type="text"
/>
...
}
Remove the ref attribute in the input tag. If you really need to use it, use useRef as an {object}, not as a "String".
I ran into the same issue today at work!

Show Component inside a Collapsible

Hello I'm trying to show a Form Component inside an 'antd' Collapsible when the user clicks on the form icon the Form Component should appear inside the Collapsible below the text that's already there
I'm using the antd library for the Collapsible
import React from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import { Collapse, Icon } from 'antd';
import Form from './Form';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const genExtra = () => (
<Icon
type="form"
onClick={event => {
// If you don't want click extra trigger collapse, you can prevent this:
event.stopPropagation();
console.log('You have click on edit form');
}}
/>
);
const customPanelStyle = {
background: '#f7f7f7',
borderRadius: 4,
marginBottom: 24,
border: 0,
overflow: 'hidden',
};
ReactDOM.render(
<Collapse
bordered={false}
defaultActiveKey={['1']}
expandIcon={({ isActive }) => <Icon type="caret-right" rotate={isActive ? 90 : 0} />}
>
<Panel
header="This is panel header 1"
key="1" style={customPanelStyle}
extra={genExtra()}
>
<p>{text}</p>
</Panel>
</Collapse>,
document.getElementById('container'),
);
this is the Form Component:
import React from 'react';
const Form = () => {
return(
<div id="wrapper">
<div className="group">
<label for="name">Name</label>
<input type="text" id="name" />
</div>
<hr/>
<div className="group">
<label for="email">Email</label>
<input type="email" id="email" />
</div>
</div>
);
}
export default Form;
--
I just want the Form Component to appear inside the collapsible when the user clicks on the little icon in the header I'll leave a link to the stackblitz: https://stackblitz.com/edit/react-pkffgm
You need to move your Collapsible to another class based component, where you can have state to show / hide your Form component,
In newly constructed class based component you need to maintain state like,
constructor(props){
super(props);
this.state ={
showForm: false
}
}
Then in render you can show your Form like this,
<Panel
header="This is panel header 1"
key="1" style={customPanelStyle}
extra={this.genExtra()}
>
<p>{text}</p>
{this.state.showForm && <Form />}
</Panel>
And finally on click of form edit icon you need to change state of showForm like,
genExtra = () => (
<Icon
type="form"
onClick={event => {
// If you don't want click extra trigger collapse, you can prevent this:
event.stopPropagation();
this.setState({showForm: true})
console.log('You have click on edit form');
}}
/>
);
Note: In the Form component you are getting warning for your lable,
<label htmlFor="name">Name</label> //instead of `for` attribute in react we have `htmlFor` attribute.
Demo

Input Box problem In reactjs, On single click cursor is not pointing in text-box , On double click in the text-box Input Cursor is coming

I am very new to this. Below is the code, please Help
On single click Input cursor is not pointing in text-box, On double click on the text-box Input Cursor is coming. Also if I am adding a placeholder, not able to input anything.
export default class Login extends Component {
state = {
UserID: "",
Password: ""
};
UserIdchangeHandler = text => {
this.setState({
UserID: text.target.value
});
};
PasswordchangeHandler = text => {
this.setState({
Password: text.target.value
});
};
render() {
return (
<div className="backgroundImg">
<span>
<FontAwesomeIcon icon={faUserTie} size="lg" />
</span>
<input
type="text"
onChange={text => {
this.UserIdchangeHandler(text);
}}
/>
<br />
<span>
<FontAwesomeIcon icon={faKey} size="lg" />
</span>
<input
type="password"
onChange={text => {
this.UserIdchangeHandler(text);
}}
/>
<br />
<button>Login</button>
</div>
);
}
}
What is happening is that you have onChange handler but didn't set the value in your input.
If you add a onChange handler you need to add the value prop
<input
type="text"
value={this.stateUserId} // You're missing this here
onChange={evt => {
this.UserIdchangeHandler(evt);
}}
/>
You can learn more about controlled/uncontrolled on the React Docs here. In your case you're trying to create a controlled input
https://reactjs.org/docs/forms.html#controlled-components
Side Note:
In your onChange you labeled the property text. But its better to call it event
<input
type="text"
value={this.state.UserID} // you are missing value here.
onChange={text => {
this.UserIdchangeHandler(text);
}
}
/>
and same as the password input field.
import React, {Component} from 'react';
import "./login.css";
import { library, text } from '#fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faUserTie, faKey, } from '#fortawesome/free-solid-svg-icons'
library.add(faUserTie)
export default class Login extends Component{
state={
UserID:"",
Password:""
}
UserIdchangeHandler=(text)=>{
this.setState({
UserID:text.target.value
})
}
PasswordchangeHandler=(pass)=>{
this.setState({
Password:pass.target.value
})
}
render() {
return (
<div className="backgroundImg">
<span>
<FontAwesomeIcon icon={faUserTie} size="lg"></FontAwesomeIcon>
</span>
<input type="text" onChange={(text)=>{this.UserIdchangeHandler(text)}} ></input>
<br/>
<span>
<FontAwesomeIcon icon={faKey} size="lg"></FontAwesomeIcon>
</span>
<input type="password" onChange={(pass)=>{this.PasswordchangeHandler(pass)}}></input>
<br/>
<button>Login</button>
</div>
);
}
}
Issue is resolved now. The problem was with Css of the class. Z-index was set to lower value.Increasing the z-index helped me here.

Radio Button in stateless component in ReactJs

I'm new to react and redux and i want to create component which contain two radio buttons so i write something like this:
import React, { PropTypes } from 'react';
const renderCashRadioButtons = currentCashSelector => (
<form onClick={currentCashSelector}>
<input
type="radio"
name="cash-transaction"
value="Transcation"
onChange={value => currentCashSelector(value)}
/>
<input
type="radio"
name="cash-transfer"
value="Transfer"
onChange={value => currentCashSelector(value)}
/>
</form>
);
const CashRadioButtons = ({ currentCashSelector }) => (
<div className="container">
{renderCashRadioButtons(currentCashSelector)}
</div>
);
CashRadioButtons.propTypes = {
currentCashSelector: PropTypes.func.isRequired
};
export default CashRadioButtons;
currentCashSelector is a function. When i render this it does not seem to work. The value does not change and i'm not seeing the state to be updated. Do you have any ideas?
You probably want your radio buttons to have the same name, so that when one is selected, the other is deselected.
It looks like your onChange functions are expecting the value, but they're actually receiving the event.
You likely have unwanted duplication between the onChange on your form, and the ones on your radio buttons.
Possible Solution
<form onClick={event => currentCashSelector(event.target.value)}>
<input
type="radio"
name="cash-type"
value="Transaction"
/>
<input
type="radio"
name="cash-type"
value="Transfer"
/>
</form>

Categories

Resources