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

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

Fixes #442: Allow pathology and blood registration wizards to save patients without names

File size: 34.7 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 && rnaLaterTimestamp.getDate() != samplingTimestamp.getDate())
456    {
457      setInputStatus('rnaLaterDate', 'Sampling and RNA later dates are different', 'warning');
458    }
459  }
460}
461
462function getCaseInfo()
463{
464  // Check entered case and pnr with AJAX
465  var frm = document.forms['reggie'];
466  var caseName = frm.caseName.value;
467  var request = Ajax.getXmlHttpRequest();
468  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=GetCaseInfo';
469  url += '&caseName=' + caseName;
470  request.open("GET", url, false);
471  request.send(null);
472 
473  if (debug) Main.debug(request.responseText);
474
475  var response = JSON.parse(request.responseText);
476  if (response.status != 'ok')
477  {
478    setFatalError(response.message);
479    return false;
480  }
481 
482  // Get biosource information from the AJAX response
483  caseInfo = response.caseInfo;
484  bloodInfo = response.bloodInfo;
485 
486  if (caseInfo && caseInfo.patient)
487  {
488    frm.personalNumber.value = caseInfo.patient.personalNumber;
489    gotoStep2();
490  }
491  else if (bloodInfo && bloodInfo.patient)
492  {
493    frm.personalNumber.value = bloodInfo.patient.personalNumber;
494    gotoStep2();
495  }
496}
497
498function gotoStep2()
499{
500  // Check entered case and pnr with AJAX
501  var frm = document.forms['reggie'];
502  frm.caseName.disabled = true;
503  frm.personalNumber.disabled = true;
504  currentStep = 2;
505 
506  var pnr = frm.personalNumber.value;
507  if (pnr.length == 10 && pnrIsValid) 
508  {
509    var year = fullYear(parseInt(pnr.substr(0, 2), 10));
510    pnr = year + pnr.substr(2);
511  }
512  var request = Ajax.getXmlHttpRequest();
513  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=GetPatientInfo';
514  url += '&personalNumber=' + pnr;
515  url += '&pnrIsValid=' + pnrIsValid;
516  request.open("GET", url, false);
517  request.send(null);
518 
519  if (debug) Main.debug(request.responseText);
520 
521  var response = JSON.parse(request.responseText);
522  if (response.status != 'ok')
523  {
524    setFatalError(response.message);
525    return false;
526  }
527 
528  // Get patient information from the AJAX response
529  patientInfo = response.patientInfo;
530
531  Main.show('gocancel');
532 
533  if (!patientInfo.id)
534  {
535    Main.show('newPatientSection');
536    frm.patientCode.value=patientInfo.name;
537    setInnerHTML('new.dateOfBirth', patientInfo.dateOfBirth ? patientInfo.dateOfBirth : "---");
538    setInnerHTML('new.gender', patientInfo.gender ? patientInfo.gender : "---");
539    frm.familyName.focus();
540    if (!pnrIsValid)
541    {
542      setInputStatus('gender', 'Gender and DateOfBirth can\'t be automatically generated for non-standard Personal number', 'warning');
543    }
544  }
545  else
546  {
547    Main.show('existingPatientSection');
548    setInnerHTML('existing.patientCode', patientInfo.name);
549    frm.existingFamilyName.value = patientInfo.familyName;
550    frm.existingAllFirstNames.value = patientInfo.allFirstNames;
551    if (patientInfo.dateOfBirth) setInnerHTML('existing.dateOfBirth', patientInfo.dateOfBirth);
552    if (patientInfo.gender) setInnerHTML('existing.gender', patientInfo.gender);
553    frm.existingFamilyName.focus();
554  }
555}
556
557function gotoStep3()
558{
559  // Check entered case and pnr with AJAX
560  var frm = document.forms['reggie'];
561 
562  if (!patientInfo.id) // new patient
563  {
564    frm.patientCode.disabled = true;
565    frm.familyName.disabled = true;
566    frm.allFirstNames.disabled = true;
567    patientInfo.familyName = frm.familyName.value;
568    patientInfo.allFirstNames = frm.allFirstNames.value;
569  }
570  else // existing patient
571  {
572    frm.existingFamilyName.disabled = true;
573    frm.existingAllFirstNames.disabled = true;
574    patientInfo.familyName = frm.existingFamilyName.value;
575    patientInfo.allFirstNames = frm.existingAllFirstNames.value;
576  }
577  currentStep = 3;
578 
579  var updateMode = caseInfo.id && caseInfo.patient;
580 
581  // Generate list of specimen tubes
582  var hasLeftSpecimen = false;
583  var hasRightSpecimen = false;
584  var hasUnknownSpecimen = false;
585  var thisCaseLaterality = caseInfo.laterality;
586  var hasSpecimen = caseInfo.specimen && caseInfo.specimen.length > 0;
587  var thisCasePAD = null;
588  var hasPAD = false;
589  var thisCaseSamplingDate = null;
590  var thisCaseRNALaterDate = null;
591 
592  if (hasSpecimen)
593  {
594    var specimenTubes = '';
595    Main.hide('reasonIfNoSpecimenSection');
596    for (var i = 0; i < caseInfo.specimen.length; i++)
597    {
598      var specimen = caseInfo.specimen[i];
599      specimenTubes += specimen.name;
600      if (specimen.pad && !hasPAD) 
601      {
602        hasPAD = true;
603        thisCasePAD = specimen.pad;
604      }
605      if (specimen.samplingDate && !thisCaseSamplingDate) 
606      {
607        thisCaseSamplingDate = specimen.samplingDate;
608      }
609      if (specimen.rnaLaterDate && !thisCaseRNALaterDate) 
610      {
611        thisCaseRNALaterDate = specimen.rnaLaterDate;
612      }
613      if (specimen.laterality) 
614      {
615        specimenTubes += ' ('+specimen.laterality + ')';
616        Forms.checkRadio(frm.laterality, specimen.laterality);
617        if (specimen.laterality == 'LEFT') hasLeftSpecimen = true;
618        if (specimen.laterality == 'RIGHT') hasRightSpecimen = true;
619        if (!thisCaseLaterality) thisCaseLaterality = specimen.laterality;
620      }
621      else
622      {
623        hasUnknownSpecimen = true;
624        specimenTubes += ' (<i>unknown laterality</i>)';
625      }
626      specimenTubes += '<br>';
627    }
628    setInnerHTML('specimenTubes', specimenTubes);
629   
630    // Check that all specimen tubes have the same laterality
631    var numLateralities = 0;
632    if (hasLeftSpecimen) numLateralities++;
633    if (hasRightSpecimen) numLateralities++;
634    if (hasUnknownSpecimen) numLateralities++;
635    if (numLateralities > 1)
636    {
637      setInputStatus('specimenTubes', 'Specimen tubes with different laterality', 'warning');
638      thisCaseLaterality = null;
639    }
640   
641    Main.show('samplingDateSection');
642    Main.show('rnaLaterDateSection');
643
644  }
645  else
646  {
647    if (caseInfo.noSpecimen)
648    {
649      // This case is registered with 'NoSpecimen'
650      thisCasePAD = caseInfo.noSpecimen.pad;
651      thisCaseSamplingDate = caseInfo.noSpecimen.samplingDate;
652      frm.reasonIfNoSpecimen.value = caseInfo.noSpecimen.reasonIfNoSpecimen;
653    }
654   
655    // Hide & disable 'Sampling time' field
656    Main.hide('samplingTimeField');
657    frm.samplingTime.disabled = true;
658   
659    // Hide 'RNA Later date' field
660    Main.hide('rnaLaterDateSection');
661  }
662
663  // Populate 'Sampling date' and 'RNA Later date' fields
664  if (thisCaseSamplingDate != null)
665  {
666    frm.samplingDate.value = thisCaseSamplingDate.substring(0, 8);
667    if (!frm.samplingTime.disabled)
668    {
669      frm.samplingTime.value = thisCaseSamplingDate.substring(9, 13);
670    }
671    samplingDateTimeOnChange();
672  }
673  if (thisCaseRNALaterDate != null)
674  {
675    frm.rnaLaterDate.value = thisCaseRNALaterDate.substring(0, 8);
676    frm.rnaLaterTime.value = thisCaseRNALaterDate.substring(9, 13);
677    rnaLaterDateTimeOnChange();
678  }
679 
680  frm.pad.value = thisCasePAD;
681 
682  Main.show('caseSection');
683 
684  // Existing cases for this patient
685  var hasLeftCase = false;
686  var hasRightCase = false;
687  var hasUnknownCase = false;
688  if (patientInfo.cases && patientInfo.cases.length > 0)
689  {
690    var cases = '';
691    for (var i = 0; i < patientInfo.cases.length; i++)
692    {
693      var cc = patientInfo.cases[i];
694      if (cc.laterality == 'LEFT') 
695      {
696        if (hasLeftCase && !updateMode) setInputStatus('laterality', 'Two cases with laterality=LEFT', 'warning');
697        hasLeftCase = true;
698      }
699      else if (cc.laterality == 'RIGHT') 
700      {
701        if (hasRightCase && !updateMode) setInputStatus('laterality', 'Two cases with laterality=RIGHT', 'warning');
702        hasRightCase = true;
703      }
704      else
705      {
706        hasUnknownCase = true; 
707      }
708      if (!updateMode || cc.id == caseInfo.id)
709      {
710        cases += '<input type="radio" name="laterality" value="' + cc.id + '" id="laterality'+cc.id+'"';
711        if (cc.laterality == thisCaseLaterality) cases += ' checked';
712        cases += ' onclick="lateralityOnChange()"><label for="laterality' + cc.id + '">';
713        if (cc.laterality)
714        {
715          cases += cc.laterality;
716        }
717        else
718        {
719          cases += '<i>unknown laterality</i>';
720        }
721        if (!updateMode)
722        {
723          cases += ' [merge with ' + cc.name + ']';
724        }
725        cases += '</label><br>';
726      }
727    }
728   
729    if (patientInfo.cases.length == 1 || updateMode)
730    {
731      if (!hasLeftCase)
732      {
733        cases += '<input type="radio" name="laterality" value="LEFT" id="lateralityLeft"';
734        if (thisCaseLaterality == 'LEFT') cases += ' checked';
735        cases += ' onclick="lateralityOnChange()"><label for="lateralityLeft">LEFT';
736        if (!updateMode) cases += ' [<i>new case</i>]</label>';
737        cases += '<br>';
738      }
739      if (!hasRightCase)
740      {
741        cases += '<input type="radio" name="laterality" value="RIGHT" id="lateralityRight"';
742        if (thisCaseLaterality == 'RIGHT') cases += ' checked';
743        cases += ' onclick="lateralityOnChange()"><label for="lateralityRight">RIGHT';
744        if (!updateMode) cases += ' [<i>new case</i>]</label>';
745        cases += '<br>';
746      }
747      if (!updateMode && !hasLeftCase && !hasRightCase)
748      {
749        cases += '<input type="radio" name="laterality" value="" id="lateralityUnknown"';
750        if (thisCaseLaterality == null) cases += ' checked';
751        cases += ' onclick="lateralityOnChange()"><label for="lateralityUnknown"><i>unknown laterality</i> [<i>new case</i>]</label><br>';
752      }
753     
754      if (!updateMode && patientInfo.cases[0].consent)
755      {
756        var c = patientInfo.cases[0];
757        var html = "From case '" + c.name;
758        html += "' (" + c.consent;
759        if (c.consentDate) html += '; ' + c.consentDate;
760        html += ')';
761        setInnerHTML('copyConsent.text', html);
762        frm.copyConsent.value = patientInfo.cases[0].id;
763        copyConsentEnabled = true;
764      }
765     
766    }
767   
768    if (updateMode)
769    {
770      if (caseInfo.merged)
771      {
772        setInnerHTML('step3.title', 'Update case \''+caseInfo.originalName+'\' (which is merged with case \'' + caseInfo.name + '\')');
773      }
774      else
775      {
776        setInnerHTML('step3.title', 'Update case \''+caseInfo.name+'\'');
777      }
778     
779    }
780    else if (patientInfo.cases.length == 2)
781    {
782      setInnerHTML('step3.title', 'Merge with existing case'); 
783    }
784    else if (patientInfo.cases.length > 0)
785    {
786      setInnerHTML('step3.title', 'Create new case or merge with existing case');
787    }
788   
789    setInnerHTML('laterality.input', cases);
790  }
791 
792  // Check the blood registration for consent information
793  if (!copyConsentEnabled && bloodInfo && bloodInfo.consent)
794  {
795    var html = "From blood '" + bloodInfo.name;
796    html += "' (" + bloodInfo.consent;
797    if (bloodInfo.consentDate) html += '; ' + bloodInfo.consentDate;
798    html += ')';
799    setInnerHTML('copyConsent.text', html);
800    frm.copyConsent.value = bloodInfo.id;
801    copyConsentEnabled = true;
802  }
803
804 
805  lateralityOnChange();
806
807  Main.hide('gonext');
808  if (updateMode)
809  {
810    Main.show('goupdate');
811  }
812  else
813  {
814    Main.show('gocreate');
815  }
816 
817  if (lateralityIsValid) frm.pad.focus();
818}
819
820function goCreate()
821{
822  if (!step3IsValid()) return;
823 
824  Main.hide('gocreate');
825  Main.hide('gocancel');
826  Main.hide('goupdate');
827  var frm = document.forms['reggie'];
828
829  caseInfo.laterality = Forms.getCheckedRadio(frm.laterality).value;
830  caseInfo.reasonIfNoSpecimen = frm.reasonIfNoSpecimen.value;
831  caseInfo.pad = frm.pad.value;
832 
833  // 'C' suffix is only for 'SpecimenCoreBiopsy' items
834  var caseName = frm.caseName.value;
835  if (caseName.length > 7 && caseName.substring(7, 8) == 'C')
836  {
837    caseInfo.biopsyType = 'SpecimenCoreBiopsy';
838  }
839  if (frm.samplingTime.disabled)
840  {
841    // No time part if no specimen has been received
842    caseInfo.samplingDate = Main.trimString(frm.samplingDate.value);
843  }
844  else
845  {
846    caseInfo.samplingDate = Main.trimString(frm.samplingDate.value + ' ' + frm.samplingTime.value);
847  }
848  caseInfo.rnaLaterDate = Main.trimString(frm.rnaLaterDate.value + ' ' + frm.rnaLaterTime.value);
849  if (frm.copyConsent.checked && frm.copyConsent.value)
850  {
851    caseInfo.copyConsent = parseInt(frm.copyConsent.value, 10);
852  }
853
854  for (var i = 0; i < frm.laterality.length; i++)
855  {
856    frm.laterality[i].disabled = true;
857  }
858  frm.reasonIfNoSpecimen.disabled = true;
859  frm.pad.disabled = true;
860  frm.samplingDate.disabled = true;
861  frm.samplingTime.disabled = true;
862  frm.rnaLaterDate.disabled = true;
863  frm.rnaLaterTime.disabled = true;
864  frm.copyConsent.disabled = true;
865
866  var updateMode = caseInfo.id && caseInfo.patient;
867  var submitInfo = new Object();
868  submitInfo.patientInfo = patientInfo;
869  submitInfo.caseInfo = caseInfo;
870
871  if (debug) Main.debug(JSON.stringify(submitInfo));
872 
873  var request = Ajax.getXmlHttpRequest();
874  var url = 'PersonalRegistration.servlet?ID=<%=ID%>&cmd=';
875  url += updateMode ? 'UpdateCase' : 'CreateCase';
876  request.open("POST", url, false);
877  request.setRequestHeader("Content-Type", "application/json");
878  request.send(JSON.stringify(submitInfo));
879
880  if (debug) Main.debug(request.responseText);
881
882  var response = JSON.parse(request.responseText);
883  if (response.status != 'ok')
884  {
885    setFatalError(response.message);
886    return false;
887  }
888 
889  var msg = '<ul>';
890  for (var i = 0; i < response.messages.length; i++)
891  {
892    msg += '<li>' + response.messages[i];
893  }
894  msg += '</ul>';
895  setInnerHTML('done', msg);
896  Main.show('done');
897  Main.show('gorestart');
898
899}
900</script>
901
902</base:head>
903<base:body onload="init()">
904
905  <p:path><p:pathelement
906    title="Reggie" href="<%="index.jsp?ID="+ID%>" 
907    /><p:pathelement title="Personal information registration" 
908    /></p:path>
909
910  <div class="content">
911  <%
912  if (sc.getActiveProjectId() == 0)
913  {
914    %>
915    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
916      No project has been selected. You may proceed with the registration but
917      created items will not be shared.
918    </div>
919    <%
920  }
921  %>
922
923  <form name="reggie" onsubmit="return false;">
924 
925  <!-- 1. Case + Personal number -->
926  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
927  <tr>
928    <td rowspan="3" class="stepno">1</td>
929    <td class="steptitle">Enter Case Name and Personal Number</td>
930  </tr>
931  <tr>
932    <td class="stepfields">
933      <table border="0" cellspacing="0" cellpadding="0" width="100%">
934      <tr valign="top">
935        <td class="prompt">Case name</td>
936        <td class="input"><input type="text" name="caseName" 
937          size="18" maxlength="12" onblur="caseNameOnChange()" onkeypress="focusOnEnter(event, 'personalNumber')"></td>
938        <td class="status" id="case.status"></td>
939        <td class="help"><span id="case.message" class="message" style="display: none;"></span>The case (barcode) associated with this patient.</td>
940      </tr>
941      <tr>
942        <td class="prompt">Personal number</td>
943        <td class="input"><input type="text" name="personalNumber" 
944          size="18" maxlength="12" onkeyup="personalNumberOnChange()" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
945        <td class="status" id="pnr.status"></td>
946        <td class="help"><span id="pnr.message" class="message" style="display: none;"></span>([YY]YYMMDDZZZZ)</td>
947      </tr>
948      </table>
949    </td>
950  </tr>
951  </table>
952
953  <!-- 2. New patient registration -->
954  <div id="newPatientSection" style="display: none;">
955  <p>
956  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
957  <tr>
958    <td rowspan="2" class="stepno">2</td>
959    <td class="steptitle">New patient: Enter all names</td>
960  </tr>
961  <tr>
962    <td class="stepfields">
963      <table border="0" cellspacing="0" cellpadding="0" width="100%">
964      <tr>
965        <td class="prompt">Patient code</td>
966        <td class="input"><input type="text" name="patientCode" 
967          value="" size="18" maxlength="12" 
968          onkeypress="focusOnEnter(event, 'familyName')"></td>
969        <td class="status" id="patientCode.status"></td>
970        <td class="help"><span id="patientCode.message" class="message" style="display: none;"></span></td>
971      </tr>
972      <tr valign="top">
973        <td class="prompt">Family name</td>
974        <td class="input"><input type="text" name="familyName" 
975          value="" size="35" maxlength="255" onblur="nameOnChange(event)"
976          onkeypress="focusOnEnter(event, 'allFirstNames')"></td>
977        <td class="status" id="familyName.status"></td>
978        <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>
979      </tr>
980      <tr valign="top">
981        <td class="prompt">All first names</td>
982        <td class="input"><input type="text" name="allFirstNames" onblur="nameOnChange(event)"
983          size="35" maxlength="255" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
984        <td class="status" id="allFirstNames.status"></td>
985        <td class="help"><span id="allFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
986      </tr>
987      <tr>
988        <td class="prompt">Gender</td>
989        <td class="input" id="new.gender"></td>
990        <td class="status" id="gender.status" rowspan="2"></td>
991        <td class="help" rowspan="2"><span id="gender.message" class="message" style="display:none;"></span></td>
992      </tr>
993      <tr>
994        <td class="prompt">Date of birth</td>
995        <td class="input" id="new.dateOfBirth"></td>
996      </tr>
997      </table>
998    </td>
999  </tr>
1000  </table>
1001  </div>
1002 
1003  <!-- 2b. Existing patient -->
1004  <div id="existingPatientSection" style="display: none;">
1005  <p>
1006  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1007  <tr>
1008    <td rowspan="2" class="stepno">2</td>
1009    <td class="steptitle">Existing patient: Verify names</td>
1010  </tr>
1011  <tr>
1012    <td class="stepfields">
1013      <table border="0" cellspacing="0" cellpadding="0" width="100%">
1014      <tr>
1015        <td class="prompt">Patient code</td>
1016        <td class="input" id="existing.patientCode"></td>
1017        <td class="status"></td>
1018        <td class="help"></td>
1019      </tr>
1020      <tr valign="top">
1021        <td class="prompt">Family name</td>
1022        <td class="input"><input type="text" name="existingFamilyName" 
1023          value="" size="35" maxlength="255" onblur="nameOnChange(event)"
1024          onkeypress="focusOnEnter(event, 'existingAllFirstNames')"></td>
1025        <td class="status" id="existingFamilyName.status"></td>
1026        <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>
1027      </tr>
1028      <tr valign="top">
1029        <td class="prompt">All first names</td>
1030        <td class="input"><input type="text" name="existingAllFirstNames" onblur="nameOnChange(event)"
1031          size="35" maxlength="255" onkeypress="doOnTabOrEnter(event, goNextAuto)"></td>
1032        <td class="status" id="existingAllFirstNames.status"></td>
1033        <td class="help"><span id="existingAllFirstNames.message" class="message" style="display: none;"></span>Type all names, see FamilyName comment on valid characters.</td>
1034      </tr>
1035      <tr>
1036        <td class="prompt">Gender</td>
1037        <td class="input" id="existing.gender"></td>
1038        <td class="status"></td>
1039        <td class="help"></td>
1040      </tr>
1041      <tr>
1042        <td class="prompt">Date of birth</td>
1043        <td class="input" id="existing.dateOfBirth"></td>
1044        <td class="status"></td>
1045        <td class="help"></td>
1046      </tr>
1047      </table>
1048    </td>
1049  </tr>
1050  </table>
1051  </div>
1052
1053
1054  <!-- 3. Case registration -->
1055  <div id="caseSection" style="display: none;">
1056  <p>
1057  <table border="0" cellspacing="0" cellpadding="0" class="stepform">
1058  <tr>
1059    <td rowspan="2" class="stepno">3</td>
1060    <td class="steptitle" id="step3.title">Create new case</td>
1061  </tr>
1062  <tr>
1063    <td class="stepfields">
1064      <table border="0" cellspacing="0" cellpadding="0" width="100%">
1065      <tr valign="top">
1066        <td class="prompt" id="laterality.prompt">Laterality</td>
1067        <td class="input" id="laterality.input">
1068          <input type="radio" name="laterality" value="LEFT" id="lateralityLeft" onclick="lateralityOnChange()"><label for="lateralityLeft">LEFT</label><br>
1069          <input type="radio" name="laterality" value="RIGHT" id="lateralityRight" onclick="lateralityOnChange()"><label for="lateralityRight">RIGHT</label><br>
1070          <input type="radio" name="laterality" value="" checked id="lateralityUnknown" onclick="lateralityOnChange()"><i><label for="lateralityUnknown">unknown</label></i>
1071        </td>
1072        <td class="status" id="laterality.status"></td>
1073        <td class="help"><span id="laterality.message" class="message" style="display: none;"></span></td>
1074      </tr>
1075      <tr id="copyConsentSection" style="display: none;">
1076        <td class="prompt">Copy consent?</td>
1077        <td class="input">
1078          <input type="checkbox" name="copyConsent" id="copyConsent" value="" checked>
1079          <label for="copyConsent"><span id="copyConsent.text"></span></label>
1080        </td>
1081        <td class="status" id="copyConsent.status"></td>
1082        <td class="help"></td>
1083      </tr>
1084      <tr id="padSection" valign="top">
1085        <td class="prompt">PAD</td>
1086        <td class="input"><input type="text" name="pad" 
1087          value="" size="18" maxlength="12" 
1088          onkeypress="focusOnEnter(event, 'samplingDate')"
1089          onblur="padOnChange()"></td>
1090        <td class="status" id="pad.status"></td>
1091        <td class="help"><span id="pad.message" class="message" style="display: none;"></span></td>
1092      </tr>
1093      <tr valign="top">
1094        <td class="prompt">Specimen tubes</td>
1095        <td class="input" id="specimenTubes"><i>not found</i></td>
1096        <td class="status" id="specimenTubes.status"></td>
1097        <td class="help"><span id="specimenTubes.message" class="message" style="display: none;"></span>The specimen tube(s) associated with this case.</td>
1098      </tr>
1099      <tr id="samplingDateSection" valign="top">
1100        <td class="subprompt">Sampling date</td>
1101        <td class="input"><input type="text" name="samplingDate" value="" size="12" maxlength="10" 
1102            onkeypress="focusOnEnter(event, caseInfo.specimen && caseInfo.specimen.length > 0 ? 'samplingTime' : 'reasonIfNoSpecimen')" onblur="samplingDateTimeOnChange()">
1103          <span id="samplingTimeField">Time <input type="text" name="samplingTime" value="" size="6" maxlength="5" 
1104            onkeypress="focusOnEnter(event, caseInfo.specimen && caseInfo.specimen.length > 0 ? 'rnaLaterDate' : 'reasonIfNoSpecimen')" onblur="samplingDateTimeOnChange()"></span>
1105        </td>
1106        <td class="status" id="samplingDate.status"></td>
1107        <td class="help"><span id="samplingDate.message" class="message" style="display: none;"></span>Date (+time) of surgical removal (YYYYMMDD, HHMM)</td>
1108      </tr>
1109      <tr id="rnaLaterDateSection" valign="top">
1110        <td class="subprompt">RNA Later date</td>
1111        <td class="input"><input type="text" name="rnaLaterDate" value="" size="12" maxlength="10"
1112            onkeypress="focusOnEnter(event, 'rnaLaterTime')" onblur="rnaLaterDateTimeOnChange()">
1113          Time <input type="text" name="rnaLaterTime" value="" size="6" maxlength="5"
1114            onblur="rnaLaterDateTimeOnChange()"></td>
1115        <td class="status" id="rnaLaterDate.status"></td>
1116        <td class="help"><span id="rnaLaterDate.message" class="message" style="display: none;"></span>Date+time of pathology handling (YYYYMMDD, HHMM)</td>
1117      </tr>
1118      <tr id="reasonIfNoSpecimenSection" valign="top">
1119        <td class="subprompt">Reason if no specimen</td>
1120        <td class="input"><textarea rows="3" cols="30" name="reasonIfNoSpecimen" value=""></textarea></td>
1121        <td class="status"></td>
1122        <td class="help">Comment why there was no specimen tubes in the delivery.</td>
1123      </tr>
1124      </table>
1125    </td>
1126  </tr>
1127  </table>
1128  </div>
1129
1130  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
1131
1132  <div id="done" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
1133
1134  <table style="margin-left: 20px; margin-top: 10px;" class="navigation">
1135  <tr>
1136    <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;"/></td>
1137    <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)"/></td>
1138    <td><base:button id="gocreate" title="Create" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;"/></td>
1139    <td><base:button id="goupdate" title="Update" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;"/></td>
1140    <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
1141    <td id="gonext.message" class="message"></td>
1142  </tr>
1143  </table>
1144  </form>
1145  </div>
1146 
1147</base:body>
1148</base:page>
1149<%
1150}
1151finally
1152{
1153  if (dc != null) dc.close();
1154}
1155%>
Note: See TracBrowser for help on using the repository browser.