SearchForm.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import React from 'react';
  2. import { FormGroup, Button, InputGroup } from 'react-bootstrap';
  3. import { AsyncTypeahead } from 'react-bootstrap-typeahead';
  4. import UserPicture from '../User/UserPicture';
  5. import PageListMeta from '../PageList/PageListMeta';
  6. import PagePath from '../PageList/PagePath';
  7. // Header.SearchForm
  8. export default class SearchForm extends React.Component {
  9. constructor(props) {
  10. super(props);
  11. this.state = {
  12. keyword: '',
  13. searchedKeyword: '',
  14. };
  15. this.search = this.search.bind(this);
  16. this.clearForm = this.clearForm.bind(this);
  17. this.getFormClearComponent = this.getFormClearComponent.bind(this);
  18. this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);
  19. }
  20. componentDidMount() {
  21. }
  22. componentWillUnmount() {
  23. }
  24. search(keyword) {
  25. this.setState({keyword});
  26. if (this.state.searchedKeyword != keyword) {
  27. this.props.onSearchFormChanged({keyword});
  28. this.setState({searchedKeyword: keyword});
  29. }
  30. }
  31. getFormClearComponent() {
  32. let isHidden = (this.state.keyword.length === 0);
  33. return isHidden ? <span></span> : (
  34. <a className="btn btn-link search-top-clear" onClick={this.clearForm} hidden={isHidden}>
  35. <i className="fa fa-times-circle" />
  36. </a>
  37. );
  38. }
  39. clearForm() {
  40. this._typeahead.getInstance().clear();
  41. this.setState({keyword: ''});
  42. }
  43. renderMenuItemChildren(option, props, index) {
  44. const page = option;
  45. return (
  46. <span>
  47. <UserPicture user={page.revision.author} />
  48. <PagePath page={page} />
  49. <PageListMeta page={page} />
  50. </span>
  51. );
  52. }
  53. render() {
  54. const options = this.props.searchedPages;
  55. const emptyLabel = (this.props.searchError !== null) ? 'Error on searching.' : 'No matches found.';
  56. const formClear = this.getFormClearComponent();
  57. return (
  58. <form
  59. action="/_search"
  60. className="search-form form-group input-group search-top-input-group"
  61. >
  62. <FormGroup>
  63. <InputGroup>
  64. <AsyncTypeahead
  65. ref={ref => this._typeahead = ref}
  66. name="q"
  67. labelKey="path"
  68. options={options}
  69. placeholder="Search ... Page Title (Path) and Content"
  70. emptyLabel={emptyLabel}
  71. submitFormOnEnter={true}
  72. onSearch={this.search}
  73. renderMenuItemChildren={this.renderMenuItemChildren}
  74. />
  75. {formClear}
  76. <InputGroup.Button>
  77. <Button type="submit">
  78. <i className="search-top-icon fa fa-search"></i>
  79. </Button >
  80. </InputGroup.Button>
  81. </InputGroup>
  82. </FormGroup>
  83. </form>
  84. );
  85. }
  86. }
  87. SearchForm.propTypes = {
  88. onSearchFormChanged: React.PropTypes.func.isRequired,
  89. searchedPages: React.PropTypes.array.isRequired,
  90. };
  91. SearchForm.defaultProps = {
  92. searchError: null
  93. };