source: extensions/net.sf.basedb.reggie/branches/ticket-489/resources/sampleproc/histology_score.jsp @ 2124

Last change on this file since 2124 was 2124, checked in by Nicklas Nordborg, 8 years ago

References #489: Histology scoring wizard

Implemented 'Find HE glass', 'Select HE glass' and menu with uncompleted HE glass functions.

File size: 22.8 KB
Line 
1<%@ page
2  pageEncoding="UTF-8"
3  session="false"
4  import="net.sf.basedb.core.User"
5  import="net.sf.basedb.core.DbControl"
6  import="net.sf.basedb.core.SessionControl"
7  import="net.sf.basedb.core.Application"
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="java.text.SimpleDateFormat"
12  import="java.util.Date"
13%>
14<%@ taglib prefix="base" uri="/WEB-INF/base.tld" %>
15<%@ taglib prefix="p" uri="/WEB-INF/path.tld" %>
16<%@ taglib prefix="tbl" uri="/WEB-INF/table.tld" %>
17<%@ taglib prefix="t" uri="/WEB-INF/tab.tld" %>
18<%
19final SessionControl sc = Base.getExistingSessionControl(request, true);
20final String ID = sc.getId();
21final float scale = Base.getScale(sc);
22final String home = ExtensionsControl.getHomeUrl("net.sf.basedb.reggie");
23DbControl dc = null;
24try
25{
26  dc = sc.newDbControl();
27  final User user = User.getById(dc, sc.getLoggedInUserId());
28  final String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
29  final String name = request.getParameter("name");
30%>
31<base:page type="default" >
32<base:head scripts="ajax.js,tabcontrol.js" styles="path.css,toolbar.css,tabcontrol.css">
33  <link rel="stylesheet" type="text/css" href="../css/reggie.css">
34  <script language="JavaScript" src="../reggie.js" type="text/javascript" charset="UTF-8"></script>
35
36<script language="JavaScript">
37var debug = 1;
38var currentStep = 1;
39var selectedSample;
40var heGlass;
41
42function init()
43{
44  var frm = document.forms['reggie'];
45 
46  var glassName = '<%=HTML.javaScriptEncode(name)%>'
47  heGlass = getHeGlassForScoring(glassName);
48 
49  if (heGlass != null && heGlass.length > 0)
50  {
51    // Generate HE glass HTML
52    var html = '';
53    for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
54    {
55      var glass = heGlass[glassNo];
56      html += createHeGlassSection(glass);
57    }
58    setInnerHTML('he-glass-container', html);
59    Main.show('he-glass-container');
60   
61    // Fill form with know information
62    var firstGoodSample;
63    for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
64    {
65      var glass = heGlass[glassNo];
66      for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
67      {
68        var sample = glass.samples[sampleNo];
69       
70        // Save ID of HE glass since we need that later
71        sample.heGlassId = glass.id;
72       
73        // Save the first GoodStain sample so we can select it later
74        if (sample.GoodStain && firstGoodSample == null)
75        {
76          firstGoodSample = sample;
77        }
78       
79        // Calculate sum of scores
80        var total = calculateTotalScore(sample)
81       
82        // Generate text inside table cell
83        var html = sample.name.replace(/\.he\d+$/, '');
84        html += '<div class="progress" id="'+sample.id+'.progress">' + total + '%</div>';
85       
86        var td = document.getElementById(sample.heGlassId+'-'+sample.well.location);
87        td.innerHTML = html;
88        td.sample = sample;
89        setSampleClassName(sample);
90       
91        td.addEventListener('click', sampleOnClick, false);
92      }
93    }
94   
95    if (firstGoodSample != null)
96    {
97      selectSample(firstGoodSample);
98      Main.show('score-container');
99    }
100    Main.show('gocreate');
101  }
102  else
103  {
104    var msg;
105    if (glassName)
106    {
107      msg = 'Could not find HE glass with name: ' + Main.encodeTags(glassName);
108    }
109    else
110    {
111      msg = 'No HE glass available for scoring.';
112      msg += ' Specify HE glass name above to re-score.';
113    }
114    setInnerHTML('he-glass-container', '<div class="messagecontainer note">'+msg+'</div>');
115    Main.show('he-glass-container');
116  }
117 
118  // Wait a second until loading uncompleted HE glass
119  setTimeout(loadUncompletedHeGlass, 1000);
120}
121
122function findHeGlass(glassName)
123{
124  var frm = document.forms['reggie'];
125  if (!glassName)
126  {
127    glassName = frm.findGlassName.value;
128    if (glassName.match(/^\d+$/))
129    {
130      while (glassName.length < 5)
131      {
132        glassName = '0'+glassName;
133      }
134      glassName = 'HE'+glassName;
135    }
136  }
137  location.href = '<%=home%>/sampleproc/histology_score.jsp?ID=<%=ID%>&name='+encodeURIComponent(glassName);
138}
139
140function selectHeGlass()
141{
142  var url = getRoot() + 'biomaterials/bioplates/index.jsp?ID=<%=ID%>&cmd=UpdateContext&mode=selectone';
143  url += '&resetTemporary=1';
144  url += '&tmpfilter:STRING:name='+encodeURIComponent('HE%');
145  url += '&callback=setSelectedHeGlass'
146  Main.openPopup(url, 'SelectHeGlass', 1050, 700);
147}
148
149function setSelectedHeGlass(id, name)
150{
151  findHeGlass(name);
152}
153
154function getHeGlassForScoring(glassName)
155{
156  var frm = document.forms['reggie']; 
157  var request = Ajax.getXmlHttpRequest();
158  try
159  {
160    var msg = glassName ? 'Finding HE glass: '+Main.encodeTags(glassName) : 'Loading next HE glass for scoring...';
161    showLoadingAnimation(msg);
162    var url = '../Histology.servlet?ID=<%=ID%>&cmd=GetHeGlassToScore';
163    if (glassName)
164    {
165      url += '&name='+encodeURIComponent(glassName);
166    }
167    request.open("GET", url, false); 
168    request.send(null);
169  }
170  finally
171  {
172    hideLoadingAnimation();
173  }
174 
175  if (debug) Main.debug(request.responseText);
176  var response = JSON.parse(request.responseText); 
177  if (response.status != 'ok')
178  {
179    setFatalError(response.message);
180    return false;
181  }
182  return response.heGlasses;
183}
184
185
186function createHeGlassSection(glass)
187{
188  var html = '';
189  html += '<div class="he-glass">';
190 
191  html += '<div class="he-name">' + Main.encodeTags(glass.name || '') + '</div>';
192 
193  html += '<div class="he-info">';
194  html += '<span class="he-tray">' +  Main.encodeTags(glass.tray || '') + '</span>; <span class="he-position">' + Main.encodeTags(glass.position || '') + '</span>';
195  html += '<div class="he-comment">' + Main.encodeTags(glass.comments || '') + '</div>';
196  html += '</div>';
197 
198  html += '<table class="he-table">';
199  html += '<tr>';
200  html += '<td class="not-used" id="'+glass.id+'-A1"></td>';
201  html += '<td class="not-used" id="'+glass.id+'-A2"></td>';
202  html += '</tr>';
203  html += '<tr>';
204  html += '<td class="not-used" id="'+glass.id+'-B1"></td>';
205  html += '<td class="not-used" id="'+glass.id+'-B2"></td>';
206  html += '</tr>';
207  html += '<tr>';
208  html += '<td class="not-used" id="'+glass.id+'-C1"></td>';
209  html += '<td class="not-used" id="'+glass.id+'-C2"></td>';
210  html += '</tr>';
211  html += '</table>';
212  html += '</div>';
213
214  return html;
215 
216}
217
218function setSampleClassName(sample)
219{
220  var className = 'used';
221  if (sample.GoodStain)
222  {
223    className += ' good-stain';
224  }
225 
226  if (sample.ScoreTotal == 0)
227  {
228    className += ' score-none';
229  }
230  else if (sample.ScoreTotal != 100 || !sample.ScoreComplete)
231  {
232    className += ' score-incomplete';
233  }
234  else
235  {
236    className += ' score-complete';
237  }
238 
239  if (selectedSample && selectedSample.id == sample.id)
240  {
241    className += ' selected';
242  }
243 
244  var td = document.getElementById(sample.heGlassId+'-'+sample.well.location);
245  td.className = className;
246}
247
248function selectSample(sample)
249{
250  var frm = document.forms['reggie'];
251 
252  // Sample name
253  setInnerHTML('sample.name', sample.name);
254 
255  // Scores
256  frm.score_invasive_cancer.value = sample.ScoreInvasiveCancer;
257  frm.score_insitu_cancer.value = sample.ScoreInsituCancer;
258  frm.score_lymphocytes.value = sample.ScoreLymphocytes;
259  frm.score_normal.value = sample.ScoreNormal;
260  frm.score_stroma.value = sample.ScoreStroma;
261  frm.score_fat.value = sample.ScoreFat;
262 
263  // Total score + score complete
264  var total = calculateTotalScore(sample);
265  setInnerHTML('score_total', total);
266  if (total == 100)
267  {
268    frm.score_complete.disabled = false;
269    frm.score_complete.checked = sample.ScoreComplete;
270    setInputStatus('score_total', '', 'valid');
271  }
272  else
273  {
274    frm.score_complete.disabled = true;
275    frm.score_complete.checked = false;
276    setInputStatus('score_total', 'Not 100%', 'warning');
277  }
278 
279  // Good stain
280  if (sample.GoodStain)
281  {
282    frm.good_stain.checked = true;
283    frm.good_stain.disabled = true;
284  }
285  else
286  {
287    frm.good_stain.checked = false;
288    frm.good_stain.disabled = false;
289  }
290 
291  // Comments
292  frm.comments.value = sample.comments;
293 
294  // Class name of selected table cell
295  if (selectedSample != null)
296  {
297    var td = document.getElementById(selectedSample.heGlassId+'-'+selectedSample.well.location);
298    Main.removeClass(td, ' selected');
299  }
300 
301  selectedSample = sample;
302  setSampleClassName(sample);
303 
304  frm.score_invasive_cancer.focus();
305}
306
307function sampleOnClick(event)
308{
309  var td = event.currentTarget;
310  selectSample(td.sample);
311}
312
313function checkScores()
314{
315  var frm = document.forms['reggie'];
316
317  selectedSample.ScoreInvasiveCancer = toScore(frm.score_invasive_cancer.value);
318  selectedSample.ScoreInsituCancer = toScore(frm.score_insitu_cancer.value);
319  selectedSample.ScoreLymphocytes = toScore(frm.score_lymphocytes.value);
320  selectedSample.ScoreNormal = toScore(frm.score_normal.value);
321  selectedSample.ScoreStroma = toScore(frm.score_stroma.value);
322  selectedSample.ScoreFat = toScore(frm.score_fat.value);
323 
324  var oldTotal = selectedSample.ScoreTotal;
325  var total = calculateTotalScore(selectedSample);
326 
327  setInnerHTML('score_total', total);
328  setInnerHTML(selectedSample.id+'.progress', total + '%');
329 
330  if (total == 100)
331  {
332    frm.score_complete.disabled = false;
333    if (oldTotal != total)
334    {
335      // Only check the 'Score complete' if value has changed
336      frm.score_complete.checked = true;
337      selectedSample.ScoreComplete = true;
338    }
339    setInputStatus('score_total', '', 'valid');
340  }
341  else
342  {
343    frm.score_complete.disabled = true;
344    frm.score_complete.checked = false;
345    selectedSample.ScoreComplete = false;
346    setInputStatus('score_total', 'Not 100%', 'warning');
347  }
348
349  setSampleClassName(selectedSample);
350}
351
352function calculateTotalScore(sample)
353{
354  var total = sumScore(sample.ScoreInvasiveCancer);
355  total += sumScore(sample.ScoreInsituCancer);
356  total += sumScore(sample.ScoreLymphocytes);
357  total += sumScore(sample.ScoreNormal);
358  total += sumScore(sample.ScoreStroma);
359  total += sumScore(sample.ScoreFat);
360  sample.ScoreTotal = total;
361  return total;
362}
363
364function toScore(value)
365{
366  var score = parseInt(value);
367  return isNaN(score) ? null : score;
368}
369
370function sumScore(score)
371{
372  return score || 0;
373}
374
375function scoreCompleteOnClick()
376{
377  var frm = document.forms['reggie'];
378  selectedSample.ScoreComplete = frm.score_complete.checked;
379  setSampleClassName(selectedSample);
380}
381
382function goodStainOnClick()
383{
384  var frm = document.forms['reggie'];
385 
386  // Reset GoodStain on other samples on same location
387  for (var glassNo = 0; glassNo < heGlass.length; glassNo++)
388  {
389    var glass = heGlass[glassNo];
390   
391    for (var sampleNo = 0; sampleNo < glass.samples.length; sampleNo++)
392    {
393      var sample = glass.samples[sampleNo];
394      if (sample.well.location == selectedSample.well.location)
395      {
396        sample.GoodStain = false;
397        var td = document.getElementById(glass.id+'-'+sample.well.location);
398        Main.removeClass(td, 'good-stain');
399      }
400    }
401  }
402 
403  selectedSample.GoodStain = frm.good_stain.checked;
404  frm.good_stain.disabled = true;
405  setSampleClassName(selectedSample);
406}
407
408function commentsOnBlur()
409{
410  var frm = document.forms['reggie'];
411  selectedSample.comments = frm.comments.value;
412}
413
414function loadUncompletedHeGlass()
415{
416  var request = Ajax.getXmlHttpRequest();
417  try
418  {
419    //showLoadingAnimation('Loading next HE glass for scoring...');
420    var url = '../Histology.servlet?ID=<%=ID%>&cmd=GetUncompletedHeGlass';
421    request.open("GET", url, false); 
422    request.send(null);
423  }
424  finally
425  {
426    //hideLoadingAnimation();
427  }
428 
429  if (debug) Main.debug(request.responseText);
430  var response = JSON.parse(request.responseText); 
431  if (response.status == 'ok')
432  {
433    var uncompleted = response.heGlasses;
434   
435    if (uncompleted.length > 0)
436    {
437      // Populate menu item
438      setInnerHTML('uncompletedHeGlass.text', uncompleted.length + ' uncompleted');
439      var html = ''; 
440      for (var glassNo = 0; glassNo < uncompleted.length; glassNo++)
441      {
442        var glass = uncompleted[glassNo];
443     
444        html += '<div class="menuitem enabled" id="glass-'+glass.id+'">';
445        html += Main.encodeTags(glass.name)+'</div>';
446      }
447      setInnerHTML('select-uncompleted-heglass-menu', html);
448      Main.show('uncompletedHeGlass');
449    }
450    else
451    {
452      Main.hide('uncompletedHeGlass');
453    }
454  }
455}
456
457function showUncompletedHeGlassMenu(event)
458{
459  var menu = document.getElementById('select-uncompleted-heglass');
460  menu.style.display = 'block';
461 
462  var pos = Main.getElementPosition(document.getElementById('uncompletedHeGlass'));
463  var x = pos.left;
464  var y = pos.top+pos.height;
465
466  menu.style.left = (x)+'px';
467  menu.style.top = (y)+'px';
468  event.stopPropagation();
469}
470
471function uncompletedGlassSelected(event)
472{
473  findHeGlass(event.target.innerHTML);
474}
475</script>
476<style>
477
478/* Less wide to make more space for help text */
479.stepfields .input
480{
481  width: 200px;
482}
483
484input.score
485{
486  width: 6em;
487  text-align: right;
488  padding-right: 4px;
489}
490
491#he-glass-container
492{
493  white-space: nowrap;
494  overflow: auto;
495}
496
497.he-glass
498{
499  display: inline-block;
500  border: 1px solid #A0A0A0;
501  margin: 1em;
502  width: 20em;
503  background: #E8E8E8;
504}
505
506.he-name
507{
508  font-weight: bold;
509  background-color: #E0E0E0;
510  border-bottom: 1px solid #A0A0A0;
511  padding: 0.25em;
512}
513
514.he-info
515{
516  background-color: #FFFFFF;
517  border-bottom: 1px solid #A0A0A0;
518  padding: 0.25em;
519  height: 5em;
520  overflow: auto;
521  white-space: normal;
522}
523
524.he-tray:before
525{
526  content: 'Tray: ';
527}
528
529.he-position:before
530{
531  content: 'Position: ';
532}
533
534.he-comment
535{
536  font-style: italic;
537}
538
539
540#score-container
541{
542  clear: both;
543}
544
545.he-table
546{
547  margin-top: 1em;
548  margin-bottom: 1em;
549  margin-left: auto;
550  margin-right: auto;
551  border: 1px solid #A0A0A0;
552}
553
554.he-table td
555{
556  width: 10em;
557  height: 10em;
558  border: 1px solid #A0A0A0;
559  padding: 2px;
560  background: #FFFFFF;
561  background-position: center center;
562  background-repeat: no-repeat;
563  vertical-align: top;
564  text-align: center;
565  font-size: 75%;
566  color: #666666;
567  cursor: pointer;
568}
569
570.he-table td.used:hover
571{
572  border: 2px solid #2288AA;
573  border-radius: 4px;
574  padding: 1px;
575}
576
577.he-table td.not-used
578{
579  background-color: #D0D0D0;
580  background-image: url('../images/not-used.png');
581  cursor: default;
582}
583
584.he-table td.selected
585{
586  background-color: #D8FFFF;
587  border: 2px solid #2288AA;
588  border-radius: 4px;
589  padding: 1px;
590}
591
592.he-table td.good-stain
593{
594  font-weight: bold;
595  color: #000000;
596}
597
598.he-table td.good-stain.score-none
599{
600  background-image: url('../images/score-none.png');
601}
602
603.he-table td.good-stain.score-incomplete
604{
605  background-image: url('../images/score-incomplete.png');
606}
607
608.he-table td.good-stain.score-complete
609{
610  background-image: url('../images/score-complete.png');
611}
612
613/* Hide progress by default */
614.progress
615{
616  display: none;
617}
618
619/* Show progress for GoodStain or total score > 0 */
620td.good-stain .progress, td.score-incomplete .progress, td.score-complete .progress
621{
622  display: block;
623}
624
625td.score-incomplete .progress:before
626{
627  content: '(';
628}
629td.score-incomplete .progress:after
630{
631  content: ')';
632}
633
634.score-align
635{
636  width: 6em;
637  display: inline-block;
638  padding: 3px;
639  text-align: right;
640}
641
642#score_total
643{
644  background-color: #E8E8E8;
645  font-weight: bold;
646  padding-right: 6px;
647}
648
649#select-uncompleted-heglass-menu
650{
651  max-height: 20em;
652  overflow: auto;
653}
654
655#select-uncompleted-heglass .menuitem
656{
657  padding-left: 16px;
658}
659
660#select-uncompleted-heglass .menuitem:hover
661{
662  padding-left: 14px;
663  background-position: 0px 50%;
664}
665</style>
666
667</base:head>
668<base:body onload="init()">
669
670  <p:path><p:pathelement 
671    title="Reggie" href="<%="../index.jsp?ID="+ID%>" 
672    /><p:pathelement title="Register HE glass score" 
673    /></p:path>
674
675  <div class="content" onclick="Main.hide('select-uncompleted-heglass')">
676  <%
677  if (sc.getActiveProjectId() == 0)
678  {
679    %>
680    <div class="messagecontainer note" style="width: 950px; margin-left: 20px; margin-bottom: 20px; margin-right: 0px; font-weight: bold; color: #cc0000;">
681      No project has been selected. You may proceed with the registration but
682      created items will not be shared.
683    </div>
684    <%
685  }
686  %>
687 
688  <div id="select-uncompleted-heglass" class="menu vertical" style="width: 150px; display: none;"
689    onclick="uncompletedGlassSelected(event)">
690    <div id="select-uncompleted-heglass-menu"></div>
691  </div>
692 
693  <form name="reggie" onsubmit="return false;">
694 
695  <table class="stepform">
696  <tr>
697    <td rowspan="3" class="stepno">1</td>
698    <td class="steptitle">HE glass to score</td>
699  </tr>
700  <tr>
701    <td class="stepfields">
702      <tbl:toolbar subclass="bottomborder">
703        <tbl:label>
704        <input type="text" style="width: 12em;" name="findGlassName" 
705          placeholder="Find HE glass" title="Enter a full HE glass name or the last digits in the it's number before the dot"
706          onkeypress="if (event.keyCode==13 && this.value) findHeGlass()"
707          >
708          <base:icon image="<%=home+"/images/gonext.png"%>" onclick="findHeGlass()"></base:icon>
709        </tbl:label>
710       
711     
712        <tbl:button 
713          title="Select HE glass&hellip;" 
714          image="<%=home + "/images/microscope.png"%>" 
715          onclick="selectHeGlass()"
716          tooltip="Manually select a different HE glass"
717        />
718
719        <tbl:button
720          id="uncompletedHeGlass"
721          title="Loading..."
722          image="mini_scroll_down.png"
723          onclick="showUncompletedHeGlassMenu(event)"
724          tooltip="This list contain HE glass with partial scores"
725        />
726
727      </tbl:toolbar>
728     
729      <div id="he-glass-container" style="display: none;">
730       
731      </div>
732
733      <div id="score-container" style="display: none;">
734        <table style="border-collapse: collapse; width: 100%;">
735        <tr valign="top" style="background-color: #E8E8E8; border-top: 1px solid #A0A0A0; border-bottom: 1px solid #A0A0A0;">
736          <td class="prompt" style="padding: 0.25em;">Sample</td>
737          <td class="input" id="sample.name" style="padding: 0.25em; font-weight: bold;"></td>
738          <td class="status"></td>
739          <td class="help"></td>
740        </tr>
741       
742        <tr>
743          <td class="prompt">GoodStain</td>
744          <td class="input"><span class="score-align"><input type="checkbox" name="good_stain" onclick="goodStainOnClick()"
745            title="Mark this checkbox to overtake the GoodStain annotation"
746            ></span></td>
747          <td class="status" id="good_stain.status"></td>
748          <td class="help" rowspan="2">
749            Check to overtake the GoodStain annotation.
750            Disabled if this sample is already annotated.
751          </td>
752        </tr>
753       
754        <tr>
755          <td class="prompt">Scores</td>
756          <td class="input"></td>
757          <td class="status"></td>
758        </tr>
759        <tr>
760          <td class="subprompt">Invasive cancer</td>
761          <td class="input"><input type="text" class="score" name="score_invasive_cancer"
762            onkeypress="focusOnEnter(event, 'score_insitu_cancer'); return Numbers.integerOnly(event)"
763            onblur="checkScores()"
764            >%</td>
765          <td class="status" id="score_invasive_cancer.status"></td>
766          <td class="help" rowspan="2">
767            Enter the percentage for each cell type.
768            They must sum up to 100% before scoring can be compeleted.
769          </td>
770        </tr>   
771
772        <tr>
773          <td class="subprompt">In situ cancer</td>
774          <td class="input"><input type="text" class="score" name="score_insitu_cancer"
775            onkeypress="focusOnEnter(event, 'score_lymphocytes'); return Numbers.integerOnly(event)"
776            onblur="checkScores()"
777            >%</td>
778          <td class="status" id="score_insitu_cancer.status"></td>
779        </tr>   
780        <tr>
781          <td class="subprompt">Lymphocytes</td>
782          <td class="input"><input type="text" class="score" name="score_lymphocytes"
783            onkeypress="focusOnEnter(event, 'score_normal'); return Numbers.integerOnly(event)"
784            onblur="checkScores()"
785            >%</td>
786          <td class="status" id="score_lymphocytes.status"></td>
787          <td class="help"></td>
788        </tr>   
789        <tr>
790          <td class="subprompt">Normal</td>
791          <td class="input"><input type="text" class="score" name="score_normal"
792            onkeypress="focusOnEnter(event, 'score_stroma'); return Numbers.integerOnly(event)"
793            onblur="checkScores()"
794            >%</td>
795          <td class="status" id="score_normal.status"></td>
796          <td class="help"></td>
797        </tr>   
798        <tr>
799          <td class="subprompt">Stroma</td>
800          <td class="input"><input type="text" class="score" name="score_stroma"
801            onkeypress="focusOnEnter(event, 'score_fat'); return Numbers.integerOnly(event)"
802            onblur="checkScores()"
803            >%</td>
804          <td class="status" id="score_stroma.status"></td>
805          <td class="help"></td>
806        </tr>   
807        <tr>
808          <td class="subprompt">Fat</td>
809          <td class="input"><input type="text" class="score" name="score_fat"
810            onkeypress="focusOnEnter(event, 'comments'); return Numbers.integerOnly(event)"
811            onblur="checkScores()"
812            >%</td>
813          <td class="status" id="score_fat.status"></td>
814          <td class="help"></td>
815        </tr>
816        <tr>
817          <td class="subprompt" style="font-weight: bold; background-color: #E8E8E8;">Total</td>
818          <td class="input" style="padding: 0;"><span class="score-align" id="score_total"></span>%</td>
819          <td class="status" id="score_total.status"></td>
820          <td class="help"><span class="message" id="score_total.message"></span></td>
821        </tr>
822       
823        <tr>
824          <td class="subprompt">Score complete</td>
825          <td class="input"><span class="score-align"><input type="checkbox" name="score_complete" 
826            onclick="scoreCompleteOnClick()"
827            title="Uncheck if scoring is not complete"></span></td>
828          <td class="status" id="score_complete.status"></td>
829          <td class="help">Uncheck
830            if scoring is not complete. Disabled if the total score is not 100%.
831          </td>
832        </tr>
833       
834        <tr>
835          <td class="prompt" colspan="3">Comments<br>
836            <textarea rows="3" style="width: 97%;" name="comments" onblur="commentsOnBlur()"></textarea>
837          </td>
838          <td class="help"></td>
839        </tr>
840        </table>
841      </div>   
842
843    </td>
844  </tr>
845  </table>
846 
847
848  <div class="loading" id="loading" style="display: none;"><table><tr><td><img src="../images/loading.gif"></td><td id="loading.msg">Please wait...</td></tr></table></div>
849 
850  <div class="messagecontainer error" id="errorMessage" style="display: none; width: 950px; margin-left: 20px; margin-bottom: 0px;"></div>
851 
852  <div id="done" class="success" style="display: none; width: 950px; margin-left: 20px; margin-top: 20px;"></div>
853 
854  <table style="margin-left: 20px; margin-top: 10px;" class="navigation" id="navigation">
855    <tr>
856      <td><base:button id="gocancel" title="Cancel" onclick="goRestart(false)" style="display: none;" /></td>
857      <td><base:button id="gonext" title="Next" image="<%=home+"/images/gonext.png"%>" onclick="goNext(true)" style="display: none;" /></td>
858      <td><base:button id="gocreate" title="Save" image="<%=home+"/images/gonext.png"%>" onclick="goCreate()" style="display: none;" /></td>
859      <td><base:button id="gorestart" title="Restart" image="<%=home+"/images/goback.png"%>" onclick="goRestart(true)" style="display: none;"/></td>
860      <td id="gonext.message" class="message"></td>
861    </tr>
862  </table>
863  </form>
864  </div>
865 
866</base:body>
867</base:page>
868<%
869}
870finally
871{
872  if (dc != null) dc.close();
873}
874%>
Note: See TracBrowser for help on using the repository browser.