source: extensions/net.sf.basedb.reggie/trunk/resources/persinfo.jsp @ 1768

Last change on this file since 1768 was 1768, checked in by Nicklas Nordborg, 10 years ago

Fixes #437: Rules for comparing 'sampling date' and 'RNA later' date should be the same

File size: 34.8 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  <script language="JavaScript" src="reggie.js" type="text/javascript" charset="UTF-8"></script>
30 
31 
32<script language="JavaScript">
33
34var debug = false;
35var currentStep = 1;
36var pnrIsValid = false;
37var pnrIsAcceptable = false;
38var caseIsValid = false;
39var lateralityIsValid = false;
40var samplingDateIsValid = true;
41var rnaLaterDateIsValid = true;
42
43var patientInfo = null;
44var caseInfo = null;
45var bloodInfo = null;
46
47var copyConsentEnabled = false;
48
49function init()
50{
51  var frm = document.forms['reggie'];
52  frm.caseName.focus();
53}
54
55function step1IsValid()
56{
57  return pnrIsValid && caseIsValid;
58}
59
60function step1IsAcceptable()
61{
62  return pnrIsAcceptable && caseIsValid;
63}
64
65function step2IsValid()
66{
67  var formOk = true;
68  var frm = document.forms['reggie'];
69
70  // New patient only
71  if (!patientInfo.id)
72  {
73    // Validate 'New patient' form
74    if (frm.allFirstNames.value == '')
75    {
76      setInputStatus('allFirstNames', 'Missing', 'warning');
77      formOk = false;
78    }
79    else
80    {
81      setInputStatus('allFirstNames', '', 'valid');
82    }
83   
84    if (frm.familyName.value == '')
85    {
86      setInputStatus('familyName', 'Missing', 'warning');
87      formOk = false;
88    }
89    else
90    {
91      setInputStatus('familyName', '', 'valid');
92    }
93
94    if (frm.patientCode.value == '')
95    {
96      setInputStatus('patientCode', 'Missing', 'invalid');
97      frm.patientCode.focus();
98      formOk = false;
99    }
100    else
101    {
102      setInputStatus('patientCode', '', 'valid');
103    }
104  }
105  else // existing patient
106  {
107    if (frm.existingAllFirstNames.value == '')
108    {
109      setInputStatus('existingAllFirstNames', 'Missing', 'warning');
110      formOk = false;
111    }
112    else
113    {
114      setInputStatus('existingAllFirstNames', '', 'valid');
115    }
116   
117    if (frm.existingFamilyName.value == '')
118    {
119      setInputStatus('existingFamilyName', 'Missing', 'warning');
120      formOk = false;
121    }
122    else
123    {
124      setInputStatus('existingFamilyName', '', 'valid');
125    }
126   
127  }
128  return formOk;
129}
130
131function step2IsAcceptable()
132{
133  var formOk = true;
134  var frm = document.forms['reggie'];
135  // New patient only
136  if (!patientInfo.id)
137  {
138    formOk = frm.patientCode.value != '';
139  }
140  return formOk;
141}
142
143
144
145function step3IsValid()
146{
147  var isValid = lateralityIsValid && samplingDateIsValid;
148  if (caseInfo.specimen && caseInfo.specimen.length > 0)
149  {
150    isValid = isValid && rnaLaterDateIsValid;
151  }
152  return isValid;
153}
154
155function goNextAuto()
156{
157  goNext(false);
158}
159
160function goNext(manual)
161{
162  var frm = document.forms['reggie'];
163  setInnerHTML('gonext.message', '');
164  if (currentStep == 1)
165  {
166    if (step1IsValid())
167    {
168      gotoStep2();
169    }
170    else if (step1IsAcceptable())
171    {
172      if (manual)
173      {
174        gotoStep2();
175      }
176      else
177      {
178        frm.personalNumber.focus();
179        setInnerHTML('gonext.message', 'Personal number is non-standard. Click \'Next\' to continue registration.');
180      }
181    }
182  }
183  else if (currentStep == 2)
184  {
185    if (step2IsValid())
186    {
187      gotoStep3();
188    }
189    else if (step2IsAcceptable())
190    {
191      if (manual)
192      {
193        gotoStep3();
194      }
195      else
196      {
197        setInnerHTML('gonext.message', 'Missing name(s). Click \'Next\' to continue registration.');
198      }
199    }
200  }
201}
202
203function caseNameOnChange()
204{
205  var frm = document.forms['reggie'];
206  var caseName = frm.caseName.value.toUpperCase();
207  caseIsValid = false;
208  if (caseName == '')
209  {
210    setInputStatus('case', 'Missing', 'invalid');
211    frm.caseName.focus();
212    return;
213  }
214  if (!isValidCaseName(caseName, true)) // Allow 'C' suffix to be used
215  {
216    setInputStatus('case', 'Only 7-digits name + optional \'C\' is allowed .', 'invalid');
217    frm.caseName.focus();
218    return;
219  }
220
221  frm.caseName.value = caseName;
222  setInputStatus('case', '', 'valid');
223  caseIsValid = true;
224  getCaseInfo();
225}
226
227function personalNumberOnChange()
228{
229  var frm = document.forms['reggie'];
230  var pnr = frm.personalNumber.value;
231  pnrIsValid = false;
232  pnrIsAcceptable = true;
233 
234  var pnrLen = pnr.length;
235  if (pnrLen != 12 && pnrLen != 10)
236  {
237    setInputStatus('pnr', pnrLen < 12 ? 'Too short' : 'Too long', 'warning');
238    return;
239  }
240
241  if (!pnr.match(/^\d+$/))
242  {
243    setInputStatus('pnr', 'Non-standard personal number', 'warning');
244    return;
245  }
246 
247  var datePart = pnr.substring(0, pnrLen - 4); // Remove last four digits
248  var dateFormat = pnrLen == 10 ? 'yyMMdd' : 'yyyyMMdd';
249  var isValidDate = Dates.isDate(datePart, dateFormat);
250  if (!isValidDate)
251  {
252    var dayInMonth = parseInt(datePart.substring(-2), 10); // Last two characters
253    if (dayInMonth > 60)
254    {
255      // 'Samordningsnummer' has day-in-month + 60; check this
256      dayInMonth -= 60;
257      var tmpPnr = pnr.substring(0, pnrLen - 6); // First 4 or 6 digits is year+month
258      if (dayInMonth < 10) tmpPnr += '0';
259      tmpPnr += dayInMonth;
260      isValidDate = Dates.isDate(tmpPnr, dateFormat);
261    }
262  }
263  if (!isValidDate)
264  {
265    setInputStatus('pnr', 'Not a valid date', 'warning');
266    return;
267  }
268 
269  if (!personalNumberControlDigitCheck(pnr.substr(pnrLen == 10 ? 0 : 2)))
270  {
271    setInputStatus('pnr', 'Invalid control digit', 'warning');
272    return;
273  }
274
275  setInputStatus('pnr', '', 'valid');
276  pnrIsValid = true;
277}
278
279function nameOnChange(event)
280{
281  var field = event.target;
282  if (field.value == '')
283  {
284    setInputStatus(field.name, 'Missing', 'warning');
285  }
286  else
287  {
288    setInputStatus(field.name, '', 'valid');
289  }
290}
291
292function lateralityOnChange()
293{
294  lateralityIsValid = false;
295  var updateMode = caseInfo.id;
296 
297  // Check selected laterality against specimen tubes
298  var frm = document.forms['reggie'];
299  var selectedLaterality = Forms.getCheckedRadio(frm.laterality);
300 
301  // No laterality/case selected
302  if (selectedLaterality == null) 
303  {
304    setInputStatus('laterality', 'Not selected', 'invalid');
305    return;
306  }
307 
308  var numCases = patientInfo.cases ? patientInfo.cases.length : 0;
309  setInputStatus('laterality', updateMode && numCases > 1 ? 'NOTE! Some alternatives may be missing if there is another case for the patient.' : '', 'valid');
310  lateralityIsValid = true;
311   
312  var laterality = selectedLaterality.value;
313  if (laterality.match(/\d+/))
314  {
315    // It is the ID of an existing case
316    for (var i = 0; i < patientInfo.cases.length; i++)
317    {
318      var cse = patientInfo.cases[i];
319      if (cse.id == laterality)
320      {
321        laterality = cse.laterality;
322        break;
323      }
324    }
325  }
326  else if (laterality == '') 
327  {
328    laterality = null;
329  }
330 
331  // If the selected laterality/case is not the same as the other case with consent enable the copy consent option
332  Main.showHide('copyConsentSection', copyConsentEnabled && selectedLaterality.value != frm.copyConsent.value);
333   
334  // No specimen tubes?
335  if (!caseInfo.specimen || caseInfo.specimen.length == 0) return;
336 
337  for (var i = 0; i < caseInfo.specimen.length; i++)
338  {
339    var specimen = caseInfo.specimen[i];
340    if (specimen.laterality != laterality)
341    {
342      if (specimen.laterality == null || updateMode)
343      {
344        setInputStatus('laterality', 'Specimen tubes are updated to: ' + laterality, 'valid')
345      }
346      else
347      {
348        setInputStatus('laterality', 'Not same laterality as specimen tubes', 'warning');
349      }
350      return;
351    }
352  }
353 
354}
355
356function padOnChange()
357{
358  var frm = document.forms['reggie'];
359  var PAD = frm.pad.value;
360  if (PAD == '')
361  {
362    setInputStatus('pad', 'Missing', 'warning');
363    return;
364  }
365  frm.pad.value = PAD.replace(/\+/, '-');
366  setInputStatus('pad', '', 'valid');
367}
368
369function samplingDateTimeOnChange()
370{
371  var frm = document.forms['reggie'];
372  samplingDateIsValid = false;
373  setInputStatus('samplingDate', '', '');
374 
375  var samplingDate = frm.samplingDate.value;
376  var samplingTime = frm.samplingTime.disabled ? null : frm.samplingTime.value;
377 
378  if (samplingDate != '' || samplingTime != '')
379  {
380    // Auto-fill the date if it's only given with 4(MMdd) or 6(yyMMdd) digits.
381    samplingDate = autoFillDate(samplingDate);
382    frm.samplingDate.value = samplingDate;
383
384    if (!frm.samplingTime.disabled)
385    {
386      samplingTime = autoFillTime(samplingTime);
387      frm.samplingTime.value = samplingTime;
388    }
389   
390    if (samplingDate != '' && !Dates.isDate(samplingDate, 'yyyyMMdd'))
391    {
392      setInputStatus('samplingDate', 'Not a valid date', 'invalid');
393      return;
394    }
395    if (frm.rnaLaterDate.value == '') frm.rnaLaterDate.value = samplingDate;
396   
397    if (!frm.samplingTime.disabled)
398    {
399      if (!Dates.isDate(samplingDate + ' ' + samplingTime, 'yyyyMMdd HHmm'))
400      {
401        if (samplingDate != '') setInputStatus('samplingDate', 'Not a valid time', 'invalid');
402        return;
403      }
404    }
405    if (samplingDate == '')
406    {
407      setInputStatus('samplingDate', 'Missing', 'warning');
408    }
409    else
410    {
411      setInputStatus('samplingDate', '', 'valid');
412    }
413  }
414  samplingDateIsValid = true;
415}
416
417function rnaLaterDateTimeOnChange()
418{
419  var frm = document.forms['reggie'];
420  rnaLaterDateIsValid = false;
421  setInputStatus('rnaLaterDate', '', '');
422 
423  var rnaLaterDate = frm.rnaLaterDate.value;
424  var rnaLaterTime = frm.rnaLaterTime.value;
425  var rnaLaterTimestamp;
426 
427  if (rnaLaterDate != '' || rnaLaterTime != '')
428  {
429    // Auto-fill the date if it's only given with 4(MMdd) or 6(yyMMdd) digits.
430    rnaLaterDate = autoFillDate(rnaLaterDate);
431    frm.rnaLaterDate.value = rnaLaterDate;
432
433    rnaLaterTime = autoFillTime(rnaLaterTime);
434    frm.rnaLaterTime.value = rnaLaterTime;
435   
436    if (!Dates.isDate(rnaLaterDate, 'yyyyMMdd'))
437    {
438      setInputStatus('rnaLaterDate', 'Not a valid date', 'invalid');
439      return;
440    }
441    rnaLaterTimestamp = Dates.parseString(rnaLaterDate + ' ' + rnaLaterTime, 'yyyyMMdd HHmm');
442    if (rnaLaterTimestamp == null)
443    {
444      if (rnaLaterDate != '') setInputStatus('rnaLaterDate', 'Not a valid time', 'invalid');
445      return;
446    }
447    setInputStatus('rnaLaterDate', '', 'valid');
448  }
449 
450  rnaLaterDateIsValid = true;
451
452  if (samplingDateIsValid && rnaLaterTimestamp && !frm.samplingTime.disabled)
453  {
454    var samplingTimestamp = Dates.parseString(frm.samplingDate.value + ' ' + frm.samplingTime.value, 'yyyyMMdd Hmm');
455    if (samplingTimestamp)
456    {
457      if (rnaLaterTimestamp.getDate() != samplingTimestamp.getDate())
458      {
459        setInputStatus('rnaLaterDate', 'Sampling and RNA later dates are different', 'warning');
460      }
461      else if (rnaLaterTimestamp.getTime() < samplingTimestamp.getTime())
462      {
463        setInputStatus('rnaLaterDate', 'RNA later time is before Sampling time', 'warning');
464      }
465    }
466  }
467}
468
469function getCaseInfo()
470{
471  // Check entered case and pnr with AJAX
472  var frm = document.forms['reggie'];
473  var caseName = frm.caseName.value;
474  var request = Ajax.getXmlHttpRequest();
475  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=GetCaseInfo';
476  url += '&caseName=' + caseName;
477  request.open("GET", url, false);
478  request.send(null);
479 
480  if (debug) Main.debug(request.responseText);
481
482  var response = JSON.parse(request.responseText);
483  if (response.status != 'ok')
484  {
485    setFatalError(response.message);
486    return false;
487  }
488 
489  // Get biosource information from the AJAX response
490  caseInfo = response.caseInfo;
491  bloodInfo = response.bloodInfo;
492 
493  if (caseInfo && caseInfo.patient)
494  {
495    frm.personalNumber.value = caseInfo.patient.personalNumber;
496    gotoStep2();
497  }
498  else if (bloodInfo && bloodInfo.patient)
499  {
500    frm.personalNumber.value = bloodInfo.patient.personalNumber;
501    gotoStep2();
502  }
503}
504
505function gotoStep2()
506{
507  // Check entered case and pnr with AJAX
508  var frm = document.forms['reggie'];
509  frm.caseName.disabled = true;
510  frm.personalNumber.disabled = true;
511  currentStep = 2;
512 
513  var pnr = frm.personalNumber.value;
514  if (pnr.length == 10 && pnrIsValid) 
515  {
516    var year = fullYear(parseInt(pnr.substr(0, 2), 10));
517    pnr = year + pnr.substr(2);
518  }
519  var request = Ajax.getXmlHttpRequest();
520  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=GetPatientInfo';
521  url += '&personalNumber=' + pnr;
522  url += '&pnrIsValid=' + pnrIsValid;
523  request.open("GET", url, false);
524  request.send(null);
525 
526  if (debug) Main.debug(request.responseText);
527 
528  var response = JSON.parse(request.responseText);
529  if (response.status != 'ok')
530  {
531    setFatalError(response.message);
532    return false;
533  }
534 
535  // Get patient information from the AJAX response
536  patientInfo = response.patientInfo;
537
538  Main.show('gocancel');
539 
540  if (!patientInfo.id)
541  {
542    Main.show('newPatientSection');
543    frm.patientCode.value=patientInfo.name;
544    setInnerHTML('new.dateOfBirth', patientInfo.dateOfBirth ? patientInfo.dateOfBirth : "---");
545    setInnerHTML('new.gender', patientInfo.gender ? patientInfo.gender : "---");
546    frm.familyName.focus();
547    if (!pnrIsValid)
548    {
549      setInputStatus('gender', 'Gender and DateOfBirth can\'t be automatically generated for non-standard Personal number', 'warning');
550    }
551  }
552  else
553  {
554    Main.show('existingPatientSection');
555    setInnerHTML('existing.patientCode', patientInfo.name);
556    frm.existingFamilyName.value = patientInfo.familyName;
557    frm.existingAllFirstNames.value = patientInfo.allFirstNames;
558    if (patientInfo.dateOfBirth) setInnerHTML('existing.dateOfBirth', patientInfo.dateOfBirth);
559    if (patientInfo.gender) setInnerHTML('existing.gender', patientInfo.gender);
560    frm.existingFamilyName.focus();
561  }
562}
563
564function gotoStep3()
565{
566  // Check entered case and pnr with AJAX
567  var frm = document.forms['reggie'];
568 
569  if (!patientInfo.id) // new patient
570  {
571    frm.patientCode.disabled = true;
572    frm.familyName.disabled = true;
573    frm.allFirstNames.disabled = true;
574    patientInfo.familyName = frm.familyName.value;
575    patientInfo.allFirstNames = frm.allFirstNames.value;
576  }
577  else // existing patient
578  {
579    frm.existingFamilyName.disabled = true;
580    frm.existingAllFirstNames.disabled = true;
581    patientInfo.familyName = frm.existingFamilyName.value;
582    patientInfo.allFirstNames = frm.existingAllFirstNames.value;
583  }
584  currentStep = 3;
585 
586  var updateMode = caseInfo.id && caseInfo.patient;
587 
588  // Generate list of specimen tubes
589  var hasLeftSpecimen = false;
590  var hasRightSpecimen = false;
591  var hasUnknownSpecimen = false;
592  var thisCaseLaterality = caseInfo.laterality;
593  var hasSpecimen = caseInfo.specimen && caseInfo.specimen.length > 0;
594  var thisCasePAD = null;
595  var hasPAD = false;
596  var thisCaseSamplingDate = null;
597  var thisCaseRNALaterDate = null;
598 
599  if (hasSpecimen)
600  {
601    var specimenTubes = '';
602    Main.hide('reasonIfNoSpecimenSection');
603    for (var i = 0; i < caseInfo.specimen.length; i++)
604    {
605      var specimen = caseInfo.specimen[i];
606      specimenTubes += specimen.name;
607      if (specimen.pad && !hasPAD) 
608      {
609        hasPAD = true;
610        thisCasePAD = specimen.pad;
611      }
612      if (specimen.samplingDate && !thisCaseSamplingDate) 
613      {
614        thisCaseSamplingDate = specimen.samplingDate;
615      }
616      if (specimen.rnaLaterDate && !thisCaseRNALaterDate) 
617      {
618        thisCaseRNALaterDate = specimen.rnaLaterDate;
619      }
620      if (specimen.laterality) 
621      {
622        specimenTubes += ' ('+specimen.laterality + ')';
623        Forms.checkRadio(frm.laterality, specimen.laterality);
624        if (specimen.laterality == 'LEFT') hasLeftSpecimen = true;
625        if (specimen.laterality == 'RIGHT') hasRightSpecimen = true;
626        if (!thisCaseLaterality) thisCaseLaterality = specimen.laterality;
627      }
628      else
629      {
630        hasUnknownSpecimen = true;
631        specimenTubes += ' (<i>unknown laterality</i>)';
632      }
633      specimenTubes += '<br>';
634    }
635    setInnerHTML('specimenTubes', specimenTubes);
636   
637    // Check that all specimen tubes have the same laterality
638    var numLateralities = 0;
639    if (hasLeftSpecimen) numLateralities++;
640    if (hasRightSpecimen) numLateralities++;
641    if (hasUnknownSpecimen) numLateralities++;
642    if (numLateralities > 1)
643    {
644      setInputStatus('specimenTubes', 'Specimen tubes with different laterality', 'warning');
645      thisCaseLaterality = null;
646    }
647   
648    Main.show('samplingDateSection');
649    Main.show('rnaLaterDateSection');
650
651  }
652  else
653  {
654    if (caseInfo.noSpecimen)
655    {
656      // This case is registered with 'NoSpecimen'
657      thisCasePAD = caseInfo.noSpecimen.pad;
658      thisCaseSamplingDate = caseInfo.noSpecimen.samplingDate;
659      frm.reasonIfNoSpecimen.value = caseInfo.noSpecimen.reasonIfNoSpecimen;
660    }
661   
662    // Hide & disable 'Sampling time' field
663    Main.hide('samplingTimeField');
664    frm.samplingTime.disabled = true;
665   
666    // Hide 'RNA Later date' field
667    Main.hide('rnaLaterDateSection');
668  }
669
670  // Populate 'Sampling date' and 'RNA Later date' fields
671  if (thisCaseSamplingDate != null)
672  {
673    frm.samplingDate.value = thisCaseSamplingDate.substring(0, 8);
674    if (!frm.samplingTime.disabled)
675    {
676      frm.samplingTime.value = thisCaseSamplingDate.substring(9, 13);
677    }
678    samplingDateTimeOnChange();
679  }
680  if (thisCaseRNALaterDate != null)
681  {
682    frm.rnaLaterDate.value = thisCaseRNALaterDate.substring(0, 8);
683    frm.rnaLaterTime.value = thisCaseRNALaterDate.substring(9, 13);
684    rnaLaterDateTimeOnChange();
685  }
686 
687  frm.pad.value = thisCasePAD;
688 
689  Main.show('caseSection');
690 
691  // Existing cases for this patient
692  var hasLeftCase = false;
693  var hasRightCase = false;
694  var hasUnknownCase = false;
695  if (patientInfo.cases && patientInfo.cases.length > 0)
696  {
697    var cases = '';
698    for (var i = 0; i < patientInfo.cases.length; i++)
699    {
700      var cc = patientInfo.cases[i];
701      if (cc.laterality == 'LEFT') 
702      {
703        if (hasLeftCase && !updateMode) setInputStatus('laterality', 'Two cases with laterality=LEFT', 'warning');
704        hasLeftCase = true;
705      }
706      else if (cc.laterality == 'RIGHT') 
707      {
708        if (hasRightCase && !updateMode) setInputStatus('laterality', 'Two cases with laterality=RIGHT', 'warning');
709        hasRightCase = true;
710      }
711      else
712      {
713        hasUnknownCase = true; 
714      }
715      if (!updateMode || cc.id == caseInfo.id)
716      {
717        cases += '<input type="radio" name="laterality" value="' + cc.id + '" id="laterality'+cc.id+'"';
718        if (cc.laterality == thisCaseLaterality) cases += ' checked';
719        cases += ' onclick="lateralityOnChange()"><label for="laterality' + cc.id + '">';
720        if (cc.laterality)
721        {
722          cases += cc.laterality;
723        }
724        else
725        {
726          cases += '<i>unknown laterality</i>';
727        }
728        if (!updateMode)
729        {
730          cases += ' [merge with ' + cc.name + ']';
731        }
732        cases += '</label><br>';
733      }
734    }
735   
736    if (patientInfo.cases.length == 1 || updateMode)
737    {
738      if (!hasLeftCase)
739      {
740        cases += '<input type="radio" name="laterality" value="LEFT" id="lateralityLeft"';
741        if (thisCaseLaterality == 'LEFT') cases += ' checked';
742        cases += ' onclick="lateralityOnChange()"><label for="lateralityLeft">LEFT';
743        if (!updateMode) cases += ' [<i>new case</i>]</label>';
744        cases += '<br>';
745      }
746      if (!hasRightCase)
747      {
748        cases += '<input type="radio" name="laterality" value="RIGHT" id="lateralityRight"';
749        if (thisCaseLaterality == 'RIGHT') cases += ' checked';
750        cases += ' onclick="lateralityOnChange()"><label for="lateralityRight">RIGHT';
751        if (!updateMode) cases += ' [<i>new case</i>]</label>';
752        cases += '<br>';
753      }
754      if (!updateMode && !hasLeftCase && !hasRightCase)
755      {
756        cases += '<input type="radio" name="laterality" value="" id="lateralityUnknown"';
757        if (thisCaseLaterality == null) cases += ' checked';
758        cases += ' onclick="lateralityOnChange()"><label for="lateralityUnknown"><i>unknown laterality</i> [<i>new case</i>]</label><br>';
759      }
760     
761      if (!updateMode && patientInfo.cases[0].consent)
762      {
763        var c = patientInfo.cases[0];
764        var html = "From case '" + c.name;
765        html += "' (" + c.consent;
766        if (c.consentDate) html += '; ' + c.consentDate;
767        html += ')';
768        setInnerHTML('copyConsent.text', html);
769        frm.copyConsent.value = patientInfo.cases[0].id;
770        copyConsentEnabled = true;
771      }
772     
773    }
774   
775    if (updateMode)
776    {
777      if (caseInfo.merged)
778      {
779        setInnerHTML('step3.title', 'Update case \''+caseInfo.originalName+'\' (which is merged with case \'' + caseInfo.name + '\')');
780      }
781      else
782      {
783        setInnerHTML('step3.title', 'Update case \''+caseInfo.name+'\'');
784      }
785     
786    }
787    else if (patientInfo.cases.length == 2)
788    {
789      setInnerHTML('step3.title', 'Merge with existing case'); 
790    }
791    else if (patientInfo.cases.length > 0)
792    {
793      setInnerHTML('step3.title', 'Create new case or merge with existing case');
794    }
795   
796    setInnerHTML('laterality.input', cases);
797  }
798 
799  // Check the blood registration for consent information
800  if (!copyConsentEnabled && bloodInfo && bloodInfo.consent)
801  {
802    var html = "From blood '" + bloodInfo.name;
803    html += "' (" + bloodInfo.consent;
804    if (bloodInfo.consentDate) html += '; ' + bloodInfo.consentDate;
805    html += ')';
806    setInnerHTML('copyConsent.text', html);
807    frm.copyConsent.value = bloodInfo.id;
808    copyConsentEnabled = true;
809  }
810
811 
812  lateralityOnChange();
813
814  Main.hide('gonext');
815  if (updateMode)
816  {
817    Main.show('goupdate');
818  }
819  else
820  {
821    Main.show('gocreate');
822  }
823 
824  if (lateralityIsValid) frm.pad.focus();
825}
826
827function goCreate()
828{
829  if (!step3IsValid()) return;
830 
831  Main.hide('gocreate');
832  Main.hide('gocancel');
833  Main.hide('goupdate');
834  var frm = document.forms['reggie'];
835
836  caseInfo.laterality = Forms.getCheckedRadio(frm.laterality).value;
837  caseInfo.reasonIfNoSpecimen = frm.reasonIfNoSpecimen.value;
838  caseInfo.pad = frm.pad.value;
839 
840  // 'C' suffix is only for 'SpecimenCoreBiopsy' items
841  var caseName = frm.caseName.value;
842  if (caseName.length > 7 && caseName.substring(7, 8) == 'C')
843  {
844    caseInfo.biopsyType = 'SpecimenCoreBiopsy';
845  }
846  if (frm.samplingTime.disabled)
847  {
848    // No time part if no specimen has been received
849    caseInfo.samplingDate = Main.trimString(frm.samplingDate.value);
850  }
851  else
852  {
853    caseInfo.samplingDate = Main.trimString(frm.samplingDate.value + ' ' + frm.samplingTime.value);
854  }
855  caseInfo.rnaLaterDate = Main.trimString(frm.rnaLaterDate.value + ' ' + frm.rnaLaterTime.value);
856  if (frm.copyConsent.checked && frm.copyConsent.value)
857  {
858    caseInfo.copyConsent = parseInt(frm.copyConsent.value, 10);
859  }
860
861  for (var i = 0; i < frm.laterality.length; i++)
862  {
863    frm.laterality[i].disabled = true;
864  }
865  frm.reasonIfNoSpecimen.disabled = true;
866  frm.pad.disabled = true;
867  frm.samplingDate.disabled = true;
868  frm.samplingTime.disabled = true;
869  frm.rnaLaterDate.disabled = true;
870  frm.rnaLaterTime.disabled = true;
871  frm.copyConsent.disabled = true;
872
873  var updateMode = caseInfo.id && caseInfo.patient;
874  var submitInfo = new Object();
875  submitInfo.patientInfo = patientInfo;
876  submitInfo.caseInfo = caseInfo;
877
878  if (debug) Main.debug(JSON.stringify(submitInfo));
879 
880  var request = Ajax.getXmlHttpRequest();
881  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=';
882  url += updateMode ? 'UpdateCase' : 'CreateCase';
883  request.open("POST", url, false);
884  request.setRequestHeader("Content-Type", "application/json");
885  request.send(JSON.stringify(submitInfo));
886
887  if (debug) Main.debug(request.responseText);
888
889  var response = JSON.parse(request.responseText);
890  if (response.status != 'ok')
891  {
892    setFatalError(response.message);
893    return false;
894  }
895 
896  var msg = '<ul>';
897  for (var i = 0; i < response.messages.length; i++)
898  {
899    msg += '<li>' + response.messages[i];
900  }
901  msg += '</ul>';
902  setInnerHTML('done', msg);
903  Main.show('done');
904  Main.show('gorestart');
905
906}
907</script>
908
909</base:head>
910<base:body onload="init()">
911
912  <p:path><p:pathelement
913    title="Reggie" href="<%="index.jsp?ID="+ID%>" 
914    /><p:pathelement title="Personal information registration" 
915    /></p:path>
916
917  <div class="content">
918  <%
919  if (sc.getActiveProjectId() == 0)
920  {
921    %>
922    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
923      No project has been selected. You may proceed with the registration but
924      created items will not be shared.
925    </div>
926    <%
927  }
928  %>
929
930  <form name="reggie" onsubmit="return false;">
931 
932  <!-- 1. Case + Personal number -->
933  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
934  <tr>
935    <td rowspan="3" class="stepno">1</td>
936    <td class="steptitle">Enter Case Name and Personal Number</td>
937  </tr>
938  <tr>
939    <td class="stepfields">
940      <table border="0" cellspacing="0" cellpadding="0" width="100%">
941      <tr valign="top">
942        <td class="prompt">Case name</td>
943        <td class="input"><input type="text" name="caseName" 
944          size="18" maxlength="12" onblur="caseNameOnChange()" onkeypress="focusOnEnter(event, 'personalNumber')"></td>
945        <td class="status" id="case.status"></td>
946        <td class="help"><span id="case.message" class="message" style="display: none;"></span>The case (barcode) associated with this patient.</td>
947      </tr>
948      <tr>
949        <td class="prompt">Personal number</td>
950        <td class="input"><input type="text" name="personalNumber" 
951          size="18" maxlength="12" onkeyup="personalNumberOnChange()" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
952        <td class="status" id="pnr.status"></td>
953        <td class="help"><span id="pnr.message" class="message" style="display: none;"></span>([YY]YYMMDDZZZZ)</td>
954      </tr>
955      </table>
956    </td>
957  </tr>
958  </table>
959
960  <!-- 2. New patient registration -->
961  <div id="newPatientSection" style="display: none;">
962  <p>
963  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
964  <tr>
965    <td rowspan="2" class="stepno">2</td>
966    <td class="steptitle">New patient: Enter all names</td>
967  </tr>
968  <tr>
969    <td class="stepfields">
970      <table border="0" cellspacing="0" cellpadding="0" width="100%">
971      <tr>
972        <td class="prompt">Patient code</td>
973        <td class="input"><input type="text" name="patientCode" 
974          value="" size="18" maxlength="12" 
975          onkeypress="focusOnEnter(event, 'familyName')"></td>
976        <td class="status" id="patientCode.status"></td>
977        <td class="help"><span id="patientCode.message" class="message" style="display: none;"></span></td>
978      </tr>
979      <tr valign="top">
980        <td class="prompt">Family name</td>
981        <td class="input"><input type="text" name="familyName" 
982          value="" size="35" maxlength="255" onblur="nameOnChange(event)"
983          onkeypress="focusOnEnter(event, 'allFirstNames')"></td>
984        <td class="status" id="familyName.status"></td>
985        <td class="help"><span id="familyName.message" class="message" style="display: none;"></span>Keep hyphens, keep åäö, replace all special accented letters [e.g. éèü etc] with standard alphabet character.</td>
986      </tr>
987      <tr valign="top">
988        <td class="prompt">All first names</td>
989        <td class="input"><input type="text" name="allFirstNames" onblur="nameOnChange(event)"
990          size="35" maxlength="255" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
991        <td class="status" id="allFirstNames.status"></td>
992        <td class="help"><span id="allFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
993      </tr>
994      <tr>
995        <td class="prompt">Gender</td>
996        <td class="input" id="new.gender"></td>
997        <td class="status" id="gender.status" rowspan="2"></td>
998        <td class="help" rowspan="2"><span id="gender.message" class="message" style="display:none;"></span></td>
999      </tr>
1000      <tr>
1001        <td class="prompt">Date of birth</td>
1002        <td class="input" id="new.dateOfBirth"></td>
1003      </tr>
1004      </table>
1005    </td>
1006  </tr>
1007  </table>
1008  </div>
1009 
1010  <!-- 2b. Existing patient -->
1011  <div id="existingPatientSection" style="display: none;">
1012  <p>
1013  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1014  <tr>
1015    <td rowspan="2" class="stepno">2</td>
1016    <td class="steptitle">Existing patient: Verify names</td>
1017  </tr>
1018  <tr>
1019    <td class="stepfields">
1020      <table border="0" cellspacing="0" cellpadding="0" width="100%">
1021      <tr>
1022        <td class="prompt">Patient code</td>
1023        <td class="input" id="existing.patientCode"></td>
1024        <td class="status"></td>
1025        <td class="help"></td>
1026      </tr>
1027      <tr valign="top">
1028        <td class="prompt">Family name</td>
1029        <td class="input"><input type="text" name="existingFamilyName" 
1030          value="" size="35" maxlength="255" onblur="nameOnChange(event)"
1031          onkeypress="focusOnEnter(event, 'existingAllFirstNames')"></td>
1032        <td class="status" id="existingFamilyName.status"></td>
1033        <td class="help"><span id="existingFamilyName.message" class="message" style="display: none;"></span>Keep hyphens, keep åäö, replace all special accented letters [e.g. éèü etc] with standard alphabet character.</td>
1034      </tr>
1035      <tr valign="top">
1036        <td class="prompt">All first names</td>
1037        <td class="input"><input type="text" name="existingAllFirstNames" onblur="nameOnChange(event)"
1038          size="35" maxlength="255" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
1039        <td class="status" id="existingAllFirstNames.status"></td>
1040        <td class="help"><span id="existingAllFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
1041      </tr>
1042      <tr>
1043        <td class="prompt">Gender</td>
1044        <td class="input" id="existing.gender"></td>
1045        <td class="status"></td>
1046        <td class="help"></td>
1047      </tr>
1048      <tr>
1049        <td class="prompt">Date of birth</td>
1050        <td class="input" id="existing.dateOfBirth"></td>
1051        <td class="status"></td>
1052        <td class="help"></td>
1053      </tr>
1054      </table>
1055    </td>
1056  </tr>
1057  </table>
1058  </div>
1059
1060
1061  <!-- 3. Case registration -->
1062  <div id="caseSection" style="display: none;">
1063  <p>
1064  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1065  <tr>
1066    <td rowspan="2" class="stepno">3</td>
1067    <td class="steptitle" id="step3.title">Create new case</td>
1068  </tr>
1069  <tr>
1070    <td class="stepfields">
1071      <table border="0" cellspacing="0" cellpadding="0" width="100%">
1072      <tr valign="top">
1073        <td class="prompt" id="laterality.prompt">Laterality</td>
1074        <td class="input" id="laterality.input">
1075          <input type="radio" name="laterality" value="LEFT" id="lateralityLeft" onclick="lateralityOnChange()"><label for="lateralityLeft">LEFT</label><br>
1076          <input type="radio" name="laterality" value="RIGHT" id="lateralityRight" onclick="lateralityOnChange()"><label for="lateralityRight">RIGHT</label><br>
1077          <input type="radio" name="laterality" value="" checked id="lateralityUnknown" onclick="lateralityOnChange()"><i><label for="lateralityUnknown">unknown</label></i>
1078        </td>
1079        <td class="status" id="laterality.status"></td>
1080        <td class="help"><span id="laterality.message" class="message" style="display: none;"></span></td>
1081      </tr>
1082      <tr id="copyConsentSection" style="display: none;">
1083        <td class="prompt">Copy consent?</td>
1084        <td class="input">
1085          <input type="checkbox" name="copyConsent" id="copyConsent" value="" checked>
1086          <label for="copyConsent"><span id="copyConsent.text"></span></label>
1087        </td>
1088        <td class="status" id="copyConsent.status"></td>
1089        <td class="help"></td>
1090      </tr>
1091      <tr id="padSection" valign="top">
1092        <td class="prompt">PAD</td>
1093        <td class="input"><input type="text" name="pad" 
1094          value="" size="18" maxlength="12" 
1095          onkeypress="focusOnEnter(event, 'samplingDate')"
1096          onblur="padOnChange()"></td>
1097        <td class="status" id="pad.status"></td>
1098        <td class="help"><span id="pad.message" class="message" style="display: none;"></span></td>
1099      </tr>
1100      <tr valign="top">
1101        <td class="prompt">Specimen tubes</td>
1102        <td class="input" id="specimenTubes"><i>not found</i></td>
1103        <td class="status" id="specimenTubes.status"></td>
1104        <td class="help"><span id="specimenTubes.message" class="message" style="display: none;"></span>The specimen tube(s) associated with this case.</td>
1105      </tr>
1106      <tr id="samplingDateSection" valign="top">
1107        <td class="subprompt">Sampling date</td>
1108        <td class="input"><input type="text" name="samplingDate" value="" size="12" maxlength="10" 
1109            onkeypress="focusOnEnter(event, caseInfo.specimen && caseInfo.specimen.length > 0 ? 'samplingTime' : 'reasonIfNoSpecimen')" onblur="samplingDateTimeOnChange()">
1110          <span id="samplingTimeField">Time <input type="text" name="samplingTime" value="" size="6" maxlength="5" 
1111            onkeypress="focusOnEnter(event, caseInfo.specimen && caseInfo.specimen.length > 0 ? 'rnaLaterDate' : 'reasonIfNoSpecimen')" onblur="samplingDateTimeOnChange()"></span>
1112        </td>
1113        <td class="status" id="samplingDate.status"></td>
1114        <td class="help"><span id="samplingDate.message" class="message" style="display: none;"></span>Date (+time) of surgical removal (YYYYMMDD, HHMM)</td>
1115      </tr>
1116      <tr id="rnaLaterDateSection" valign="top">
1117        <td class="subprompt">RNA Later date</td>
1118        <td class="input"><input type="text" name="rnaLaterDate" value="" size="12" maxlength="10"
1119            onkeypress="focusOnEnter(event, 'rnaLaterTime')" onblur="rnaLaterDateTimeOnChange()">
1120          Time <input type="text" name="rnaLaterTime" value="" size="6" maxlength="5"
1121            onblur="rnaLaterDateTimeOnChange()"></td>
1122        <td class="status" id="rnaLaterDate.status"></td>
1123        <td class="help"><span id="rnaLaterDate.message" class="message" style="display: none;"></span>Date+time of pathology handling (YYYYMMDD, HHMM)</td>
1124      </tr>
1125      <tr id="reasonIfNoSpecimenSection" valign="top">
1126        <td class="subprompt">Reason if no specimen</td>
1127        <td class="input"><textarea rows="3" cols="30" name="reasonIfNoSpecimen" value=""></textarea></td>
1128        <td class="status"></td>
1129        <td class="help">Comment why there was no specimen tubes in the delivery.</td>
1130      </tr>
1131      </table>
1132    </td>
1133  </tr>
1134  </table>
1135  </div>
1136
1137  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
1138
1139  <div id="done" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
1140
1141  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
1142  <tr>
1143    <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
1144    <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)"/></td>
1145    <td><base:button id="gocreate" title="Create" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;"/></td>
1146    <td><base:button id="goupdate" title="Update" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;"/></td>
1147    <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
1148    <td id="gonext.message" class="message"></td>
1149  </tr>
1150  </table>
1151  </form>
1152  </div>
1153 
1154</base:body>
1155</base:page>
1156<%
1157}
1158finally
1159{
1160  if (dc != null) dc.close();
1161}
1162%>
Note: See TracBrowser for help on using the repository browser.