Skip to content
This repository was archived by the owner on Jul 19, 2019. It is now read-only.

Trigger event on enter #25 #83

Closed
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 48 additions & 30 deletions examples/async-data/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import ReactDOM from 'react-dom'
import Autocomplete from '../../lib/index'
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../../lib/utils'

Expand All @@ -7,52 +8,69 @@ let App = React.createClass({
getInitialState () {
return {
unitedStates: getStates(),
loading: false
loading: false,
valueEntered: ''
}
},

render () {
return (
<div>
<h1>Async Data</h1>

<p>
Autocomplete works great with async data by allowing you to pass in
items. The <code>onChange</code> event provides you the value to make
a server request with, then change state and pass in new items, it will
attempt to autocomplete the first one.
</p>

<Autocomplete
labelText="Choose a state from the US"
inputProps={{name: "US state"}}
ref="autocomplete"
items={this.state.unitedStates}
getItemValue={(item) => item.name}
onSelect={(value, item) => {
// set the menu to only the selected item
this.setState({ unitedStates: [ item ] })
// or you could reset it to a default list again
// this.setState({ unitedStates: getStates() })
}}
onChange={(event, value) => {
this.setState({loading: true})
fakeRequest(value, (items) => {
this.setState({ unitedStates: items, loading: false })
})
}}
renderItem={(item, isHighlighted) => (
<div
style={isHighlighted ? styles.highlightedItem : styles.item}
key={item.abbr}
id={item.abbr}
>{item.name}</div>
)}
/>
<Autocomplete {...this.getAutocompleteProps()} />
{this.renderMessage()}
</div>
)
},

renderMessage () {
let dataToRender = null;

if (this.state.valueEntered) {
dataToRender = <p>Your search {this.state.valueEntered} is not in the list of states. Making service call...</p>;
}

return dataToRender;
},

getAutocompleteProps () {
return {
labelText: "Choose a state from the US",
inputProps: { name: "US state" },
ref: "autocomplete",
items: this.state.unitedStates,
getItemValue: (item) => item.name,
onSelect: (value, item) => {
// set the menu to only the selected item
this.setState({ unitedStates: [ item ] })
// or you could reset it to a default list again
// this.setState({ unitedStates: getStates() })
},
onChange: (event, value) => {
this.setState({loading: true})
fakeRequest(value, (items) => {
this.setState({unitedStates: items, loading: false})
})
},
onSearch: (value) => {
this.setState({valueEntered: value})
},
renderItem: (item, isHighlighted) => (
<div
style={isHighlighted ? styles.highlightedItem : styles.item}
key={item.abbr}
id={item.abbr}
>{item.name}</div>
)
};
}
})

React.render(<App/>, document.getElementById('container'))
ReactDOM.render(<App/>, document.getElementById('container'))

3 changes: 2 additions & 1 deletion examples/custom-menu/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import ReactDOM from 'react-dom'
import Autocomplete from '../../lib/index'
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../../lib/utils'

Expand Down Expand Up @@ -75,6 +76,6 @@ let App = React.createClass({
}
})

React.render(<App/>, document.getElementById('container'))
ReactDOM.render(<App/>, document.getElementById('container'))


3 changes: 2 additions & 1 deletion examples/static-data/app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { getStates, matchStateToTerm, sortStates, styles } from '../../lib/utils'
import Autocomplete from '../../lib/index'

Expand Down Expand Up @@ -33,5 +34,5 @@ let App = React.createClass({
}
})

React.render(<App/>, document.getElementById('container'))
ReactDOM.render(<App/>, document.getElementById('container'))

6 changes: 5 additions & 1 deletion lib/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let Autocomplete = React.createClass({
initialValue: React.PropTypes.any,
onChange: React.PropTypes.func,
onSelect: React.PropTypes.func,
onSearch: React.PropTypes.func,
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to suggest another name for this props.

shouldItemRender: React.PropTypes.func,
renderItem: React.PropTypes.func.isRequired,
menuStyle: React.PropTypes.object,
Expand Down Expand Up @@ -145,7 +146,10 @@ let Autocomplete = React.createClass({
this.setState({
isOpen: false
}, () => {
this.refs.input.select()
if (this.props.onSearch)
this.props.onSearch(this.state.value);
else
this.refs.input.select();
})
}
else {
Expand Down
19 changes: 17 additions & 2 deletions lib/__tests__/Autocomplete-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ReactDOM from 'react-dom'
import TestUtils from 'react-addons-test-utils'
import jsdom from 'mocha-jsdom';
import chai from 'chai';
import sinon from 'sinon';
const expect = chai.expect;
import chaiEnzyme from 'chai-enzyme'
import { ok, equal } from 'assert';
Expand All @@ -12,6 +13,8 @@ import { getStates, matchStateToTerm, sortStates, styles } from '../utils'

chai.use(chaiEnzyme());

let onSearchStub = sinon.stub();

function AutocompleteComponentJSX (extraProps) {
return (
<Autocomplete
Expand Down Expand Up @@ -162,10 +165,12 @@ describe('Autocomplete kewDown->ArrowUp event handlers', () => {
});

describe('Autocomplete kewDown->Enter event handlers', () => {

var autocompleteWrapper = mount(AutocompleteComponentJSX({}));
var autocompleteWrapper = mount(AutocompleteComponentJSX({
onSearch: onSearchStub
}));
var autocompleteInputWrapper = autocompleteWrapper.find('input');


it('should do nothing if the menu is closed', () => {
autocompleteWrapper.setState({'isOpen': false});
autocompleteWrapper.simulate('keyDown', { key : 'Enter', keyCode: 13, which: 13 });
Expand All @@ -188,6 +193,16 @@ describe('Autocomplete kewDown->Enter event handlers', () => {

});

it('should call onSearch prop when no item has been selected and then the Enter key is hit', () => {
autocompleteWrapper.setState({'isOpen': true, highlightedIndex: null});
autocompleteInputWrapper.simulate('focus');
autocompleteInputWrapper.simulate('change', { target: { value: 'TEST' } });
autocompleteInputWrapper.simulate('keyDown', { key : 'Enter', keyCode: 13, which: 13 });

expect(onSearchStub.called).to.equal(true);
expect(onSearchStub.calledWith('TEST')).to.equal(true);
});

it('should update input value from selected menu item and close the menu', () => {
autocompleteWrapper.setState({'isOpen': true});
autocompleteInputWrapper.simulate('focus');
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"mocha-jsdom": "^1.1.0",
"rackt-cli": "^0.4.0",
"react": "^0.14.0",
"react-addons-test-utils": "^0.14.7"
"react-addons-test-utils": "^0.14.7",
"sinon": "^1.17.3"
},
"tags": [
"react",
Expand Down