Put inside Textarea button with Jsx (react) - reactjs

Okey small question from junior to pro about Jsx and react:
I have textarea and i wanna put inside button
renderButton() {
const { mod } = this.state
return (
<button className={classNames({
[styles.button]: mod == 'default',
[styles.fullScreenButton]: mod == 'fullscreen'
})} onClick={this.fullScreen} >
{this.renderIcon()}
</button>
)
}
render() {
const { text, rows } = this.props
const { mod } = this.state
return (
<div>
<textarea rows={rows} value='text'
className={classNames({
[styles.textArea]: mod == 'default',
[styles.fullScreen]: mod == 'fullscreen'
})}>
</textarea>
{this.renderButton()}
</div>
)
}
}
How i can do that?
Just
<textarea> <button> </button> </textarea>
not working
Using position: absolute maybe yes, but have any another way to do that?

As you have discovered, placing an HTML button as a child of a <textarea> will not work. This is not a limitation of React or JSX but of the <textarea> element. If you want the button to be placed inside the <textarea> visually you'll need to use CSS to reposition it. Something like this:
div {
position: relative;
}
textarea {
width: 100%;
height: 300px;
margin: 0;
padding: 0;
}
button {
position: absolute;
bottom: 15px;
right: 10px;
}
<div>
<textarea>
</textarea>
<button>Submit</button>
</div>

Related

React - Modal expands div in footer div not on main screen

New to coding, trying to get a modal to work. It is not opening the way I expected it to.
The component is currently loaded within the footer div of my site. And when the button is toggled it simply hides or shows a div within the footer. I want it to appear in the centre of the webpage as a modal.
import React, {useState} from 'react';
import './policy.css'
export default function Policy() {
const [modal, setModal] = useState(false);
const toggleModal = () => {
setModal(!modal);
};
if(modal) {
document.body.classList.add('active-modal')
} else {
document.body.classList.remove('active-modal')
}
return (
<>
<div>
<button onClick={toggleModal} className='btn-modal'>
<p>Privacy Policy</p>
</button>
</div>
{modal && (
<div className="modal">
<div onClick={toggleModal} className="overlay"></div>
<div className="modal-content">
<h2>Privacy Policy</h2>
<p>This is the privacy policy</p>
<button className='close-modal' onClick={toggleModal}>Close</button>
</div>
</div>
)}
</>
);
}
The simplest way to achieve a modal effect is to use some CSS.
You could try a very crude style like (from MUI Modal docs):
const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
bgcolor: "lightgrey",
border: "2px solid #000",
boxShadow: 24,
padding: 4,
};
Then apply it to your modal:
<div className="modal" style={style}>

How can i create a new div when i onclick the button in React js?

code 1 component:-
const TableheaderText = props => {
//const [playlist, setPlaylist] = useState(props);
const [playlist, setPlaylist] = useState("playlist");
const [showing, SetShowing] = useState();
const [isActive, setActive] = useState(true);
//console.log(playlist);
useEffect(() => {
// setPlaylist(props);
SetShowing("PLAYLIST:");
setPlaylist(props.val);
}, [props])
return (
<div className="mainContent">
<div className="tableHeaderBody" >
<div className="TableText" >
<div id="HIDE">{showing}</div><div id="SHOW">{playlist}</div>
</div>
<div className="ClossIcon"><FaCircle style={{ color: "#FC0000", width: "10px", height: "10px", alignItems: "right" }} /></div>
</div>
</div>
)
}
code 2 component:-
<NavLink to={`/Table`} onClick={(e) => myClick(val, index)} >
<button className='notActive buttonLeft'
onClick={() => handleOnClick(index)} // pass the index
className={activeIndex === index ? "active" : "notActive"}>
{val}
</button>
</NavLink>
Right now i have one div and when i click the menu value then one div replace the name
but i want that when i click the 1 value its create one div and when click the 2 value its create second div with the name of 2 div and place right side of 1 div and so.. (if 3,4 value menu ..)
This may be one possible solution to achieve the desired objective (copied from OP's question):
i want that when i click the 1 value its create one div and when click
the 2 value its create second div with the name of 2 div and place
right side of 1 div and so..
Code Snippet
const {useState} = React;
const Thingy = () => {
const myDivs = [...Array(4).keys()].map(i => `My Div # ${i+1}`);
const [flipDivs, setFlipDivs] = useState([
...myDivs.map(
(text, id) => ({id, text, show: false})
)
]);
const handleClick = e => {
const idx = e.target.id;
const newArr = [...flipDivs];
newArr[idx].show = !flipDivs[idx].show;
setFlipDivs(newArr);
};
const myButtons = [...Array(4).keys()];
return (
<div>
<div class="allDivs">
<div> Fixed Div </div>
{
flipDivs.filter(({show}) => !!show).map(
({text, id, show}, idx) => (
<div
key={idx}
class="simpleMargin rightBorder"
>
{text}
</div>
)
)
}
</div>
<div class="buttons">
{myButtons.map(id => (
<button
id={id}
class="simpleMargin"
onClick={handleClick}
>
{flipDivs[id].show ? 'Hide' : 'Show'} Div # {id+1}
</button>
))}
</div>
</div>
);
};
ReactDOM.render(
<div>
DEMO
<Thingy />
</div>,
document.getElementById("rd")
);
.allDivs {
border: 2px solid black;
width: fit-content;
display: flex;
align-items: center;
margin: 10px 15px;
}
.simpleMargin { margin: 5px 10px; }
.rightBorder { border: 2px solid black; }
.buttons {
display: flex;
margin: 10px 5px;
}
<div id="rd" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
Explanation
simple, straightforward approach
Add a flag to determine which div needs to be rendered on which button click
On the click-handler, simply update the flag to show / hide div
For this you need to make a div element and whoe it conditionally ( with state declared with useState ) and then toggle the state on button click to show it. like :
{
showDiv ? <div></div> : null
}
Here showDiv is:
const [showDiv, setShowDiv] = useState (false)
Now toggle showDiv on button click to true. :)

Overlay is blocking input to xlsx spreadsheet how to fix that in my case

I created a codesandbox to illustrate this.
Basically what happens is the XLSX spreadsheet cells can't be clicked on because the overlay transparent box is blocking this. I know why this happens and it can be fixed by setting style pointer-events: none; But then the overlay stops working because it slides out when mouse moves.
The overlay with green buttons slides in and out and the "Box" that catches the mouse move for the overlay is blocking the clicks to go through to the spreadsheet under.
How can I fix so I can edit all cells in the spreadsheet and still have the overlay working? IS there a way to make an overlay like this that let click through and also react to mouse events?
Unfortunately it seems impossible to achieved that having the Overlay as a sibling of the element you're overlaying, but it works if you are allowed to change the structure putting the XLSX component as child of the overlay
Overlay.js
class Overlay extends Component {
constructor(props) {
super(props);
this.state = {
hoverIndex: null
};
}
handleMouseEnter = (e) => {
if (e.currentTarget.id) {
this.setState({ hoverIndex: e.currentTarget.id });
}
};
handleMouseLeave = (e) => {
this.setState({ hoverIndex: null });
};
render() {
const { fileData, children } = this.props;
const { hoverIndex } = this.state;
return (
<div
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
className={`box-container`}
id={fileData}
key={fileData}
>
<div
onMouseLeave={this.handleMouseLeave}
className={`box-content ${hoverIndex === fileData ? "hovered" : ""}`}
>
<div className="text-group">SpreadSheet File</div>
<div className="btn-group">
<button className="btn btn-secondary" type="button">
Open File
</button>
<button className="btn btn-secondary" type="button">
Edit Description
</button>
<button className="btn btn-secondary" type="button">
Download
</button>
<button className="btn btn-secondary" type="button">
Push me for fun
</button>
</div>
</div>
{children}
</div>
);
}
}
overlay-xlsx-renderer.scss
.box-container {
width: 100%;
height: 100%;
margin: 0% auto;
overflow: hidden;
position: relative;
}
.box-content {
width: 60%;
height: 100%;
background: #1d1d1e;
position: absolute;
left: -60%;
transition: left 0.6s;
color: white;
overflow: auto;
z-index: 10;
}
ItemRendered.js
...
case "xlsx": {
return (
<div className="outer">
<Overlay fileData={fileData}>
<div className="pg-viewer-wrapper">
<div className="pg-viewer" id="pg-viewer">
<XlsxViewer
responseType="arraybuffer"
filePath={filePath}
width={0}
height={0}
/>
</div>
</div>
</Overlay>
</div>
);
}
...
you can check it working in this sandbox fork

How to Prevent Parent Component State from Resetting to Original after Closing the Child Component

I have a search form with a lot of search components and a List container component which contains Item component to display the search results. When I click a selected Item, it pops up a Detail component. Right now, everything works fine except when clicking Close button inside the Detail component, the form gets reset and list of items also disappears. The Close button should just close the Detail component so I can select a different item in the list to view. What is the problem in my code? Thanks.
App.js
class App extends Component {
state={ showPopup: false,
selectedItem:'',
Items:[]};
togglePopup=()=> {
this.setState({
showPopup: !this.state.showPopup
});
}
onItemseSelect=(item)=>{
this.setState({selectedItem:item});
};
render(){
const Items=['aa','bb','cc'];
return(
<List
Items={this.state.Items}
onItemSelect={this.onItemSelect}
onClick={this.togglePopup}
/>
{this.state.showPopup ?
<Detail
item={this.state.selectedItem}
closePopup={this.togglePopup.bind(this)}
/>
: null
}
);
}
}
List.js
import React from 'react';
import Item from './Item';
const List=({Items,onItemSelect})=>{
const renderedList= Items.map(item=>{
return (
<Item key={item.ID} item={item} onItemSelect={onItemSelect} />
);
})
return <div>
{renderedList}</div>
}
export default List;
Item.js
import React from 'react';
const Item=({item, onItemSelect})=>{
return <div onClick={()=>onItemSelect(item)} >
<div class="content">
<div class="header">
{/*display contents*/}
View More
</div>
</div>
};
export default Item;
Detail.js
import React from 'react';
const Detail=({item,closePopup})=>{
if (!item){
return <div>loading</div>
}
return (
<div className='popup'>
<div className='popup_inner'>
<p>
{/*contents here*/}
</p>
<button onClick={()=>closePopup}>close me</button>
</div>
</div>);
};
export default Detail;
css code:
.popup {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
background-color: rgba(0,0,0, 0.5);
}
.popup_inner {
position: absolute;
left: 25%;
right: 25%;
top: 25%;
bottom: 25%;
margin: auto;
background: white;
}
No error message. The form resets to the original state.
I think the problem is here only, I doubt how your list items are rendered first time only.
Items:[]
render(){
const Items=['aa','bb','cc']; //static values which are not in use
return(
<List
Items={this.state.Items} //You are using state which is blank
onItemSelect={this.onItemSelect}
onClick={this.togglePopup}
/>
...
)
}
Complete Running code is like this.

Changing style of a button on click

Is it possible to change background-color of my button onClick function?
ex. click background-color: black, another click background-color: white
I've tried something like this.style, no result.
I've managed to get overlay working and insert needed data inside of it.
But didn't managed to find any post that could help me.
I am using react-bootstrap.
This is my code.
const metaDataOverlay = (
<div>
<style type="text/css">{`
.btn-overlay {
background-color: white;
margin-right: -15px;
margin-left: -15px;
padding-bottom: -20px;
padding: 0;
}
`}</style>
<ButtonToolbar>
<ButtonGroup>
<OverlayTrigger trigger={['hover', 'focus']} placement="left" overlay={popoverHoverFocus}>
<Button bsStyle="overlay" onClick={ clicked } onKeyPress={ keypress }>
<div className={bemBlocks.item().mix(bemBlocks.container("item"))} data-qa="hit">
<a href={url} onClick={(e)=>{e.preventDefault(); console.log("123")}}>
<div>
<img data-qa="poster" className={bemBlocks.item("poster")} src={result._source.poster} width="240" height="240"/>
</div>
</a>
</div>
</Button>
</OverlayTrigger>
</ButtonGroup>
</ButtonToolbar>
</div>
)
You can try to use state to store the color. Maybe this would give you the idea how to solve the problem :
class Test extends React.Component {
constructor(){
super();
this.state = {
black: true
}
}
changeColor(){
this.setState({black: !this.state.black})
}
render(){
let btn_class = this.state.black ? "blackButton" : "whiteButton";
return (
<button className={btn_class} onClick={this.changeColor.bind(this)}>
Button
</button>
)
}
}
React.render(<Test />, document.getElementById('container'));
Here is a fiddle.
You also have access to event and current target of the event
handleClick = (event) => {
// accessible
event.target.style
event.target.classList //to change style via css
}
Here is another solution
changeStyles = () => {
let element = document.getElementById('button')
ReactDOM.findDOMNode(element).style.backgroundColor = this.state.isClicked?'black' : 'white'
}
In this way you can change only needed style property preventing duplicates in CSS.
This is how you can access
handleClick=(e)=>{
console.log("this is working fine");
e.preventDefault();
e.target.style.color = 'black'
console.log(e.target);
}
If you want more dynamically you can initialize state with some default value of style afterwords use setState function to update your state
Add this to your Tooltip
<Tooltip cursor={{ fill: 'transparent' }} />
Here is another solution :
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
BackgroundColor: "BLACK"};
};
render(){
return (
<div className='app'>
<button className={this.state.BackgroundColor === "BLACK" ? "Black" : "nothing"}
onClick={() => {this.setState({BackgroundColor: "WHITE"})}}>CHANGE TO BLACK</button>
<button className={this.state.BackgroundColor === "WHITE" ? "White" : "nothing"}
onClick={() => {this.setState({BackgroundColor: "BLACK"})}}>CHANGE TO WHITE</button>
</div>
);
}
}
export default App;
This code will help you to hide the ex black button and change with new button with white background. This function will also work for the new white button. If maybe you just want to change background-color of button without repeat situation you can also try to change conditional state in render
render(){
return (
<div className='app'>
<button className={this.state.BackgroundColor === "BLACK" ? "Black" : "White"}
onClick={() => {this.setState({BackgroundColor: "WHITE"})}}>CHANGE TO BLACK</button>
</div>
);
}
}
Here is the CSS :
*{
margin: 0;
padding: 0;
}
.app{
display: flex;
justify-content: center;
align-items: center;
}
.Black{
background-color: black;
color: white;
}
.White{
background-color: white;
color: black;
}
.nothing{
display: none;
}

Resources