From e4aa40211840bb99c7186a10adc457741d35a463 Mon Sep 17 00:00:00 2001
From: Emiliano Santi
Date: Tue, 22 Mar 2016 20:54:32 -0300
Subject: [PATCH 1/4] [Added] Trigger event with query when Enter key is
pressed
---
examples/async-data/app.js | 75 ++++++++++++++++++------------
lib/Autocomplete.js | 6 ++-
lib/__tests__/Autocomplete-test.js | 19 +++++++-
package.json | 3 +-
4 files changed, 70 insertions(+), 33 deletions(-)
diff --git a/examples/async-data/app.js b/examples/async-data/app.js
index c1ff0b17..7e34805f 100644
--- a/examples/async-data/app.js
+++ b/examples/async-data/app.js
@@ -7,7 +7,8 @@ let App = React.createClass({
getInitialState () {
return {
unitedStates: getStates(),
- loading: false
+ loading: false,
+ valueEntered: ''
}
},
@@ -15,42 +16,58 @@ let App = React.createClass({
return (
Async Data
-
Autocomplete works great with async data by allowing you to pass in
items. The onChange
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.
-
-
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) => (
- {item.name}
- )}
- />
+
+ {this.renderMessage()}
)
+ },
+
+ renderMessage () {
+ let dataToRender = null;
+
+ if (this.state.valueEntered) {
+ dataToRender = Your search {this.state.valueEntered} is not in the list of states. Making service call...
;
+ }
+
+ 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) => (
+ {item.name}
+ )
+ };
}
})
diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js
index fe479517..1fe6e4b7 100644
--- a/lib/Autocomplete.js
+++ b/lib/Autocomplete.js
@@ -10,6 +10,7 @@ let Autocomplete = React.createClass({
initialValue: React.PropTypes.any,
onChange: React.PropTypes.func,
onSelect: React.PropTypes.func,
+ onSearch: React.PropTypes.func,
shouldItemRender: React.PropTypes.func,
renderItem: React.PropTypes.func.isRequired,
menuStyle: React.PropTypes.object,
@@ -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 {
diff --git a/lib/__tests__/Autocomplete-test.js b/lib/__tests__/Autocomplete-test.js
index 0ed62408..92c6938e 100644
--- a/lib/__tests__/Autocomplete-test.js
+++ b/lib/__tests__/Autocomplete-test.js
@@ -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';
@@ -12,6 +13,8 @@ import { getStates, matchStateToTerm, sortStates, styles } from '../utils'
chai.use(chaiEnzyme());
+let onSearchStub = sinon.stub();
+
function AutocompleteComponentJSX (extraProps) {
return (
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 });
@@ -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');
diff --git a/package.json b/package.json
index e08e8de3..24ca63ca 100644
--- a/package.json
+++ b/package.json
@@ -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",
From eecee25074dede11fba4a9591282b0fee1c24e5f Mon Sep 17 00:00:00 2001
From: Emiliano Santi
Date: Tue, 22 Mar 2016 21:07:51 -0300
Subject: [PATCH 2/4] [changed] Fixing console warning - React.render is
deprecated. Please use ReactDOM.render
---
examples/async-data/app.js | 3 ++-
examples/custom-menu/app.js | 3 ++-
examples/static-data/app.js | 3 ++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/examples/async-data/app.js b/examples/async-data/app.js
index 7e34805f..d215a03e 100644
--- a/examples/async-data/app.js
+++ b/examples/async-data/app.js
@@ -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'
@@ -71,5 +72,5 @@ let App = React.createClass({
}
})
-React.render(, document.getElementById('container'))
+ReactDOM.render(, document.getElementById('container'))
diff --git a/examples/custom-menu/app.js b/examples/custom-menu/app.js
index 1ea62c24..1699fc62 100644
--- a/examples/custom-menu/app.js
+++ b/examples/custom-menu/app.js
@@ -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'
@@ -75,6 +76,6 @@ let App = React.createClass({
}
})
-React.render(, document.getElementById('container'))
+ReactDOM.render(, document.getElementById('container'))
diff --git a/examples/static-data/app.js b/examples/static-data/app.js
index 9def5b08..613d259f 100644
--- a/examples/static-data/app.js
+++ b/examples/static-data/app.js
@@ -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'
@@ -33,5 +34,5 @@ let App = React.createClass({
}
})
-React.render(, document.getElementById('container'))
+ReactDOM.render(, document.getElementById('container'))
From d0c5e93da17cebf10921559edcf07afe0fdd77e0 Mon Sep 17 00:00:00 2001
From: Emiliano Santi
Date: Fri, 25 Mar 2016 01:05:44 -0300
Subject: [PATCH 3/4] Revert "[changed] Fixing console warning - React.render
is deprecated. Please use ReactDOM.render"
This reverts commit eecee25074dede11fba4a9591282b0fee1c24e5f.
---
examples/async-data/app.js | 3 +--
examples/custom-menu/app.js | 3 +--
examples/static-data/app.js | 3 +--
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/examples/async-data/app.js b/examples/async-data/app.js
index d215a03e..7e34805f 100644
--- a/examples/async-data/app.js
+++ b/examples/async-data/app.js
@@ -1,5 +1,4 @@
import React from 'react'
-import ReactDOM from 'react-dom'
import Autocomplete from '../../lib/index'
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../../lib/utils'
@@ -72,5 +71,5 @@ let App = React.createClass({
}
})
-ReactDOM.render(, document.getElementById('container'))
+React.render(, document.getElementById('container'))
diff --git a/examples/custom-menu/app.js b/examples/custom-menu/app.js
index 1699fc62..1ea62c24 100644
--- a/examples/custom-menu/app.js
+++ b/examples/custom-menu/app.js
@@ -1,5 +1,4 @@
import React from 'react'
-import ReactDOM from 'react-dom'
import Autocomplete from '../../lib/index'
import { getStates, matchStateToTerm, sortStates, styles, fakeRequest } from '../../lib/utils'
@@ -76,6 +75,6 @@ let App = React.createClass({
}
})
-ReactDOM.render(, document.getElementById('container'))
+React.render(, document.getElementById('container'))
diff --git a/examples/static-data/app.js b/examples/static-data/app.js
index 613d259f..9def5b08 100644
--- a/examples/static-data/app.js
+++ b/examples/static-data/app.js
@@ -1,5 +1,4 @@
import React from 'react'
-import ReactDOM from 'react-dom'
import { getStates, matchStateToTerm, sortStates, styles } from '../../lib/utils'
import Autocomplete from '../../lib/index'
@@ -34,5 +33,5 @@ let App = React.createClass({
}
})
-ReactDOM.render(, document.getElementById('container'))
+React.render(, document.getElementById('container'))
From 6469f22d57e952562d9f831566344e7dd5961702 Mon Sep 17 00:00:00 2001
From: Emiliano Santi
Date: Fri, 25 Mar 2016 11:14:43 -0300
Subject: [PATCH 4/4] [Added] Trigger event with query when Enter key is
pressed - Code Review changes.
---
examples/async-data/app.js | 76 ++++++++++++------------------
lib/Autocomplete.js | 12 +++--
lib/__tests__/Autocomplete-test.js | 8 ++--
3 files changed, 43 insertions(+), 53 deletions(-)
diff --git a/examples/async-data/app.js b/examples/async-data/app.js
index 7e34805f..2b964e28 100644
--- a/examples/async-data/app.js
+++ b/examples/async-data/app.js
@@ -7,8 +7,7 @@ let App = React.createClass({
getInitialState () {
return {
unitedStates: getStates(),
- loading: false,
- valueEntered: ''
+ loading: false
}
},
@@ -22,52 +21,37 @@ let App = React.createClass({
a server request with, then change state and pass in new items, it will
attempt to autocomplete the first one.
-
- {this.renderMessage()}
+ 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 })
+ })
+ }}
+ onSubmit={(value, setValue) => {
+ setValue(value.split(',').reverse().join())
+ }}
+ renderItem={(item, isHighlighted) => (
+ {item.name}
+ )}
+ />
)
- },
-
- renderMessage () {
- let dataToRender = null;
-
- if (this.state.valueEntered) {
- dataToRender = Your search {this.state.valueEntered} is not in the list of states. Making service call...
;
- }
-
- 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) => (
- {item.name}
- )
- };
}
})
diff --git a/lib/Autocomplete.js b/lib/Autocomplete.js
index 1fe6e4b7..ee83edd4 100644
--- a/lib/Autocomplete.js
+++ b/lib/Autocomplete.js
@@ -10,7 +10,7 @@ let Autocomplete = React.createClass({
initialValue: React.PropTypes.any,
onChange: React.PropTypes.func,
onSelect: React.PropTypes.func,
- onSearch: React.PropTypes.func,
+ onSubmit: React.PropTypes.func,
shouldItemRender: React.PropTypes.func,
renderItem: React.PropTypes.func.isRequired,
menuStyle: React.PropTypes.object,
@@ -146,8 +146,8 @@ let Autocomplete = React.createClass({
this.setState({
isOpen: false
}, () => {
- if (this.props.onSearch)
- this.props.onSearch(this.state.value);
+ if (this.props.onSubmit)
+ this.props.onSubmit(this.state.value, this.setValue);
else
this.refs.input.select();
})
@@ -178,6 +178,12 @@ let Autocomplete = React.createClass({
}
},
+ setValue (newValue) {
+ this.setState({
+ value: newValue
+ })
+ },
+
getFilteredItems () {
let items = this.props.items
diff --git a/lib/__tests__/Autocomplete-test.js b/lib/__tests__/Autocomplete-test.js
index 92c6938e..e1202e0f 100644
--- a/lib/__tests__/Autocomplete-test.js
+++ b/lib/__tests__/Autocomplete-test.js
@@ -13,7 +13,7 @@ import { getStates, matchStateToTerm, sortStates, styles } from '../utils'
chai.use(chaiEnzyme());
-let onSearchStub = sinon.stub();
+let onSubmitStub = sinon.stub();
function AutocompleteComponentJSX (extraProps) {
return (
@@ -166,7 +166,7 @@ describe('Autocomplete kewDown->ArrowUp event handlers', () => {
describe('Autocomplete kewDown->Enter event handlers', () => {
var autocompleteWrapper = mount(AutocompleteComponentJSX({
- onSearch: onSearchStub
+ onSubmit: onSubmitStub
}));
var autocompleteInputWrapper = autocompleteWrapper.find('input');
@@ -199,8 +199,8 @@ describe('Autocomplete kewDown->Enter event handlers', () => {
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);
+ expect(onSubmitStub.called).to.equal(true);
+ expect(onSubmitStub.calledWith('TEST', autocompleteWrapper.component.getWrappedComponent().setValue)).to.equal(true);
});
it('should update input value from selected menu item and close the menu', () => {