PageListSearch.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. // This is the root component for #page-list-search
  2. import React from 'react';
  3. import axios from 'axios'
  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. axios.get('/_api/search', {params: {q: keyword, tree: tree}})
  100. .then((res) => {
  101. if (res.data.ok) {
  102. this.setState({
  103. searchedKeyword: keyword,
  104. searchedPages: res.data.data,
  105. searchResultMeta: res.data.meta,
  106. });
  107. } else {
  108. this.setState({
  109. searchError: res.data,
  110. });
  111. }
  112. // TODO error
  113. })
  114. .catch((res) => {
  115. this.setState({
  116. searchError: res.data,
  117. });
  118. // TODO error
  119. });
  120. };
  121. render() {
  122. return (
  123. <div>
  124. <input
  125. type="hidden"
  126. name="q"
  127. value={this.state.searchingKeyword}
  128. onChange={this.handleChange}
  129. className="form-control"
  130. />
  131. <SearchResult
  132. tree={this.state.tree}
  133. pages={this.state.searchedPages}
  134. searchingKeyword={this.state.searchingKeyword}
  135. searchResultMeta={this.state.searchResultMeta}
  136. searchError={this.state.searchError}
  137. />
  138. </div>
  139. );
  140. }
  141. }
  142. PageListSearch.propTypes = {
  143. query: React.PropTypes.object,
  144. };
  145. PageListSearch.defaultProps = {
  146. //pollInterval: 1000,
  147. query: PageListSearch.getQueryByLocation(location || {}),
  148. };