Project

General

Profile

1 5509 leinfelder
<%@ page language="java"%>
2 5788 leinfelder
<%@page import="edu.ucsb.nceas.metacat.util.AuthUtil"%>
3 5509 leinfelder
<%
4
/**
5
 *
6
 * '$RCSfile$'
7
 * Copyright: 2008 Regents of the University of California and the
8
 *             National Center for Ecological Analysis and Synthesis
9
 *    '$Author$'
10
 *      '$Date$'
11
 * '$Revision$'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27 5385 leinfelder
%>
28 5632 leinfelder
29 5509 leinfelder
<%@ include file="../../common/common-settings.jsp"%>
30
<%@ include file="../../common/configure-check.jsp"%>
31 5604 leinfelder
32 5385 leinfelder
<html>
33
<head>
34 5509 leinfelder
<title>Semantic search</title>
35
<link rel="stylesheet" type="text/css" href="<%=STYLE_SKINS_URL%>/semtools/semtools.css">
36 5703 leinfelder
<link rel="stylesheet" type="text/css" href="<%=STYLE_COMMON_URL%>/jquery/jqueryui/css/smoothness/jquery-ui-1.8.6.custom.css">
37 5509 leinfelder
38 5703 leinfelder
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/jquery/jquery.js"></script>
39
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/jquery/jsTree/_lib/jquery.cookie.js"></script>
40
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/jquery/jsTree/jquery.jstree.js"></script>
41
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/jquery/jqueryui/js/jquery-ui-1.8.6.custom.min.js"></script>
42
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/jquery/busy/jquery.busy.js"></script>
43 5669 leinfelder
44 5703 leinfelder
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/search.js"></script>
45 5509 leinfelder
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/semtools.js"></script>
46
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/branding.js"></script>
47
48 5656 leinfelder
<script language="Javascript" type="text/JavaScript"><!--
49 5633 leinfelder
function populateActiveDomain(divId, class) {
50 5656 leinfelder
	// collect the filtering values we have so far
51
	// these are hidden input fields in the form for holding the selected values
52
	var entity = $("#activeEntitiesValue").val() ? $("#activeEntitiesValue").val() : "";
53
	var characteristic = $("#activeCharacteristicsValue").val() ? $("#activeCharacteristicsValue").val() : "";
54
	var protocol = $("#activeProtocolsValue").val() ? $("#activeProtocolsValue").val() : "";
55
	var measurement = $("#activeMeasurementsValue").val() ? $("#activeMeasurementsValue").val() : "";
56 5633 leinfelder
57 5656 leinfelder
	// TODO: remember the selected value for this when filtering by active domain
58
	var selectedNode = $("#" + divId).jstree("get_selected", $("#" + divId));
59
	var selectedNodeId = $(selectedNode).attr("id");
60 5668 leinfelder
	//alert(divId + " selected node: " + selectedNodeId);
61 5656 leinfelder
62
	// load the tree for the given div, passing in the other filtered values
63 5633 leinfelder
	$("#" + divId).load(
64 5656 leinfelder
		"<%=SERVLET_URL%>",
65
		{
66
			'action': "getactivedomain",
67
			'class': class,
68
			'entity': entity,
69
			'characteristic': characteristic,
70
			'protocol': protocol,
71
			'measurement': measurement
72
		},
73
		// call back function when loading finishes
74
		function(response, status, xhr) {
75
			//alert("callback for: " + divId + " selected node: " + selectedNodeId);
76
			// error
77
			if (status == "error") {
78
				var msg = "Sorry but there was an error: ";
79
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
80
			}
81
82
			// make it a js tree
83
			$(function () {
84
				$("#" + divId)
85 5660 leinfelder
					//bind calls here
86 5656 leinfelder
					.jstree({
87
						"ui" : {
88
							"select_limit" : 1,
89
							"select_multiple_modifier" : "alt",
90
							"selected_parent_close" : "select_parent"//,
91
							//"initially_select" : [ selectedNodeId ]
92 5659 leinfelder
						},
93
						"themes" : {
94
							"theme" : "default",
95
							"dots" : true,
96
							"icons" : false
97
						},
98 5656 leinfelder
						//"core" : { "initially_open" : [ selectedNodeId ] },
99 5658 leinfelder
						"search" : { "case_insensitive" : true },
100 5668 leinfelder
						//"cookies" : {
101
						//		"save_opened" : "jstree_open_" + divId,
102
						//		"save_selected" : "jstree_select_" + divId,
103
						//},
104 5666 leinfelder
						"plugins" : [
105
							"themes",
106
							"html_data",
107
							"ui",
108 5668 leinfelder
							//"cookies",
109 5666 leinfelder
							"search" ]
110 5656 leinfelder
					});
111
			});
112
113 5658 leinfelder
			// enable searching on it
114
			$("#" + divId + "Search").keyup(
115
				function () {
116 5688 leinfelder
					var searchTerm = $("#" + divId + "Search").val();
117
					if (searchTerm.length >= 3) {
118 5678 leinfelder
						// search
119 5688 leinfelder
						$("#" + divId).jstree("search", searchTerm);
120 5663 leinfelder
						// now prune
121 5664 leinfelder
						prune(divId, "jstree-search");
122 5688 leinfelder
						// is it an exact match?
123
						checkExactMatch(divId, searchTerm, "jstree-search");
124 5658 leinfelder
					}
125
				});
126 5664 leinfelder
127
			// toggle the active domain prune
128 5668 leinfelder
			$("#" + divId + "Only").click(function() {
129
				doActiveDomain(divId);
130
			});
131 5658 leinfelder
132 5668 leinfelder
			// actually prune if we should
133
			doActiveDomain(divId);
134 5687 leinfelder
135
			// open first node always
136
			$("#" + divId).jstree("open_node", $("#" + divId).children("ul").first().children("li").first());
137 5668 leinfelder
138
			// open to the node to last selected
139 5667 leinfelder
			var nodePath = $("#" + divId).jstree("get_path", $(selectedNode));
140
			if (nodePath) {
141
				for (var index = 0; index < nodePath.length; index++) {
142
					$("#" + divId).jstree("open_node", $("#" + nodePath[index]));
143
				}
144
				// select the original node
145
				$("#" + divId).jstree("select_node", $(selectedNode), false);
146
				$("#" + divId).jstree("refresh", $(selectedNode));
147
				// TODO: scroll to selected node.
148
				// This is supposed to be part of jsTree 1.0-rc2 but appears to be broken
149
			}
150
151 5656 leinfelder
		});
152 5633 leinfelder
}
153 5664 leinfelder
/**
154
* Prunes the given tree to inlcude the given matched class
155
**/
156
function prune(divId, matchClass) {
157 5663 leinfelder
158
	// show all nodes (reset)
159
	$("#" + divId).find("li").show();
160
161 5664 leinfelder
	// done if we don't have any thing to prune
162
	if (!matchClass) {
163
		return;
164
	}
165
166 5663 leinfelder
	// get all non-matched anchor tags
167 5664 leinfelder
	var nonmatches = $("#" + divId).find("a").not("." + matchClass);
168 5663 leinfelder
169
	// get their parent nodes
170
	nonmatches = $(nonmatches).parents("li");
171
172
	// are there any matches under each parent node?
173
	$(nonmatches).each(
174
		function(index) {
175
			// do any chidren match?
176 5664 leinfelder
			var childMatches = $(this).find("a." + matchClass);
177 5663 leinfelder
			if (childMatches && childMatches.length > 0) {
178
				return true;
179
			}
180
			// parent matches?
181 5664 leinfelder
			var parentMatches = $(this).parents("li").children("a." + matchClass);
182 5663 leinfelder
			if (parentMatches && parentMatches.length > 0) {
183
				return true;
184
			}
185
			// hide this node if no matches under it
186
			$(this).hide();
187
		});
188
}
189 5688 leinfelder
function checkExactMatch(divId, searchTerm, matchClass) {
190
	// get the current search matches
191
	var matches = $("#" + divId).find("a." + matchClass);
192
	// get their parent nodes
193
	matches = $(matches).parents("li");
194
	// check for exact matches
195
	var exactMatch = $(matches).filter("#" + searchTerm).first();
196
	if (exactMatch && exactMatch.length == 1) {
197
		//alert("exactMatch: " + exactMatch);
198 5689 leinfelder
		// select in the tree, honoring the configured selection limit
199
		$("#" + divId).jstree("select_node", $(exactMatch), true);
200
		// act as those you clicked it
201
		// TODO: convert to event listeners on the tree
202 5688 leinfelder
		select($(exactMatch).children("a"));
203
	}
204
}
205 5668 leinfelder
function doActiveDomain(divId) {
206
	if ($("#" + divId + "Only").is(":checked")) {
207
		// prune to active
208
		prune(divId, "bold");
209
	} else {
210
		// reset
211
		prune(divId, null);
212
	}
213
}
214 5633 leinfelder
function initialize(source) {
215 5656 leinfelder
	// we don't want to reload the source of the filtering request
216
	// but we do want to reload the other trees for active domains
217
	// we reload all of them if no source is given - first time the page loads
218 5633 leinfelder
	if (source) {
219 5656 leinfelder
		source = $(source).attr("id");
220 5633 leinfelder
	}
221
	if (!source) {
222
		source = "";
223
	}
224
	if (source != 'activeEntities') {
225
		populateActiveDomain('activeEntities', 'org.ecoinformatics.sms.annotation.Entity');
226
	}
227
	if (source != 'activeCharacteristics') {
228
		populateActiveDomain('activeCharacteristics', 'org.ecoinformatics.sms.annotation.Characteristic');
229
	}
230
	if (source != 'activeProtocols') {
231
		populateActiveDomain('activeProtocols', 'org.ecoinformatics.sms.annotation.Protocol');
232
	}
233
	if (source != 'activeMeasurements') {
234
		populateActiveDomain('activeMeasurements', 'org.ecoinformatics.sms.annotation.Measurement');
235
	}
236
}
237 5656 leinfelder
function select(item) {
238 5633 leinfelder
239 5656 leinfelder
	// get the selected value, stored in the title attribute of the item <a> tag
240
	var value = $(item).attr("title");
241
	//alert("value: " + value);
242
243
	// get the parent div so we know what kind of class it is meant to filter
244
	// this is "the first parent of the class 'select'"
245
	var parent = $(item).parents("div.select:first");
246
	//alert("parent: " + parent);
247
248
	// set the value for the hidden input value
249 5774 leinfelder
	// the input field of class "conceptValue" will hold it, this way we don't need to know the id
250
	var input = $(parent).children("input.conceptValue");
251 5656 leinfelder
	$(input).val(value);
252
	//alert("input: " + input);
253 5662 leinfelder
254
	// set it in the search field
255
	var treeInstance = $(item).parents("div.jstree:first");
256
	var shortName = $(item).parent().attr("id");
257
	$("#" + $(treeInstance).attr("id") + "Search").val(shortName)
258 5656 leinfelder
259 5665 leinfelder
	// refresh the search results
260 5996 leinfelder
	doSearch();
261 5665 leinfelder
262 5656 leinfelder
	// refresh the other trees for active domain after this filtering action
263 5666 leinfelder
	initialize($(parent).children("div"));
264 5656 leinfelder
}
265 5996 leinfelder
function doSearch() {
266
267
	// get a reference
268
	var formObj = $("#searchForm").get(0);
269
270 5665 leinfelder
	// set the hidden parameters based on the current state of the form
271
	checkSearch(formObj);
272
273 5678 leinfelder
	// start the busy indicator
274 5684 leinfelder
	$("#searchResults").busy(
275
			{
276
				position	: 'left',
277
				offset		: -30,
278
				hide		: true,
279 5703 leinfelder
				img			: "<%=STYLE_COMMON_URL%>/jquery/busy/busy.gif"
280 5684 leinfelder
			});
281 5678 leinfelder
282 5665 leinfelder
	//load the results
283
	$("#searchResults").load(
284
		"<%=SERVLET_URL%>" + " #content_wrapper",
285
		$(formObj).serialize(),
286
		// call back function when loading finishes
287
		function(response, status, xhr) {
288
			if (status == "error") {
289
				var msg = "Sorry but there was an error performing the search: ";
290
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
291
			}
292 5762 leinfelder
			// collapsible search results - show and hide the next div
293 5675 leinfelder
			$(function() {
294 5785 leinfelder
				$('#searchResults').find('.accordian').click(function() {
295 5765 leinfelder
					var ref = $(this);
296
					$(this).parent().next().slideToggle(
297
						"slow",
298
						function() {
299
							if ($(ref).parent().next().is(":visible")) {
300
								$(ref).html("-");
301
							} else {
302
								$(ref).html("+");
303
							}
304
						});
305 5675 leinfelder
					return false;
306 5762 leinfelder
				}).parent().next().hide();
307 5675 leinfelder
			});
308
309 5678 leinfelder
			// stop the busy indicator
310
			$("#searchResults").busy("hide");
311 5665 leinfelder
		});
312
313
	return false;
314
315
}
316 5781 leinfelder
function loadCart() {
317
318
	// start the busy indicator
319
	$("#cartResults").busy(
320 5785 leinfelder
		{
321
			position	: 'left',
322
			offset		: -30,
323
			hide		: true,
324
			img			: "<%=STYLE_COMMON_URL%>/jquery/busy/busy.gif"
325
		});
326 5781 leinfelder
327
	// for looking up the cart
328
	var params =
329
	{
330
		'action': 'getcart',
331
		'showAdd': 'false',
332
		'showRemove': 'true',
333
		'qformat': 'semtools'
334
	};
335
	//load the cart results
336
	$("#cartResults").load(
337
		"<%=SERVLET_URL%>" + " #content_wrapper",
338
		params,
339
		// call back function when loading finishes
340
		function(response, status, xhr) {
341
			if (status == "error") {
342
				var msg = "Sorry but there was an error performing the search: ";
343
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
344
			}
345
			// collapsible search results - show and hide the next div
346
			$(function() {
347 5785 leinfelder
				$('#cartResults').find('.accordian').click(function() {
348 5781 leinfelder
					var ref = $(this);
349
					$(this).parent().next().slideToggle(
350
						"slow",
351
						function() {
352
							if ($(ref).parent().next().is(":visible")) {
353
								$(ref).html("-");
354
							} else {
355
								$(ref).html("+");
356
							}
357
						});
358
					return false;
359
				}).parent().next().hide();
360
			});
361
362
			// stop the busy indicator
363
			$("#cartResults").busy("hide");
364 5784 leinfelder
365
			//set the count for the tab label
366
			var title = "Cart (" + $("#cartResults").find(".resultCount:first").html() + ")";
367
			$("#searchTabs > ul > li").last().children("a").html("<span>" + title + "</span>");
368
369 5781 leinfelder
		});
370
	return true;
371
}
372
function clearCart() {
373
374
	// for looking up the cart
375
	var params =
376
	{
377
		'action': 'editcart',
378
		'operation': 'clear',
379
		'qformat': 'semtools'
380
	};
381
	// post the cart clear
382
	$("#cartResults").load(
383
		"<%=SERVLET_URL%>",
384
		params,
385
		// call back function when loading finishes
386
		function(response, status, xhr) {
387
			if (status == "error") {
388
				var msg = "Sorry but there was an error clearing the cart: ";
389
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
390
			}
391
		});
392
	return true;
393
}
394 5790 leinfelder
function addAllToCart() {
395
	// press all the add cart buttons?
396
	// TODO: add them in a single request (the service handles multiple docids)
397
	$(".addCartButton").click();
398
}
399 5668 leinfelder
function clearForm() {
400 5793 leinfelder
	// remember the check boxes
401
	var matchAll = $('#matchAll').attr("checked");
402
	var strict = $('#strict').attr("checked");
403
404 5668 leinfelder
	// clear the form values
405
	$('#searchForm').get(0).reset();
406
	// clear each of the tree selections
407
	$(".jstree").each(function(index) {
408
		$(this).jstree("deselect_all");
409
	});
410 5774 leinfelder
	$("input.conceptValue").each(function(index) {
411 5668 leinfelder
		$(this).val("");
412
	});
413 5793 leinfelder
414 5668 leinfelder
	// reload the trees
415
	initialize();
416 5793 leinfelder
417
	// set the saved checkbox values
418
	$('#matchAll').attr("checked", matchAll);
419
	$('#strict').attr("checked", strict);
420
421 5668 leinfelder
	// reload the search results
422
	//alert($('#searchForm').get(0));
423 5996 leinfelder
	doSearch();
424 5668 leinfelder
}
425 5774 leinfelder
function addCurrent() {
426
427
	// make a container for this item
428
	var count = $("#searchCriteria").children(".searchItem").length;
429
	count++;
430
	var containerId = "searchItem_" + count;
431 5789 leinfelder
	// ensure the containerId is unique
432
	while ($("#" + containerId).length > 0) {
433
		count++;
434
		containerId = "searchItem_" + count;
435
	}
436 5774 leinfelder
	var container = "<div class='searchItem' id='" + containerId + "'/>";
437
	$("#searchCriteria").append(container);
438
439
	// get the current values
440
	$("input.conceptValue").each(function(index) {
441
		var title = $(this).attr("title");
442
		var value = $(this).val();
443
		var shortName = value.substr(value.lastIndexOf("#") + 1);
444
		var clone = $(this).clone();
445
		$(clone).removeClass("conceptValue");
446
		// put the value in the container
447
		$("#" + containerId).append(clone);
448
		$("#" + containerId).append("[" + title + " = " + shortName + "] ");
449
	});
450
	// get the current classes (for search to work correctly we need class+value for each entry)
451
	$("input.conceptClass").each(function(index) {
452
		var clone = $(this).clone();
453
		$(clone).removeClass("conceptClass");
454
		// put the class in the container
455
		$("#" + containerId).append(clone);
456
	});
457
458 5993 leinfelder
	// get the current data values (and operator)
459
	$("#" + containerId).append("(");
460
	$(".dataClass").each(function(index) {
461
		var clone = $(this).clone();
462
		var value = $(this).val();
463
		var name = $(this).attr("name");
464
		var id = $(this).attr("id");
465
466
		// put the data conditions in as hidden params
467
		$("#" + containerId).append("<input type='hidden' name='" + name + "' id='" + id + "' value='" + value + "'");
468
		// with a text representation
469
		if (index > 0) {
470
			$("#" + containerId).append(" ");
471
		}
472
		$("#" + containerId).append(value);
473
474
	});
475
	$("#" + containerId).append(")");
476
477 5774 leinfelder
	// add the remove button
478 5789 leinfelder
	var removeButtonId = containerId + "_remove";
479
	$("#" + containerId).append("<input type='button' value='Remove' id='" + removeButtonId + "'/>");
480
	$("#" + removeButtonId).click(function() {
481 5774 leinfelder
		// remove the container (includes the form objects we added)
482
		$("#" + containerId).remove();
483
		// refresh the search results now that they are less restrictive
484 5996 leinfelder
		doSearch();
485 5774 leinfelder
	});
486 5790 leinfelder
487
	// clear the form of what we just saved to the criteria list
488
	clearForm();
489 5774 leinfelder
}
490 5790 leinfelder
function clearCriteria() {
491
492
	// remove all children of the criteria
493
	$("#searchCriteria").children().remove();
494
495
	// clear the form of any selections
496
	clearForm();
497
498
	// refresh the search results now that they are less restrictive
499 5996 leinfelder
	doSearch();
500 5790 leinfelder
}
501 5685 leinfelder
/**
502
 * Perform this when the page first loads
503
 */
504
function pageLoad() {
505
	initialize();
506 5996 leinfelder
	doSearch();
507 5786 leinfelder
	loadCart();
508 5685 leinfelder
}
509 5656 leinfelder
function donothing() {}
510
--></script>
511
512 5385 leinfelder
</head>
513 5685 leinfelder
<body onload="pageLoad()">
514 5509 leinfelder
<script language="javascript">
515
	insertTemplateOpening("<%=CONTEXT_URL%>");
516
</script>
517 5385 leinfelder
518 5574 leinfelder
<div id="content_wrapper">
519 5669 leinfelder
520 5690 leinfelder
<h2>Semantic search</h2>
521 5385 leinfelder
522 5633 leinfelder
<div id="error">
523
	<!-- error messages here -->
524
</div>
525
526 5669 leinfelder
<!-- set up the tabs -->
527
<script>
528
	$(function() {
529
		$("#searchTabs").tabs();
530
		$("#searchTabs").tabs("add", "#ecpTab", "Entity, Characteristic, Protocol");
531
		$("#searchTabs").tabs("add", "#measurementTab", "Measurement");
532 5672 leinfelder
		$("#searchTabs").tabs("add", "#optionsTab", "Options");
533 5782 leinfelder
		$("#searchTabs").tabs("add", "#cartTab", "Cart");
534 5669 leinfelder
	});
535
</script>
536
537 5665 leinfelder
<form method="POST"
538
		action="<%=SERVLET_URL%>"
539
		target="_top"
540
		id="searchForm"
541
		name="searchForm"
542 5996 leinfelder
		onSubmit="return doSearch()">
543 5509 leinfelder
	<input name="query" type="hidden" />
544
	<input name="qformat" value="semtools" type="hidden" />
545 5665 leinfelder
	<input name="includeHeader" value="false" type="hidden" />
546 5790 leinfelder
	<input name="showAdd" value="<%=AuthUtil.isUserLoggedIn(request)%>" type="hidden" />
547 5781 leinfelder
	<input name="showRemove" value="false" type="hidden" />
548 5533 leinfelder
	<input name="action" value="semquery" type="hidden" />
549 5509 leinfelder
550 5672 leinfelder
	<!-- tabs for the search interface -->
551
	<div id="searchTabs">
552
		<!-- place holder for ui tabs -->
553
		<ul></ul>
554
555
		<!-- other criteria tabs -->
556
		<div id="ecpTab">
557
			<table>
558
				<tr>
559
					<td>
560
						<table class="subGroup subGroup_border">
561
562 5669 leinfelder
							<tr>
563 5672 leinfelder
								<th><p>Find observations of</p></th>
564
							</tr>
565
							<tr>
566 5669 leinfelder
								<td>
567 5672 leinfelder
									<input type="text" id="activeEntitiesSearch" />
568
									<input type="checkbox" id="activeEntitiesOnly" title="Show only active concepts" />
569
									<div class="select">
570
										<div id="activeEntities" class="activeTree">
571
											<p>loading...</p>
572
										</div>
573 5774 leinfelder
										<input type="hidden" class="conceptValue" name="activeEntitiesValue" id="activeEntitiesValue" title="Entity"/>
574
										<input type="hidden" class="conceptClass" name="activeEntitiesClass" id="activeEntitiesClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Entity"/>
575 5672 leinfelder
									</div>
576 5669 leinfelder
								</td>
577 5672 leinfelder
							</tr>
578
						</table>
579
					</td>
580
					<td>
581
						<table class="subGroup subGroup_border">
582
							<tr>
583
								<th><p>with measurements of</p></th>
584
							</tr>
585
							<tr>
586 5669 leinfelder
								<td>
587 5672 leinfelder
									<input type="text" id="activeCharacteristicsSearch" />
588
									<input type="checkbox" id="activeCharacteristicsOnly" title="Show only active concepts" />
589
									<div class="select">
590
										<div id="activeCharacteristics" class="activeTree">
591
											<p>loading...</p>
592
										</div>
593 5774 leinfelder
										<input type="hidden" class="conceptValue" name="activeCharacteristicsValue" id="activeCharacteristicsValue" title="Characteristic"/>
594
										<input type="hidden" class="conceptClass" name="activeCharacteristicsClass" id="activeCharacteristicsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Characteristic"/>
595 5672 leinfelder
									</div>
596 5993 leinfelder
597 5669 leinfelder
								</td>
598
							</tr>
599 5993 leinfelder
							<tr>
600
								<th>
601
									<p>and data values</p>
602
								</th>
603
							</tr>
604
							<tr>
605
								<td>
606
									<div id="characteristicData">
607 5996 leinfelder
										<select id="dataOperator" name="dataOperator" class="dataClass" onchange="doSearch()">
608 5993 leinfelder
											<option value="EQUALS">=</option>
609
											<option value="NOT EQUALS">!=</option>
610
611
											<option value="LESS THAN OR EQUALS">&lt;=</option>
612
											<option value="LESS THAN">&lt;</option>
613
											<option value="GREATER THAN OR EQUALS">&gt;=</option>
614 5995 leinfelder
											<option value="GREATER THAN">&gt;</option>
615 5993 leinfelder
616
											<option value="LIKE">like</option>
617
											<option value="NOT LIKE">not like</option>
618
										</select>
619
										<input type="text" id="dataValue" name="dataValue" class="dataClass"/>
620
									</div>
621
								</td>
622
							</tr>
623 5669 leinfelder
						</table>
624 5672 leinfelder
					</td>
625
					<td>
626
						<table class="subGroup subGroup_border">
627 5669 leinfelder
							<tr>
628 5672 leinfelder
								<th><p>using procedures outlined by</p></th>
629 5669 leinfelder
							</tr>
630
							<tr>
631
								<td>
632 5672 leinfelder
									<input type="text" id="activeProtocolsSearch" />
633
									<input type="checkbox" id="activeProtocolsOnly" title="Show only active concepts" />
634 5669 leinfelder
									<div class="select">
635 5672 leinfelder
										<div id="activeProtocols" class="activeTree">
636 5669 leinfelder
											<p>loading...</p>
637
										</div>
638 5774 leinfelder
										<input type="hidden" class="conceptValue" name="activeProtocolsValue" id="activeProtocolsValue" title="Protocol"/>
639
										<input type="hidden" class="conceptClass" name="activeProtocolsClass" id="activeProtocolsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Protocol"/>
640 5669 leinfelder
									</div>
641
								</td>
642
							</tr>
643
						</table>
644 5672 leinfelder
					</td>
645
				</tr>
646
			</table>
647 5782 leinfelder
648
			<!-- collected search criteria here -->
649
			<table class="subGroup subGroup_border onehundred_percent">
650
				<tr>
651
					<th>
652
						<p>
653
						Search criteria
654 5790 leinfelder
						<input type="button" value="Add selected criteria" onclick="addCurrent()"/>
655
						<input type="button" value="Remove all" onclick="clearCriteria()"/>
656 5782 leinfelder
						</p>
657
					</th>
658
				</tr>
659
				<tr>
660
					<td>
661
						<div id="searchCriteria">
662
						</div>
663
					</td>
664
				</tr>
665
			</table>
666
667 5672 leinfelder
		</div>
668
669
		<!-- measurement -->
670
		<div id="measurementTab">
671
			<table class="subGroup subGroup_border onehundred_percent">
672 5669 leinfelder
673 5672 leinfelder
				<tr>
674
					<th><p>a template that defines Entity, Characteristic, Standard, and/or Protocol</p></th>
675
				</tr>
676
677
				<tr>
678
					<td>
679
						<input type="text" id="activeMeasurementsSearch" />
680
						Only active? <input type="checkbox" id="activeMeasurementsOnly" title="Show only active concepts"/>
681
						<div class="select">
682
							<div id="activeMeasurements" class="activeTree" style="width: 100%">
683
								<p>loading...</p>
684
							</div>
685 5774 leinfelder
							<input type="hidden" class="conceptValue" name="activeMeasurementsValue" id="activeMeasurementsValue" title="Measurement"/>
686
							<input type="hidden" class="conceptClass" name="activeMeasurementsClass" id="activeMeasurementsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Measurement"/>
687 5672 leinfelder
						</div>
688
					</td>
689
				</tr>
690
			</table>
691
		</div>
692 5669 leinfelder
693 5672 leinfelder
		<!-- query options -->
694
		<div id="optionsTab">
695
			<table class="group group_border">
696
				<tr>
697
					<th colspan="2">
698
						<p>
699
							Locate <b>data packages</b> that have been semantically annotated within the observation model by
700
							selecting concepts from OBOE extension ontologies
701
						</p>
702
					</th>
703
				</tr>
704
705
				<tr>
706
707 5793 leinfelder
					<td colspan="1">
708
						Match All?
709 5996 leinfelder
						<input type="checkbox" name="matchAll" id="matchAll" checked="checked" onchange="doSearch()"/>
710 5793 leinfelder
					</td>
711 5672 leinfelder
712 5793 leinfelder
					<td colspan="1">
713
						From same Observation?
714 5996 leinfelder
						<input type="checkbox" name="strict" id="strict" onchange="doSearch()"/>
715 5793 leinfelder
					</td>
716 5672 leinfelder
				</tr>
717
718
			</table>
719 5782 leinfelder
		</div>
720
721
		<!-- cart -->
722
		<div id="cartTab">
723
			<!--cart here -->
724
			<table class="subGroup subGroup_border onehundred_percent">
725
				<tr>
726
					<th>
727
						<p>
728 5788 leinfelder
						Cart
729
						<%
730 5790 leinfelder
							if (AuthUtil.isUserLoggedIn(request)) {
731 5788 leinfelder
						%>
732
							<!-- <input type="button" value="Refresh" onclick="loadCart()"/> -->
733
							<input type="button" value="Remove all" onclick="clearCart(); loadCart()"/>
734
						<%
735
							} else {
736
						%>
737
							(<a target="_top" href="<%=STYLE_SKINS_URL%>/semtools/login.jsp">Login</a> to edit cart)
738
						<%
739
							}
740
						%>
741 5782 leinfelder
						</p>
742
					</th>
743
				</tr>
744
				<tr>
745
					<td>
746
						<div id="cartResults">
747
						No items in cart
748
						</div>
749
					</td>
750
				</tr>
751
			</table>
752 5787 leinfelder
		</div>
753 5672 leinfelder
754
	</div>
755
756
	<br/>
757 5781 leinfelder
758 5672 leinfelder
	<!-- search results here -->
759
	<table class="subGroup subGroup_border onehundred_percent">
760 5632 leinfelder
		<tr>
761 5672 leinfelder
			<th>
762
				Search Results
763 5790 leinfelder
				<%
764
					if (AuthUtil.isUserLoggedIn(request)) {
765
				%>
766
					<input type="button" value="Add all to cart" onclick="addAllToCart()"/>
767
				<%
768
					}
769
				%>
770 5672 leinfelder
			</th>
771 5509 leinfelder
		</tr>
772
		<tr>
773 5672 leinfelder
			<td>
774
				<div id="searchResults">
775
				No query has been specified
776
				</div>
777
			</td>
778 5509 leinfelder
		</tr>
779 5672 leinfelder
	</table>
780
781 5509 leinfelder
</form>
782
783 5665 leinfelder
784 5672 leinfelder
785 5509 leinfelder
<!-- Included default search/login -->
786
<% if ( PropertyService.getProperty("spatial.runSpatialOption").equals("true") ) { %>
787
<script language="javascript">
788
	insertMap("<%=CONTEXT_URL%>");
789
</script>
790
<br/>
791
<% } %>
792
793
<script language="javascript">
794
	insertSearchBox("<%=CONTEXT_URL%>");
795
	insertLoginBox("<%=CONTEXT_URL%>");
796
</script>
797
798 5574 leinfelder
</div>
799
800 5509 leinfelder
<script language="javascript">
801
	insertTemplateClosing("<%=CONTEXT_URL%>");
802
</script>
803
804 5385 leinfelder
</body>
805
</html>