blob: 9e685181208a73f5cdbd348944504b2a86d10bdf [file] [log] [blame]
Alison Craigef12da82015-03-06 09:41:43 -07001<!DOCTYPE html>
2<html lang="en-US">
3
4<head>
5 <title>Atmospheric Query and Retrieval Tool</title>
6 <meta charset="UTF-8" />
7
8
Alison Craig1aced7d2015-04-10 12:00:02 -06009 <script type="text/javascript" src="../jquery/jquery-latest.min.js"></script>
10 <script type="text/javascript" src="../jquery/ui/1.10.1/jquery-ui.js"></script>
11 <script type="text/javascript" src="../ndn-js/build/ndn.js"></script>
Alison Craigef12da82015-03-06 09:41:43 -070012
13
14 <link rel="stylesheet" href="query.css">
Alison Craig1aced7d2015-04-10 12:00:02 -060015 <link rel="stylesheet" href="../jquery/ui/1.11.4/themes/smoothness/jquery-ui.css">
Alison Craigef12da82015-03-06 09:41:43 -070016
17 <script>
Alison Craig1aced7d2015-04-10 12:00:02 -060018 // {@ @todo: this need to be configured before the document load
19 var catalog = "/catalog/myUniqueName";
20 var face = new Face({
21 host: "localhost",
22 port: 9696
23 });
24
25 // @}
26
27 var searchMenuOptions = {}
28 var results = [];
Alison Craigef12da82015-03-06 09:41:43 -070029 var resultCount = 0;
30 var page = 1;
31 var totalPages = 1;
Alison Craig1aced7d2015-04-10 12:00:02 -060032 var selectedSearch = {};
33 var dropdown = [];
Alison Craigef12da82015-03-06 09:41:43 -070034
35 $(document).ready(function () {
36 var searchMenu = $(".cssmenu");
37 var currentPage = $(".page");
38 var resultTable = $(".resultTable");
Alison Craig1aced7d2015-04-10 12:00:02 -060039 var data = $.getJSON("search_catagories.json", function () {}).done(function (data) {
Alison Craigef12da82015-03-06 09:41:43 -070040 $.each(data, function (pageSection, contents) {
41 if (pageSection == "SearchCatagories") {
Alison Craigef12da82015-03-06 09:41:43 -070042 $.each(contents, function (search, searchOptions) {
43 search = search.replace(/\_/g, " ");
44
45 searchMenu.append('<li id="' + search + '" onclick="getDropDown(this.id)"><a href="#">' + search + '</a></li>');
Alison Craig1aced7d2015-04-10 12:00:02 -060046 searchMenuOptions[String(search)] = searchOptions;
Alison Craigef12da82015-03-06 09:41:43 -070047 });
Alison Craigef12da82015-03-06 09:41:43 -070048 }
49 });
Alison Craig1aced7d2015-04-10 12:00:02 -060050 });
Alison Craigef12da82015-03-06 09:41:43 -070051 });
52
Alison Craig1aced7d2015-04-10 12:00:02 -060053 function onData(data) {
54 var payloadStr = data.content.toString().split("\n")[0];
55
56 var queryResults = JSON.parse(payloadStr);
57
58 var resultTable = $(".resultTable");
59 $.each(queryResults, function (queryResult, field) {
60
61 if (queryResult == "next") {
62 populateAutocomplete(field);
63 }
64
65 $.each(field, function (entryCount, name) {
66 results.push(name);
67 });
68 });
69
70 // Calculating the current page and the view
71 totalPages = Math.ceil(resultCount / 20);
72 populateResults(0);
73 }
74
75 var state = {};
76
77 function query(prefix, parameters, callback, pipeline) {
78 results = [];
79 dropdown = [];
80
81 var resultTable = $(".resultTable");
82 resultTable.empty();
83 resultTable.append('<tr><td>Results</td></tr>');
84
85 var queryPrefix = new Name(prefix);
86 queryPrefix.append("query");
87
88 queryPrefix.append(JSON.stringify(parameters));
89
90 state = {
91 prefix: new Name(prefix),
92 userOnData: callback,
93 outstanding: {},
94 nextSegment: 0,
95 };
96
97 /*if (state.hasOwnProperty("version")) {
98 console.log("state already has version");
99 }*/
100
101 var queryInterest = new Interest(queryPrefix);
102 queryInterest.setInterestLifetimeMilliseconds(10000);
103
104 face.expressInterest(queryInterest,
105 onQueryData,
106 onQueryTimeout);
107
108 state["outstanding"][queryInterest.getName().toUri()] = 0;
109 }
110
111 function expressNextInterest() {
112 // @todo pipelines
113 var nextName = new Name(state["results"]);
114 nextName.appendSegment(state["nextSegment"]);
115
116 var nextInterest = new Interest(nextName);
117 nextInterest.setInterestLifetimeMilliseconds(10000);
118
119 face.expressInterest(nextInterest,
120 onQueryResultsData,
121 onQueryResultsTimeout);
122
123 state["nextSegment"] ++;
124 state["outstanding"][nextName.toUri()] = 0;
125 }
126
127 function onQueryData(interest, data) {
128 var name = data.getName();
129
130 delete state["outstanding"][interest.getName().toUri()];
131
132 state["version"] = name.get(state["prefix"].size() + 2).toVersion();
133
134 state["results"] = new Name(state["prefix"]).append("query-results").appendVersion(state["version"]);
135
136 expressNextInterest();
137 }
138
139 function onQueryResultsData(interest, data) {
140 var name = data.getName();
141 delete state["outstanding"][interest.getName().toUri()];
142
143 if (!name.get(-1).equals(new Name.Component("END"))) {
144 expressNextInterest();
145 } else {
146 alert("found final block");
147 }
148
149 state["userOnData"](data);
150 }
151
152 function onQueryTimeout(interest) {
153 var uri = interest.getName().toUri();
154 if (state["outstanding"][uri] < 1) {
155 state["outstanding"][uri] ++;
156 face.expressInterest(interest,
157 onQueryData,
158 onQueryTimeout);
159 } else {
160 delete state["outstanding"][uri];
161
162 // We modify the autocomplete box here because we need to know
163 // we have all of the entries first. Fairly hacky.
164 var autocompleteFullName = autocompleteText.value;
165 for (var i = 0; i < dropdown.length; ++i) {
166 if (dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === autocompleteText.value.toUpperCase || dropdown.length == 1) {
167 autocompleteText.value = dropdown[i];
168 }
169 }
170 }
171 }
172
173 function onQueryResultsTimeout(interest) {
174 var uri = interest.getName().toUri();
175 if (state["outstanding"][uri] < 1) {
176 state["outstanding"][uri] ++;
177 face.expressInterest(interest,
178 onQueryResultsData,
179 onQueryResultsTimeout);
180 } else {
181 delete state["outstanding"][uri];
182 // We modify the autocomplete box here because we need to know
183 // we have all of the entries first. Fairly hacky.
184 var autocompleteFullName = autocompleteText.value;
185 for (var i = 0; i < dropdown.length; ++i) {
186 if (dropdown[i].substr(0, dropdown[i].length - 1).toUpperCase === autocompleteText.value.toUpperCase || dropdown.length == 1) {
187 autocompleteText.value = dropdown[i];
188 }
189 }
190 }
191 }
192
193
194 var currentViewIndex = 0;
195
196 function populateResults(startIndex) {
197 var resultTable = $(".resultTable");
198 resultTable.empty();
199 resultTable.append('<tr><td>Results</td></tr>');
200
201
202 for (var i = startIndex; i < startIndex + 20 && i < results.length; ++i) {
203 resultTable.append('<tr><td>' + results[i] + '</td></tr>');
204 }
205
206 if (results.length <= 20) {
207 page = 1;
208 } else {
209 page = startIndex / 20 + 1;
210 }
211
212 totalPages = Math.ceil(results.length / 20);
213
214 var currentPage = $(".page");
215 currentPage.empty();
216 if (page != 1) {
217 currentPage.append('<a href="#" onclick="getPage(this.id);" id="<"><</a>');
218 }
219 // This section of code creates the paging for the results.
220 // To prevent it from having a 1000+ pages, it will only show the 5 pages before/after
221 // the current page and the total pages (expect users not to really jump around a lot).
222 for (var i = 1; i <= totalPages; ++i) {
223 if (i == 1 || i == totalPages // Min or max
224 || (i <= page && i + 5 >= page) // in our current page range
225 || (i >= page && i - 5 <= page)) { // in our current page range
226 if (i != page) {
227 currentPage.append(' <a href="#" onclick="getPage(' + i + ');">' + i + '</a>')
228 if (i == 1 && page > i + 5) {
229 currentPage.append(' ... ');
230 }
231 } else {
232 currentPage.append(' ' + i);
233 }
234 } else { // Need to skip ahead
235 if (i == page + 6) {
236 currentPage.append(' ... ');
237
238 currentPage.append(' <a href="#" onclick="getPage(this.id);" id=">">></a>')
239 i = totalPages - 1;
240 }
241 }
242 }
243 currentPage.append(' ' + results.length + ' results');
244 }
245
246 var dropState = "";
Alison Craigef12da82015-03-06 09:41:43 -0700247
248 function getDropDown(str) {
249 var searchMenu = $(".cssmenu");
Alison Craig1aced7d2015-04-10 12:00:02 -0600250 if (str == dropState) {
251 dropState = "";
Alison Craigef12da82015-03-06 09:41:43 -0700252 searchMenu.find("#" + str).find("#options_" + str).empty();
253 } else {
Alison Craig1aced7d2015-04-10 12:00:02 -0600254 dropState = str;
Alison Craigef12da82015-03-06 09:41:43 -0700255
256 $.each(searchMenuOptions, function (search, fields) {
257 if (search === str) {
258 searchMenu.find("#" + search).append('<ul id="options_' + search + '" class="sub-menu">');
259 for (var i = 0; i < fields.length; ++i) {
Alison Craig1aced7d2015-04-10 12:00:02 -0600260 searchMenu.find("#options_" + search).append('<li id="' + fields[i] + '"onclick="submitCatalogSearch(this.id)"><a href="#">' + fields[i] + '</a></li>');
Alison Craigef12da82015-03-06 09:41:43 -0700261 }
262 searchMenu.append('</ul>');
263 } else {
264 var ul = $("options_" + search);
265 ul.empty();
266 searchMenu.find("#" + search).find("#options_" + search).empty();
267 }
268 });
269 }
270 }
271
Alison Craig1aced7d2015-04-10 12:00:02 -0600272 function getPage(clickedPage) {
273 console.log(clickedPage);
Alison Craigef12da82015-03-06 09:41:43 -0700274
Alison Craig1aced7d2015-04-10 12:00:02 -0600275 var nextPage = clickedPage;
276 if (clickedPage === "<") {
277 nextPage = page - 5;
278 } else if (clickedPage === ">") {
279 console.log("> enabled");
Alison Craigef12da82015-03-06 09:41:43 -0700280
Alison Craig1aced7d2015-04-10 12:00:02 -0600281 nextPage = page + 5;
Alison Craigef12da82015-03-06 09:41:43 -0700282 }
283
Alison Craig1aced7d2015-04-10 12:00:02 -0600284 nextPage--; // Need to adjust for starting at 0
285
286 if (nextPage < 0 ) {
287 nextPage = 0;
288 console.log("0 enabled");
289 } else if (nextPage > totalPages - 1) {
290 nextPage = totalPages - 1;
291 console.log("total enabled");
292 }
293
294 populateResults(nextPage * 20);
295 return false;
296 }
297
298 function submitAutoComplete() {
299 if (autocompleteText.value.length > 0) {
300 var selection = autocompleteText.value;
301 $.each(dropdown, function (i, dropdownEntry) {
302 if (dropdownEntry.substr(0, dropdownEntry.length - 1) == selection) {
303 selection = dropdownEntry;
304 }
305 });
306
307 selectedSearch["?"] = selection;
308 query(catalog, selectedSearch, onData, 1);
309 delete selectedSearch["?"];
310 }
311 }
312
313 function submitCatalogSearch(field) {
314 console.log("Sumbit Catalog Search: " + field);
315 // @todo: this logic isn't quite right
316 var remove = false;
317 $.each(selectedSearch, function (search, f) {
318 if (field == f) {
319 delete selectedSearch[field];
320 remove = true;
321 }
322 });
323 if (!remove) {
324 $.each(searchMenuOptions, function (search, fields) {
325 $.each(fields, function (index, f) {
326 if (f == field) {
327 selectedSearch[search] = field;
328 }
329 });
330 });
331 }
332 query(catalog, selectedSearch, onData, 1);
333 populateCurrentSelections();
334 return false;
335 }
336
337 function populateAutocomplete(fields) {
338 var isAutocompleteFullName = (autocompleteText.value.charAt(autocompleteText.value.length - 1) === "/");
339 var autocompleteFullName = autocompleteText.value;
340 for (var i = 0; i < fields.length; ++i) {
341 var fieldFullName = fields[i];
342 var entry = autocompleteFullName;
343 var skipahead = "";
344
345 if (isAutocompleteFullName) {
346 skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
347 } else {
348 if (fieldFullName.charAt(autocompleteText.value.length) === "/") {
349 entry += "/";
350 skipahead = fieldFullName.substr(autocompleteText.value.length + 1, fieldFullName.length);
351 } else {
352 skipahead = fieldFullName.substr(autocompleteText.value.length, fieldFullName.length);
353 }
354 }
355 if (skipahead.indexOf("/") != -1) {
356 entry += skipahead.substr(0, skipahead.indexOf("/") + 1);
357 } else {
358 entry += skipahead;
359 }
360
361 var added = false;
362 for (var j = 0; j < dropdown.length && !added; ++j) {
363 if (dropdown[j] === entry) {
364 added = true;
365 } else if (dropdown[j] > entry) {
366 dropdown.splice(j, 0, entry);
367 added = true;
368 }
369 }
370 if (!added) {
371 dropdown.push(entry);
372 }
373
374 }
375 $("#autocompleteText").autocomplete({
376 source: dropdown
377 });
378 }
379
380 function populateCurrentSelections() {
381 var currentSelection = $(".currentSelections");
382 currentSelection.empty();
383
384 currentSelection.append("<p>Filtering on:");
385
386 $.each(selectedSearch, function (searchMenuCatagory, selection) {
387 currentSelection.append(' <a href="#" onclick="removeFilter(this.id);" id="' + searchMenuCatagory + ':' + selection + '">[X] ' + searchMenuCatagory + ":" + selection + '</a>');
388 });
389
390 currentSelection.append("</p>");
391 }
392
393
394 function removeFilter(filter) {
395 console.log("Remove filter" + filter);
396 var searchFilter = filter.split(":");
397
398 var search = "";
399 for (var j = 0; j < searchFilter.length; ++j) {
400 search += searchFilter[j] + " ";
401 }
402 console.log("Split values: '" + search + "'");
403
404 delete selectedSearch[searchFilter[0]];
405 query(catalog, selectedSearch, onData, 1);
406 populateCurrentSelections();
407
408 return false;
Alison Craigef12da82015-03-06 09:41:43 -0700409 }
410 </script>
411</head>
412
413<body id="body">
414 <header>
415 <h1>Atmospheric Query and Retrieval Tool</h1>
416 </header>
417
418 <ul class='cssmenu'>
419
420 </ul>
421
Alison Craig1aced7d2015-04-10 12:00:02 -0600422 <div class="currentSelections"></div>
423
424
Alison Craigef12da82015-03-06 09:41:43 -0700425 <div class="autocomplete">
Alison Craig1aced7d2015-04-10 12:00:02 -0600426 <div class="ui-widget">
427 <label for="tags"> Search: </label>
428 <input id="autocompleteText" placeholder="/cmip" class="textbox" onkeydown="if (event.keyCode == 13) submitAutoComplete(); ">
429 <button id="autoButton" value="Search" onclick="submitAutoComplete()" id="autocompleteButton">Search</button>
430 </div>
431
432 <div class="page"></div>
433
434 <table class="resultTable">
435
436
437 </table>
Alison Craigef12da82015-03-06 09:41:43 -0700438 </div>
Alison Craigef12da82015-03-06 09:41:43 -0700439
440
Alison Craigef12da82015-03-06 09:41:43 -0700441</body>
442
443</html>