<!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>$validate-code example</h2>
    <p>
      This page allows you to explore the behaviour of FHIR's <a href="http://hl7.org/fhir/STU3/valueset-operations.html#validate-code"><tt>/ValueSet/$validate-code</tt></a> operation.
    </p>
    <p>
      To use it, you can either click on a row in the table below to pre-populate the form fields or manually enter/alter the values in each field. That is:
    </p>
    <ol>
      <li>select a ValueSet of interest,</li>
      <li>enter values for a code and the URI of its CodeSystem, and</li>
      <li>(optionally) provide associated display text.</li>
    </ol>
    <p>
      To test the operation, click the <b>Validate</b> button to issue the appropriate <tt>/ValueSet/$validate-code</tt> call to Ontoserver. The actual request URL and the results will be displayed below.
    </p>
    <table class="table table-striped table-sm table-hover">
      <thead class="thead-dark">
        <tr>
          <th>System</th>
          <th>Code</th>
          <th>Display</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th colspan="100%">SNOMED CT Clinical Findings</th>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','22298006', '', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-info">
          <td>http://snomed.info/sct</td>
          <td>22298006</td>
          <td></td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','22298006', 'Myocardial infarction', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-success">
          <td>http://snomed.info/sct</td>
          <td>22298006</td>
          <td>Myocardial infarction</td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','22298006', 'Myocardial exfarction', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-danger">
          <td>http://snomed.info/sct</td>
          <td>22298006</td>
          <td>Myocardial exfarction</td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','22298006', 'Heart attack', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-success">
          <td>http://snomed.info/sct</td>
          <td>22298006</td>
          <td>Heart attack</td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','22298006', 'EKG: Myocardial infarction', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-danger">
          <td>http://snomed.info/sct</td>
          <td>22298006</td>
          <td>EKG: Myocardial infarction</td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','80146002', 'Appendisectomy', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-danger">
          <td>http://snomed.info/sct</td>
          <td>80146002</td>
          <td>Appendisectomy</td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','80146002', 'Appendectomy', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-danger">
          <td>http://snomed.info/sct</td>
          <td>80146002</td>
          <td>Appendectomy</td>
        </tr>
        <tr onclick="preload('http://snomed.info/sct','80146002', 'Appendicitis', 'http://snomed.info/sct?fhir_vs=isa/404684003')" class="table-danger">
          <td>http://snomed.info/sct</td>
          <td>80146002</td>
          <td>Appendicitis</td>
        </tr>
      </tbody>
      <tbody>
        <tr>
          <th colspan="100%">LOINC Codes</th>
        </tr>
        <tr onclick="preload('http://loinc.org','76629-5', '', 'http://loinc.org/vs')" class="table-info">
          <td>http://loinc.org</td>
          <td>76629-5</td>
          <td></td>
        </tr>
        <tr onclick="preload('http://loinc.org','76629-5','Fasting glucose [Moles/volume] in Blood', 'http://loinc.org/vs')" class="table-success">
          <td>http://loinc.org</td>
          <td>76629-5</td>
          <td>Fasting glucose [Moles/volume] in Blood</td>
        </tr>
        <tr onclick="preload('http://loinc.org','76629-5','Fasting glucose [Mass/volume] in Blood', 'http://loinc.org/vs')" class="table-danger">
          <td>http://loinc.org</td>
          <td>76629-5</td>
          <td>Fasting glucose [Mass/volume] in Blood</td>
        </tr>
        <tr onclick="preload('http://loinc.org','76629-5','Glucose p fast Bld-sCnc', 'http://loinc.org/vs')" class="table-success">
          <td>http://loinc.org</td>
          <td>76629-5</td>
          <td>Glucose p fast Bld-sCnc</td>
        </tr>
        <tr onclick="preload('http://loinc.org','76629-5','Glucose:SCnc:Pt:Bld:Qn:', 'http://loinc.org/vs')" class="table-success">
          <td>http://loinc.org</td>
          <td>76629-5</td>
          <td>Glucose:SCnc:Pt:Bld:Qn:</td>
        </tr>
        <tr onclick="preload('http://loinc.org','76629-5','Fasting glucose', 'http://loinc.org/vs')" class="table-danger">
          <td>http://loinc.org</td>
          <td>76629-5</td>
          <td>Fasting glucose</td>
        </tr>
      </tbody>
    </table>
    <form class="clearfix">
      <div class="form-group row">
        <label for="valueset" class="col-sm-2 col-form-label">ValueSet</label>
        <div class="col-sm-10">
          <select class="form-control" id="valuesetSelect">
            <option class="text-muted" disabled selected value="">Choose a ValueSet...</option>
            <option value="http://snomed.info/sct?fhir_vs=isa/404684003">SNOMED CT Clinical Findings</option>
            <option value="http://loinc.org/vs">LOINC Codes</option>
          </select>
        </div>
      </div>
      <div class="form-group row">
        <label for="formUri" class="col-sm-2 col-form-label">System</label>
        <div class="col-sm-10">
          <input type="text" class="form-control" id="formUri" placeholder="CodeSystem URI" value="http://snomed.info/sct">
        </div>
      </div>
      <div class="form-group row">
        <label for="formCode" class="col-sm-2 col-form-label">Code</label>
        <div class="col-sm-10">
          <input type="text" class="form-control" id="formCode" placeholder="Code" value="233607000">
        </div>
      </div>
      <div class="form-group row">
        <label for="formDisplay" class="col-sm-2 col-form-label">Display</label>
        <div class="col-sm-10">
          <input type="text" class="form-control" id="formDisplay" placeholder="Display text (optional)">
        </div>
      </div>
      <button type="button" class="btn btn-primary float-right" onclick="validate()">Validate</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 $validate-code 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://stu3.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() {
  function label(r) {
    return r.title || r.name || r.url || "unknown";
  }

  function vsListener() {
    var json = JSON.parse(this.responseText);
    var sel = document.getElementById("valuesetSelect");
    json.entry
      .sort(function(a, b) {
        return label(a.resource).localeCompare(label(b.resource));
      })
      .forEach(function(e) {
        var option = document.createElement("option");
        var r = e.resource;
        option.text = label(r);
        option.value = r.url;
        sel.add(option);
      });
  }

  var oReq = new XMLHttpRequest();
  oReq.addEventListener("load", vsListener);
  oReq.open("GET", base + "/ValueSet?_elements=url,name,title&_format=json");
  oReq.send();

})();

function preload(system, code, display, vs) {
  document.getElementById("formUri").value = system || '';
  document.getElementById("formCode").value = code || '';
  document.getElementById("formDisplay").value = display || '';
  document.getElementById("valuesetSelect").value = vs || '';
}

function validate() {
  var vs = document.getElementById("valuesetSelect").value;
  var system = document.getElementById("formUri").value;
  var code = document.getElementById("formCode").value;
  var display = document.getElementById("formDisplay").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 ('Parameters' === json.resourceType) {
      json.parameter.forEach(function(p) {
        if ("result" == p.name) {
          if (p.valueBoolean) {
            table.classList.add("table-success");
            table.classList.remove("table-danger");
          } else {
            table.classList.add("table-danger");
            table.classList.remove("table-success");
          }
        }

        var row = document.createElement('tr');
        var name = document.createElement('th');
        name.setAttribute("scope", "row");
        name.textContent = p.name;
        var value = document.createElement('td');
        value.textContent = p.valueString || p.valueInt || p.valueBoolean;

        row.appendChild(name);
        row.appendChild(value);
        table.appendChild(row);
      });
    } 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 extra = display ? "&display=" + encodeURIComponent(display) : "";
  var request = "/ValueSet/$validate-code?url=" + encodeURIComponent(vs) + "&system=" + encodeURIComponent(system) + "&code=" + encodeURIComponent(code) + extra;

  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+ */
}