All child elements inheriting onclick event from parent div on React - reactjs

This is my code on return section. All children elements is ineriting click events and when I click it is giving me the object of that child element not parent.
return (
<div className={css(style.cell)} onClick={this.props.onClickHandle}>
<div className={css(style.image)}>
<CircleImage size={50} url = {"http://www.ruralagriventures.com/wp-content/uploads/2017/05/man-team.jpg"}/>
</div>
<div className={css(style.info)}>
<div className={css(style.profile)}>
<span>{this.props.name}</span>
<span className={css(style.lastMessage)}>Latest Message</span>
</div>
<div className={css(style.detail)}>
<span>a few seconds ago</span>
<span className={css(style.counter)}>5</span>
</div>
</div>
</div>
)
I only want an object from parent div, not children. Before passing props
I assigned this.onClickHandle = this.onClickHandle.bind(this);

You can use refs, refer this link
onClickHandle(e){
this.parentDiv //parent object
}
return (
<div ref={(parentDiv) => { this.parentDiv = parentDiv; }} className={css(style.cell)} onClick={this.props.onClickHandle}>
<div className={css(style.image)}>
<CircleImage size={50} url = {"http://www.ruralagriventures.com/wp-content/uploads/2017/05/man-team.jpg"}/>
</div>
<div className={css(style.info)}>
<div className={css(style.profile)}>
<span>{this.props.name}</span>
<span className={css(style.lastMessage)}>Latest Message</span>
</div>
<div className={css(style.detail)}>
<span>a few seconds ago</span>
<span className={css(style.counter)}>5</span>
</div>
</div>
</div>
)

Related

How to open only one Modal with using Modal template that I created

I was able to use the map method to display my static data in each container. There's a Modal template I created in order to provide more object/values info but if I click the button it opens all the modals of each containers at the same time because Modal tag wasn't assigned with unique index number when I mapped through my static data. Big brothers, please look at my codes and teach me how I can open only one associated Modal.
I created function Modal (template) and import to function Projects
function Modal({closeModal}) {
return (
<div className="modal-main">
<div className='modal-card'>
<img src="" />
<div className='modal-info'>
<div className='modal-title'>
<p className="title">title</p>
</div>
<div className='modal-body'>
<p className="tech">tech</p>
<p className="description">description</p>
<p className="github">github</p>
<p className="website">website</p>
</div >
<Button>detail</Button>
<Button onClick={()=> closeModal(false)}>close</Button>
</div>
</div>
</div>
)
}
export default Modal
function Projects() {
const [openModal, setOpenModal] = useState(false);
const [oneProject, setOneProject]
= useState(list_of_projects)
return (
<div className="section-header text-center mt-5">
<h4>projects</h4>
<p>list of proejcts</p>
<div className="proj-container">
{oneProject.map((item, index)=> {
return(
<div className='proj-map mx-2 my-2'key={index} >
<button type='button' className="btn btn-link " onClick={() => setOpenModal(true)}>
<div className=" proj-card card">
<img className='proj-img' src={item.thumbnail} style={{ width:300, height:300 }}/>
<div className="proj-text card-text">
<h3 className='title'>{item.title}</h3>
<h5 className='description'>description</h5>
<br/>
<h4>+</h4>
</div>
</div>
</button>
{openModal && <**Modal** closeModal={setOpenModal} /> }
</div>
)
})}
</div>
</div>

How can I click on a button on the same element with a specific name?

This is ant-react project.
html:
<div class="list">
<div class="item">
<div>
<div>
<div class="head">
<span>name 1</span>
</div>
<div class="body">
<div>
<button>done</button>
</div>
</div>
</div>
</div>
</div>
<div class="item">
<div>
<div>
<div class="head">
<span>name 2</span>
</div>
<div class="body">
<div>
<button>done</button>
</div>
</div>
</div>
</div>
</div>
js:
cy.get(`div:contains('name1')`)
.should('be.visible')
.invoke('show')
.should('be.visible')
.find('button:contains("Done")').eq(0).click({ multiple: true })
There are a lot of item elements. I need to click on the 'Done' button of the element with name "name 1".
But every time i get error:
Timed out retrying after 4050ms: cy.click() failed because this element is detached from the DOM.
...
Cypress requires elements be attached in the DOM to interact with them.
How can I do it?
You can do something like this. The first parent will go to <div class="head"> and the next parent will move to div just above. Now using within we will make sure that the Done button is clicked for name 1.
cy.contains('span', 'name1')
.parent()
.parent()
.within(() => {
cy.contains('button', 'done').click()
})

react How to make onClick not work only on certain elements

development environment
react.js
typescript
next.js
I don't want to trigger the onClick process when the span tag is pressed.
How should I implement it?
return (
<div className="padding-16 flex gap-5 flex-container" onClick={onClickUser}>
<img src={img} />
<div className="flex flex-direction gridgap-5">
<p>
{name}
</p>
<p>
{age}
</p>
</div>
<span className="hover" onClick={isShowCard}>
<img src="img/dot.svg" />
</span>
</div>
)
You can use stopPropagation() for span click event.
isShowCard = (event) => {
event.stopPropagation()
...
}
return (
<div className="padding-16 flex gap-5 flex-container" onClick={onClickUser}>
<img src={img} />
<div className="flex flex-direction gridgap-5">
<p>
{name}
</p>
<p>
{age}
</p>
</div>
<span className="hover" onClick={isShowCard}>
<img src="img/dot.svg" />
</span>
</div>
)
Have onClickUser check to see whether it has an ancestor with a class name of hover before continuing. For example, change:
const onClickUser = (e) => {
// code
};
to
const onClickUser = (e) => {
if (e.target.closest('.hover')) {
// do nothing
return;
}
// code
};

Get bootstrap modal close event in reactjs

I am using React 16 with Bootstrap 4.
I am using bootstrap modal to display some values. I need to reset these values whenever modal is closed.
For Modal I have created a separate component. I dont want to use React-Modal as I get all the functionality in the current modal.
I know in plain javascript it is achieved using below code:
$(".modal").on("hidden.bs.modal"){
//reset values here
};
But I dont know how this is achieved in ReactJS?
Below is my code for modal:
<div className="modal fade modal-flex" id="large-Modal-OneUser" tabIndex={-1} role="dialog">
<div className="modal-dialog modal-lg" role="document">
<div className="modal-content">
<div className="modal-header" style={{display: 'block'}}>
<div className="row">
<div className="col-md-6">
<h2 style={{fontWeight:600}}>{newTimelineData.length > 0 ? newTimelineData[0].candidateName : ""}</h2>
</div>
<div className="col-md-6">
<span style={{display: 'inline-flex',alignItems: 'center',float:'right'}}><h4 style={{paddingRight:20}}>{isNotEmpty(this.state.scheduledFor) ? moment(this.state.scheduledFor).format("DD-MMM-YYYY"):this.checkScheduledFor(newTimelineData)}</h4>
<h3 style={{paddingRight: 10}}>{isNotEmpty(this.state.probability) ? this.getProbabilityHTML() : this.checkProbability(newTimelineData)}</h3>
{/*<button type="button" className="close" data-dismiss="modal" aria-label="Close" style={{marginTop: 0,marginBottom: 10}}>
<span aria-hidden="true">×</span>
</button>*/}
</span>
</div>
</div>
</div>
<div className="modal-body">
<div className="col-md-12">
{/*<div className="card">*/}
{/*<div className="card-block">*/}
{/* Horizontal Timeline start */}
<div className="cd-horizontal-timeline">
<div className="timeline">
<div className="events-wrapper">
<div className="events" id="foo">
<ol>
{newTimelineData.map((item, index) => (
<li key={item.id}>
<a
href="#0" onClick={()=> this.setHeaders(item)}
data-date={moment(item.scheduledFor).format('DD/MM/YYYY')}
className={index === 0 ? 'selected' : null}>
<Moment unix format="DD MMM">
{item.scheduledFor / 1000}
</Moment>
</a>
</li>
))}
</ol>
<span className="filling-line" aria-hidden="true" />
</div>
{/* .events */}
</div>
{/* .events-wrapper */}
<ul className="cd-timeline-navigation">
<li>
<a href="#0" className="prev inactive">
Prev
</a>
</li>
<li>
<a href="#0" className="next">
Next
</a>
</li>
</ul>
{/* .cd-timeline-navigation */}
</div>
{/* .timeline */}
<div className="events-content">
<ol>
{newTimelineData.map((item, index) => (
<li
key={item.id}
className={index === 0 ? 'selected' : null}
data-date={moment(item.scheduledFor).format('DD/MM/YYYY')}>
<div className="row">
<div className="col-sm-8" style={{fontSize:'1rem',paddingLeft: 3,paddingRight:0}}><b>Job</b> : {item.jobName}</div>
{isNotEmpty(joiningDate) && <div className="col-sm-4" style={{fontSize:'1rem',paddingLeft: 3,paddingRight:0}}><b>Joined Date : </b>{joiningDate}</div>}
</div>
<div className="row">
<div className="col-sm-8" style={{fontSize:'1rem',padding:0}}><b>Stage</b> : {this.props.stage}</div>
{isNotEmpty(offerDate) && <div className="col-sm-4" style={{fontSize:'1rem',paddingLeft: 0,paddingRight:0}}><b>Offer Date : </b>{offerDate}</div>}
</div>
<br></br>
<div className="row">
<div className="col-sm-12" style={{fontSize:'1rem',paddingLeft: 0}}><b>Comments</b> :<br></br>{item.comments}</div>
</div>
</li>
))}
</ol>
</div>
{/* .events-content */}
</div>
{/* Horizontal Timeline end */}
{/*</div>*/}
{/*</div>*/}
</div>
</div>
<div className="modal-footer">
<button style={{backgroundColor: '#8080808f',borderColor:'#8080808f'}}
type="button"
className="btn btn-primary waves-effect waves-light"
data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
Can anyone help?
See below snapshot for the work around I have tried suggested by #Jayavel.
Implemented a small workaround and hope it's fulfills your need, With my understanding you load your modal body with state and user will change something and you store those in the same state.
While closing the modal(close button) you need to reset the initial state i.e reset to default values.
Is that right !!! check this demo
what you need is,
store your default state like below:
const initialState = {
isOpen: false,
value: "defaultvalue"
};
and in component :
class App extends Component {
constructor(props) {
super(props);
this.state = initialState; // stored defaultstate
}
toggleModal = () => {
this.setState({
isOpen: !this.state.isOpen
});
}
toggleModalClose = () => { // modal close to reset input val
this.setState(initialState);
}
handleChange = (e) => {
this.setState({
value: e.target.value //input new value
});
}
render() {
return (
<div className="App">
<button onClick={this.toggleModal}>
Open the modal
</button>
<Modal show={this.state.isOpen}
onClose={this.toggleModalClose}>
<input type="text" value={this.state.value} onChange={this.handleChange} />
</Modal>
</div>
);
}
}
Hope this helps.

Materialize in React not showing

I am implementing Materialize modal in react but it does not show anything. I separated the modal into component and the button that calls the modal in the parent container.
Here is my code:
Parent.js:
return (
<div>
<div>
<HelpForm />
</div>
<div className="container">
<ul className="collection">
{items.map(item =>
<a refs="modalTrigger" className="modal-trigger"
key={item.id}
data-target="#modal1">
<HelpFeedItem key={item.id} item={item} />
</a>
)}
</ul>
<HelpFeedModal />
</div>
</div>
);
Modal.js
render() {
return (
<div id="modal1" className="modal modal-fixed-footer">
<div className="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div className="modal-footer">
Agree
</div>
</div>
);
Is there something obvious that I am missing?
Thanks!
I got this to work by including jQuery in my project and then adding the suggested jQuery code at the top the render function in a component.
index.html:
<html>
<body>
//Any other html
<script src="jquery cdn of your choice"></script>
</body>
</html>
ModalComponent.js:
class Modal extends Component {
render() {
//You must use window.$ or $ will be undefined
window.$(document).ready(function() {
window.$('.modal').modal();
});
return (
<div>
//this is the trigger
<a class="waves-effect waves-light btn" href="#modal1">Modal</a>
//this is the modal
<div id='modal1' className='modal'>
<div className='modal-content'>
<h4>Modal Header</h4>
<p>Text in the modal body</p>
</div>
</div>
</div>
)
}
}
You need to use react-materialize in order to use Materialize's javascript components. https://github.com/react-materialize/react-materialize

Resources