Project

General

Profile

1
<%@ page language="java"%>
2
<%@page import="edu.ucsb.nceas.metacat.util.AuthUtil"%>
3
<%
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: leinfelder $'
10
 *      '$Date: 2011-02-25 12:01:38 -0800 (Fri, 25 Feb 2011) $'
11
 * '$Revision: 5993 $'
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
%>
28

    
29
<%@ include file="../../common/common-settings.jsp"%>
30
<%@ include file="../../common/configure-check.jsp"%>
31

    
32
<html>
33
<head>
34
<title>Semantic search</title>
35
<link rel="stylesheet" type="text/css" href="<%=STYLE_SKINS_URL%>/semtools/semtools.css">
36
<link rel="stylesheet" type="text/css" href="<%=STYLE_COMMON_URL%>/jquery/jqueryui/css/smoothness/jquery-ui-1.8.6.custom.css">
37

    
38
<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

    
44
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/search.js"></script>
45
<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
<script language="Javascript" type="text/JavaScript"><!--
49
function populateActiveDomain(divId, class) {
50
	// 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
	
57
	// 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
	//alert(divId + " selected node: " + selectedNodeId);
61
	
62
	// load the tree for the given div, passing in the other filtered values
63
	$("#" + divId).load(
64
		"<%=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
					//bind calls here
86
					.jstree({
87
						"ui" : {
88
							"select_limit" : 1,
89
							"select_multiple_modifier" : "alt",
90
							"selected_parent_close" : "select_parent"//,
91
							//"initially_select" : [ selectedNodeId ]
92
						},
93
						"themes" : {
94
							"theme" : "default",
95
							"dots" : true,
96
							"icons" : false
97
						},
98
						//"core" : { "initially_open" : [ selectedNodeId ] },
99
						"search" : { "case_insensitive" : true },
100
						//"cookies" : { 
101
						//		"save_opened" : "jstree_open_" + divId,
102
						//		"save_selected" : "jstree_select_" + divId,
103
						//},
104
						"plugins" : [ 
105
							"themes", 
106
							"html_data", 
107
							"ui", 
108
							//"cookies", 
109
							"search" ]
110
					});
111
			});
112

    
113
			// enable searching on it
114
			$("#" + divId + "Search").keyup(
115
				function () {
116
					var searchTerm = $("#" + divId + "Search").val();
117
					if (searchTerm.length >= 3) {
118
						// search
119
						$("#" + divId).jstree("search", searchTerm);
120
						// now prune
121
						prune(divId, "jstree-search");
122
						// is it an exact match?
123
						checkExactMatch(divId, searchTerm, "jstree-search");
124
					}
125
				});
126
			
127
			// toggle the active domain prune
128
			$("#" + divId + "Only").click(function() {
129
				doActiveDomain(divId);
130
			});	
131

    
132
			// actually prune if we should
133
			doActiveDomain(divId);
134

    
135
			// open first node always
136
			$("#" + divId).jstree("open_node", $("#" + divId).children("ul").first().children("li").first());
137
			
138
			// open to the node to last selected
139
			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
		});
152
}
153
/**
154
* Prunes the given tree to inlcude the given matched class 
155
**/
156
function prune(divId, matchClass) {
157

    
158
	// show all nodes (reset)
159
	$("#" + divId).find("li").show();
160
	
161
	// done if we don't have any thing to prune
162
	if (!matchClass) {
163
		return;
164
	}
165
	
166
	// get all non-matched anchor tags
167
	var nonmatches = $("#" + divId).find("a").not("." + matchClass);
168
	
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
			var childMatches = $(this).find("a." + matchClass);
177
			if (childMatches && childMatches.length > 0) {
178
				return true;
179
			}
180
			// parent matches?
181
			var parentMatches = $(this).parents("li").children("a." + matchClass);
182
			if (parentMatches && parentMatches.length > 0) {
183
				return true;
184
			}
185
			// hide this node if no matches under it
186
			$(this).hide();
187
		});
188
}
189
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
		// 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
		select($(exactMatch).children("a"));
203
	}
204
}
205
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
function initialize(source) {
215
	// 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
	if (source) {
219
		source = $(source).attr("id");
220
	}
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
function select(item) {
238

    
239
	// 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
	// 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
	$(input).val(value);
252
	//alert("input: " + input);
253
	
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

    
259
	// refresh the search results
260
	doSearch($("#searchForm").get(0));
261
	
262
	// refresh the other trees for active domain after this filtering action
263
	initialize($(parent).children("div"));
264
}
265
function doSearch(formObj) {
266
	// set the hidden parameters based on the current state of the form
267
	checkSearch(formObj);
268
	
269
	// start the busy indicator
270
	$("#searchResults").busy(
271
			{
272
				position	: 'left', 
273
				offset		: -30, 
274
				hide		: true, 
275
				img			: "<%=STYLE_COMMON_URL%>/jquery/busy/busy.gif" 
276
			});
277
	
278
	//load the results
279
	$("#searchResults").load(
280
		"<%=SERVLET_URL%>" + " #content_wrapper",
281
		$(formObj).serialize(),
282
		// call back function when loading finishes
283
		function(response, status, xhr) {
284
			if (status == "error") {
285
				var msg = "Sorry but there was an error performing the search: ";
286
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
287
			}
288
			// collapsible search results - show and hide the next div
289
			$(function() {
290
				$('#searchResults').find('.accordian').click(function() {
291
					var ref = $(this);
292
					$(this).parent().next().slideToggle(
293
						"slow",
294
						function() {
295
							if ($(ref).parent().next().is(":visible")) {
296
								$(ref).html("-");
297
							} else {
298
								$(ref).html("+");
299
							}
300
						});
301
					return false;
302
				}).parent().next().hide();
303
			});
304
			
305
			// stop the busy indicator
306
			$("#searchResults").busy("hide");
307
		});
308
		
309
	return false;
310
	
311
}
312
function loadCart() {
313

    
314
	// start the busy indicator
315
	$("#cartResults").busy(
316
		{
317
			position	: 'left', 
318
			offset		: -30, 
319
			hide		: true, 
320
			img			: "<%=STYLE_COMMON_URL%>/jquery/busy/busy.gif" 
321
		});
322
	
323
	// for looking up the cart
324
	var params = 
325
	{
326
		'action': 'getcart',
327
		'showAdd': 'false',
328
		'showRemove': 'true',
329
		'qformat': 'semtools'
330
	};
331
	//load the cart results
332
	$("#cartResults").load(
333
		"<%=SERVLET_URL%>" + " #content_wrapper",
334
		params,
335
		// call back function when loading finishes
336
		function(response, status, xhr) {
337
			if (status == "error") {
338
				var msg = "Sorry but there was an error performing the search: ";
339
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
340
			}
341
			// collapsible search results - show and hide the next div
342
			$(function() {
343
				$('#cartResults').find('.accordian').click(function() {
344
					var ref = $(this);
345
					$(this).parent().next().slideToggle(
346
						"slow",
347
						function() {
348
							if ($(ref).parent().next().is(":visible")) {
349
								$(ref).html("-");
350
							} else {
351
								$(ref).html("+");
352
							}
353
						});
354
					return false;
355
				}).parent().next().hide();
356
			});
357
			
358
			// stop the busy indicator
359
			$("#cartResults").busy("hide");
360
			
361
			//set the count for the tab label
362
			var title = "Cart (" + $("#cartResults").find(".resultCount:first").html() + ")";
363
			$("#searchTabs > ul > li").last().children("a").html("<span>" + title + "</span>"); 
364
			
365
		});
366
	return true;
367
}
368
function clearCart() {
369

    
370
	// for looking up the cart
371
	var params = 
372
	{
373
		'action': 'editcart',
374
		'operation': 'clear',
375
		'qformat': 'semtools'
376
	};
377
	// post the cart clear
378
	$("#cartResults").load(
379
		"<%=SERVLET_URL%>",
380
		params,
381
		// call back function when loading finishes
382
		function(response, status, xhr) {
383
			if (status == "error") {
384
				var msg = "Sorry but there was an error clearing the cart: ";
385
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
386
			}
387
		});
388
	return true;
389
}
390
function addAllToCart() {
391
	// press all the add cart buttons?
392
	// TODO: add them in a single request (the service handles multiple docids)
393
	$(".addCartButton").click();
394
}
395
function clearForm() {
396
	// remember the check boxes
397
	var matchAll = $('#matchAll').attr("checked");
398
	var strict = $('#strict').attr("checked");
399
	
400
	// clear the form values
401
	$('#searchForm').get(0).reset();
402
	// clear each of the tree selections
403
	$(".jstree").each(function(index) {
404
		$(this).jstree("deselect_all");
405
	});
406
	$("input.conceptValue").each(function(index) {
407
		$(this).val("");
408
	});
409
	
410
	// reload the trees
411
	initialize();
412
	
413
	// set the saved checkbox values
414
	$('#matchAll').attr("checked", matchAll);
415
	$('#strict').attr("checked", strict);
416
	
417
	// reload the search results
418
	//alert($('#searchForm').get(0));
419
	doSearch($('#searchForm').get(0));
420
}
421
function addCurrent() {
422

    
423
	// make a container for this item
424
	var count = $("#searchCriteria").children(".searchItem").length;
425
	count++;
426
	var containerId = "searchItem_" + count;
427
	// ensure the containerId is unique
428
	while ($("#" + containerId).length > 0) {
429
		count++;
430
		containerId = "searchItem_" + count;
431
	}
432
	var container = "<div class='searchItem' id='" + containerId + "'/>";
433
	$("#searchCriteria").append(container);
434
	
435
	// get the current values
436
	$("input.conceptValue").each(function(index) {
437
		var title = $(this).attr("title");
438
		var value = $(this).val();
439
		var shortName = value.substr(value.lastIndexOf("#") + 1);
440
		var clone = $(this).clone();
441
		$(clone).removeClass("conceptValue");
442
		// put the value in the container
443
		$("#" + containerId).append(clone);
444
		$("#" + containerId).append("[" + title + " = " + shortName + "] ");
445
	});
446
	// get the current classes (for search to work correctly we need class+value for each entry)
447
	$("input.conceptClass").each(function(index) {
448
		var clone = $(this).clone();
449
		$(clone).removeClass("conceptClass");
450
		// put the class in the container
451
		$("#" + containerId).append(clone);
452
	});
453
	
454
	// get the current data values (and operator)
455
	$("#" + containerId).append("(");
456
	$(".dataClass").each(function(index) {
457
		var clone = $(this).clone();
458
		var value = $(this).val();
459
		var name = $(this).attr("name");
460
		var id = $(this).attr("id");
461
		
462
		// put the data conditions in as hidden params
463
		$("#" + containerId).append("<input type='hidden' name='" + name + "' id='" + id + "' value='" + value + "'");
464
		// with a text representation
465
		if (index > 0) {
466
			$("#" + containerId).append(" ");
467
		}
468
		$("#" + containerId).append(value);
469
		
470
	});
471
	$("#" + containerId).append(")");
472
	
473
	// add the remove button
474
	var removeButtonId = containerId + "_remove";
475
	$("#" + containerId).append("<input type='button' value='Remove' id='" + removeButtonId + "'/>");
476
	$("#" + removeButtonId).click(function() {
477
		// remove the container (includes the form objects we added)
478
		$("#" + containerId).remove();
479
		// refresh the search results now that they are less restrictive
480
		doSearch($("#searchForm").get(0));
481
	});
482

    
483
	// clear the form of what we just saved to the criteria list
484
	clearForm();
485
}
486
function clearCriteria() {
487

    
488
	// remove all children of the criteria
489
	$("#searchCriteria").children().remove();
490

    
491
	// clear the form of any selections
492
	clearForm();
493

    
494
	// refresh the search results now that they are less restrictive
495
	doSearch($("#searchForm").get(0));
496
}
497
/**
498
 * Perform this when the page first loads
499
 */
500
function pageLoad() {
501
	initialize();
502
	doSearch($('#searchForm').get(0));
503
	loadCart();
504
}
505
function donothing() {}
506
--></script>
507

    
508
</head>
509
<body onload="pageLoad()">
510
<script language="javascript">
511
	insertTemplateOpening("<%=CONTEXT_URL%>");
512
</script>
513

    
514
<div id="content_wrapper">
515
 
516
<h2>Semantic search</h2>
517

    
518
<div id="error">
519
	<!-- error messages here -->
520
</div>
521

    
522
<!-- set up the tabs -->
523
<script>
524
	$(function() {
525
		$("#searchTabs").tabs();
526
		$("#searchTabs").tabs("add", "#ecpTab", "Entity, Characteristic, Protocol");
527
		$("#searchTabs").tabs("add", "#measurementTab", "Measurement");
528
		$("#searchTabs").tabs("add", "#optionsTab", "Options");
529
		$("#searchTabs").tabs("add", "#cartTab", "Cart");
530
	});
531
</script>
532

    
533
<form method="POST" 
534
		action="<%=SERVLET_URL%>" 
535
		target="_top" 
536
		id="searchForm" 
537
		name="searchForm" 
538
		onSubmit="return doSearch(this)">
539
	<input name="query" type="hidden" />
540
	<input name="qformat" value="semtools" type="hidden" />
541
	<input name="includeHeader" value="false" type="hidden" />
542
	<input name="showAdd" value="<%=AuthUtil.isUserLoggedIn(request)%>" type="hidden" />
543
	<input name="showRemove" value="false" type="hidden" />
544
	<input name="action" value="semquery" type="hidden" />
545

    
546
	<!-- tabs for the search interface -->		
547
	<div id="searchTabs">
548
		<!-- place holder for ui tabs -->
549
		<ul></ul>
550
	
551
		<!-- other criteria tabs -->
552
		<div id="ecpTab">
553
			<table>
554
				<tr>
555
					<td>
556
						<table class="subGroup subGroup_border">
557
							
558
							<tr>
559
								<th><p>Find observations of</p></th>
560
							</tr>
561
							<tr>
562
								<td>
563
									<input type="text" id="activeEntitiesSearch" />
564
									<input type="checkbox" id="activeEntitiesOnly" title="Show only active concepts" />
565
									<div class="select">
566
										<div id="activeEntities" class="activeTree">
567
											<p>loading...</p>
568
										</div>
569
										<input type="hidden" class="conceptValue" name="activeEntitiesValue" id="activeEntitiesValue" title="Entity"/>
570
										<input type="hidden" class="conceptClass" name="activeEntitiesClass" id="activeEntitiesClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Entity"/>
571
									</div>
572
								</td>
573
							</tr>
574
						</table>
575
					</td>
576
					<td>
577
						<table class="subGroup subGroup_border">
578
							<tr>
579
								<th><p>with measurements of</p></th>
580
							</tr>
581
							<tr>
582
								<td>
583
									<input type="text" id="activeCharacteristicsSearch" />
584
									<input type="checkbox" id="activeCharacteristicsOnly" title="Show only active concepts" />
585
									<div class="select">
586
										<div id="activeCharacteristics" class="activeTree">
587
											<p>loading...</p>
588
										</div>
589
										<input type="hidden" class="conceptValue" name="activeCharacteristicsValue" id="activeCharacteristicsValue" title="Characteristic"/>
590
										<input type="hidden" class="conceptClass" name="activeCharacteristicsClass" id="activeCharacteristicsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Characteristic"/>
591
									</div>
592
									
593
								</td>
594
							</tr>
595
							<tr>
596
								<th>
597
									<p>and data values</p>
598
								</th>
599
							</tr>
600
							<tr>
601
								<td>
602
									<div id="characteristicData">
603
										<select id="dataOperator" name="dataOperator" class="dataClass">
604
											<option value="EQUALS">=</option>
605
											<option value="NOT EQUALS">!=</option>
606

    
607
											<option value="LESS THAN OR EQUALS">&lt;=</option>
608
											<option value="LESS THAN">&lt;</option>
609
											<option value="GREATER THAN OR EQUALS">&gt;=</option>
610
											<option value="GREATER THAN OR EQUALS">&gt;</option>
611

    
612
											<option value="LIKE">like</option>
613
											<option value="NOT LIKE">not like</option>
614
										</select>
615
										<input type="text" id="dataValue" name="dataValue" class="dataClass"/>
616
									</div>
617
								</td>
618
							</tr>
619
						</table>
620
					</td>
621
					<td>
622
						<table class="subGroup subGroup_border">
623
							<tr>
624
								<th><p>using procedures outlined by</p></th>
625
							</tr>
626
							<tr>
627
								<td>
628
									<input type="text" id="activeProtocolsSearch" />
629
									<input type="checkbox" id="activeProtocolsOnly" title="Show only active concepts" />
630
									<div class="select">
631
										<div id="activeProtocols" class="activeTree">
632
											<p>loading...</p>
633
										</div>
634
										<input type="hidden" class="conceptValue" name="activeProtocolsValue" id="activeProtocolsValue" title="Protocol"/>
635
										<input type="hidden" class="conceptClass" name="activeProtocolsClass" id="activeProtocolsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Protocol"/>
636
									</div>
637
								</td>
638
							</tr>
639
						</table>
640
					</td>
641
				</tr>
642
			</table>
643

    
644
			<!-- collected search criteria here -->
645
			<table class="subGroup subGroup_border onehundred_percent">
646
				<tr>
647
					<th>
648
						<p>
649
						Search criteria
650
						<input type="button" value="Add selected criteria" onclick="addCurrent()"/>
651
						<input type="button" value="Remove all" onclick="clearCriteria()"/>
652
						</p>
653
					</th>
654
				</tr>
655
				<tr>
656
					<td>
657
						<div id="searchCriteria">
658
						</div>
659
					</td>
660
				</tr>
661
			</table>
662

    
663
		</div>
664
		
665
		<!-- measurement -->
666
		<div id="measurementTab">
667
			<table class="subGroup subGroup_border onehundred_percent">
668
				
669
				<tr>
670
					<th><p>a template that defines Entity, Characteristic, Standard, and/or Protocol</p></th>
671
				</tr>
672
				
673
				<tr>
674
					<td>
675
						<input type="text" id="activeMeasurementsSearch" />
676
						Only active? <input type="checkbox" id="activeMeasurementsOnly" title="Show only active concepts"/>
677
						<div class="select">
678
							<div id="activeMeasurements" class="activeTree" style="width: 100%">
679
								<p>loading...</p>
680
							</div>
681
							<input type="hidden" class="conceptValue" name="activeMeasurementsValue" id="activeMeasurementsValue" title="Measurement"/>
682
							<input type="hidden" class="conceptClass" name="activeMeasurementsClass" id="activeMeasurementsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Measurement"/>
683
						</div>
684
					</td>
685
				</tr>
686
			</table>
687
		</div>
688
		
689
		<!-- query options -->
690
		<div id="optionsTab">
691
			<table class="group group_border">
692
				<tr>
693
					<th colspan="2">
694
						<p>
695
							Locate <b>data packages</b> that have been semantically annotated within the observation model by
696
							selecting concepts from OBOE extension ontologies
697
						</p>
698
					</th>
699
				</tr>
700
				
701
				<tr>
702
					
703
					<td colspan="1">
704
						Match All? 
705
						<input type="checkbox" name="matchAll" id="matchAll" checked="checked" onchange="doSearch($('#searchForm').get(0))"/>
706
					</td>
707
				
708
					<td colspan="1">
709
						From same Observation? 
710
						<input type="checkbox" name="strict" id="strict" onchange="doSearch($('#searchForm').get(0))"/>
711
					</td>
712
				</tr>
713
				
714
			</table>
715
		</div>
716

    
717
		<!-- cart -->
718
		<div id="cartTab">
719
			<!--cart here -->	
720
			<table class="subGroup subGroup_border onehundred_percent">
721
				<tr>
722
					<th>
723
						<p>
724
						Cart 
725
						<%
726
							if (AuthUtil.isUserLoggedIn(request)) {
727
						%>
728
							<!-- <input type="button" value="Refresh" onclick="loadCart()"/> -->
729
							<input type="button" value="Remove all" onclick="clearCart(); loadCart()"/>
730
						<%
731
							} else {
732
						%>
733
							(<a target="_top" href="<%=STYLE_SKINS_URL%>/semtools/login.jsp">Login</a> to edit cart)
734
						<%
735
							}
736
						%>
737
						</p>
738
					</th>
739
				</tr>
740
				<tr>
741
					<td>
742
						<div id="cartResults">
743
						No items in cart
744
						</div>
745
					</td>
746
				</tr>
747
			</table>
748
		</div>
749
					
750
	</div>
751
	
752
	<br/>
753

    
754
	<!-- search results here -->	
755
	<table class="subGroup subGroup_border onehundred_percent">
756
		<tr>
757
			<th>
758
				Search Results
759
				<%
760
					if (AuthUtil.isUserLoggedIn(request)) {
761
				%>
762
					<input type="button" value="Add all to cart" onclick="addAllToCart()"/>
763
				<%
764
					}
765
				%>
766
			</th>
767
		</tr>
768
		<tr>
769
			<td>
770
				<div id="searchResults">
771
				No query has been specified	
772
				</div>
773
			</td>
774
		</tr>
775
	</table>	
776

    
777
</form>
778

    
779

    
780

    
781
<!-- Included default search/login -->
782
<% if ( PropertyService.getProperty("spatial.runSpatialOption").equals("true") ) { %>
783
<script language="javascript">
784
	insertMap("<%=CONTEXT_URL%>");
785
</script>
786
<br/>
787
<% } %>
788
  
789
<script language="javascript">
790
	insertSearchBox("<%=CONTEXT_URL%>");
791
	insertLoginBox("<%=CONTEXT_URL%>");	
792
</script>
793

    
794
</div>
795

    
796
<script language="javascript">
797
	insertTemplateClosing("<%=CONTEXT_URL%>");
798
</script>
799

    
800
</body>
801
</html>
(5-5/16)