You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
5.5 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. {% extends "base.html" %}
  2. {% block content %}
  3. <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.min.js"></script>
  4. <script type="module">
  5. //import { createApp } from 'https://unpkg.com/petite-vue?module'
  6. //import { createApp } from 'https://unpkg.com/vue@2.7.14/dist/vue.esm-browser.prod.js'
  7. function valid(str) {
  8. return !isNaN(str) && !isNaN(parseFloat(str))
  9. }
  10. function debounce(func, timeout = 300){
  11. let timer;
  12. return (...args) => {
  13. clearTimeout(timer);
  14. timer = setTimeout(() => { func.apply(this, args); }, timeout);
  15. };
  16. }
  17. const app = new Vue({
  18. el: "#search",
  19. data() {
  20. return {
  21. mz_min: 0,
  22. mz_max: 0,
  23. rt_min: 0,
  24. rt_max: 0,
  25. // query parameters for the maximum date possible.
  26. year_max: 2021,
  27. month_max: 1,
  28. day_max: 31,
  29. // results
  30. results: [],
  31. error: null,
  32. }
  33. },
  34. methods: {
  35. // methods
  36. prepare_query() {
  37. // validation
  38. let query = {}
  39. const fields = ["mz_min", "mz_max", "rt_min", "rt_max",
  40. "year_max", "month_max", "day_max"]
  41. for (let i = 0; i < fields.length; i++) {
  42. const field = fields[i];
  43. if (!valid(this[field])) {
  44. console.log(query, field, this[field])
  45. return null;
  46. } else {
  47. query[field] = this[field]
  48. }
  49. }
  50. return query
  51. },
  52. async fetch_data() {
  53. const query = this.prepare_query()
  54. if (query === null) return;
  55. const api = `/chemical/search`;
  56. fetch(api, {
  57. method: 'POST',
  58. headers: {
  59. 'Content-Type': 'application/json',
  60. },
  61. body: JSON.stringify(query)
  62. }).then(async res => {
  63. if (res.status !== 200) {
  64. console.log(`Error Status, ${res.status}`)
  65. const json = await res.json()
  66. throw Error(json.error);
  67. }
  68. return res.json()
  69. }).then(json => {
  70. this.results = json;
  71. this.error = null;
  72. }).catch(e => {
  73. this.error = e.message;
  74. })
  75. }
  76. },
  77. created() {
  78. this.fetch_data = debounce(this.fetch_data, 300)
  79. }
  80. });
  81. </script>
  82. <h1>Search Box</h1>
  83. <div id="search">
  84. <main>
  85. <table>
  86. <tr>
  87. <td>
  88. <label for="mz_min">Minimum M/Z Ratio</label>
  89. </td>
  90. <td>
  91. <input id="mz_min" type="number" name="mz_min" v-model="mz_min" value="0">
  92. </td>
  93. </tr>
  94. <tr>
  95. <td>
  96. <label for="mz_min">Maximum M/Z Ratio</label>
  97. </td>
  98. <td>
  99. <input id="mz_max" type="number" name="mz_max" v-model="mz_max" value="0">
  100. </td>
  101. </tr>
  102. <tr>
  103. <td>
  104. <label for="mz_min">Minimum Retention Time</label>
  105. </td>
  106. <td>
  107. <input id="rt_min" type="number" name="rt_min" v-model="rt_min" value="0">
  108. </td>
  109. </tr>
  110. <tr>
  111. <td>
  112. <label for="mz_min">Maximum Retention Time</label>
  113. </td>
  114. <td>
  115. <input id="rt_max" type="number" name="rt_max" v-model="rt_max" value="0">
  116. </td>
  117. </tr>
  118. <tr>
  119. <td>
  120. <label for="mz_min">Maximum Date</label>
  121. </td>
  122. <td>
  123. <input id="year_max" type="number" name="year_max"
  124. v-model="year_max" placeholder="year">
  125. <input id="month_max" type="number" name="month_max"
  126. v-model="month_max" placeholder="month">
  127. <input id="day_max" type="number" name="day_max"
  128. v-model="day_max" placeholder="day">
  129. </td>
  130. </tr>
  131. </table>
  132. <br>
  133. <button @click="fetch_data()">Search</button>
  134. </main>
  135. <hr>
  136. {% raw %}
  137. <div id="search">
  138. <div v-if="error !== null" style="color: red;">
  139. Uh Oh! There is an Error! {{error}}
  140. </div>
  141. <div v-for="result in results">
  142. <a :href="result.url">
  143. <h3>{{result.name}}</h3>
  144. </a>
  145. <table>
  146. <tr>
  147. <td>Retention Time</td>
  148. <td>{{result.rt}}</td>
  149. </tr>
  150. <tr>
  151. <td>M/Z Ratio</td>
  152. <td>{{result.mz}}</td>
  153. </tr>
  154. </table>
  155. <hr>
  156. </div>
  157. </div>
  158. {% endraw %}
  159. </div>
  160. {% endblock %}