Source: search/Search.js

  1. import { EventObject } from "../events/EventObject.js";
  2. export { Search }
  3. /**
  4. * Full-text search base class. Listen on events "prepare", "process", "finished" or "failed"
  5. * for processing UI preparations and search results. The finished() method is fired
  6. * even in case of errors.
  7. *
  8. * @author rkoppe <roland.koppe@awi.de>
  9. * @author rhess <robin.hess@awi.de>
  10. *
  11. * @memberof vef.search
  12. */
  13. class Search extends EventObject {
  14. // initialize properties
  15. baseUrl = "";
  16. searchRequest = null;
  17. searchResult = null;
  18. page = 0;
  19. pages = 0;
  20. /**
  21. * Initializes the search aganist the given base URL.
  22. *
  23. * @param {string} baseUrl
  24. */
  25. constructor(baseUrl) {
  26. if (!baseUrl) throw new Error("baseUrl is not set");
  27. if (!baseUrl.endsWith('/')) baseUrl += '/';
  28. // Initialize EventObject
  29. super({
  30. "prepare": [], // pre-processes the given data. Example: create a table header,
  31. "process": [], // Processes the given object record of the search result.
  32. "finished": [], // Fired when the search request finished
  33. "failed": [] // Fired if there was an error during the search request.
  34. });
  35. // Initialize baseUrl
  36. this.baseUrl = baseUrl;
  37. }
  38. /**
  39. * Processes the responseText from the ajax request and
  40. * fires the necessary events for processing
  41. *
  42. * @private
  43. */
  44. processResult_(responseText) {
  45. try {
  46. // parse respons
  47. const data = JSON.parse(responseText);
  48. this.searchResult = data;
  49. // prepare pages
  50. this.page = Math.ceil(data.offset / this.searchRequest.hits) + 1;
  51. this.pages = Math.ceil(data.totalHits / this.searchRequest.hits);
  52. this.fire("prepare", data);
  53. // process
  54. const objects = data.records;
  55. for (let i = 0; i < objects.length; ++i) {
  56. this.fire("process", objects[i]);
  57. }
  58. this.fire("finished", data);
  59. } catch (e) {
  60. this.fire("failed", e);
  61. }
  62. }
  63. /**
  64. * Performs the given searchRequest
  65. *
  66. * @param {SearchRequest} request
  67. * @returns {XMLHttpRequest}
  68. */
  69. request(request) {
  70. // reset properties
  71. this.searchRequest = request;
  72. this.searchResult = null;
  73. this.page = 0;
  74. this.pages = 0;
  75. // create request
  76. const http = new XMLHttpRequest();
  77. http.open("POST", this.baseUrl, true);
  78. http.setRequestHeader("Content-Type", 'application/json');
  79. http.onreadystatechange = (e) => {
  80. if (http.readyState == 4) {
  81. if (http.status === 200) {
  82. this.processResult_(http.responseText);
  83. } else {
  84. this.fire("failed", e);
  85. }
  86. }
  87. }
  88. http.onerror = (e) => this.fire("failed", e);
  89. http.send(JSON.stringify(request));
  90. return http;
  91. }
  92. /**
  93. * Returns the current page number.
  94. *
  95. * @returns {number} page number
  96. */
  97. getPage() {
  98. return this.page;
  99. }
  100. /**
  101. * Returns the previous page number.
  102. *
  103. * @returns {number} page number
  104. */
  105. getPreviousPage() {
  106. return this.page == 1 ? 1 : this.page - 1;
  107. }
  108. /**
  109. * Returns the next page number lower or equals pages.
  110. *
  111. * @returns {number} page number
  112. */
  113. getNextPage() {
  114. return this.page >= this.pages ? this.pages : this.page + 1;
  115. }
  116. }