click redirect from button to file input - javascript

Hey is there a smarter way to redirect a click from a button to file input element ?
Currently I'm using:
function clickRedirect() {
document.getElementById("uploadFileButton").click();
}
Works. However I've been clearing any DOM manipulation (outside of appState) in my react project and this is the last bit remaining. I'd like to get rid of it.

You can use ref with hidden button
<input id="myInput" type="file" ref={(ref) => this.myInput = ref} style={{ display: 'none' }} />
<FloatingActionButton
className="floatingButton"
backgroundColor='#293C8E'
onClick={(e) => this.myInput.click() }
>
</FloatingActionButton>
attached demo here:
https://jsfiddle.net/432yz8qg/58/

Related

search functionality in table without clicking enter button from keyboard

I am new react developer, here i have antd table with search functionality, is there an easy way to make this work without clicking 'enter' button from keyboard when searching ? for example when user starts writing 'd..' it should search it without needing to click 'enter' button, here is the code :
https://codesandbox.io/s/z3ln7y0p04?file=/src/StatusFilter.js
You can just use the onChange prop instead::
handleChange = (e) => {
const searchText = e.target.value;
const filteredEvents = eventsData.filter(({ title }) => {
title = title.toLowerCase();
return title.includes(searchText);
});
this.setState({
eventsData: filteredEvents,
});
};
<>
<Search
placeholder="Enter Title"
onSearch={onSearch}
onChange={onChange}
style={{ width: 200 }}
/>
<TitleSearch
onSearch={this.handleSearch}
onChange={this.handleChange}
className={styles.action}
/>
</>;
https://codesandbox.io/s/antd-table-filter-search-forked-4731q?file=/src/TitleSearch.js:174-305
For scenarios like whenever a search call should go , as we start entering into the search field we can handle this with onChange

How do I change the attributes of an RMWC Component?

I have an RMWC Button element, and I want to change the icon attribute when an onClick event is fired.
<Button outlined icon={<CircularProgress />}
onClick={(e)=> {
// e.currentTarget.icon = '';
// console.log(e.currentTarget.icon)
// ??? :V
}}
>Export</Button>
More specifically, I'm trying to make the Button stop loading when the button is clicked :P
You could do with useState update method
const [load,setLoad] = useState(true);
<Button outlined icon={load ? <CircularProgress />:<SomeOtherIcon/>}
onClick={(e)=> setLoad(false)} >Export</Button>

React-spring - Animated div removes onclick function

I'm facing problem with my onClick function which is on a element. Without React-spring animations it works perfectly. But since I've added animations to it, function is not working. No errors in console, and I really can't find any problems like this on google. Have you encountered this type of problem?
Declaring an animation
import {useTransition, animated} from 'react-spring';
const gameOptionsTransitions = useTransition(showGameOptions, null, {
from: { opacity: 0, transform:'translateY(200px)' },
enter: { opacity: 1, transform:'translateY(0)' },
leave: { opacity: 0, transform:'translateY(200px)'}
});
In return
{gameOptionsTransitions.map(({ item, key, props }) =>
item &&
<animated.div key={key} style={props}>
<Link to="/play">
<a className="playerVsComputer-btn" onClick={props.playPlayerVsComputer}>Player vs. Computer</a>
</Link>
<Link to="/play">
<a className="playerVsComputer-btn" onClick={props.playPlayerVsPlayer}>Player vs. Player</a>
</Link>
<form onSubmit={handleSubmit}>
<input type="text" ref={sizeOfBoard} onChange={removeHighlightInput} autoFocus />
</form>
</animated.div>
)};
As you can see, both of a elements are wrapped in Link element. So after click, you will be redirected to that path but also function should be fired. This function is sent to this component from App.js as a prop. I've tried to move whole onClick={props.playPlayerVsComputer} from a element to Link but nothing changes.
Sent function
function playPlayerVsPlayer(){
setPlayerVsPlayer({
AI:false,
AImove:false
});
setDimensions({
rows:"3",
columns:"3"
})
generateMatrix(3,3);
}
This function sets dimensions state and then create matrix according to these dimensions. Then generateMatrix function fires another function, which renders rows x columns table to App. But it's not that important because there will be problem with that animated div, not with these functions.
I've changed animated div like this, so Link element don't have any other elements inside, also classNames moved to Link element.
{gameOptionsTransitions.map(({ item, key, props }) =>
item &&
<animated.div key={key} style={props}>
<Link to="/play" className="setGameMode-btn" onClick={playPlayerVsComputer}>
Player vs. Computer
</Link>
<Link to="/play" className="setGameMode-btn" onClick={playPlayerVsPlayer}>
Player vs. Player
</Link>
<form onSubmit={handleSubmit}>
<input type="text" ref={sizeOfBoard} onChange={removeHighlightInput} autoFocus />
</form>
</animated.div>
)};
For onClick events I have created two new functions which are calling these functions from App.js as a props.
//Fire animations sent as a props
function playPlayerVsComputer(){
props.playPlayerVsComputer();
}
function playPlayerVsPlayer(){
props.playPlayerVsPlayer();
}
You are adding a react spring transition which have its own props ,
All you have to do just rename the props => to other name (annimationProps by example ) in order to not confuse the props passed to your component by the App file
as below :
{gameOptionsTransitions.map(({ item, key, annimationProps }) =>
item &&
<animated.div key={key} style={annimationProps}>
<Link to="/play">
<a className="playerVsComputer-btn" onClick={props.playPlayerVsComputer}>Player vs. Computer</a>
</Link>
<Link to="/play">
<a className="playerVsComputer-btn" onClick={props.playPlayerVsPlayer}>Player vs. Player</a>
</Link>
<form onSubmit={handleSubmit}>
<input type="text" ref={sizeOfBoard} onChange={removeHighlightInput} autoFocus />
</form>
</animated.div>
)};

Text editor value disappears in React Js

I am making a simple accordion and inside each accordion, there is a text editor.
Accordion.js
<div className="wrapper">
{accordionData.map((item, index) => (
<Accordion>
<Heading>
<div
style={{ padding: "10px", cursor: "pointer" }}
className="heading"
onClick={() => toggleHandler(index)}
>
{toggleValue !== index ? `Expand` : `Shrink`}
</div>
</Heading>
<Text> {toggleValue === index && item.content && <EditorContainer />} </Text>
</Accordion>
))}
</div>
Here accordion is made up of as a component. This line {toggleValue === index && item.content && <EditorContainer />} is made to check the accordion clicked and then it loads the content and text editor accordingly.
Complete working example:
https://codesandbox.io/s/react-accordion-forked-dcqbo
Steps to reproduce the issue:
-> Open the above link
-> There will be three accordion
-> Click on any of the accordion, that will change the text from Expand to Shrink
-> Now fill some random text inside the editor then click on the text Shrink
-> Again open the same accordion by clicking Expand
-> Now already entered value is missing
I doubt it happens because every time we expand/shrink, the text_editor.js component gets called and that has the state value like,
this.state = {
editorState: EditorState.createEmpty()
};
Here instead of EditorState.createEmpty(), Should I need to give any other thing?
Requirement:
How can I store the already entered value in the text editor. Even though user clicks expand/shrink, the entered text needs to be remain there in the editor.
Any help is much appreciated.
You are correct, the entered value is missing because you are unmounting the EditorContainer component when its shrinked — that when you expand it again it creates a new editorState which is empty.
2 Possible solutions I could think of.
Move editorState and onEditorStateChange to the Parent component and pass that to EditorContainer. This way, when we unmount the EditorContainer we won't lose the previous editorState because it's on the Parent.
We wrap our EditorContainer inside a div and we'll apply a display style when we toggle between shrink/expand. This way, we are only hiding the EditorContainer not unmounting so its states will retain.
I would choose to implement the 2nd solution because we only have to make changes to our Accordion.js file. In either ways, I would create a new component that would handle the current item. I call it NormalAccordionItem.
const NormalAccordionItem = ({ data }) => {
const [show, setShow] = useState(false);
function toggle() {
setShow((prev) => !prev);
}
return (
<Accordion>
<Heading>
<div
style={{ padding: "10px", cursor: "pointer" }}
className="heading"
onClick={toggle}
>
{show ? "Shrink" : "Expand"}
</div>
</Heading>
<Text>
<div style={{ display: show ? "block" : "none" }}> // notice this
<EditorContainer />
</div>
</Text>
</Accordion>
);
};
Then on our NormalAccordion we'll use NormalAccordionItem.
const NormalAccordion = () => {
return (
<div className="wrapper">
{accordionData.map((data) => (
<NormalAccordionItem data={data} key={data.id} />
))}
</div>
);
};
That's it, check the demo below.
Edit Updated demo to expand NormalAccordionItem one at a time.

React can't figure out how to change a text through buttons onClick events

I'm new to React, Nodejs and JavaScript so bear with me.
I'm doing some practice with onClick events to change text by clicking some buttons, I have an input type="checkbox" to make the text bold when checked and vise versa, 2 buttons to increase and decrease the text size by 1+ or 1- and a span that shows the current text size (16 is my default), and finally a span with the id="textSpan" that have the text meant to be modified. I also want this buttons, the checkbox and the span with the id="fontSizeSpan" that shows the current font size to be hidden by default and when you click the text it appears on its left.
This is the code so far:
class FontChooser extends React.Component {
constructor(props) {
super(props);
this.state = {hidden: true};
this.checkInput = React.createRef();
this.hide = React.createRef();
}
toggle(){
this.setState({hidden: !this.state.hidden});
this.hide.current
}
makeBold(){
this.setState({bold: !this.state.bold});
this.checkInput.current
}
changeSize(){
this.setState({size: !this.props.size})
for(var i = this.props.size; i <= this.props.max; i++);
}
render() {
return(
<div>
<input type="checkbox" id="boldCheckbox" ref={this.hide} hidden={false} onClick={this.makeBold.bind(this)}/>
<button id="decreaseButton" ref={this.hide} hidden={false}>-</button>
<span id="fontSizeSpan" ref={this.hide} hidden={false}>{this.props.size}</span>
<button id="increaseButton" ref={this.hide} hidden={false} onClick={this.changeSize.bind(this)}>+</button>
<span id="textSpan" ref={this.checkInput} onClick={this.toggle.bind(this)}>{this.props.text}</span>
</div>
);
}
right now their hidden attribute is false so I can see them.Here's the html which is not much:
<div id='container'></div>
<script type="text/jsx">
ReactDOM.render(
<div>
<FontChooser min='4' max='40' size='16' text='You can change me!' bold='false'/>
</div>,
document.getElementById('container'))
;
</script>
So far all I have managed is for the browser console(I'm using Firefox react component addon) to confirm there is a functioning event that doesn't really work, as in when I click the text, the buttons or the input checkbox the props does change to false or true every click but that's about it.
I appreciate it if someone could guide me through this.
NOTE:
just in case nothing is imported, also I setup a local server with Nodejs
Here is an Example of what you want: https://codesandbox.io/s/mystifying-cookies-v7w3l?file=/src/App.js
Basically, I have 4 variables: text, fontWeight, fontSize and showTools.
Each button has its own task and also you can select if show or not.
In React you don't have to care about ids like in older frameworks. You can generate the elements just in the place where you are with the information which you need. So, basically, we have the 4 variables and use them wisely where we want (as styles props, as text and even as a conditional to show components). It's the magic of React and JSX.
In the code I've use hooks, part of the latest definition of React. For that my Components is functional and not a Class. it makes it easier and faster for examples and prototyping.
The tools are show by default just to let you play with it
import React from "react";
import "./styles.css";
export default function App() {
const [text, setText] = React.useState("");
const [boldFont, setBoldFont] = React.useState(false);
const [fontSize, setFontSize] = React.useState(14);
const [showTools, setShowTools] = React.useState(true);
return (
<div className="App">
<div
style={{
fontWeight: boldFont ? "bold" : "normal",
fontSize: `${fontSize}px`
}}
>
<span onClick={() => setShowTools(!showTools)}>
{text || "Text Example"}
</span>
</div>
{showTools && (
<div>
<button onClick={() => setBoldFont(!boldFont)}>Bold</button> |
<button onClick={() => setFontSize(fontSize + 1)}>A+</button>
<button onClick={() => setFontSize(fontSize - 1)}>a-</button>
<input
type="text"
value={text}
onChange={event => {
setText(event.target.value);
}}
/>
</div>
)}
</div>
);
}

Categories