toggle contentEditable on and off inside React function? - javascript

I have a react function that puts out a div. This div is a draggable, and it should also be editable. I have tried using contentEditable, which makes the div editable when set to 'true', but then i can no longer drag the item, only edit it.
Is there a way to make the div "editability" to toggle on and off, for example using an onclick to turn contentEditable to 'on', and a doubleClick to turn contentEditable to 'true', enabling the dragging?
return (
<div
onDoubleClick contentEditable={true} // needs to be toggleable, in some way
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
{item.content};
</div>
)

This is how you would do it with hooks. I assume you are using them.
const [contentEditable, setContentEditable] = React.useState(false)
return (
<div
onDoubleClick={()=> setContentEditable(!contentEditable)}
ref={provided.innerRef}
{...provided.draggableProps}
{...provided.dragHandleProps}
{item.content};
</div>
)

Related

Dropdown layout on hover for multiple elements

I face a problem with react.js, I'm new to it and haven't seen such questions as mine so far.
My problem is that I wanted to reproduce epic games website to learn react, but I can't manage to do the dropdown layout menu.
So here is what I've done so far (tried many things but my final result is this) :
const [selectedMenu, setSelectedMenu] = useState(null);
And the html part :
<div className="col-2" onMouseEnter={() => setSelectedMenu(1)}>
<div className="wrapper">
<li className="select-none bot_line">news & events</li>
</div>
{selectedMenu === 1 && (
<div
className="bot_menu"
onMouseEnter={() => setSelectedMenu(1)}
onMouseLeave={() => setSelectedMenu(null)}
>}
But this is not what I want exactly, I have 7 element to set from hidden to visible.
The way I want to do it is by targeting each child components with the "onMouseEnter" function through the col-2 element.
What I wish is to change the previous class to a new one by hovering col-2 to show the bot_menu onMonseEnter.The css part is done, my trouble is only with the react part.
So the previous className to be "hidden" and onMouseEnter set it to "visible" className.
And to do it by targeting child elements so I only have to do it once and not 7 times.
Please

remove an element from dom in react so as to make another z index element clickable

I have a header div and alert div in my app. The alert div has a z-index of 2 to stack on the front on the header, so as to show notifications inside it.
However, this is making the header div unclickable. Both header and alert divs are positioned absolutely.
Alert is overlayed to the right of the header on top of it.
New to React. In angular would do with *ngIf (or) set the display to none on alert div when the notifications array length is zero or null.
Not sure how to do here.
index.jsx
<div className={classname('aclass', 'bclass')}>
<div classname={styles.notificationWrapper}>
{this.notificationArray.map( (alert) => (
<pxAlert
visible
classes={classnames(style.aert, 'alert'}>
</pxalert>
)
)}
</div>
It could be done with an inline if with logical && operator:
<div className={classname('aclass', 'bclass')}>
<div classname={styles.notificationWrapper}>
{this.notificationArray && this.notificationArray.map( (alert) => (
<pxAlert
visible
classes={classnames(style.aert, 'alert'}>
</pxalert>
)
)}
</div>
Hope this helps,

Making whole card clickable in Reactstrap

I'm trying to create a card that, when clicked, performs an action.
I've managed to make this work by adding a button to the card, which is bound to an event handler, and works as expected.
I'm trying to get the whole card to work with the same event handler, as opposed to using the button, but I can't seem to get this to work as I would expect.
const SiteCard = props => {
const { site, siteSelectedCallback } = props;
return (
<Card onClick={siteSelectedCallback} className="card-item">
<CardBody>
<CardTitle>{site.name}</CardTitle>
<CardText className="text-muted">{site.address}</CardText>
<Button color="primary" className="float-right" value={site.id}>
CHOOSE ME
</Button>
</CardBody>
</Card>
);
};
I've tried wrapping it in an <a> tag, but that also doesn't work.
With the example, I'd expect the card to be clickable, but actually the button still works with the event handler. I've also tried removing the button, but that doesn't make the card clickable.
Note that adding onClick on the Card component is enough to make it clickable. Changing the cursor through style makes it more obvious to the user.
<Card onClick={onClick} style={{ cursor: "pointer" }}>
<CardBody>This is a clickable card.</CardBody>
</Card>
Wrapping the card with an a tag will also work, though, it won't have the pointer cursor without a href which can be changed easily with CSS.
const SiteCard = ({ site, siteSelectedCallback }) => (
<a style={{ cursor: 'pointer' }} onClick={siteSelectedCallback}>
<Card className="card-item">
<CardBody>
<CardTitle>{site.name}</CardTitle>
<CardText className="text-muted">{site.address}</CardText>
</CardBody>
</Card>
</a>
);
Tested it just now with a console.log, so if that doesn't work, it's because the callback isn't working as you're expecting it to.
Another way would be to make the Card an a tag by passing a tag prop.
<Card tag="a" onClick={siteSelectedCallback} style={{ cursor: "pointer" }}>
All the options available are clearly defined in the source of the reactstrap's Card component.
I also tested with a button inside the Card without any problems.
In case anyone arrives here for the same question, but with react-bootstrap's Card, the solution is very similar. However, instead of using the tag property, you need to use as.
<Card as="a" onClick={siteSelectedCallback} style={{ cursor: "pointer" }}>

Conditionally activate Material UI tooltip?

I have the following React component using Material UI:
const MyButton = ({ warningText }) => (
<Tooltip title={warningText}>
<Button>Do action</Button>
</Tooltip>
)
Currently, this shows an empty tooltip when warningText is undefined. Instead I would like to show no tooltip at all. Is there a way to conditionally surpress the tooltip in these cases?
Off course I could just use an if statement to not render the tooltip component, but this would lead to rather ugly code in my opinion.
Should be
<Tooltip title={warningText == null ? "" : warningText}>
<Button>Do action</Button>
</Tooltip>
the docs say that it won't be displayed if the string length is zero.
https://material-ui.com/api/tooltip/
Tooltip title. Zero-length titles string are never displayed.
If you're looking to manually play around for customization, you can try to use the following solution:
As per the documentation, you can use the open prop and mouse events to handle it manually.
In the following scenario, we will use state to set showing the tooltip when we enter the mouse over the element, and we will also use text && to assert that text has a value, this will prevent the tooltip from showing when text is undefined.
const [showTooltip, setShowTooltip] = useState(false);
<Tooltip
open={text && showTooltip}
onMouseEnter={() => { setShowTooltip(true) }}
onMouseLeave={() => { setShowTooltip(false) }}
placement="top" title={text}
>
<div>
{text}
</div>
</Tooltip>
Note, the mui-tooltip is not a perfect component to begin with and is not very straight forward, this solution works for me but might not work in your situation as is, I will try to put it out, you can try to make it work on your end.
If it doesn't work for you, please leave a comment and I'll try to help.
You should take a look at https://material-ui.com/api/tooltip/
There are options like
disableFocusListener
disableHoverListener
disableTouchListener
interactive
I think interactive={true} should fit your needs best
<Tooltip title={warningText} interactive={!warningText}>...</Tooltip>

Fade out / in text when changing in React

I want to create a button that changes its text based on the state of the application. I want the old text to fade out, and then the new text to fade in.
Here's a pen where I've implemented what I want in pure JS.
How would I achieve the same effect in React - or what would be the best approach?
For reference, here is my JSX:
<div className="buttons">
<div className="half">
<button className="button" onClick={this.chooseLeft}>{this.state.leftButton}</button>
</div>
<div className="half">
<button className="button" onClick={this.chooseRight}>{this.state.rightButton}</button>
</div>
</div>
Edit:
I tried with ReactCSSTransitionGroup, but it didn't work quite as expected. It added the new text, then faded out the old one while fading in the new one.
Use ReactCSSTransitionGroup, part of react's animation add-ons. It's designed for your exact use case.
Had a similar use case and ended up using a timer to update a couple state variables.
One state var to track the message text, another to track application of a fade class in the components className. The fade class basically controls opacity of the text block.
For instance:
...
// in some handler code
this.setState({fading: true}); // fade out
this.timer = setTimeout(_ => {
this.setState({msg: 'Some new text'}); // swap the text
this.setState({fading: false}); // fade back in
}, 500); // animation timing offset
// in render
render() {
const {msg, fading} = this.state;
return (
<h1 className={`${fading ? 'faded' : ''}`}>
{msg}
</h1>
);
}

Categories

Resources