mirror of
https://github.com/danog/react-datalist-input.git
synced 2024-12-04 10:28:19 +01:00
open menu on click on input if length of input is bigger as required, click outside of menu, will close dropdown
This commit is contained in:
parent
8499550754
commit
873642c1b0
@ -18,7 +18,45 @@ class DataListInput extends React.Component {
|
|||||||
visible: false,
|
visible: false,
|
||||||
/* index of the currently focused item in the drop down menu */
|
/* index of the currently focused item in the drop down menu */
|
||||||
focusIndex: 0,
|
focusIndex: 0,
|
||||||
|
/* cleaner click events */
|
||||||
|
interactionHappened: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
window.addEventListener( 'click', this.onClickCloseMenu, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount = () => {
|
||||||
|
window.removeEventListener( 'click', this.onClickCloseMenu );
|
||||||
|
}
|
||||||
|
|
||||||
|
onClickCloseMenu = ( event ) => {
|
||||||
|
const menu = document.getElementsByClassName( 'datalist-items' );
|
||||||
|
if ( !menu || !menu.length ) return;
|
||||||
|
// if rerender, items inside might change, allow one click without further checking
|
||||||
|
const { interactionHappened } = this.state;
|
||||||
|
if ( interactionHappened ) {
|
||||||
|
this.setState( { interactionHappened: false } );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// do not do anything if input is clicked, as we have a dedicated func for that
|
||||||
|
const input = document.getElementByClassName( 'autocomplete-input' );
|
||||||
|
if( !input ) return;
|
||||||
|
for( let i = 0; i < input.length; i+=1 ) {
|
||||||
|
const targetIsInput = event.target === input[i];
|
||||||
|
const targetInInput = input[i].contains( event.target );
|
||||||
|
if ( targetIsInput || targetInInput ) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do not close menu if user clicked inside
|
||||||
|
for( let i = 0; i < input.length; i+=1 ) {
|
||||||
|
const targetInMenu = menu[ i ].contains( event.target );
|
||||||
|
const targetIsMenu = event.target === menu[ i ];
|
||||||
|
if ( targetIsInput || targetInInput ) return;
|
||||||
|
}
|
||||||
|
const { visible } = this.state;
|
||||||
|
if ( visible && ( !targetInMenu && !targetIsMenu ) ) {
|
||||||
|
this.setState( { visible: false, focusIndex: -1 } );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,6 +176,7 @@ class DataListInput extends React.Component {
|
|||||||
currentInput: clearInputOnSelect ? '' : selectedItem.label,
|
currentInput: clearInputOnSelect ? '' : selectedItem.label,
|
||||||
visible: false,
|
visible: false,
|
||||||
focusIndex: -1,
|
focusIndex: -1,
|
||||||
|
interactionHappened: true,
|
||||||
} );
|
} );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -147,6 +186,7 @@ class DataListInput extends React.Component {
|
|||||||
lastValidItem: selectedItem,
|
lastValidItem: selectedItem,
|
||||||
visible: false,
|
visible: false,
|
||||||
focusIndex: -1,
|
focusIndex: -1,
|
||||||
|
interactionHappened: true,
|
||||||
} );
|
} );
|
||||||
// callback function onSelect
|
// callback function onSelect
|
||||||
const { onSelect } = this.props;
|
const { onSelect } = this.props;
|
||||||
@ -186,9 +226,10 @@ class DataListInput extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
renderInputField = ( placeholder, currentInput, inputClassName ) => (
|
renderInputField = ( placeholder, currentInput, inputClassName, reachedRequiredLength ) => (
|
||||||
<input
|
<input
|
||||||
onChange={this.onHandleInput}
|
onChange={this.onHandleInput}
|
||||||
|
onClick={ reachedRequiredLength && this.setState( { visible: true } ) }
|
||||||
onKeyDown={this.onHandleKeydown}
|
onKeyDown={this.onHandleKeydown}
|
||||||
type="text"
|
type="text"
|
||||||
className={`autocomplete-input ${ inputClassName }`}
|
className={`autocomplete-input ${ inputClassName }`}
|
||||||
@ -207,7 +248,7 @@ class DataListInput extends React.Component {
|
|||||||
const reachedRequiredLength = currentInput.length >= requiredInputLength;
|
const reachedRequiredLength = currentInput.length >= requiredInputLength;
|
||||||
return (
|
return (
|
||||||
<div className="datalist-input">
|
<div className="datalist-input">
|
||||||
{ this.renderInputField( placeholder, currentInput, inputClassName ) }
|
{ this.renderInputField( placeholder, currentInput, inputClassName, reachedRequiredLength ) }
|
||||||
{ reachedRequiredLength && visible
|
{ reachedRequiredLength && visible
|
||||||
&& this.renderItems( currentInput, matchingItems, focusIndex,
|
&& this.renderItems( currentInput, matchingItems, focusIndex,
|
||||||
activeItemClassName, itemClassName )
|
activeItemClassName, itemClassName )
|
||||||
|
Loading…
Reference in New Issue
Block a user