FreakProgrammer FreakProgrammer - 3 months ago 23
React JSX Question

Outside Click handle event on element

can you tell me how can i handle a click on outside of element .For example i have that

<td><input type="number" className="hour" onKeyDown={this.editInlineHour(this)} /></td>


and i want only when i click outside of that element to execute some function and that is it in react !

I try it with that

window.addEventListener('mousedown', this.pageClick, false);


but even when i click on input field the function is executed.Thanks
This is my full code ..basically it is inline edit on field on table.. when i click on that field it show input field.. and i want when i click outside that field do go away

editInlineHour:function () {

},
showInlineEditHour:function (i) {
this.setState({
index:i,
showInlineHour:true
})
},
showInlineEditStart:function (i) {
this.setState({
index:i,
showInlineStart:true
})
},
showInlineEditEnd:function (i) {
this.setState({
index:i,
showInlineEnd:true
})
},
pageClick:function () {
this.setState({
showInlineStart:false,
showInlineEnd:false,
showInlineHour:false
});
},
render: function () {

var itemMap = this.state.items.map(function (item, i) {
var fieldDp1;
if(this.state.showInlineStart){
fieldDp1 = <input id="inlineDp1" className="flatpickr" data-date-format="m/d/Y"/>
}else{
fieldDp1 = <td onDoubleClick={this.showInlineEditStart.bind(this,i)} ><FormattedDate value={item.startDate}/></td>
}
var fieldDp2;
if(this.state.showInlineEnd){
fieldDp2 = <input id="inlineDp2" className="flatpickr" data-date-format="m/d/Y" />
}else{
fieldDp2 = <td onDoubleClick={this.showInlineEditEnd.bind(this,i)}><FormattedDate value={item.endDate}/></td>
}
var fieldHours;
if(this.state.showInlineHour){
fieldHours = <td><input type="number" className="hour" onKeyDown={this.editInlineHour(this)} /></td>
}else{
fieldHours = <td onDoubleClick={this.showInlineEditHour.bind(this,i)} >{item.workInHours}</td>

}
return (
<tr key={i}>
<td><input type="checkbox" checked={item.selected} onClick={this.handleChange.bind(this,i)} /></td>
{fieldDp1}
{fieldDp2}
{fieldHours}
<td><label type="button" onClick={this.handleShowModal.bind(this,i)}><img height="30px" src="moliv.jpg"/></label>
</td>
</tr>
);

}.bind(this));
return (
<div>
<button className="btn btn-primary center-block" onClick={this.addElem}>Add</button>
{this.state.list.theList.length > 0 ? <button className="btn btn-primary" onClick={this.putResult}>Put result</button> :null}
<table className="table scroll2">
<thead>
<tr className="danger">
<th><input type="checkbox" checked={this.state.allChecked} onClick={this.toggleAll}/></th>
<th>Start Date</th>
<th>End Date</th>
<th>Hours</th>
<th></th>
</tr>
</thead>
<tbody>
{itemMap}

</tbody>

</table>
{this.state.items.length > 0 ? <button type="button" className="btn btn-danger" onClick={this.deleteItems}>Remove</button> : null}
<Modal parentState={this.state} modalPropsId={this.props.theProps.id} handleHideModal={this.handleHideModal}/>
</div>
);

Answer

You can add ref to your element and check if click event comes outside of it.

function handleClickOutside(evt) {
  if (this.refs.yourInput !== evt.target) {
    callSomeFunction();
  }
  return true;
}

componentDidMount() {
  this.clickHandler = handleClickOutside.bind(this);
  document.addEventListener('click', this.clickHandler, true);
} 

componentWillUnmount() {
  document.removeEventListener('click', this.clickHandler, true);
}

In case if you want to check outside click for some component with children, you can use contains

if (!this.refs.yourComponent.contains(evt.target)) {
  callSomeFunction();
}