2 // Copyright (C) 2006-2011 Rod Roark <rod@sunsetsystems.com>
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 include_once(dirname(__FILE__
) . '/api.inc');
10 include_once(dirname(__FILE__
) . '/forms.inc');
11 include_once(dirname(__FILE__
) . '/../interface/forms/fee_sheet/codes.php');
22 // encode a string from a form field for database writing.
23 function form2db($fldval) {
24 $fldval = trim($fldval);
25 if (!get_magic_quotes_gpc()) $fldval = addslashes($fldval);
29 // encode a plain string for database writing.
30 function real2db($fldval) {
31 return addslashes($fldval);
34 // Get the actual string from a form field.
35 function form2real($fldval) {
36 $fldval = trim($fldval);
37 if (get_magic_quotes_gpc()) $fldval = stripslashes($fldval);
41 // encode a plain string for html display.
42 function real2form($fldval) {
43 return htmlspecialchars($fldval, ENT_QUOTES
);
46 if (empty($spreadsheet_title)) $spreadsheet_title = 'Injury Log';
48 // Putting an error message in here will result in a javascript alert.
51 // If we are invoked as a popup (not in an encounter):
52 $popup = $_GET['popup'];
54 // The form ID is passed to us when an existing encounter form is loaded.
55 $formid = $_GET['id'];
57 // $tempid is the currently selected template, if any.
58 $tempid = $_POST['form_template'] +
0;
60 // This is the start date to be saved with the spreadsheet.
63 $form_completed = '0';
65 if (!$popup && !$encounter) { // $encounter comes from globals.php
66 die("Internal error: we do not seem to be in an encounter!");
69 // Get the name of the template selected by the dropdown, if any;
70 // or if we are loading a form then it comes from that.
73 $trow = sqlQuery("SELECT value FROM form_$spreadsheet_form_name WHERE " .
74 "id = $tempid AND rownbr = -1 AND colnbr = -1");
75 $template_name = $trow['value'];
78 $trow = sqlQuery("SELECT value FROM form_$spreadsheet_form_name WHERE " .
79 "id = $formid AND rownbr = -1 AND colnbr = -1");
80 list($form_completed, $start_date, $template_name) = explode('|', $trow['value'], 3);
83 if (!$start_date) $start_date = form2real($_POST['form_start_date']);
85 // Used rows and columns are those beyond which there are only unused cells.
89 // If we are saving...
91 if ($_POST['bn_save_form'] ||
$_POST['bn_save_template']) {
93 // The form data determines how many rows and columns are now used.
94 $cells = $_POST['cell'];
95 for ($i = 0; $i < count($cells); ++
$i) {
97 for ($j = 0; $j < count($row); ++
$j) {
98 if (substr($row[$j], 0, 1)) {
99 if ($i >= $num_used_rows) $num_used_rows = $i +
1;
100 if ($j >= $num_used_cols) $num_used_cols = $j +
1;
105 if ($_POST['bn_save_form']) {
106 $form_completed = $_POST['form_completed'] ?
'1' : '0';
108 // If updating an existing form...
110 sqlStatement("UPDATE form_$spreadsheet_form_name SET " .
111 "value = '$form_completed|$start_date|$template_name' " .
112 "WHERE id = '$formid' AND rownbr = -1 AND colnbr = -1");
113 sqlStatement("DELETE FROM form_$spreadsheet_form_name WHERE " .
114 "id = '$formid' AND rownbr >= 0 AND colnbr >= 0");
116 // If adding a new form...
118 sqlStatement("LOCK TABLES form_$spreadsheet_form_name WRITE, log WRITE");
119 $tmprow = sqlQuery("SELECT MAX(id) AS maxid FROM form_$spreadsheet_form_name");
120 $formid = $tmprow['maxid'] +
1;
121 if ($formid <= 0) $formid = 1;
122 sqlInsert("INSERT INTO form_$spreadsheet_form_name ( " .
123 "id, rownbr, colnbr, datatype, value " .
125 "$formid, -1, -1, 0, " .
126 "'$form_completed|$start_date|$template_name' " .
128 sqlStatement("UNLOCK TABLES");
129 addForm($encounter, $spreadsheet_title, $formid, "$spreadsheet_form_name",
130 $pid, $userauthorized);
134 else { // saving a template
135 // The rule is, we can update the original name, or insert a new name
136 // which must not match any existing template name.
137 $new_template_name = form2real($_POST['form_new_template_name']);
138 if ($new_template_name != $template_name) {
139 $trow = sqlQuery("SELECT id FROM form_$spreadsheet_form_name WHERE " .
140 "id < 0 AND rownbr = -1 AND colnbr = -1 AND value = '" .
141 real2db($new_template_name) . "'");
143 $alertmsg = "Template \"" . real2form($new_template_name) .
144 "\" already exists!";
147 $tempid = 0; // to force insert of new template
148 $template_name = $new_template_name;
152 // If updating an existing template...
154 sqlStatement("DELETE FROM form_$spreadsheet_form_name WHERE " .
155 "id = '$tempid' AND rownbr >= 0 AND colnbr >= 0");
157 // If adding a new template...
159 sqlStatement("LOCK TABLES form_$spreadsheet_form_name WRITE, log WRITE");
160 $tmprow = sqlQuery("SELECT MIN(id) AS minid FROM form_$spreadsheet_form_name");
161 $tempid = $tmprow['minid'] - 1;
162 if ($tempid >= 0) $tempid = -1;
163 sqlInsert("INSERT INTO form_$spreadsheet_form_name ( " .
164 "id, rownbr, colnbr, datatype, value " .
166 "$tempid, -1, -1, 0, " .
167 "'" . real2db($template_name) . "' " .
169 sqlStatement("UNLOCK TABLES");
176 // Finally, save the table cells.
177 for ($i = 0; $i < $num_used_rows; ++
$i) {
178 for ($j = 0; $j < $num_used_cols; ++
$j) {
179 $tmp = $cells[$i][$j];
180 $celltype = substr($tmp, 0, 1) +
0;
181 $cellvalue = form2db(substr($tmp, 1));
183 sqlInsert("INSERT INTO form_$spreadsheet_form_name ( " .
184 "id, rownbr, colnbr, datatype, value " .
186 "$saveid, $i, $j, $celltype, '$cellvalue' )");
192 else if ($_POST['bn_delete_template'] && $tempid) {
193 sqlStatement("DELETE FROM form_$spreadsheet_form_name WHERE " .
199 if ($_POST['bn_save_form'] && !$alertmsg && !$popup) {
200 formHeader("Redirecting....");
206 // If we get here then we are displaying a spreadsheet, either a template or
207 // an encounter form.
209 // Get the array of template names.
210 $tres = sqlStatement("SELECT id, value FROM form_$spreadsheet_form_name WHERE " .
211 "id < 0 AND rownbr = -1 AND colnbr = -1 ORDER BY value");
215 # If we are reloading a form, get it.
217 $dres = sqlStatement("SELECT * FROM form_$spreadsheet_form_name WHERE " .
218 "id = '$formid' ORDER BY rownbr, colnbr");
219 $tmprow = sqlQuery("SELECT MAX(rownbr) AS rowmax, MAX(colnbr) AS colmax " .
220 "FROM form_$spreadsheet_form_name WHERE id = '$formid'");
221 $num_used_rows = $tmprow['rowmax'] +
1;
222 $num_used_cols = $tmprow['colmax'] +
1;
224 # Otherwise if we are editing a template, get it.
226 $dres = sqlStatement("SELECT * FROM form_$spreadsheet_form_name WHERE " .
227 "id = '$tempid' ORDER BY rownbr, colnbr");
228 $tmprow = sqlQuery("SELECT MAX(rownbr) AS rowmax, MAX(colnbr) AS colmax " .
229 "FROM form_$spreadsheet_form_name WHERE id = '$tempid'");
230 $num_used_rows = $tmprow['rowmax'] +
1;
231 $num_used_cols = $tmprow['colmax'] +
1;
234 // Virtual rows and columns are those available when in Edit Structure mode,
235 // and include some additional ones beyond those used. This allows quite a
236 // lot of stuff to be entered before having to save the template.
237 $num_virtual_rows = $num_used_rows ?
$num_used_rows +
5 : 10;
238 $num_virtual_cols = $num_used_cols ?
$num_used_cols +
5 : 10;
242 <?php
html_header_show();?
>
243 <link rel
="stylesheet" href
="<?php echo $css_header;?>" type
="text/css">
244 <style type
="text/css">@import
url(../../../library
/dynarch_calendar
.css
);</style
>
247 font
-family
: sans
-serif
;
252 font
-family
: sans
-serif
;
255 background
-color
: transparent
;
258 font
-family
: sans
-serif
;
261 background
-color
: transparent
;
264 font
-family
: sans
-serif
;
267 background
-color
: transparent
;
275 <script type
="text/javascript" src
="../../../library/textformat.js"></script
>
276 <script type
="text/javascript" src
="../../../library/dynarch_calendar.js"></script
>
277 <script type
="text/javascript" src
="../../../library/dynarch_calendar_en.js"></script
>
278 <script type
="text/javascript" src
="../../../library/dynarch_calendar_setup.js"></script
>
280 <script language
="JavaScript">
281 var mypcc
= '<?php echo $GLOBALS['phone_country_code
']; ?>';
282 var ssChanged
= false; // if they have changed anything in the spreadsheet
283 var startDate
= '<?php echo $start_date ? $start_date : date('Y
-m
-d
'); ?>';
285 // Helper function to set the contents of a block.
286 function setBlockContent(id
, content
) {
287 if (document
.getElementById
) {
288 var x
= document
.getElementById(id
);
290 x
.innerHTML
= content
;
292 else if (document
.all
) {
293 var x
= document
.all
[id
];
294 x
.innerHTML
= content
;
296 // alert("ID = \"" + id + "\", string = \"" + content + "\"");
299 // Called when a different template name is selected.
300 function newTemplate(sel
) {
301 if (ssChanged
&& !confirm('You have made changes that will be discarded ' +
302 'if you select a new template. Do you really want to do this?'))
304 // Restore the original template selection.
305 for (var i
= 0; i
< sel
.options
.length
; ++i
) {
306 if (sel
.options
[i
].value
== '<?php echo $tempid ?>') {
307 sel
.options
[i
].selected
= true;
312 top
.restoreSession();
313 document
.forms
[0].submit();
316 // Called when the Cancel button is clicked.
317 function doCancel() {
318 if (!ssChanged ||
confirm('You have made changes that will be discarded ' +
319 'if you close now. Click OK if you really want to exit this form.'))
321 <?php
if ($popup) { ?
>
324 top
.restoreSession();
325 location
='<?php echo $GLOBALS['form_exit_url
'] ?>';
330 // Called when the Edit Structure checkbox is clicked.
331 function editChanged() {
332 var f
= document
.forms
[0];
333 var newdisplay
= f
.form_edit_template
.checked ?
'' : 'none';
336 for (var i
= 0; i
< <?php
echo $num_virtual_rows; ?
>; ++i
) {
337 for (var j
= 0; j
< <?php
echo $num_virtual_cols; ?
>; ++j
) {
338 if (f
['cell['+i+
']['+j+
']'].value
.charAt(0) != '0') {
339 if (i
>= usedrows
) usedrows
= i +
1;
340 if (j
>= usedcols
) usedcols
= j +
1;
344 for (var i
= 0; i
< <?php
echo $num_virtual_rows; ?
>; ++i
) {
345 for (var j
= 0; j
< <?php
echo $num_virtual_cols; ?
>; ++j
) {
346 // document.getElementById('div_'+i+'_'+j).style.display = newdisplay;
347 document
.getElementById('sel_'+i+
'_'+j
).style
.display
= newdisplay
;
348 if (i
>= usedrows || j
>= usedcols
) {
349 document
.getElementById('td_'+i+
'_'+j
).style
.display
= newdisplay
;
355 // Prepare a string for use as an HTML value attribute in single quotes.
356 function escQuotes(s
) {
357 return s
.replace(/'/g, "'");
360 // Parse static text to evaluate possible functions.
361 function genStatic(s) {
365 while ((i = s.indexOf('%day
(')) >= 0) {
366 var s1 = s.substring(0, i);
368 var j = s.indexOf(')', i);
370 var dayinc = parseInt(s.substring(i,j));
371 var mydate = new Date(parseInt(startDate.substring(0,4)),
372 parseInt(startDate.substring(5,7))-1, parseInt(startDate.substring(8)));
373 mydate.setTime(1000 * 60 * 60 * 24 * dayinc + mydate.getTime());
374 var year = mydate.getYear(); if (year < 1900) year += 1900;
375 s = s1 + year + '-' +
376 ('' + (mydate.getMonth() + 101)).substring(1) + '-' +
377 ('' + (mydate.getDate() + 100)).substring(1) +
381 // Parse "%sel(first,second,third,...,default)".
382 while ((i = s.indexOf('%sel
(')) >= 0) {
383 var s1 = s.substring(0, i);
385 var j = s.indexOf(')', i);
387 var x = s.substring(0,j);
388 var k = x.lastIndexOf(',');
390 var dflt = s.substring(k+1, j);
391 x = "<select class='selgen
' onchange='newsel(this
)'>";
392 while ((k = s.indexOf(',', i)) > i) {
394 var elem = s.substring(i,k);
395 x += "<option value='" + elem + "'";
396 if (elem == dflt) x += " selected";
397 x += ">" + elem + "</option>";
401 s = s1 + x + s.substring(j + 1);
402 break; // only one %sel allowed
405 // Parse "%ptp(default)".
406 while ((i = s.indexOf('%ptp
(')) >= 0) {
407 var s1 = s.substring(0, i);
409 var j = s.indexOf(')', i);
411 var dflt = s.substring(i, j);
412 x = "<select class='selgen
' onchange='newptp(this
)'>";
413 x += "<option value=''>-- Select --</option>";
415 foreach ($bcodes['Phys
']['Physiotherapy Procedures
'] as $key => $value) {
416 echo " x += \"<option value='$key'\";\n";
417 echo " if (dflt == '$key') x += ' selected
';\n";
418 echo " x += '>$value</option
>';\n";
422 s = s1 + x + s.substring(j + 1);
423 break; // only one %ptp allowed
429 // Called when a cell type selector in the spreadsheet is clicked.
430 function newType(i,j) {
432 var f = document.forms[0];
433 var typeval = f['cell
['+i+']['+j+']'].value;
434 var thevalue = typeval.substring(1);
435 var thetype = document.getElementById('sel_
'+i+'_
'+j).value;
436 var s = "<input type='hidden
' name='cell
[" + i + "][" + j + "]' " +
437 "value='" + thetype + escQuotes(thevalue) + "' />";
439 if (thetype == '1') {
440 s += genStatic(thevalue);
442 else if (thetype == '2') {
443 s += "<input type='checkbox
' value='1' onclick='cbClick(this
," + i + "," + j + ")'";
444 if (thevalue) s += " checked";
447 else if (thetype == '3') {
448 s += "<input type='text
' onchange='textChange(this
," + i + "," + j + ")'" +
449 " class='intext
' value='" + escQuotes(thevalue) + "' size='12' />";
451 else if (thetype == '4') {
452 s += "<textarea rows='3' cols='25' wrap='virtual
' class='intext
' " +
453 "onchange='longChange(this
," + i + "," + j + ")'>" +
454 escQuotes(thevalue) + "</textarea>";
456 setBlockContent('vis_
' + i + '_
' + j, s);
459 // Called when a checkbox in the spreadsheet is clicked.
460 function cbClick(elem,i,j) {
462 var f = document.forms[0];
463 var cell = f['cell
['+i+']['+j+']'];
464 cell.value = '2' + (elem.checked ? '1' : '');
467 // Called when a text value in the spreadsheet is changed.
468 function textChange(elem,i,j) {
470 var f = document.forms[0];
471 var cell = f['cell
['+i+']['+j+']'];
472 cell.value = '3' + elem.value;
475 // Called when a textarea value in the spreadsheet is changed.
476 function longChange(elem,i,j) {
478 var f = document.forms[0];
479 var cell = f['cell
['+i+']['+j+']'];
480 cell.value = '4' + elem.value;
483 // Helper function to get the value element of a table cell given any
484 // other element within that cell.
485 function getHidden(sel) {
486 var p = sel.parentNode;
487 while (p.tagName != 'TD
') {
488 if (!p.parentNode || p.parentNode == p) {
489 alert("JavaScript error, cannot find TD element");
494 // Get the <input type=hidden> element within this table cell.
495 var f = document.forms[0];
496 var s = p.id.substring(3);
497 var uix = s.indexOf('_
');
498 var i = s.substring(0, uix);
499 var j = s.substring(uix+1);
500 return f['cell
[' + i + '][' + j + ']'];
503 // Called when a user-defined select list has a new selection.
504 // This rewrites the function definition for the select list.
505 function newsel(sel) {
506 var inelem = getHidden(sel);
507 var s = inelem.value;
508 var i = s.indexOf('%sel
(');
509 var j = s.indexOf(')', i);
510 var x = s.substring(0, j);
511 var k = x.lastIndexOf(',');
512 inelem.value = s.substring(0, k+1) + sel.value + s.substring(j);
515 // Called when a physiotherapy select list has a new selection.
516 // This rewrites the function definition for the select list.
517 function newptp(sel) {
518 var inelem = getHidden(sel);
519 var s = inelem.value;
520 var i = s.indexOf('%ptp
(') + 5;
521 var j = s.indexOf(')', i);
522 inelem.value = s.substring(0, i) + sel.value + s.substring(j);
529 <body class="body_top">
530 <form method="post" action="<?php echo "$rootdir/forms/$spreadsheet_form_name/new.php?id=$formid"; if ($popup) echo '&popup
=1'; ?>"
531 onsubmit="return top.restoreSession()">
534 <table border='0' cellpadding='5' cellspacing='0' style='margin
:8pt
'>
535 <tr bgcolor='#ddddff'>
537 <?php
xl('Start Date','e'); ?
>:
538 <input type
='text' name
='form_start_date' id
='form_start_date'
539 size
='10' value
='<?php echo $start_date; ?>'
540 onkeyup
='datekeyup(this,mypcc)' onblur
='dateblur(this,mypcc)' title
='yyyy-mm-dd'
541 <?php
if ($formid && $start_date) echo 'disabled '; ?
>/>
542 <?php
if (!$formid ||
!$start_date) { ?
>
543 <img src
='../../pic/show_calendar.gif' align
='absbottom' width
='24' height
='22'
544 id
='img_start_date' border
='0' alt
='[?]' style
='cursor:pointer'
545 title
='Click here to choose a date'>
548 <?php
xl('Template:','e') ?
>
549 <select name
='form_template' onchange
='newTemplate(this)'<?php
if ($formid) echo ' disabled'; ?
>>
550 <option value
='0'>-- Select
--</option
>
552 while ($trow = sqlFetchArray($tres)) {
553 echo " <option value='" . $trow['id'] . "'";
554 if ($tempid && $tempid == $trow['id'] ||
555 $formid && $template_name == $trow['value'])
559 echo ">" . $trow['value'] . "</option>\n";
564 <input type
='checkbox' name
='form_edit_template'
565 onclick
='editChanged()'
566 title
='<?php xl("If you want to change data types, or add rows or columns","e") ?>' />
567 <?php
xl('Edit Structure','e') ?
>
568 <?php
if ($formid) { ?
>
570 <input type
='checkbox' name
='form_completed'
571 title
='<?php xl("If all data for all columns are complete for this form","e") ?>'
572 <?php
if ($form_completed) echo 'checked '; ?
>/>
573 <?php
xl('Completed','e') ?
>
579 <table border
='1' cellpadding
='2' cellspacing
='0' class='sstable'>
581 if ($dres) $drow = sqlFetchArray($dres);
582 $typeprompts = array('unused','static','checkbox','text');
584 for ($i = 0; $i < $num_virtual_rows; ++
$i) {
586 for ($j = 0; $j < $num_virtual_cols; ++
$j) {
588 // Match up with the database for cell type and value.
592 while ($drow && $drow['rownbr'] < $i)
593 $drow = sqlFetchArray($dres);
594 while ($drow && $drow['rownbr'] == $i && $drow['colnbr'] < $j)
595 $drow = sqlFetchArray($dres);
596 if ($drow && $drow['rownbr'] == $i && $drow['colnbr'] == $j) {
597 $celltype = $drow['datatype'];
598 $cellvalue = real2form($drow['value']);
599 $cellstatic = addslashes($drow['value']);
603 echo " <td id='td_${i}_${j}' valign='top'";
604 if ($i >= $num_used_rows ||
$j >= $num_used_cols)
605 echo " style='display:none'";
608 /*****************************************************************
609 echo "<span id='div_${i}_${j}' ";
610 echo "style='float:right;cursor:pointer;display:none' ";
611 echo "onclick='newType($i,$j)'>[";
612 echo $typeprompts[$celltype];
614 *****************************************************************/
615 echo "<div class='seldiv'>";
616 echo "<select id='sel_${i}_${j}' class='seltype' style='display:none' " .
617 "onchange='newType($i,$j)'>";
618 foreach ($celltypes as $key => $value) {
619 echo "<option value='$key'";
620 if ($key == $celltype) echo " selected";
621 echo ">$value</option>";
625 /****************************************************************/
627 echo "<span id='vis_${i}_${j}'>"; // new //
629 echo "<input type='hidden' name='cell[$i][$j]' value='$celltype$cellvalue' />";
630 if ($celltype == '1') {
631 // So we don't have to write a PHP version of genStatic():
632 echo "<script language='JavaScript'>document.write(genStatic('$cellstatic'));</script>";
634 else if ($celltype == '2') {
635 echo "<input type='checkbox' value='1' onclick='cbClick(this,$i,$j)'";
636 if ($cellvalue) echo " checked";
639 else if ($celltype == '3') {
640 echo "<input type='text' class='intext' onchange='textChange(this,$i,$j)'";
641 echo " value='$cellvalue'";
642 echo " size='12' />";
644 else if ($celltype == '4') {
645 echo "<textarea rows='3' cols='25' wrap='virtual' class='intext' " .
646 "onchange='longChange(this,$i,$j)'>";
651 echo "</span>"; // new //
661 <input type
='submit' name
='bn_save_form' value
='Save Form' />
662 <?php
if (!$formid) { ?
>
664 <input type
='submit' name
='bn_save_template' value
='Save as Template:' />
666 <input type
='text' name
='form_new_template_name' value
='<?php echo $template_name ?>' />
668 <input type
='submit' name
='bn_delete_template' value
='Delete Template' />
671 <input type
='button' value
='Cancel' onclick
="doCancel()" />
676 <script language
='JavaScript'>
677 Calendar
.setup({inputField
:"form_start_date", ifFormat
:"%Y-%m-%d", button
:"img_start_date"});
679 if ($alertmsg) echo " alert('$alertmsg');\n";