Skip to content

Instantly share code, notes, and snippets.

@raysuelzer
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raysuelzer/935bba6b50ed4836350b to your computer and use it in GitHub Desktop.
Save raysuelzer/935bba6b50ed4836350b to your computer and use it in GitHub Desktop.
ReactJS Flux Typeahead Gist
var React = require('react');
var TypeaheadStore = require('../stores/TypeaheadStore');
var TypeaheadActions = require('../actions/TypeaheadActions');
var _ = require('lodash');
var TypeaheadItem = React.createClass({
render() {
return (
<div>{this.props.name}</div>
)
}
})
var Typeahead = React.createClass({
propTypes: {
dataKey: React.PropTypes.string.isRequired, //used as key for the results in the typeahead store
url: React.PropTypes.string.isRequired, // request url
queryParam: React.PropTypes.string.isRequired, // paramater for query ie "q" "?q=...",
transform: React.PropTypes.func,
placeholder: React.PropTypes.string
},
getInitialState: function() {
return {
isHidden: true,
itemData: []
};
},
componentDidMount: function() {
TypeaheadStore.addChangeListener(this.props.dataKey, this._onFreshData);
},
componentWillUnmount: function() {
TypeaheadStore.removeChangeListener(this.props.dataKey, this._onFreshData);
},
onKeyUp(event) {
var query = {};
query[this.props.queryParam] = event.target.value;
TypeaheadActions.fetch(this.props.url, query, this.props.dataKey);
},
render() {
var itemNodes = this.makeItemNodes();
return (
<div>
<input type="text" autoComplete="off" className="form-control"
onKeyUp={this.onKeyUp} placeHolder={this.props.placeholder}/>
<div>
{itemNodes}
</div>
</div>
);
},
makeItemNodes() {
if (this.state.itemData && this.state.itemData.length) {
return this.state.itemData.map((item) => {
return (
<TypeaheadItem name={item.name}/>
);
});
}
else
return null;
},
_onFreshData() {
this.setState({itemData: TypeaheadStore.get(this.props.dataKey)})
}
})
module.exports = Typeahead;
var AppDispatcher = require('../dispatcher/AppDispatcher');
var Constants = require('../constants/constants');
var request = require('then-request');
var _ = require('lodash');
var opts = {
headers: {"Accept": "application/json"}
};
var TypeaheadActions = {
fetch: _.debounce(function(url, query, typeaheadDataKey) {
opts.qs = query;
request('GET', url, opts).done(function(res) {
var data = JSON.parse(res.body);
AppDispatcher.dispatch({
actionType: Constants.TYPEAHEAD_FRESH_DATA,
key: typeaheadDataKey,
newData: data
});
});
}, 200)
};
module.exports = TypeaheadActions;
var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var Constants = require('../constants/constants');
var assign = require('object-assign');
var _typeaheadResponses = {};
var CHANGE_EVENT = '_change'; //make it for the key val
function update(key, values) {
_typeaheadResponses[key] = values;
}
var TypeaheadResultsStore = assign({}, EventEmitter.prototype, {
/**
* Get the current results from the store for a specific ckey
*/
get: function (key) {
return _typeaheadResponses[key];
},
emitChange: function (key) {
this.emit(key + CHANGE_EVENT);
},
addChangeListener: function (key, callback) {
this.on(key + CHANGE_EVENT, callback);
},
removeChangeListener: function (key, callback) {
this.removeListener(key + CHANGE_EVENT, callback);
}
});
// Register callback to handle all updates
AppDispatcher.register(function (action) {
switch (action.actionType) {
case Constants.TYPEAHEAD_FRESH_DATA:
update(action.key, action.newData);
TypeaheadResultsStore.emitChange(action.key); //emit a change event that a portion of the store has been updated
break;
default:
// no op
}
});
module.exports = TypeaheadResultsStore;
var React = require('react');
var WorkSiteQuickListStore = require('../stores/WorkSiteQuickListStore');
var WorkSiteQuickListActions = require('../actions/WorkSiteQuickListActions');
var Typeahead = require('./Typeahead');
var UseInComponent = React.createClass({
render() {
return (
<div className="panel panel-primary">
<Typeahead dataKey='workSite' url='/api/core/work_site/search' />
</div>
);
}
});
module.exports = UseInComponent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment