PageListSearch.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // This is the root component for #page-list-search
  2. import React from 'react';
  3. import PropTypes from 'prop-types';
  4. import SearchResult from './SearchPage/SearchResult';
  5. export default class PageListSearch extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. location: location,
  10. tree: $('#search-listpage-input').data('path'),
  11. searchingKeyword: this.props.query.q || '',
  12. searchedKeyword: '',
  13. searchedPages: [],
  14. searchResultMeta: {},
  15. searchError: null,
  16. };
  17. this.changeURL = this.changeURL.bind(this);
  18. this.search = this.search.bind(this);
  19. this.handleChange = this.handleChange.bind(this);
  20. }
  21. componentDidMount() {
  22. const $pageListSearchForm = $('#search-listpage-input');
  23. // search after page initialized
  24. if (this.state.searchingKeyword !== '') {
  25. const keyword = this.state.searchingKeyword;
  26. $pageListSearchForm.val(keyword);
  27. this.search({keyword});
  28. }
  29. // This is temporary data bind ... (out of component)
  30. $('#search-listpage-form').on('submit', () => {
  31. const keyword = $pageListSearchForm.val();
  32. if (keyword != this.state.searchingKeyword) {
  33. this.search({keyword});
  34. }
  35. return false;
  36. });
  37. $('#search-listpage-clear').on('click', () => {
  38. $pageListSearchForm.val('');
  39. this.search({keyword: ''});
  40. return false;
  41. });
  42. }
  43. componentWillUnmount() {
  44. }
  45. static getQueryByLocation(location) {
  46. let search = location.search || '';
  47. let query = {};
  48. search.replace(/^\?/, '').split('&').forEach(function(element) {
  49. let queryParts = element.split('=');
  50. query[queryParts[0]] = decodeURIComponent(queryParts[1]).replace(/\+/g, ' ');
  51. });
  52. return query;
  53. }
  54. handleChange(event) {
  55. // this is not fired now because of force-data-bound by jQuery
  56. const keyword = event.target.value;
  57. this.setState({searchedKeyword: keyword});
  58. //console.log('Changed');
  59. }
  60. stopSearching() {
  61. $('#content-main').show();
  62. $('#search-listpage-clear').hide();
  63. $('.main-container').removeClass('aside-hidden');
  64. }
  65. startSearching() {
  66. $('#content-main').hide();
  67. $('#search-listpage-clear').show();
  68. $('.main-container').addClass('aside-hidden');
  69. }
  70. changeURL(keyword, refreshHash) {
  71. const tree = this.state.tree;
  72. let hash = location.hash || '';
  73. // TODO 整理する
  74. if (refreshHash || this.state.searchedKeyword !== '') {
  75. hash = '';
  76. }
  77. if (window.history && window.history.pushState) {
  78. window.history.pushState('', `Search - ${keyword}`, `${tree}?q=${keyword}${hash}`);
  79. }
  80. }
  81. search(data) {
  82. const keyword = data.keyword || '';
  83. const tree = this.state.tree;
  84. this.changeURL(keyword);
  85. if (keyword === '') {
  86. this.stopSearching();
  87. this.setState({
  88. searchingKeyword: '',
  89. searchedPages: [],
  90. searchResultMeta: {},
  91. searchError: null,
  92. });
  93. return true;
  94. }
  95. this.startSearching();
  96. this.setState({
  97. searchingKeyword: keyword,
  98. });
  99. this.props.crowi.apiGet('/search', {q: keyword, tree: tree})
  100. .then((res) => {
  101. this.setState({
  102. searchedKeyword: keyword,
  103. searchedPages: res.data,
  104. searchResultMeta: res.meta,
  105. });
  106. }).catch(err => {
  107. this.setState({
  108. searchError: err,
  109. });
  110. });
  111. }
  112. render() {
  113. return (
  114. <div>
  115. <input
  116. type="hidden"
  117. name="q"
  118. value={this.state.searchingKeyword}
  119. onChange={this.handleChange}
  120. className="form-control"
  121. />
  122. <SearchResult
  123. tree={this.state.tree}
  124. pages={this.state.searchedPages}
  125. searchingKeyword={this.state.searchingKeyword}
  126. searchResultMeta={this.state.searchResultMeta}
  127. searchError={this.state.searchError}
  128. crowi={this.props.crowi}
  129. />
  130. </div>
  131. );
  132. }
  133. }
  134. PageListSearch.propTypes = {
  135. query: PropTypes.object,
  136. crowi: PropTypes.object.isRequired,
  137. };
  138. PageListSearch.defaultProps = {
  139. //pollInterval: 1000,
  140. query: PageListSearch.getQueryByLocation(location || {}),
  141. };