From 740230c9593faaf90040e7366d78d96e444a2eb2 Mon Sep 17 00:00:00 2001 From: Oliver Song Date: Tue, 22 Sep 2015 20:33:37 -0700 Subject: [PATCH 1/4] Implement optional time delay before querying on async options --- src/Select.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/Select.js b/src/Select.js index e1124f7c03..78f135923b 100644 --- a/src/Select.js +++ b/src/Select.js @@ -26,6 +26,7 @@ var Select = React.createClass({ clearAllText: React.PropTypes.string, // title for the "clear" control when multi: true clearValueText: React.PropTypes.string, // title for the "clear" control clearable: React.PropTypes.bool, // should it be possible to reset value + delayAsyncMs: React.PropTypes.number, // time delay before querying after a keyup delimiter: React.PropTypes.string, // delimiter to use to join multiple values disabled: React.PropTypes.bool, // whether the Select is disabled or not filterOption: React.PropTypes.func, // method to filter a single option: function(option, filterString) @@ -68,6 +69,7 @@ var Select = React.createClass({ clearAllText: 'Clear all', clearValueText: 'Clear value', clearable: true, + delayAsyncMs: 0, delimiter: ',', disabled: false, ignoreCase: true, @@ -103,6 +105,7 @@ var Select = React.createClass({ * - placeholder * - focusedOption */ + inputTimer: undefined, isFocused: false, isLoading: false, isOpen: false, @@ -498,14 +501,33 @@ var Select = React.createClass({ } if (this.props.asyncOptions) { + var callAsyncLoad = function() { + this.loadAsyncOptions(event.target.value, { + isLoading: false, + isOpen: true + }, this._bindCloseMenuIfClickedOutside); + }.bind(this); + + if (this.props.delayAsyncMs) { + if (this.state.inputTimer) { + clearTimeout(this.state.inputTimer); + } + + var wait = setTimeout(function() { + callAsyncLoad(); + }, this.props.delayAsyncMs); + + this.setState({ + inputTimer: wait + }); + } else { + callAsyncLoad(); + } + this.setState({ isLoading: true, inputValue: event.target.value }); - this.loadAsyncOptions(event.target.value, { - isLoading: false, - isOpen: true - }, this._bindCloseMenuIfClickedOutside); } else { var filteredOptions = this.filterOptions(this.state.options); this.setState({ From b520b6558b4e60ce2afbc02412b30fce49b2e1e0 Mon Sep 17 00:00:00 2001 From: Oliver Song Date: Tue, 22 Sep 2015 23:50:44 -0700 Subject: [PATCH 2/4] Use internal var instead of closure --- src/Select.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Select.js b/src/Select.js index 78f135923b..0be870a1c6 100644 --- a/src/Select.js +++ b/src/Select.js @@ -497,12 +497,12 @@ var Select = React.createClass({ this._optionsFilterString = event.target.value; if (this.props.onInputChange) { - this.props.onInputChange(event.target.value); + this.props.onInputChange(this._optionsFilterString); } if (this.props.asyncOptions) { var callAsyncLoad = function() { - this.loadAsyncOptions(event.target.value, { + this.loadAsyncOptions(this._optionsFilterString, { isLoading: false, isOpen: true }, this._bindCloseMenuIfClickedOutside); From bb8853a3553de1917bf1fa405776a5f3ba87f71e Mon Sep 17 00:00:00 2001 From: Oliver Song Date: Tue, 22 Sep 2015 23:53:44 -0700 Subject: [PATCH 3/4] Change README and comment prop --- README.md | 1 + src/Select.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 27f19880ef..f3414b60bd 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ For multi-select inputs, when providing a custom `filterOptions` method, remembe clearable | bool | should it be possible to reset value clearAllText | string | title for the "clear" control when multi: true clearValueText | string | title for the "clear" control + delayAsyncMs | number | time delay before querying after an input change delimiter | string | delimiter to use to join multiple values disableCache | bool | disables the options cache for asyncOptions disabled | bool | whether the Select is disabled or not diff --git a/src/Select.js b/src/Select.js index 0be870a1c6..975fdee70b 100644 --- a/src/Select.js +++ b/src/Select.js @@ -26,7 +26,7 @@ var Select = React.createClass({ clearAllText: React.PropTypes.string, // title for the "clear" control when multi: true clearValueText: React.PropTypes.string, // title for the "clear" control clearable: React.PropTypes.bool, // should it be possible to reset value - delayAsyncMs: React.PropTypes.number, // time delay before querying after a keyup + delayAsyncMs: React.PropTypes.number, // time delay before querying after an input change delimiter: React.PropTypes.string, // delimiter to use to join multiple values disabled: React.PropTypes.bool, // whether the Select is disabled or not filterOption: React.PropTypes.func, // method to filter a single option: function(option, filterString) From aedc77766dfecd89087a26c97b5d1a180847d10a Mon Sep 17 00:00:00 2001 From: Oliver Song Date: Wed, 23 Sep 2015 13:05:59 -0700 Subject: [PATCH 4/4] Event target value -> optionsFilterString --- src/Select.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Select.js b/src/Select.js index 975fdee70b..ce4ce52e3c 100644 --- a/src/Select.js +++ b/src/Select.js @@ -526,13 +526,13 @@ var Select = React.createClass({ this.setState({ isLoading: true, - inputValue: event.target.value + inputValue: this._optionsFilterString }); } else { var filteredOptions = this.filterOptions(this.state.options); this.setState({ isOpen: true, - inputValue: event.target.value, + inputValue: this._optionsFilterString, filteredOptions: filteredOptions, focusedOption: this._getNewFocusedOption(filteredOptions) }, this._bindCloseMenuIfClickedOutside);