diff --git a/README.md b/README.md index 1e4b842f..c23a261c 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,12 @@ Type: `Function` Event handler for the `focus` event on the typeahead input. +#### props.onClick + +Type: `Function` + +Event handler for the `click` event on the typeahead input. + #### props.onOptionSelected Type: `Function` @@ -269,6 +275,12 @@ Type: `Function` Event handler for the `focus` event on the typeahead input. +#### props.onClick + +Type: `Function` + +Event handler for the `click` event on the typeahead input. + #### props.defaultSelected Type: `Array` diff --git a/dist/react-typeahead.js b/dist/react-typeahead.js index 601dddfc..62c830a7 100644 --- a/dist/react-typeahead.js +++ b/dist/react-typeahead.js @@ -99,7 +99,7 @@ fuzzy.match = function(pattern, string, opts) { pattern = opts.caseSensitive && pattern || pattern.toLowerCase(); // For each character in the string, either add it to the result - // or wrap in template if its the next string in the pattern + // or wrap in template if it's the next string in the pattern for(var idx = 0; idx < len; idx++) { ch = string[idx]; if(compareString[idx] === pattern[patternIdx]) { @@ -141,8 +141,8 @@ fuzzy.match = function(pattern, string, opts) { // // string to put after matching character // , post: '' // -// // Optional function. Input is an element from the passed in -// // `arr`, output should be the string to test `pattern` against. +// // Optional function. Input is an entry in the given arr`, +// // output should be the string to test `pattern` against. // // In this example, if `arr = [{crying: 'koala'}]` we would return // // 'koala'. // , extract: function(arg) { return arg.crying; } @@ -150,31 +150,31 @@ fuzzy.match = function(pattern, string, opts) { fuzzy.filter = function(pattern, arr, opts) { opts = opts || {}; return arr - .reduce(function(prev, element, idx, arr) { - var str = element; - if(opts.extract) { - str = opts.extract(element); - } - var rendered = fuzzy.match(pattern, str, opts); - if(rendered != null) { - prev[prev.length] = { - string: rendered.rendered - , score: rendered.score - , index: idx - , original: element - }; - } - return prev; - }, []) - - // Sort by score. Browsers are inconsistent wrt stable/unstable - // sorting, so force stable by using the index in the case of tie. - // See http://ofb.net/~sethml/is-sort-stable.html - .sort(function(a,b) { - var compare = b.score - a.score; - if(compare) return compare; - return a.index - b.index; - }); + .reduce(function(prev, element, idx, arr) { + var str = element; + if(opts.extract) { + str = opts.extract(element); + } + var rendered = fuzzy.match(pattern, str, opts); + if(rendered != null) { + prev[prev.length] = { + string: rendered.rendered + , score: rendered.score + , index: idx + , original: element + }; + } + return prev; + }, []) + + // Sort by score. Browsers are inconsistent wrt stable/unstable + // sorting, so force stable by using the index in the case of tie. + // See http://ofb.net/~sethml/is-sort-stable.html + .sort(function(a,b) { + var compare = b.score - a.score; + if(compare) return compare; + return a.index - b.index; + }); }; @@ -525,6 +525,7 @@ var Typeahead = React.createClass({displayName: "Typeahead", onKeyUp: React.PropTypes.func, onFocus: React.PropTypes.func, onBlur: React.PropTypes.func, + onClick: React.PropTypes.func, filterOption: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.func @@ -560,6 +561,7 @@ var Typeahead = React.createClass({displayName: "Typeahead", onKeyUp: function(event) {}, onFocus: function(event) {}, onBlur: function(event) {}, + onClick: function(event) {}, filterOption: null, defaultClassNames: true, customListComponent: TypeaheadSelector @@ -802,7 +804,8 @@ var Typeahead = React.createClass({displayName: "Typeahead", onKeyDown: this._onKeyDown, onKeyUp: this.props.onKeyUp, onFocus: this.props.onFocus, - onBlur: this.props.onBlur}) + onBlur: this.props.onBlur, + onClick: this.props.onClick}) ), this._renderIncrementalSearchResults() ) diff --git a/src/tokenizer/index.js b/src/tokenizer/index.js index 361dca38..8b87526b 100644 --- a/src/tokenizer/index.js +++ b/src/tokenizer/index.js @@ -40,6 +40,7 @@ var TypeaheadTokenizer = React.createClass({ onTokenAdd: React.PropTypes.func, onFocus: React.PropTypes.func, onBlur: React.PropTypes.func, + onClick: React.PropTypes.func, filterOption: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.func @@ -76,6 +77,7 @@ var TypeaheadTokenizer = React.createClass({ onKeyUp: function(event) {}, onFocus: function(event) {}, onBlur: function(event) {}, + onClick: function(event) {}, onTokenAdd: function() {}, onTokenRemove: function() {} }; @@ -193,6 +195,7 @@ var TypeaheadTokenizer = React.createClass({ onKeyUp={this.props.onKeyUp} onFocus={this.props.onFocus} onBlur={this.props.onBlur} + onClick={this.props.onClick} displayOption={this.props.displayOption} defaultClassNames={this.props.defaultClassNames} filterOption={this.props.filterOption} /> diff --git a/src/typeahead/index.js b/src/typeahead/index.js index 03466cee..d7571e8b 100644 --- a/src/typeahead/index.js +++ b/src/typeahead/index.js @@ -38,6 +38,7 @@ var Typeahead = React.createClass({ onKeyUp: React.PropTypes.func, onFocus: React.PropTypes.func, onBlur: React.PropTypes.func, + onClick: React.PropTypes.func, filterOption: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.func @@ -73,6 +74,7 @@ var Typeahead = React.createClass({ onKeyUp: function(event) {}, onFocus: function(event) {}, onBlur: function(event) {}, + onClick: function(event) {}, filterOption: null, defaultClassNames: true, customListComponent: TypeaheadSelector @@ -316,6 +318,7 @@ var Typeahead = React.createClass({ onKeyUp={this.props.onKeyUp} onFocus={this.props.onFocus} onBlur={this.props.onBlur} + onClick={this.props.onClick} /> { this._renderIncrementalSearchResults() } diff --git a/test/tokenizer-test.js b/test/tokenizer-test.js index 0d91c4a0..ef65fefa 100644 --- a/test/tokenizer-test.js +++ b/test/tokenizer-test.js @@ -123,6 +123,22 @@ describe('TypeaheadTokenizer Component', function() { TestUtils.Simulate.keyUp(input, { keyCode: 87 }); }); }); + + context('onClick', function() { + it('should bind to input', function() { + var component = TestUtils.renderIntoDocument(); + + var input = React.findDOMNode(component.refs.typeahead.refs.entry); + TestUtils.Simulate.click(input); + }); + }); + describe('props', function(){ context('displayOption', function() { it('renders simple options verbatim when not specified', function() { diff --git a/test/typeahead-test.js b/test/typeahead-test.js index 4931fec8..1c9102d3 100644 --- a/test/typeahead-test.js +++ b/test/typeahead-test.js @@ -372,6 +372,21 @@ describe('Typeahead Component', function() { }); }); + context('onClick', function() { + it('should bind to input', function() { + var component = TestUtils.renderIntoDocument(); + + var input = component.refs.entry.getDOMNode(); + TestUtils.Simulate.click(input); + }); + }); + context('inputProps', function() { it('should forward props to the input element', function() { var component = TestUtils.renderIntoDocument(