<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>FHIR Terminology exemplars with Ontoserver</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Sample code for illustrating use of FHIR's /VAlueSet/$expand" />
<meta name="author" content="CSIRO" />
<!-- Le styles -->
<link data-require="bootstrap@*" data-semver="4.1.3" rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" />
<link href="style.css" rel="stylesheet" />
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script data-require="jquery" data-semver="3.2.1" src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"></script>
<script data-require="bootstrap" data-semver="4.1.3" src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div class="container-fluid" style="margin-bottom:5rem;">
<h2>SNOMED ECL-based ValueSets</h2>
<p>
This page allows you to explore the use of SNOMED's ECL expressions via the
<a href="http://hl7.org/fhir/STU3/valueset-operations.html#expand"><tt>/ValueSet/$expand</tt></a> operation
on SNOMED Implicit ValueSets.
</p>
<p>
To use it, you can either click on a row in the table below to pre-populate the ECL or manually enter/alter the expression.
Note that the <tt>| display text |</tt>, while valid in ECL, is not strictly permitted in an Implicit ValueSet URI,
however Ontoserver is forgiving and does allow it.
</p>
<p>
To test the operation, click the <b>Expand</b> button to issue the appropriate <tt>/ValueSet/$expand</tt> call to Ontoserver.
The actual request URL and the results will be displayed below.
Note that the <tt>count</tt> parameter is being used to limit the number of concepts returned to 20.
</p>
<table class="table table-striped table-sm table-hover">
<thead class="thead-dark">
<tr>
<th>ECL expression examples</th>
</tr>
</thead>
<tbody>
<tr onclick="preload('MemberOf 32570481000036109')" class="">
<td><tt>MemberOf 32570481000036109 |Emergency department diagnosis reference set|</tt></td>
</tr>
<tr onclick="preload('< 80146002')" class="">
<td><tt><< 80146002 |Appendicitis|</tt></td>
</tr>
<tr onclick="preload('DescendantOf 80146002')" class="">
<td><tt>DescendantOf 80146002</tt></td>
</tr>
<tr onclick="preload('<< 80146002')" class="">
<td><tt><< 80146002 |Appendicitis|</tt></td>
</tr>
<tr onclick="preload('DescendantOrSelfOf 80146002')" class="">
<td><tt>DescendantOrSelfOf 80146002</tt></td>
</tr>
<tr onclick="preload('< 19829001 AND < 301867009')" class="">
<td><tt>< 19829001 |Disorder of lung| AND < 301867009 |Edema of trunk|</tt></td>
</tr>
<tr onclick="preload('< 19829001 OR < 301867009')" class="">
<td><tt>< 19829001 |Disorder of lung| OR < 301867009 |Edema of trunk|</tt></td>
</tr>
<tr onclick="preload('< 19829001 MINUS < 301867009')" class="">
<td><tt>< 19829001 |Disorder of lung| MINUS < 301867009 |Edema of trunk|</tt></td>
</tr>
<tr onclick="preload('<<404684003 : <<47429007 = <<267038008')" class="">
<td><tt><< 404684003 |Clinical finding| :<br>
<< 47429007 |Associated with| = << 267038008 |Edema|</tt></td>
</tr>
</tbody>
</table>
<form class="clearfix">
<div class="form-group row">
<div class="col-sm-12">
<tt>
<textarea class="form-control" id="ecl" placeholder="Enter ECL expression or select one from above"></textarea>
</tt>
</div>
</div>
<button type="button" class="btn btn-primary float-right" onclick="expand()">Expand</button>
</form>
<a class="clear-both" id="requestLink" target="_blank" href=""><pre class="mt-3" id="requestUrl"></pre></a>
<table class="table table-sm mt-3" id="resultTable">
</table>
<pre class="mt-3 bg-light" id="resultJson"></pre>
</div>
<!-- /container -->
<nav class="navbar fixed-bottom navbar-light bg-light">
<div class="small">
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons Licence" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a>
<br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">This exemplar</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">CSIRO</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
</div>
</nav>
</body>
</html>
var base = "https://tx.ontoserver.csiro.au/fhir";
// base = "http://tx.fhir.org/r3";
// base = "http://its.patientsfirst.org.nz/RestService.svc/Terminz";
// base = 'http://fhirtest.uhn.ca/baseDstu3';
function preload(ecl) {
document.getElementById("ecl").value = ecl || '';
}
function expand() {
var ecl = document.getElementById("ecl").value;
// console.log(system, code, display);
function reqListener() {
var resultJson = document.getElementById("resultJson");
resultJson.textContent = this.responseText;
var table = document.getElementById("resultTable");
while (table.firstChild) {
table.removeChild(table.firstChild);
}
var json;
try {
json = JSON.parse(this.responseText);
} catch (err) {
console.log('response', this.response);
throw err;
}
if ('ValueSet' === json.resourceType) {
function append(row, elt, text) {
var item = document.createElement(elt);
item.textContent = text;
row.append(item);
return row;
}
var hrow1 = document.createElement('tr');
var header = document.createElement('th');
header.setAttribute('colspan', 3);
header.textContent = "Total matches: " + json.expansion.total;
hrow1.append(header);
table.append(hrow1);
var hrow2 = document.createElement('tr');
append(hrow2, 'th', 'System');
append(hrow2, 'th', 'Code');
append(hrow2, 'th', 'Display');
table.append(hrow2);
json.expansion.contains.forEach(function(c) {
var row = document.createElement('tr');
var system = document.createElement('td');
system.innerHTML = "<tt>"+c.system+"</tt>";
var code = document.createElement('td');
code.innerHTML = "<tt class=\"font-weight-bold\">"+c.code+"</tt>";
var display = document.createElement('td');
display.textContent = c.display;
row.appendChild(system);
row.appendChild(code);
row.appendChild(display);
table.appendChild(row);
});
if (json.expansion.total > json.expansion.contains.length) {
var frow = document.createElement('tr');
var footer = document.createElement('th');
footer.setAttribute('colspan', 3);
footer.textContent = "remainder of results omitted...";
frow.append(footer);
table.append(frow);
}
} else if ('OperationOutcome' === json.resourceType) {
// [{"severity":"error","code":"invalid","diagnostics":"[a95793f4-31bd-4f7f-8a92-947444f23bfb]: ValueSet url cannot be empty."}]
json.issue.forEach(function (i) {
var row = document.createElement('tr');
if ('error' === i.severity) {
row.classList.add('table-danger');
row.classList.remove('table-warning');
row.classList.remove('table-info');
} else if ('warning' === i.severity) {
row.classList.add('table-warning');
row.classList.remove('table-danger');
row.classList.remove('table-info');
} else {
row.classList.add('table-info');
row.classList.remove('table-danger');
row.classList.remove('table-warning');
}
var code = document.createElement('td');
code.textContent = i.code;
var diagnostic = document.createElement('td');
diagnostic.textContent = i.diagnostics;
row.appendChild(code);
row.appendChild(diagnostic);
table.appendChild(row);
});
}
resultJson.textContent = JSON.stringify(json, null, 2);
}
var request = "/ValueSet/$expand?url=" + encodeURIComponent("http://snomed.info/sct?fhir_vs=ecl/" + ecl) + "&count=20";
document.getElementById("requestLink").href = base + request;
document.getElementById("requestUrl").textContent = "[base]" + request;
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", base + request + "&_format=json");
oReq.send();
}
/* Put your css in here */
pre {
white-space: pre-wrap; /* css-3 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}