From da64e9a7126ce7f7d2149f8cd1e2fcd5b5e029c6 Mon Sep 17 00:00:00 2001 From: Yongxu Ren Date: Sat, 31 Oct 2015 14:35:06 -0500 Subject: [PATCH] changed to auto-complete bug fixed --- docs/src/app/app-routes.jsx | 4 +- docs/src/app/components/pages/components.jsx | 2 +- .../pages/components/auto-complete.jsx | 82 ++++++++++++ .../pages/components/search-field.jsx | 54 -------- .../raw-code/auto-complete-code.txt | 28 +++++ .../components/raw-code/search-field-code.txt | 8 -- src/{search-field.jsx => auto-complete.jsx} | 119 +++++++++++------- src/index.js | 2 +- 8 files changed, 191 insertions(+), 108 deletions(-) create mode 100644 docs/src/app/components/pages/components/auto-complete.jsx delete mode 100644 docs/src/app/components/pages/components/search-field.jsx create mode 100644 docs/src/app/components/raw-code/auto-complete-code.txt delete mode 100644 docs/src/app/components/raw-code/search-field-code.txt rename src/{search-field.jsx => auto-complete.jsx} (68%) diff --git a/docs/src/app/app-routes.jsx b/docs/src/app/app-routes.jsx index 95105cac889440..abd5101590dd61 100644 --- a/docs/src/app/app-routes.jsx +++ b/docs/src/app/app-routes.jsx @@ -21,6 +21,7 @@ const InlineStyles = require('./components/pages/customization/inline-styles'); const Components = require('./components/pages/components'); const AppBar = require('./components/pages/components/app-bar'); +const AutoComplete = require('./components/pages/components/auto-complete'); const Avatars = require('./components/pages/components/avatars'); const Buttons = require('./components/pages/components/buttons'); const Cards = require('./components/pages/components/cards'); @@ -37,7 +38,6 @@ const Menus = require('./components/pages/components/menus'); const Paper = require('./components/pages/components/paper'); const Progress = require('./components/pages/components/progress'); const RefreshIndicator = require('./components/pages/components/refresh-indicator'); -const SearchField = require('./components/pages/components/search-field'); const Sliders = require('./components/pages/components/sliders'); const Snackbar = require('./components/pages/components/snackbar'); const Switches = require('./components/pages/components/switches'); @@ -77,6 +77,7 @@ const AppRoutes = ( + @@ -93,7 +94,6 @@ const AppRoutes = ( - diff --git a/docs/src/app/components/pages/components.jsx b/docs/src/app/components/pages/components.jsx index 2bbd3f06316b0b..75b171f4d2bf28 100644 --- a/docs/src/app/components/pages/components.jsx +++ b/docs/src/app/components/pages/components.jsx @@ -6,6 +6,7 @@ export default class Components extends React.Component { render() { let menuItems = [ { route: '/components/appbar', text: 'AppBar'}, + { route: '/components/auto-complete', text: 'Auto Complete'}, { route: '/components/avatars', text: 'Avatars'}, { route: '/components/buttons', text: 'Buttons'}, { route: '/components/cards', text: 'Cards'}, @@ -22,7 +23,6 @@ export default class Components extends React.Component { { route: '/components/paper', text: 'Paper'}, { route: '/components/progress', text: 'Progress'}, { route: '/components/refresh-indicator', text: 'Refresh Indicator'}, - { route: '/components/search-field', text: 'Search Field'}, { route: '/components/sliders', text: 'Sliders'}, { route: '/components/switches', text: 'Switches'}, { route: '/components/snackbar', text: 'Snackbar'}, diff --git a/docs/src/app/components/pages/components/auto-complete.jsx b/docs/src/app/components/pages/components/auto-complete.jsx new file mode 100644 index 00000000000000..60d0dad67f928c --- /dev/null +++ b/docs/src/app/components/pages/components/auto-complete.jsx @@ -0,0 +1,82 @@ +const React = require('react'); + +const { AutoComplete } = require('material-ui'); +const ComponentDoc = require('../../component-doc'); + +const Code = require('auto-complete-code'); + +class AutoCompletePage extends React.Component { + + constructor(props) { + super(props); + } + + render() { + + let desc = null; + + return ( + + +
+ +
+ {console.log(t); return [t, t+t, t+t+t];}} + onNewRequest={(t) => {console.log('request:'+t);}} /> + + {console.log(t); return [t, t+t, t+t+t];}} + onNewRequest={(t) => {console.log('request:'+t);}} /> + + {console.log(t); return [t, t+t, t+t+t];}} + onNewRequest={(t) => {console.log('request:'+t);}} /> + + { + console.log(t); + return [ + (), + (), + (), + ]; + }} + onNewRequest={(t, index) => {console.log('request:'+index);}} /> + + + + + + +
+ +
+ ); + + } + + +} + +module.exports = AutoCompletePage; diff --git a/docs/src/app/components/pages/components/search-field.jsx b/docs/src/app/components/pages/components/search-field.jsx deleted file mode 100644 index 13328a805cf700..00000000000000 --- a/docs/src/app/components/pages/components/search-field.jsx +++ /dev/null @@ -1,54 +0,0 @@ -let React = require('react'); - -let { SearchField } = require('material-ui'); -let ComponentDoc = require('../../component-doc'); - -let Code = require('search-field-code'); - -class SearchFields extends React.Component { - - constructor(props) { - super(props); - } - - render() { - - let desc = null; - - return ( - - -
- -
- {console.log(t); return [t, t+t, t+t+t];}} - onNewRequest={(t) => {console.log('request:'+t);}} /> - {console.log(t); return [t, t+t, t+t+t];}} - onNewRequest={(t) => {console.log('request:'+t);}} /> - - {console.log(t); return [t, t+t, t+t+t];}} - onNewRequest={(t) => {console.log('request:'+t);}} /> - -
- -
- ); - - } - - -} - -module.exports = SearchFields; diff --git a/docs/src/app/components/raw-code/auto-complete-code.txt b/docs/src/app/components/raw-code/auto-complete-code.txt new file mode 100644 index 00000000000000..55e2b14a0ff08d --- /dev/null +++ b/docs/src/app/components/raw-code/auto-complete-code.txt @@ -0,0 +1,28 @@ + {console.log(t); return [t, t+t, t+t+t];}} + onNewRequest={(t) => {console.log('request:'+t);}} /> + {console.log(t); return [t, t+t, t+t+t];}} + onNewRequest={(t) => {console.log('request:'+t);}} /> + + {console.log(t); return [t, t+t, t+t+t];}} + onNewRequest={(t) => {console.log('request:'+t);}} /> + + { + console.log(t); + return [ + (), + (), + () + ]; + }} + onNewRequest={(t,index) => {console.log('request:'+index);}} /> diff --git a/docs/src/app/components/raw-code/search-field-code.txt b/docs/src/app/components/raw-code/search-field-code.txt deleted file mode 100644 index 8a1b5b6c09c53d..00000000000000 --- a/docs/src/app/components/raw-code/search-field-code.txt +++ /dev/null @@ -1,8 +0,0 @@ - {console.log(t); return [t,t+t,t+t+t];}} - onNewRequest={(t) => {console.log('request:'+t);}} /> - - {console.log(t); return [t,t+t,t+t+t];}} - onNewRequest={(t) => {console.log('request:'+t);}} /> diff --git a/src/search-field.jsx b/src/auto-complete.jsx similarity index 68% rename from src/search-field.jsx rename to src/auto-complete.jsx index 7de494f0bbf827..2876283f2d625d 100644 --- a/src/search-field.jsx +++ b/src/auto-complete.jsx @@ -2,11 +2,13 @@ const React = require('react'); const ReactTransitionGroup = require('react-addons-transition-group'); const StylePropable = require('./mixins/style-propable'); const ClickAwayable = require('./mixins/click-awayable'); +const KeyCode = require('./utils/key-code'); const TextField = require('./text-field'); const Menu = require('./menus/menu'); const MenuItem = require('./menus/menu-item'); +const MenuDivider = require('./menus/menu-divider'); -const SearchField = React.createClass({ +const AutoComplete = React.createClass({ mixins: [ StylePropable, @@ -22,8 +24,11 @@ const SearchField = React.createClass({ floatingLabelText: React.PropTypes.string, errorStyle: React.PropTypes.object, hintText: React.PropTypes.string, + searchText: React.PropTypes.string, + dataSource: React.PropTypes.array, + updateWhenFocused: React.PropTypes.bool, + auto: React.PropTypes.bool, id: React.PropTypes.string, - onChange: React.PropTypes.func, autoWidth: React.PropTypes.bool, menuStyle: React.PropTypes.object, listStyle: React.PropTypes.object, @@ -31,16 +36,18 @@ const SearchField = React.createClass({ menuCloseDelay: React.PropTypes.number, onUpdateRequests: React.PropTypes.func, onNewSearchRequest: React.PropTypes.func, + disableFocusRipple: React.PropTypes.bool, }, getDefaultProps() { return { fullWidth: false, open: false, + auto: false, searchText: '', menuCloseDelay: 100, - - onChange: () => {}, + disableFocusRipple: true, + updateWhenFocused: false, onUpdateRequests: () => {}, onNewRequest: () => {}, }; @@ -49,11 +56,12 @@ const SearchField = React.createClass({ getInitialState() { return { searchText: this.props.searchText, - requestsList: null, + requestsList: this.props.dataSource && this.props.auto + ? this.props.dataSource : null, open: this.props.open, }; }, - + componentWillMount(){ this.focusOnInput = false; }, @@ -72,6 +80,7 @@ const SearchField = React.createClass({ menuStyle, menuProps, listStyle, + auto, ...other, } = this.props; @@ -88,7 +97,7 @@ const SearchField = React.createClass({ error: { }, menu: { - top: 40, + top: this.props.floatingLabelText? 64 : 40, left: 0, width: '100%', }, @@ -111,7 +120,8 @@ const SearchField = React.createClass({ let mergedMenuStyles = this.mergeStyles(styles.menu, menuStyle); - let menu = this.state.open && this.state.searchText !== '' && requestsList ? ( + let menu = this.state.open && (this.state.searchText !== '' || auto) + && requestsList && requestsList.length > 0 ? ( ); case 'object': - return request; + return React.cloneElement(request, { + key: index, + disableFocusRipple: this.props.disableFocusRipple, + }); default: return null; } @@ -146,25 +160,10 @@ const SearchField = React.createClass({ return (
{ - switch(e.keyCode){ - case 27: //esc - this.setState({open:false}); - break; - case 40: //down arrow - if(this.focusOnInput && this.state.open){ - e.preventDefault(); - this.focusOnInput = false; - this.setState({open:true}); - } - break; - default: - break; - } - }}> + onKeyDown={this._handleKeyDown}>
{ setTimeout(() => { - this.state({open:false}); + this.setState({open:false}); }, this.props.touchTapCloseDelay); this.props.onNewRequest(this.state.searchText); }} - onChange={ - this._handleSearchTextChange - } + onChange={(e)=>{ + let searchText = e.target.value; + this._updateRequests(searchText); + }} onBlur={()=>{ if(this.focusOnInput && this.state.open) this.refs.searchTextField.focus(); }} onFocus={()=>{ - if(!this.state.open && this.searchText !== ''){ - this.updateRequests(this.state.searchText); + if(!this.state.open && ( auto || + this.props.updateWhenFocused || this.state.searchText !== '')){ + this._updateRequests(this.state.searchText); } this.focusOnInput = true; }} @@ -207,14 +208,30 @@ const SearchField = React.createClass({ return this.state.searchText; }, - _handleSearchTextChange(e){ + _updateRequests(searchText){ - let searchText = e.target.value; + this.setState({ + searchText:searchText, + }); + this.focusOnInput = true; + + if(this.props.dataSource){ + this.props.onUpdateRequests(searchText); + + let list = this.props.dataSource.filter((v) => v.includes(searchText)); + + if(this.props.auto && searchText === ''){ + list = this.props.dataSource; + } + this.setState({ + requestsList: list, + open: true, + }) + + return; + } - this.updateRequests(searchText); - }, - updateRequests(searchText){ let requestsListPromise = new Promise((resolve, reject) => { let list = this.props.onUpdateRequests(searchText); if(list){ @@ -226,15 +243,12 @@ const SearchField = React.createClass({ }); requestsListPromise.then(list => { - this.focusOnInput = true; this.setState({ - searchText:searchText, requestsList:list, open: true, }); }, ()=>{ this.setState({ - searchText:searchText, requestsList:null, open: false, }); @@ -255,6 +269,27 @@ const SearchField = React.createClass({ }, + _handleKeyDown(e){ + switch(e.keyCode){ + case KeyCode.ESC: + this.setState({open:false}); + break; + case KeyCode.DOWN: + if(this.focusOnInput && this.state.open){ + e.preventDefault(); + this.focusOnInput = false; + this.setState({open:true}); + } + break; + default: + break; + } + }, + + }); -module.exports = SearchField; +AutoComplete.Item = MenuItem; +AutoComplete.Divider = MenuDivider; + +module.exports = AutoComplete; diff --git a/src/index.js b/src/index.js index e5a856024638ef..09e7a491dd40c0 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,7 @@ module.exports = { AppBar: require('./app-bar'), AppCanvas: require('./app-canvas'), + AutoComplete: require('./auto-complete'), Avatar: require('./avatar'), BeforeAfterWrapper: require('./before-after-wrapper'), Card: require('./card/card'), @@ -42,7 +43,6 @@ module.exports = { RefreshIndicator: require('./refresh-indicator'), Ripples: require('./ripples/'), SelectField: require('./select-field'), - SearchField: require('./search-field'), Slider: require('./slider'), SvgIcon: require('./svg-icon'), Icons: {