reactJS material UI Icon button to upload file - reactjs

I want to know how can I open the directory to upload a file using an IconButton?
<IconButton
iconClassName="fa fa-plus-square"
onClick={(e) => e.stopPropagation()}
type='file'
/>
using the code below shows the icon button and another button for the upload file
<IconButton iconClassName="fa fa-plus-square" onClick={(e) => e.stopPropagation()}>
<input type="file type='file'>
</IconButton>

I think the standard way from material ui examples:
<input accept="image/*" className={classes.input} id="icon-button-file" type="file" />
<label htmlFor="icon-button-file">
<IconButton color="primary" className={classes.button} component="span">
<PhotoCamera />
</IconButton>
</label>

A few things:
You don't need type='file' on the IconButton, just on the input
IconButton does not expect its children to be anything other than an SVGIcon, so I recommend that you use a regular button
I wouldn't call stopPropagation in this case
You have a typo in your type prop for the input. You have type="file type='file'. It should just be type="file"
So, putting that all together:
<FlatButton label="Choose file" labelPosition="before">
<input type="file" style={styles.exampleImageInput} />
</FlatButton>
If you still want it to be an icon rather than a button, I suspect you can do something with <input> or add it as the children to FlatButton with no label.

You can achieve the same with IconButton using the following code:
<IconButton onClick={() => this.fileUpload.click()}>
<FontIcon className="material-icons" >
add_a_photo
</FontIcon>
</IconButton>
<input type="file" ref={(fileUpload) => {
this.fileUpload = fileUpload;
}}
style={{ visibility: 'hidden'}} onChange={this.groupImgUpload} />

Related

TypeError: Cannot set properties of undefined (setting 'hook')

TypeError: Cannot set properties of undefined (setting 'hook')
I am working on a Nextjs application but getting this error with antd library. I'm using the modal component and tooltip component which causes a re-render on open and close and spits out this error multiple times. Same goes for the tooltip when I mouse over it. Has anyone experienced this? and how did you fix it?. Answers appreciated!
import { Button, Modal, Tooltip } from 'antd';
const [isModalOpen, setIsModalOpen] = useState(false);
<div className="d-flex gap-2">
<Tooltip title="Edit">
<EditOutlined className="h5 pointer text-warning" />
</Tooltip>
<Tooltip title="Publish">
<CheckOutlined className="h5 pointer text-success ml-2" />
</Tooltip>
</div>
<Button
className="w-100"
onClick={() => setIsModalOpen(true)}
type="primary"
shape="round"
size="large"
icon={<UploadOutlined />}
>
Open modal
</Button>
<Modal
title="Modal title"
centered
open={isModalOpen}
onCancel={() => setIsModalOpen(false)}
footer={null}
>
<p>Some contents...</p>
</Modal>

React Quill - Editing an already published text or saved draft

I am making a react web app in which I want some users to have the ability to post newsletters. I am using react quill as the text editor for this.
The issue I am experiencing is how to edit a saved draft or edit an already published newsletter. I want to pass the appropriate newsletter into the editor when i click on the 'edit-button'. But I could not figure out how on my own, neither could I find anything on the subject.
I am using sequelize for my backend and currently the editor is a popup.
<Popup
trigger={<button
class="btn">
Redigera
</button>}>
<React.StrictMode>
<Editor />
</React.StrictMode>
</Popup>
The editor looks like this. I have a text field where the user puts the title of the newsletter and a date picker if they'd like to set a specific date for when it is to be published.
return (
<div class="overlay">
<button id="closeButton">Stäng och spara</button>
<div className="text-editor">
<EditorToolbar />
<TextField
required
id="required"
fullWidth
label="Titel"
onChange={(e) => setTitle(e.target.value)}
/>
<ReactQuill
theme="snow"
value={content}
onChange={setContent}
placeholder={"Skriv ditt nyhetsbrev här..."}
modules={modules}
formats={formats}
/>
<TextField
id="date"
label="Välj dag för publicering"
type="date"
defaultValue={getCurrentDate()}
onChange={(e) => setPublishedAt(e.target.value)}
sx={{ width: 220 }}
InputLabelProps={{
shrink: true,
}}
/>
<button class="rte-button" onClick={publishNow}>Publicera</button>
<div class="buttons">
<button class="rte-button" onClick={onDelete}>Ta bort</button>
<button class="rte-button" onClick={saveNewsletterAsDraft}>Spara utkast</button>
</div>
</div>
</div>
);
};
export default Editor;
I am doing a findAll to retrieve all the existing newsletters from the backend so what I've been thinking of doing is to pass the content and title of the newsletter i want to edit into the editor as a prop. But I would rather not do that as I am not working with classes.

Autoclose bootstrap 5 Dropdown without toggle in React

I have a search field that shows data as dropdown.item when user is typing. The library is React Bootstrap (bootstrap 5). This is working great. The dropdown is showing. The problem is that the dropdown persist when clicking outside or navigating to a new link. The dropdown is in a header that does not get rerendered with the rest of the page. Using NextJS. Any tips on how to close a dropdown that has no toggle?
<form className="d-none d-sm-inline-block" style={{ zIndex: "1000" }}>
<div className="input-group input-group-navbar">
<input
type="text"
className="form-control"
placeholder="Søk"
aria-label="Search"
onChange={(event) => {
setSearchTerm(event.target.value);
}}
/>
<button className="btn" type="button">
<Icon.Search className="align-middle" />
</button>
</div>
{searchData.length >= 1 && (
<Dropdown style={{ position: "absolute", background: "white" }} autoClose="outside">
{searchData.slice(0, 10).map((element, index) => {
return (
<Link key={element.agressoResourceId} href={`employees/69918`} passHref replace={true}>
<Dropdown.Item>
{element.firstname} - {element.lastname}
</Dropdown.Item>
</Link>
);
})}
</Dropdown>
)}
</form>
The solution was to use onBlur event and hide the dropdown. The problem comes with the onblure is triggered before you press the item. The solution here was to use a setTimeout of 200ms.

How do I use the SpeedDial to upload a file?

(this seem to have been asked previously but I couldn't find any hint on if it was actually answered)
MUI has a good demo for creating upload buttons which boils down to:
<input accept="image/*" className={classes.input} id="icon-button-file" type="file" />
<label htmlFor="icon-button-file">
<IconButton color="primary" aria-label="upload picture" component="span">
<PhotoCamera />
</IconButton>
</label>
What I wonder is how to implement the same using the Speed Dial. Inherently the SpeedDialAction seems to materialize as a <button/>, but it's not possible to e.g. wrap the SpeedDialAction in a <label htmlFor /> as its parent will try to set some props on it and will fail.
So how do I initiate the file selection from within the Speed Dial or a FAB in general?
You can create a wrapper component that forwards props to SpeedDialAction.
function UploadSpeedDialAction(props) {
return (
<React.Fragment>
<input
accept="image/*"
style={{ display: "none" }}
id="icon-button-file"
type="file"
/>
<label htmlFor="icon-button-file">
<SpeedDialAction
icon={<CloudUploadIcon />}
tooltipTitle="upload"
component="span"
{...props}
></SpeedDialAction>
</label>
</React.Fragment>
);
}
https://codesandbox.io/s/material-demo-forked-h6s4l
(Note to future readers: For v5, time allowing, we hope to rationalise where props rather than context are used to control children, in order to solve exactly this kind of issue. So check whether this solution is still needed.)
It is - in my knowledge - not possible to add the htmlFor in any way. So what I would do is to add a hidden input type file and then add a ref to it. Then in the onclick of the SpeedDialAction button I would call a handler function that clicks on the input ref. Like this:
const inputRef = useRef();
const handleFileUploadClick = () => {
inputRef.current.click();
};
Then your SpeedDialAction:
<SpeedDialAction
onClick={handleFileUploadClick}
... the rest of your props
/>
And then finnaly your actual input:
<input
style={{ display: "none" }}
ref={inputRef}
accept="image/*"
id="contained-button-file"
multiple
type="file"
/>
Working demo: https://codesandbox.io/s/material-demo-forked-f9i6q?file=/demo.tsx:1691-1868

Conditionally remember radio button selection in React

I am creating a modal to filter for profiles, on react-bootstrap and redux.
I need to filter to remember it's previous selection every time the user reopen it, even if he returns from another page. It works fine with value based components, such as "range slider" or "text search" because I can grab the previous saved redux store and plug into the component's attribute, such as:
value={rangeValue}
But for radio buttons, I am not sure since the attribute itself, "checked", is its own value.
<Form.Check
inline
label="male"
name="male"
checked <-----------
onChange={(e) => onRadioChange(e)}
/>
I want it to show "checked" only if the user has previously done so. I already have the user choice (whether checked or not) saved in my store, but don't know how to plug it in conditionally.
The returned JSX below
import React, { useState } from "react";
import { Form, Button } from "react-bootstrap";
...
<Form>
<div className="form_content_wrap">
<Form.Group>
<Form.Label htmlFor="formControlRange">Age: {rangeValue}</Form.Label>
<Form.Control
type="range"
className="form-control-range"
id="formControlRange"
min="0"
max="100"
value={rangeValue}
onChange={(e) => setRangeValue(e.currentTarget.value)}
/>
</Form.Group>
<Form.Group>
<Form.Label htmlFor="formControlRange">Gender: </Form.Label>
<Form.Check
inline
label="female"
name="female"
onChange={(e) => onRadioChange(e)}
/>
<Form.Check
inline
label="male"
name="male"
checked <<<------- THIS IS WHERE I WANT TO CHANGE
onChange={(e) => onRadioChange(e)}
/>
</Form.Group>
<Form.Group>
<Form.Label>Keyword</Form.Label>
<Form.Control
type="text"
placeholder="search description"
value={descValue}
onChange={(e) => setDescValue(e.currentTarget.value)}
/>
</Form.Group>
<Button
variant="primary"
type="submit"
onClick={onFormSubmit}
style={{ marginRight: "10px" }}
>
Submit
</Button>
<Button variant="primary" type="submit" onClick={onFormClear}>
Clear
</Button>[enter image description here][1]
</div>
</Form>
Thanks
React appears to be smart enough automatically remove the attribute if you set it equal to a Javascript expression that is not truthy. You should be able to just pull this state from your store. See this question for more details.
<Form.Check checked={true} />
<Form.Check checked={false} />

Resources