source: extensions/net.sf.basedb.reggie/trunk/resources/consentform.jsp @ 1601

Last change on this file since 1601 was 1601, checked in by Nicklas Nordborg, 11 years ago

Fixes #378: Consent registration wizard should display consent date if it is already registered

File size: 17.0 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.Application"
5  import="net.sf.basedb.core.User"
6  import="net.sf.basedb.core.DbControl"
7  import="net.sf.basedb.core.SessionControl"
8  import="net.sf.basedb.clients.web.Base"
9  import="net.sf.basedb.clients.web.util.HTML"
10  import="net.sf.basedb.clients.web.extensions.ExtensionsControl"
11  import="net.sf.basedb.util.Values"
12%>
13<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
14<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
15<%
16final SessionControl sc = Base.getExistingSessionControl(request, true);
17final String ID = sc.getId();
18final float scale = Base.getScale(sc);
19final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
20DbControl dc = null;
21try
22{
23  dc = sc.newDbControl();
24  final User user = User.getById(dc, sc.getLoggedInUserId());
25%>
26<base:page type="default" >
27<base:head scripts="ajax.js" styles="path.css">
28  <link rel="stylesheet" type="text/css" href="css/reggie.css">
29  <%
30  if (Application.getMajorVersion() == 3 && Application.getMinorVersion() == 0)
31  {
32    %>
33    <link rel="stylesheet" type="text/css" href="css/base30.css">
34    <%
35  }
36  %>
37  <script language="JavaScript" src="reggie.js" type="text/javascript" charset="UTF-8"></script>
38
39<script language="JavaScript">
40
41var debug = false;
42var currentStep = 1;
43var caseIsValid = false;
44var consentDateIsValid = false;
45
46var consentToId = { "Yes": "consent.yes", "No" : "consent.no", "Not asked": "consent.notAsked" };
47var patientInfo;
48
49function init()
50{
51  var frm = document.forms['reggie'];
52  frm.caseName.focus();
53}
54
55function step1IsValid()
56{
57  var frm = document.forms['reggie'];
58  var caseName = frm.caseName.value;
59  caseIsValid = false;
60  if (caseName == '')
61  {
62    setInputStatus('case', 'Missing', 'invalid');
63    frm.caseName.focus();
64  }
65  else if (!isValidCaseName(caseName))
66  {
67    setInputStatus('case', 'Only 7-digits name is allowed .', 'invalid');
68    frm.caseName.focus();
69  }
70  else
71  {
72    setInputStatus('case', '', 'valid');
73    caseIsValid = true;
74  }
75 
76  return caseIsValid;
77}
78
79function step2IsValid()
80{
81  return consentDateIsValid;
82}
83
84function goNextAuto()
85{
86  goNext(false);
87}
88
89function goNext(manual)
90{
91  setInnerHTML('gonext.message', '');
92  if (currentStep == 1)
93  {
94    if (step1IsValid()) gotoStep2();
95  }
96  else if (currentStep == 2)
97  {
98    if (step2IsValid()) gotoStep3();
99  }
100}
101
102
103function gotoStep2()
104{
105  // Check entered case and pnr with AJAX
106  var frm = document.forms['reggie'];
107 
108  frm.caseName.disabled = true;
109  currentStep = 2;
110 
111  var caseName = frm.caseName.value;
112  var request = Ajax.getXmlHttpRequest();
113  var url = 'ConsentForm.servlet?ID=<%=ID%>&cmd=GetCaseInfo';
114  url += '&caseName=' + caseName;
115  request.open("GET", url, false);
116  request.send(null);
117 
118  if (debug) Main.debug(request.responseText);
119  var response = JSON.parse(request.responseText);
120  if (response.status != 'ok')
121  {
122    setFatalError(response.message);
123    return false;
124  }
125 
126  Main.hide('gonext');
127  Main.show('consentSection');
128 
129  // Get case information from the AJAX response
130  patientInfo = response.patientInfo;
131  var caseInfo = response.caseInfo;
132  var specimenInfo = response.specimenInfo;
133 
134  if (patientInfo)
135  {
136    var html = '';
137    var numEnabled = 0;
138    if (patientInfo.allCases)
139    {
140      for (var i = 0; i < patientInfo.allCases.length; i++)
141      {
142        var c = patientInfo.allCases[i];
143        var laterality = c.laterality ? ' ('+c.laterality+')' : '';
144        var disabled = '';
145        if (c.consent)
146        {
147          disabled = 'disabled';
148        }
149        else
150        {
151          numEnabled++;
152        }
153        if (c.name == caseName && c.consentDate)
154        {
155          frm.consentDate.value = c.consentDate;
156        }
157        html += '<input type="checkbox" name="case.'+c.id+'" id="case.'+c.id+'" checked ' + disabled +'>';
158        html += '<label for="case.'+c.id+'">Case: ' + c.name + laterality + '</label><br>';
159      }
160    }
161   
162    if (patientInfo.allBlood)
163    {
164      for (var i = 0; i < patientInfo.allBlood.length; i++)
165      {
166        var c = patientInfo.allBlood[i];
167        var disabled = '';
168        if (c.consent)
169        {
170          disabled = 'disabled';
171        }
172        else
173        {
174          numEnabled++;
175        }
176        if (c.name.indexOf(caseName) == 0 && c.consentDate)
177        {
178          frm.consentDate.value = c.consentDate;
179        }
180        html += '<input type="checkbox" name="blood.'+ c.id + '" id="blood.'+c.id+'" checked ' + disabled +'>';
181        html += '<label for="blood.'+c.id+'">Blood: ' + c.name + '</label><br>';
182      }
183    }
184   
185    document.getElementById('moreCases').innerHTML = html;
186   
187    if (numEnabled > 0)
188    {
189      enableConsentOption('consent.yes', true);
190      setInputStatus('consent', 'This patient already exists and has at least one case or blood sample with missing consent.', 'valid');
191      Main.showInline('morehelp.multiple');
192      Main.showInline('morehelp.yesonly');
193      Main.show('gocancel');
194      Main.show('goregister');
195    }
196    else
197    {
198      enableConsentOption('consent.yes', true);
199      setInputStatus('consent', '"Yes" has already been registered for all case and blood samples for this patient. It is not possible to change with this wizard.', '');
200      Main.show('gorestart');
201      frm.consentDate.disabled = true;
202    }
203    Main.show('moreCasesSection');
204  }
205  else if (caseInfo)
206  {
207    // A consent has already been registered for this case
208    // We do not support updating this
209    enableConsentOption(consentToId[caseInfo.consent], true);
210    setInputStatus('consent', '"' + caseInfo.consent + '" has already been registered for this case. It is not possible to change with this wizard.', '');
211    Main.show('gorestart');
212    if (caseInfo.consentDate)
213    {
214      frm.consentDate.value = caseInfo.consentDate;
215    }
216    frm.consentDate.disabled = true;
217  }
218  else if (specimenInfo)
219  {
220    // There is no existing case but there are specimen related to it
221    // This wizard will only allow 'Yes' option on the consent form
222    enableConsentOption('consent.yes', true);
223    setInputStatus('consent', 'Specimen tubes for this case already exists.', 'valid');
224    Main.showInline('morehelp.yesonly');
225    Main.show('gocancel');
226    Main.show('goregister');
227  }
228  else
229  {
230    // We have no information about this case -- but allow a consent to be registered in any case
231    enableConsentOption('consent.no', true);
232    enableConsentOption('consent.notAsked');
233    enableConsentOption('consent.yes');
234    Main.showInline('morehelp.any');
235    Main.show('gocancel');
236    Main.show('goregister');
237  }
238
239  if (!frm.consentDate.disabled) frm.consentDate.focus();
240}
241
242function goRegister()
243{
244  if (!step2IsValid()) return;
245 
246  var frm = document.forms['reggie'];
247  frm.otherReasonIfNotAsked.disabled = true;
248  frm.consentDate.disabled = true;
249  for (var i = 0; i < frm.consent.length; i++)
250  {
251    frm.consent[i].disabled = true;
252  }
253  for (var i = 0; i < frm.reasonIfNotAsked.length; i++)
254  {
255    frm.reasonIfNotAsked[i].disabled = true;
256  }
257 
258  Main.hide('goregister');
259  Main.hide('gocancel');
260
261  var consentInfo = new Object();
262  consentInfo.caseName = frm.caseName.value;
263  consentInfo.consentDate = frm.consentDate.value;
264  consentInfo.consent = Forms.getCheckedRadio(frm.consent).value;
265  if (consentInfo.consent == 'Not asked')
266  {
267    var reasonIfNotAsked = '';
268    for (var i = 0; i < frm.reasonIfNotAsked.length; i++)
269    {
270      var option = frm.reasonIfNotAsked[i];
271      if (option.checked)
272      {
273        if (option.id == 'notAsked.other')
274        {
275          reasonIfNotAsked += frm.otherReasonIfNotAsked.value;
276        }
277        else
278        {
279          var label = document.getElementById(option.id + '.label');
280          reasonIfNotAsked += label.innerHTML + '\n';
281        }
282      }
283    }
284    consentInfo.reasonIfNotAsked = reasonIfNotAsked;
285  }
286 
287  if (patientInfo)
288  {
289    var selectedSamples = new Array();
290    if (patientInfo.allCases)
291    {
292      for (var i = 0; i < patientInfo.allCases.length; i++)
293      {
294        var c = patientInfo.allCases[i];
295        var chk = frm['case.'+c.id];
296        if (chk.checked && !chk.disabled) selectedSamples[selectedSamples.length] = c.id;
297      }
298    }
299   
300    if (patientInfo.allBlood)
301    {
302      for (var i = 0; i < patientInfo.allBlood.length; i++)
303      {
304        var c = patientInfo.allBlood[i];
305        var chk = frm['blood.'+c.id];
306        if (chk.checked && !chk.disabled) selectedSamples[selectedSamples.length] = c.id;
307      }
308    }
309    consentInfo.selectedSamples = selectedSamples;
310  }
311
312  var submitInfo = new Object();
313  submitInfo.consentInfo = consentInfo;
314 
315  if (debug) Main.debug(JSON.stringify(submitInfo));
316  var request = Ajax.getXmlHttpRequest();
317  var url = 'ConsentForm.servlet?ID=<%=ID%>&cmd=RegisterConsent';
318  request.open("POST", url, false);
319  request.setRequestHeader("Content-Type", "application/json");
320  request.send(JSON.stringify(submitInfo));
321
322  if (debug) Main.debug(request.responseText);
323 
324  var response = JSON.parse(request.responseText);
325  if (response.status != 'ok')
326  {
327    setFatalError(response.message);
328    return false;
329  }
330 
331  var msg = '<ul>';
332  for (var i = 0; i < response.messages.length; i++)
333  {
334    msg += '<li>' + response.messages[i];
335  }
336  msg += '</ul>';
337  setInnerHTML('done', msg);
338  Main.show('done');
339  Main.show('gorestart');
340}
341
342function enableConsentOption(optionId, checkIt)
343{
344  var option = document.getElementById(optionId); // The radio button
345  option.disabled = false;
346  if (checkIt) option.checked = true;
347  var label = document.getElementById(optionId + '.label'); // The label
348  Main.removeClass(label, 'disabled');
349}
350
351function consentDateOnChange()
352{
353  var frm = document.forms['reggie'];
354  consentDateIsValid = false;
355  setInputStatus('consentDate', '', '');
356 
357  var consentDate = frm.consentDate.value;
358 
359  if (consentDate == '')
360  {
361    setInputStatus('consentDate', 'Missing', 'warning');
362  }
363  else
364  {
365    // Auto-fill the date if it's only given with 4(MMdd) or 6(yyMMdd) digits.   
366    consentDate = autoFillDate(consentDate);
367    frm.consentDate.value = consentDate;
368 
369    if (!Dates.isDate(consentDate, 'yyyyMMdd'))
370    {
371      setInputStatus('consentDate', 'Not a valid date', 'invalid');
372      return;
373    }
374    setInputStatus('consentDate', '', 'valid');
375  }
376 
377  consentDateIsValid = true;
378}
379
380
381function consentOnChange()
382{
383  // If "Not asked" is selected we must enable the second question
384  var isAsked = !document.getElementById('consent.notAsked').checked;
385 
386  var frm = document.forms['reggie'];
387  var reasonIfNotAsked = frm.reasonIfNotAsked;
388  for (var i = 0; i < reasonIfNotAsked.length; i++)
389  {
390    reasonIfNotAsked[i].disabled = isAsked;
391    var label = document.getElementById(reasonIfNotAsked[i].id + '.label');
392    Main.addOrRemoveClass(label, 'disabled', isAsked);
393  }
394  frm.otherReasonIfNotAsked.disabled = isAsked;
395 
396}
397
398</script>
399<style>
400.disabled
401{
402  color: #999999;
403  font-style: italic;
404}
405</style>
406</base:head>
407<base:body onload="init()">
408
409  <p:path><p:pathelement 
410    title="Reggie" href="<%="index.jsp?ID="+ID%>" 
411    /><p:pathelement title="Consent form registration" 
412    /></p:path>
413
414  <div class="content">
415  <%
416  if (sc.getActiveProjectId() == 0)
417  {
418    %>
419    <div class="messagecontainer note" style="width: 800px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
420      No project has been selected. You may proceed with the registration but
421      created items will not be shared.
422    </div>
423    <%
424  }
425  %>
426
427  <form name="reggie" onsubmit="return false;">
428 
429  <!-- 1. Case + Personal number -->
430  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
431  <tr>
432    <td rowspan="3" class="stepno">1</td>
433    <td class="steptitle">Enter Case Name</td>
434  </tr>
435  <tr>
436    <td class="stepfields">
437      <table border="0" cellspacing="0" cellpadding="0" width="100%">
438      <tr>
439        <td class="prompt">Case name</td>
440        <td class="input"><input type="text" name="caseName" 
441          size="18" maxlength="12" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
442        <td class="status" id="case.status"></td>
443        <td class="help"><span id="case.message" class="message" style="display: none;"></span>The 7-digit case (barcode) associated with the case.</td>
444      </tr>
445      </table>
446    </td>
447  </tr>
448  </table>
449
450  <!-- 2. Consent section -->
451  <div id="consentSection" style="display: none;">
452  <p>
453  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
454  <tr>
455    <td rowspan="2" class="stepno">2</td>
456    <td class="steptitle">Consent form</td>
457  </tr>
458  <tr>
459    <td class="stepfields">
460      <table border="0" cellspacing="0" cellpadding="0" width="100%">
461      <tr valign="top">
462        <td class="prompt">Date</td>
463        <td class="input" style="padding-left: 0px;">
464          <input type="text" name="consentDate" value="" size="12" maxlength="10"
465            onblur="consentDateOnChange()">
466        </td>
467        <td class="status" id="consentDate.status"></td>
468        <td class="help">
469          <span id="consentDate.message" class="message" style="display: none;"></span>(YYYYMMDD or MMDD)
470        </td>
471      </tr>
472      <tr valign="top">
473        <td class="prompt">Consent</td>
474        <td class="input" style="padding-left: 0px;">
475          <input id="consent.no" type="radio" name="consent" value="No" disabled onchange="consentOnChange()">
476            <label id="consent.no.label" for="consent.no" class="disabled">No</label><br>
477          <input id="consent.yes" type="radio" name="consent" value="Yes" disabled onchange="consentOnChange()">
478            <label id="consent.yes.label" for="consent.yes" class="disabled">Yes</label><br>
479          <div id="moreCasesSection" style="display: none;">
480            <table border="0" cellpadding="0" cellspacing="0">
481            <tr valign="baseline">
482              <td><img src="images/joinbottom.gif"></td>
483              <td id="moreCases"></td>
484            </tr>
485            </table>
486          </div>
487          <input id="consent.notAsked" type="radio" name="consent" value="Not asked" disabled onchange="consentOnChange()">
488            <label id="consent.notAsked.label" for="consent.notAsked" class="disabled">Not asked</label>
489        </td>
490        <td class="status" id="consent.status"></td>
491        <td class="help" rowspan="2">
492          <span id="consent.message" class="message" style="display: none;"></span>
493          <span id="morehelp.multiple" style="display:none;">
494            Select the cases and blood samples to register. Cases with
495            already existing consent can't be deselected.
496          </span>
497          <span id="morehelp.yesonly" style="display: none;">
498            <b>Yes</b> is the only option supported by this wizard. The other alternatives
499            may require manual deletion of already registered information.
500          </span>
501          <span id="morehelp.any" style="display: none;">
502            There is currently no information about this case.
503          </span>
504        </td>
505      </tr>
506      <tr valign="top">
507        <td class="subprompt">Reason if not asked</td>
508        <td class="input">
509          <table border="0" cellpadding="0" cellspacing="0">
510          <tr valign="baseline">
511            <td><img src="images/joinbottom.gif"></td>
512            <td><input id="notAsked.forgot" type="checkbox" name="reasonIfNotAsked" disabled></td>
513            <td><label id="notAsked.forgot.label" for="notAsked.forgot" class="disabled">Forgot to ask the patient</label></td>
514          </tr>
515         
516          <tr valign="baseline">
517            <td></td>
518            <td><input id="notAsked.language" type="checkbox" name="reasonIfNotAsked" disabled></td>
519            <td><label id="notAsked.language.label" for="notAsked.language" class="disabled">Language problems</label></td>
520          </tr>
521
522          <tr valign="baseline">
523            <td></td>
524            <td><input id="notAsked.condition" type="checkbox" name="reasonIfNotAsked" disabled></td>
525            <td><label id="notAsked.condition.label" for="notAsked.condition" class="disabled">Patient can't decide due to physical and/or mental condition</label></td>
526          </tr>
527
528          <tr valign="baseline">
529            <td></td>
530            <td><input id="notAsked.other" type="checkbox" name="reasonIfNotAsked" disabled></td>
531            <td><label id="notAsked.other.label" for="notAsked.other" class="disabled">Other:</label></td>
532          </tr>
533
534          <tr valign="baseline">
535            <td></td>
536            <td colspan="2">
537            <textarea name="otherReasonIfNotAsked" rows="3" cols="30" disabled
538              onfocus="document.forms['reggie'].reasonIfNotAsked[3].checked = true"></textarea>
539            </td>
540          </tr>
541          </table>
542
543        </td>
544        <td class="status" id="notAsked.status"></td>
545      </tr>
546      </table>
547    </td>
548  </tr>
549  </table>
550  </div>
551 
552  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 800px; margin-left: 20px; margin-bottom: 0px;"></div>
553
554  <div id="done" class="success" style="display: none; width: 800px; margin-left: 20px; margin-top: 20px;"></div>
555
556  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
557  <tr>
558    <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
559    <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)"/></td>
560    <td><base:button id="goregister" title="Register" image="<%=home+"/images/gonext.png"%>" onclick="goRegister()" style="display: none;"/></td>
561    <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
562    <td id="gonext.message" class="message"></td>
563  </tr>
564  </table>
565  </form>
566  </div>
567 
568</base:body>
569</base:page>
570<%
571}
572finally
573{
574  if (dc != null) dc.close();
575}
576%>
Note: See TracBrowser for help on using the repository browser.