[PROOF OF CONCEPT] For when you want "tabbable" children (e.g. in Date selector composed of a textfield for Day, Month and year) but only want to perform validation on blur-entire-component not each Textfield
class BlurCapturer extends React.Component {
static propTypes = {
name: PropTypes.string.isRequired,
onBlur: PropTypes.func,
children: PropTypes.node,
}
setListeners = (ref) => {
this.el = findDOMNode(ref);
this.el.addEventListener('blur', this.handleBlur, true);
}
handleBlur = (event) => {
if (event.target !== this.el) {
event.preventDefault();
event.stopPropagation();
}
console.log({
current: event.currentTarget && event.currentTarget.getAttribute('name'),
related: event.relatedTarget && event.relatedTarget.getAttribute('name'),
target: event.target && event.target.getAttribute('name'),
});
setTimeout(() => { // Needs timeout https://stackoverflow.com/a/121708/225813
if (this.props.onBlur && !this.el.contains(document.activeElement)) {
const inputIterator = this.el.querySelectorAll('input').values();
const values = [...inputIterator].map(input => input.value);
this.props.onBlur(this.props.name, values);
}
});
}
render() {
return (
<Padded ref={this.setListeners} {...this.props}>
{this.props.children}
<input name="day" />
<input name="month" />
<input name="year" />
</Padded>
);
}
}
Usage:
<BlurCapturer name="outer" onBlur={console.log}>
<input name="label" />
</BlurCapturer>
Note: works with children