searchbar.jsx 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. var Preact = require('preact');
  2. var h = require('preact').h;
  3. var findDOMNode = require('preact-compat').findDOMNode;
  4. var createClass = require('preact-compat').createClass;
  5. var Bacon = require('baconjs').Bacon;
  6. var SearchBar = createClass({
  7. // polyfill of sorts for string refs
  8. linkRef: function(component, name) {
  9. var cache = component._linkedRefs || (component._linkedRefs = {});
  10. if (!component.refs) component.refs = {};
  11. return cache[name] || (cache[name] = function(c) {
  12. return component.refs[name] = c;
  13. });
  14. },
  15. getInitialState: function() {
  16. return { textValue: this.props.initialValue }
  17. },
  18. handleChange: function(event) {
  19. this.setState({ textValue: event.target.value });
  20. },
  21. componentDidMount: function() {
  22. var self = this,
  23. delay = 200, // in ms
  24. inputElem = findDOMNode(this.refs.filterTextInput);
  25. // Convert input events to stream
  26. var text = Bacon.fromEvent(inputElem, 'input')
  27. .debounce(delay)
  28. .map(function(event) {
  29. return event.target.value;
  30. })
  31. .skipDuplicates();
  32. var textObservable = text.flatMapLatest(function(query) {
  33. return Bacon.once(query);
  34. });
  35. textObservable.onValue(function(val) {
  36. self.props.onUserInput(val);
  37. });
  38. inputElem.focus();
  39. },
  40. render: function() {
  41. return (
  42. <div className="input-group">
  43. <input
  44. className="form-control"
  45. type="text"
  46. autoComplete="off"
  47. placeholder={this.props.placeHolderText}
  48. value={this.state.textValue}
  49. onInput={this.handleChange}
  50. ref={this.linkRef(this, "filterTextInput")}
  51. />
  52. </div>
  53. );
  54. }
  55. });
  56. module.exports = SearchBar;