NewPageNameInputter.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. import PropTypes from 'prop-types';
  8. // Header.SearchForm
  9. export default class NewPageNameInputter extends React.Component {
  10. constructor(props) {
  11. super(props);
  12. this.crowi = window.crowi; // FIXME
  13. this.state = {
  14. input: '',
  15. keyword: '',
  16. searchedKeyword: '',
  17. pages: [],
  18. isLoading: false,
  19. searchError: null,
  20. };
  21. this.search = this.search.bind(this);
  22. this.clearForm = this.clearForm.bind(this);
  23. this.getFormClearComponent = this.getFormClearComponent.bind(this);
  24. this.renderMenuItemChildren = this.renderMenuItemChildren.bind(this);
  25. this.onInputChange = this.onInputChange.bind(this);
  26. }
  27. componentDidMount() {
  28. }
  29. componentWillUnmount() {
  30. }
  31. search(keyword) {
  32. if (keyword === '') {
  33. this.setState({
  34. keyword: '',
  35. searchedKeyword: '',
  36. });
  37. return;
  38. }
  39. this.setState({isLoading: true});
  40. this.crowi.apiGet('/search', {q: keyword})
  41. .then(res => {
  42. this.setState({
  43. isLoading: false,
  44. keyword: '',
  45. pages: res.data,
  46. });
  47. })
  48. .catch(err => {
  49. this.setState({
  50. isLoading: false,
  51. searchError: err,
  52. });
  53. });
  54. }
  55. getFormClearComponent() {
  56. let isHidden = (this.state.input.length === 0);
  57. return isHidden ? <span></span> : (
  58. <a className="btn btn-link search-top-clear" onClick={this.clearForm} hidden={isHidden}>
  59. <i className="fa fa-times-circle" />
  60. </a>
  61. );
  62. }
  63. clearForm() {
  64. this._typeahead.getInstance().clear();
  65. this.setState({keyword: ''});
  66. }
  67. onInputChange(text) {
  68. this.setState({input: text});
  69. }
  70. renderMenuItemChildren(option, props, index) {
  71. const page = option;
  72. return (
  73. <span>
  74. <UserPicture user={page.revision.author} />
  75. <PagePath page={page} />
  76. <PageListMeta page={page} />
  77. </span>
  78. );
  79. }
  80. render() {
  81. const emptyLabel = (this.state.searchError !== null)
  82. ? 'Error on searching.'
  83. : 'No matches found on title...';
  84. const formClear = this.getFormClearComponent();
  85. return (
  86. <form
  87. action="/_search"
  88. className="search-form input-group"
  89. >
  90. <InputGroup>
  91. <AsyncTypeahead
  92. ref={ref => this._typeahead = ref}
  93. inputProps={{name: "q", autoComplete: "off"}}
  94. isLoading={this.state.isLoading}
  95. labelKey="path"
  96. minLength={2}
  97. options={this.state.pages}
  98. placeholder="Input page name"
  99. emptyLabel={emptyLabel}
  100. align='left'
  101. submitFormOnEnter={true}
  102. onSearch={this.search}
  103. onInputChange={this.onInputChange}
  104. renderMenuItemChildren={this.renderMenuItemChildren}
  105. />
  106. {formClear}
  107. <input
  108. type="hidden"
  109. value={this.state.searchedKeyword}
  110. required />
  111. </InputGroup>
  112. </form>
  113. );
  114. }
  115. }
  116. NewPageNameInputter.propTypes = {
  117. };
  118. NewPageNameInputter.defaultProps = {
  119. };