Project

General

Profile

1 5509 leinfelder
<%@ page language="java"%>
2
<%
3
/**
4
 *
5
 * '$RCSfile$'
6
 * Copyright: 2008 Regents of the University of California and the
7
 *             National Center for Ecological Analysis and Synthesis
8
 *    '$Author$'
9
 *      '$Date$'
10
 * '$Revision$'
11
 *
12
 * This program is free software; you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation; either version 2 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
22
 * You should have received a copy of the GNU General Public License
23
 * along with this program; if not, write to the Free Software
24
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
 */
26 5385 leinfelder
%>
27 5632 leinfelder
28 5509 leinfelder
<%@ include file="../../common/common-settings.jsp"%>
29
<%@ include file="../../common/configure-check.jsp"%>
30 5604 leinfelder
31 5385 leinfelder
<html>
32
<head>
33 5509 leinfelder
<title>Semantic search</title>
34
<link rel="stylesheet" type="text/css" href="<%=STYLE_SKINS_URL%>/semtools/semtools.css">
35 5669 leinfelder
<link rel="stylesheet" type="text/css" href="<%=STYLE_SKINS_URL%>/semtools/jqueryui/css/smoothness/jquery-ui-1.8.6.custom.css">
36 5509 leinfelder
<script type="text/javascript"
37
	src="<%=STYLE_SKINS_URL%>/semtools/search.js"></script>
38
39
<script type="text/javascript">
40
                    	    // Set defaults for this installation
41
                    	    //var BP_SEARCH_SERVER = "http://oor-01.cim3.net";
42
                    	    //var BP_SITE = "Sandbox";
43
                    	    //var BP_ORG = "OOR";
44
                    	  </script>
45 5656 leinfelder
<!--
46
<script language="Javascript" type="text/JavaScript" src="<%=STYLE_SKINS_URL%>/semtools/bioportal/form_complete.js"></script>
47
-->
48
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/jsTree/_lib/jquery.js"></script>
49
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/jsTree/_lib/jquery.cookie.js"></script>
50
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/jsTree/jquery.jstree.js"></script>
51 5669 leinfelder
<!-- jquery ui -->
52
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/jqueryui/js/jquery-ui-1.8.6.custom.min.js"></script>
53
54 5678 leinfelder
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/jquery/jquery.busy.js"></script>
55
56 5509 leinfelder
<script language="javascript" type="text/javascript" src="<%=STYLE_SKINS_URL%>/semtools/semtools.js"></script>
57
<script language="javascript" type="text/javascript" src="<%=STYLE_COMMON_URL%>/branding.js"></script>
58
59 5656 leinfelder
<script language="Javascript" type="text/JavaScript"><!--
60 5633 leinfelder
function populateActiveDomain(divId, class) {
61 5656 leinfelder
	// collect the filtering values we have so far
62
	// these are hidden input fields in the form for holding the selected values
63
	var entity = $("#activeEntitiesValue").val() ? $("#activeEntitiesValue").val() : "";
64
	var characteristic = $("#activeCharacteristicsValue").val() ? $("#activeCharacteristicsValue").val() : "";
65
	var protocol = $("#activeProtocolsValue").val() ? $("#activeProtocolsValue").val() : "";
66
	var measurement = $("#activeMeasurementsValue").val() ? $("#activeMeasurementsValue").val() : "";
67 5633 leinfelder
68 5656 leinfelder
	// TODO: remember the selected value for this when filtering by active domain
69
	var selectedNode = $("#" + divId).jstree("get_selected", $("#" + divId));
70
	var selectedNodeId = $(selectedNode).attr("id");
71 5668 leinfelder
	//alert(divId + " selected node: " + selectedNodeId);
72 5656 leinfelder
73
	// load the tree for the given div, passing in the other filtered values
74 5633 leinfelder
	$("#" + divId).load(
75 5656 leinfelder
		"<%=SERVLET_URL%>",
76
		{
77
			'action': "getactivedomain",
78
			'class': class,
79
			'entity': entity,
80
			'characteristic': characteristic,
81
			'protocol': protocol,
82
			'measurement': measurement
83
		},
84
		// call back function when loading finishes
85
		function(response, status, xhr) {
86
			//alert("callback for: " + divId + " selected node: " + selectedNodeId);
87
			// error
88
			if (status == "error") {
89
				var msg = "Sorry but there was an error: ";
90
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
91
			}
92
93
			// make it a js tree
94
			$(function () {
95
				$("#" + divId)
96 5660 leinfelder
					//bind calls here
97 5656 leinfelder
					.jstree({
98
						"ui" : {
99
							"select_limit" : 1,
100
							"select_multiple_modifier" : "alt",
101
							"selected_parent_close" : "select_parent"//,
102
							//"initially_select" : [ selectedNodeId ]
103 5659 leinfelder
						},
104
						"themes" : {
105
							"theme" : "default",
106
							"dots" : true,
107
							"icons" : false
108
						},
109 5656 leinfelder
						//"core" : { "initially_open" : [ selectedNodeId ] },
110 5658 leinfelder
						"search" : { "case_insensitive" : true },
111 5668 leinfelder
						//"cookies" : {
112
						//		"save_opened" : "jstree_open_" + divId,
113
						//		"save_selected" : "jstree_select_" + divId,
114
						//},
115 5666 leinfelder
						"plugins" : [
116
							"themes",
117
							"html_data",
118
							"ui",
119 5668 leinfelder
							//"cookies",
120 5666 leinfelder
							"search" ]
121 5656 leinfelder
					});
122
			});
123
124 5658 leinfelder
			// enable searching on it
125
			$("#" + divId + "Search").keyup(
126
				function () {
127 5688 leinfelder
					var searchTerm = $("#" + divId + "Search").val();
128
					if (searchTerm.length >= 3) {
129 5678 leinfelder
						// search
130 5688 leinfelder
						$("#" + divId).jstree("search", searchTerm);
131 5663 leinfelder
						// now prune
132 5664 leinfelder
						prune(divId, "jstree-search");
133 5688 leinfelder
						// is it an exact match?
134
						checkExactMatch(divId, searchTerm, "jstree-search");
135 5658 leinfelder
					}
136
				});
137 5664 leinfelder
138
			// toggle the active domain prune
139 5668 leinfelder
			$("#" + divId + "Only").click(function() {
140
				doActiveDomain(divId);
141
			});
142 5658 leinfelder
143 5668 leinfelder
			// actually prune if we should
144
			doActiveDomain(divId);
145 5687 leinfelder
146
			// open first node always
147
			$("#" + divId).jstree("open_node", $("#" + divId).children("ul").first().children("li").first());
148 5668 leinfelder
149
			// open to the node to last selected
150 5667 leinfelder
			var nodePath = $("#" + divId).jstree("get_path", $(selectedNode));
151
			if (nodePath) {
152
				for (var index = 0; index < nodePath.length; index++) {
153
					$("#" + divId).jstree("open_node", $("#" + nodePath[index]));
154
				}
155
				// select the original node
156
				$("#" + divId).jstree("select_node", $(selectedNode), false);
157
				$("#" + divId).jstree("refresh", $(selectedNode));
158
				// TODO: scroll to selected node.
159
				// This is supposed to be part of jsTree 1.0-rc2 but appears to be broken
160
			}
161
162 5656 leinfelder
		});
163 5633 leinfelder
}
164 5664 leinfelder
/**
165
* Prunes the given tree to inlcude the given matched class
166
**/
167
function prune(divId, matchClass) {
168 5663 leinfelder
169
	// show all nodes (reset)
170
	$("#" + divId).find("li").show();
171
172 5664 leinfelder
	// done if we don't have any thing to prune
173
	if (!matchClass) {
174
		return;
175
	}
176
177 5663 leinfelder
	// get all non-matched anchor tags
178 5664 leinfelder
	var nonmatches = $("#" + divId).find("a").not("." + matchClass);
179 5663 leinfelder
180
	// get their parent nodes
181
	nonmatches = $(nonmatches).parents("li");
182
183
	// are there any matches under each parent node?
184
	$(nonmatches).each(
185
		function(index) {
186
			// do any chidren match?
187 5664 leinfelder
			var childMatches = $(this).find("a." + matchClass);
188 5663 leinfelder
			if (childMatches && childMatches.length > 0) {
189
				return true;
190
			}
191
			// parent matches?
192 5664 leinfelder
			var parentMatches = $(this).parents("li").children("a." + matchClass);
193 5663 leinfelder
			if (parentMatches && parentMatches.length > 0) {
194
				return true;
195
			}
196
			// hide this node if no matches under it
197
			$(this).hide();
198
		});
199
}
200 5688 leinfelder
function checkExactMatch(divId, searchTerm, matchClass) {
201
	// get the current search matches
202
	var matches = $("#" + divId).find("a." + matchClass);
203
	// get their parent nodes
204
	matches = $(matches).parents("li");
205
	// check for exact matches
206
	var exactMatch = $(matches).filter("#" + searchTerm).first();
207
	if (exactMatch && exactMatch.length == 1) {
208
		//alert("exactMatch: " + exactMatch);
209 5689 leinfelder
		// select in the tree, honoring the configured selection limit
210
		$("#" + divId).jstree("select_node", $(exactMatch), true);
211
		// act as those you clicked it
212
		// TODO: convert to event listeners on the tree
213 5688 leinfelder
		select($(exactMatch).children("a"));
214
	}
215
}
216 5668 leinfelder
function doActiveDomain(divId) {
217
	if ($("#" + divId + "Only").is(":checked")) {
218
		// prune to active
219
		prune(divId, "bold");
220
	} else {
221
		// reset
222
		prune(divId, null);
223
	}
224
}
225 5633 leinfelder
function initialize(source) {
226 5656 leinfelder
	// we don't want to reload the source of the filtering request
227
	// but we do want to reload the other trees for active domains
228
	// we reload all of them if no source is given - first time the page loads
229 5633 leinfelder
	if (source) {
230 5656 leinfelder
		source = $(source).attr("id");
231 5633 leinfelder
	}
232
	if (!source) {
233
		source = "";
234
	}
235
	if (source != 'activeEntities') {
236
		populateActiveDomain('activeEntities', 'org.ecoinformatics.sms.annotation.Entity');
237
	}
238
	if (source != 'activeCharacteristics') {
239
		populateActiveDomain('activeCharacteristics', 'org.ecoinformatics.sms.annotation.Characteristic');
240
	}
241
	if (source != 'activeProtocols') {
242
		populateActiveDomain('activeProtocols', 'org.ecoinformatics.sms.annotation.Protocol');
243
	}
244
	if (source != 'activeMeasurements') {
245
		populateActiveDomain('activeMeasurements', 'org.ecoinformatics.sms.annotation.Measurement');
246
	}
247
}
248 5656 leinfelder
function select(item) {
249 5633 leinfelder
250 5656 leinfelder
	// get the selected value, stored in the title attribute of the item <a> tag
251
	var value = $(item).attr("title");
252
	//alert("value: " + value);
253
254
	// get the parent div so we know what kind of class it is meant to filter
255
	// this is "the first parent of the class 'select'"
256
	var parent = $(item).parents("div.select:first");
257
	//alert("parent: " + parent);
258
259
	// set the value for the hidden input value
260
	// the input field of class "value" will hold it, this way we don't need to know the id
261
	var input = $(parent).children("input.value");
262
	$(input).val(value);
263
	//alert("input: " + input);
264 5662 leinfelder
265
	// set it in the search field
266
	var treeInstance = $(item).parents("div.jstree:first");
267
	var shortName = $(item).parent().attr("id");
268
	$("#" + $(treeInstance).attr("id") + "Search").val(shortName)
269 5656 leinfelder
270 5665 leinfelder
	// refresh the search results
271
	doSearch($("#searchForm").get(0));
272
273 5656 leinfelder
	// refresh the other trees for active domain after this filtering action
274 5666 leinfelder
	initialize($(parent).children("div"));
275 5656 leinfelder
}
276 5665 leinfelder
function doSearch(formObj) {
277
	// set the hidden parameters based on the current state of the form
278
	checkSearch(formObj);
279
280 5678 leinfelder
	// start the busy indicator
281 5684 leinfelder
	$("#searchResults").busy(
282
			{
283
				position	: 'left',
284
				offset		: -30,
285
				hide		: true,
286
				img			: "<%=STYLE_SKINS_URL%>/semtools/images/busy.gif"
287
			});
288 5678 leinfelder
289 5665 leinfelder
	//load the results
290
	$("#searchResults").load(
291
		"<%=SERVLET_URL%>" + " #content_wrapper",
292
		$(formObj).serialize(),
293
		// call back function when loading finishes
294
		function(response, status, xhr) {
295
			if (status == "error") {
296
				var msg = "Sorry but there was an error performing the search: ";
297
				$("#error").html(msg + xhr.status + " " + xhr.statusText);
298
			}
299 5675 leinfelder
			// collapsible search results?
300
			$(function() {
301
				$('.accordian').click(function() {
302 5676 leinfelder
					$(this).next().slideToggle("slow");
303 5675 leinfelder
					return false;
304
				}).next().hide();
305
			});
306
307 5678 leinfelder
			// stop the busy indicator
308
			$("#searchResults").busy("hide");
309 5665 leinfelder
		});
310
311
	return false;
312
313
}
314 5668 leinfelder
function clearForm() {
315
	// clear the form values
316
	$('#searchForm').get(0).reset();
317
	// clear each of the tree selections
318
	$(".jstree").each(function(index) {
319
		$(this).jstree("deselect_all");
320
	});
321
	$("input.value").each(function(index) {
322
		$(this).val("");
323
	});
324
	// reload the trees
325
	initialize();
326
	// reload the search results
327
	//alert($('#searchForm').get(0));
328
	doSearch($('#searchForm').get(0));
329
}
330 5685 leinfelder
/**
331
 * Perform this when the page first loads
332
 */
333
function pageLoad() {
334
	initialize();
335
	doSearch($('#searchForm').get(0));
336
}
337 5656 leinfelder
function donothing() {}
338
--></script>
339
340 5385 leinfelder
</head>
341 5685 leinfelder
<body onload="pageLoad()">
342 5509 leinfelder
<script language="javascript">
343
	insertTemplateOpening("<%=CONTEXT_URL%>");
344
</script>
345 5385 leinfelder
346 5574 leinfelder
<div id="content_wrapper">
347 5669 leinfelder
348 5690 leinfelder
<h2>Semantic search</h2>
349 5385 leinfelder
350 5633 leinfelder
<div id="error">
351
	<!-- error messages here -->
352
</div>
353
354 5669 leinfelder
<!-- set up the tabs -->
355
<script>
356
	$(function() {
357
		$("#searchTabs").tabs();
358
		$("#searchTabs").tabs("add", "#ecpTab", "Entity, Characteristic, Protocol");
359
		$("#searchTabs").tabs("add", "#measurementTab", "Measurement");
360 5672 leinfelder
		$("#searchTabs").tabs("add", "#optionsTab", "Options");
361 5669 leinfelder
	});
362
</script>
363
364 5665 leinfelder
<form method="POST"
365
		action="<%=SERVLET_URL%>"
366
		target="_top"
367
		id="searchForm"
368
		name="searchForm"
369
		onSubmit="return doSearch(this)">
370 5509 leinfelder
	<input name="query" type="hidden" />
371
	<input name="qformat" value="semtools" type="hidden" />
372 5665 leinfelder
	<input name="includeHeader" value="false" type="hidden" />
373 5533 leinfelder
	<input name="action" value="semquery" type="hidden" />
374 5509 leinfelder
375 5672 leinfelder
	<!-- tabs for the search interface -->
376
	<div id="searchTabs">
377
		<!-- place holder for ui tabs -->
378
		<ul></ul>
379
380
		<!-- other criteria tabs -->
381
		<div id="ecpTab">
382
			<table>
383
				<tr>
384
					<td>
385
						<table class="subGroup subGroup_border">
386
387 5669 leinfelder
							<tr>
388 5672 leinfelder
								<th><p>Find observations of</p></th>
389
							</tr>
390
							<tr>
391 5669 leinfelder
								<td>
392 5672 leinfelder
									<input type="text" id="activeEntitiesSearch" />
393
									<input type="checkbox" id="activeEntitiesOnly" title="Show only active concepts" />
394
									<div class="select">
395
										<div id="activeEntities" class="activeTree">
396
											<p>loading...</p>
397
										</div>
398
										<input type="hidden" class="value" name="activeEntitiesValue" id="activeEntitiesValue"/>
399
										<input type="hidden" name="activeEntitiesClass" id="activeEntitiesClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Entity"/>
400
									</div>
401 5669 leinfelder
								</td>
402 5672 leinfelder
							</tr>
403
						</table>
404
					</td>
405
					<td>
406
						<table class="subGroup subGroup_border">
407
							<tr>
408
								<th><p>with measurements of</p></th>
409
							</tr>
410
							<tr>
411 5669 leinfelder
								<td>
412 5672 leinfelder
									<input type="text" id="activeCharacteristicsSearch" />
413
									<input type="checkbox" id="activeCharacteristicsOnly" title="Show only active concepts" />
414
									<div class="select">
415
										<div id="activeCharacteristics" class="activeTree">
416
											<p>loading...</p>
417
										</div>
418
										<input type="hidden" class="value" name="activeCharacteristicsValue" id="activeCharacteristicsValue"/>
419
										<input type="hidden" name="activeCharacteristicsClass" id="activeCharacteristicsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Characteristic"/>
420
									</div>
421 5669 leinfelder
								</td>
422
							</tr>
423
						</table>
424 5672 leinfelder
					</td>
425
					<td>
426
						<table class="subGroup subGroup_border">
427 5669 leinfelder
							<tr>
428 5672 leinfelder
								<th><p>using procedures outlined by</p></th>
429 5669 leinfelder
							</tr>
430
							<tr>
431
								<td>
432 5672 leinfelder
									<input type="text" id="activeProtocolsSearch" />
433
									<input type="checkbox" id="activeProtocolsOnly" title="Show only active concepts" />
434 5669 leinfelder
									<div class="select">
435 5672 leinfelder
										<div id="activeProtocols" class="activeTree">
436 5669 leinfelder
											<p>loading...</p>
437
										</div>
438 5672 leinfelder
										<input type="hidden" class="value" name="activeProtocolsValue" id="activeProtocolsValue" />
439
										<input type="hidden" name="activeProtocolsClass" id="activeProtocolsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Protocol"/>
440 5669 leinfelder
									</div>
441
								</td>
442
							</tr>
443
						</table>
444 5672 leinfelder
					</td>
445
				</tr>
446
			</table>
447
		</div>
448
449
		<!-- measurement -->
450
		<div id="measurementTab">
451
			<table class="subGroup subGroup_border onehundred_percent">
452 5669 leinfelder
453 5672 leinfelder
				<tr>
454
					<th><p>a template that defines Entity, Characteristic, Standard, and/or Protocol</p></th>
455
				</tr>
456
457
				<tr>
458
					<td>
459
						<input type="text" id="activeMeasurementsSearch" />
460
						Only active? <input type="checkbox" id="activeMeasurementsOnly" title="Show only active concepts"/>
461
						<div class="select">
462
							<div id="activeMeasurements" class="activeTree" style="width: 100%">
463
								<p>loading...</p>
464
							</div>
465
							<input type="hidden" class="value" name="activeMeasurementsValue" id="activeMeasurementsValue"/>
466
							<input type="hidden" name="activeMeasurementsClass" id="activeMeasurementsClass" value="http://ecoinformatics.org/oboe/oboe.1.0/oboe-core.owl#Measurement"/>
467
						</div>
468
					</td>
469
				</tr>
470
			</table>
471
		</div>
472 5669 leinfelder
473 5672 leinfelder
		<!-- query options -->
474
		<div id="optionsTab">
475
			<table class="group group_border">
476
				<tr>
477
					<th colspan="2">
478
						<p>
479
							Locate <b>data packages</b> that have been semantically annotated within the observation model by
480
							selecting concepts from OBOE extension ontologies
481
						</p>
482
					</th>
483
				</tr>
484
485
				<tr>
486
487
					<td colspan="1">Match All? <input type="checkbox" name="matchAll" checked="checked"/></td>
488
489
					<td colspan="1">From same Observation? <input type="checkbox" name="strict"/></td>
490
				</tr>
491
492
			</table>
493
		</div>
494
495
	</div>
496
497
	<br/>
498
499
	<!-- search results here -->
500
	<table class="subGroup subGroup_border onehundred_percent">
501 5632 leinfelder
		<tr>
502 5672 leinfelder
			<th>
503
				Search Results
504 5668 leinfelder
				<input type="reset" value="Clear" onclick="clearForm()"/>
505 5672 leinfelder
			</th>
506 5509 leinfelder
		</tr>
507
		<tr>
508 5672 leinfelder
			<td>
509
				<div id="searchResults">
510
				No query has been specified
511
				</div>
512
			</td>
513 5509 leinfelder
		</tr>
514 5672 leinfelder
	</table>
515
516 5509 leinfelder
</form>
517
518 5665 leinfelder
519 5672 leinfelder
520 5509 leinfelder
<!-- Included default search/login -->
521
<% if ( PropertyService.getProperty("spatial.runSpatialOption").equals("true") ) { %>
522
<script language="javascript">
523
	insertMap("<%=CONTEXT_URL%>");
524
</script>
525
<br/>
526
<% } %>
527
528
<script language="javascript">
529
	insertSearchBox("<%=CONTEXT_URL%>");
530
	insertLoginBox("<%=CONTEXT_URL%>");
531
</script>
532
533 5574 leinfelder
</div>
534
535 5509 leinfelder
<script language="javascript">
536
	insertTemplateClosing("<%=CONTEXT_URL%>");
537
</script>
538
539 5385 leinfelder
</body>
540
</html>