6 * @link http://www.open-emr.org
7 * @author Rod Roark <rod@sunsetsystems.com>
8 * @author Brady Miller <brady.g.miller@gmail.com>
9 * @copyright Copyright (c) 2006-2011 Rod Roark <rod@sunsetsystems.com>
10 * @copyright Copyright (c) 2017 Brady Miller <brady.g.miller@gmail.com>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 require_once(dirname(__FILE__
) . '/api.inc');
15 require_once(dirname(__FILE__
) . '/forms.inc');
16 require_once(dirname(__FILE__
) . '/../interface/forms/fee_sheet/codes.php');
27 // encode a string from a form field for database writing.
28 function form2db($fldval)
30 $fldval = trim($fldval);
34 // Get the actual string from a form field.
35 function form2real($fldval)
37 $fldval = trim($fldval);
41 // encode a plain string for html display.
42 function real2form($fldval)
44 return htmlspecialchars($fldval, ENT_QUOTES
);
47 if (empty($spreadsheet_title)) {
48 $spreadsheet_title = 'Injury Log';
51 // Putting an error message in here will result in a javascript alert.
54 // Determine the encounter that we are working with.
55 $thisenc = empty($_GET['thisenc']) ?
$encounter : $_GET['thisenc'] +
0;
57 // If we are invoked as a popup (not in an encounter):
58 $popup = $_GET['popup'];
60 // The form ID is passed to us when an existing encounter form is loaded.
61 $formid = $_GET['id'];
63 // $tempid is the currently selected template, if any.
64 $tempid = $_POST['form_template'] +
0;
66 // This is the start date to be saved with the spreadsheet.
69 $form_completed = '0';
71 if (!$popup && !$encounter) { // $encounter comes from globals.php
72 die("Internal error: we do not seem to be in an encounter!");
75 // Get the name of the template selected by the dropdown, if any;
76 // or if we are loading a form then it comes from that.
79 $trow = sqlQuery("SELECT value FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
80 " WHERE id = ? AND rownbr = -1 AND colnbr = -1", array($tempid));
81 $template_name = $trow['value'];
83 $trow = sqlQuery("SELECT value FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
84 " WHERE id = ? AND rownbr = -1 AND colnbr = -1", array($formid));
85 list($form_completed, $start_date, $template_name) = explode('|', $trow['value'], 3);
89 $start_date = form2real($_POST['form_start_date']);
92 // Used rows and columns are those beyond which there are only unused cells.
96 // If we are saving...
98 if ($_POST['bn_save_form'] ||
$_POST['bn_save_template']) {
99 // The form data determines how many rows and columns are now used.
100 $cells = $_POST['cell'];
101 for ($i = 0; $i < count($cells); ++
$i) {
103 for ($j = 0; $j < count($row); ++
$j) {
104 if (substr($row[$j], 0, 1)) {
105 if ($i >= $num_used_rows) {
106 $num_used_rows = $i +
1;
109 if ($j >= $num_used_cols) {
110 $num_used_cols = $j +
1;
116 if ($_POST['bn_save_form']) {
117 $form_completed = $_POST['form_completed'] ?
'1' : '0';
119 // If updating an existing form...
122 "UPDATE " . escape_table_name('form_' . $spreadsheet_form_name) .
123 " SET value = ? WHERE id = ? AND rownbr = -1 AND colnbr = -1",
125 $form_completed . '|' . $start_date . '|' . $template_name,
130 "DELETE FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
131 " WHERE id = ? AND rownbr >= 0 AND colnbr >= 0",
134 } // If adding a new form...
137 "SELECT pid FROM form_encounter WHERE encounter = ? ORDER BY id DESC LIMIT 1",
140 $thispid = $tmprow['pid'];
142 "LOCK TABLES " . escape_table_name('form_' . $spreadsheet_form_name) .
145 $tmprow = sqlQuery("SELECT MAX(id) AS maxid FROM " .
146 escape_table_name('form_' . $spreadsheet_form_name));
147 $formid = $tmprow['maxid'] +
1;
153 "INSERT INTO " . escape_table_name('form_' .$spreadsheet_form_name) . " ( " .
154 "id, rownbr, colnbr, datatype, value " .
155 ") VALUES ( ?, -1, -1, 0, ? )",
158 $form_completed . '|' . $start_date . '|' . $template_name
161 sqlStatement("UNLOCK TABLES");
166 "$spreadsheet_form_name",
173 } else { // saving a template
174 // The rule is, we can update the original name, or insert a new name
175 // which must not match any existing template name.
176 $new_template_name = form2real($_POST['form_new_template_name']);
177 if ($new_template_name != $template_name) {
179 "SELECT id FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
180 " WHERE id < 0 AND rownbr = -1 AND colnbr = -1 AND value = ?",
181 array($new_template_name)
184 $alertmsg = "Template \"" . real2form($new_template_name) .
185 "\" already exists!";
187 $tempid = 0; // to force insert of new template
188 $template_name = $new_template_name;
193 // If updating an existing template...
196 "DELETE FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
197 " WHERE id = ? AND rownbr >= 0 AND colnbr >= 0",
200 } // If adding a new template...
203 "LOCK TABLES " . escape_table_name('form_' . $spreadsheet_form_name) .
206 $tmprow = sqlQuery("SELECT MIN(id) AS minid FROM " .
207 escape_table_name('form_' . $spreadsheet_form_name));
208 $tempid = $tmprow['minid'] - 1;
214 "INSERT INTO " . escape_table_name('form_' . $spreadsheet_form_name) . " ( " .
215 "id, rownbr, colnbr, datatype, value " .
216 ") VALUES ( ?, -1, -1, 0, ? )",
222 sqlStatement("UNLOCK TABLES");
230 // Finally, save the table cells.
231 for ($i = 0; $i < $num_used_rows; ++
$i) {
232 for ($j = 0; $j < $num_used_cols; ++
$j) {
233 $tmp = $cells[$i][$j];
234 $celltype = substr($tmp, 0, 1) +
0;
235 $cellvalue = form2db(substr($tmp, 1));
238 "INSERT INTO " . escape_table_name('form_' . $spreadsheet_form_name) .
239 " ( id, rownbr, colnbr, datatype, value ) " .
240 "VALUES ( ?, ?, ?, ?, ? )",
241 array($saveid, $i, $j, $celltype, $cellvalue)
247 } else if ($_POST['bn_delete_template'] && $tempid) {
249 "DELETE FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
257 if ($_POST['bn_save_form'] && !$alertmsg && !$popup) {
258 formHeader("Redirecting....");
264 // If we get here then we are displaying a spreadsheet, either a template or
265 // an encounter form.
267 // Get the array of template names.
268 $tres = sqlStatement("SELECT id, value FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
269 " WHERE id < 0 AND rownbr = -1 AND colnbr = -1 ORDER BY value");
273 # If we are reloading a form, get it.
275 $dres = sqlStatement("SELECT * FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
276 " WHERE id = ? ORDER BY rownbr, colnbr", array($formid));
278 "SELECT MAX(rownbr) AS rowmax, MAX(colnbr) AS colmax " .
279 "FROM " . escape_table_name('form_' . $spreadsheet_form_name) . " WHERE id = ?",
282 $num_used_rows = $tmprow['rowmax'] +
1;
283 $num_used_cols = $tmprow['colmax'] +
1;
284 } # Otherwise if we are editing a template, get it.
286 $dres = sqlStatement(
287 "SELECT * FROM " . escape_table_name('form_' . $spreadsheet_form_name) .
288 " WHERE id = ? ORDER BY rownbr, colnbr",
292 "SELECT MAX(rownbr) AS rowmax, MAX(colnbr) AS colmax " .
293 "FROM " . escape_table_name('form_' . $spreadsheet_form_name) . " WHERE id = ?",
296 $num_used_rows = $tmprow['rowmax'] +
1;
297 $num_used_cols = $tmprow['colmax'] +
1;
300 // Virtual rows and columns are those available when in Edit Structure mode,
301 // and include some additional ones beyond those used. This allows quite a
302 // lot of stuff to be entered before having to save the template.
303 $num_virtual_rows = $num_used_rows ?
$num_used_rows +
5 : 10;
304 $num_virtual_cols = $num_used_cols ?
$num_used_cols +
5 : 10;
308 <?php
html_header_show();?
>
309 <link rel
="stylesheet" href
="<?php echo $css_header;?>" type
="text/css">
310 <link rel
="stylesheet" href
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker/build/jquery.datetimepicker.min.css">
314 font
-family
: sans
-serif
;
319 font
-family
: sans
-serif
;
322 background
-color
: transparent
;
325 font
-family
: sans
-serif
;
328 background
-color
: transparent
;
331 font
-family
: sans
-serif
;
334 background
-color
: transparent
;
343 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery/dist/jquery.min.js"></script
>
344 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker/build/jquery.datetimepicker.full.min.js"></script
>
345 <script type
="text/javascript" src
="../../../library/textformat.js?v=<?php echo $v_js_includes; ?>"></script
>
347 <script language
="JavaScript">
349 var ssChanged
= false; // if they have changed anything in the spreadsheet
350 var startDate
= '<?php echo $start_date ? $start_date : date('Y
-m
-d
'); ?>';
352 // In case we are a popup (top level) window, handle top.restoreSession() calls.
353 function restoreSession() {
354 return opener
.top
.restoreSession();
357 // Helper function to set the contents of a block.
358 function setBlockContent(id
, content
) {
359 if (document
.getElementById
) {
360 var x
= document
.getElementById(id
);
362 x
.innerHTML
= content
;
364 else if (document
.all
) {
365 var x
= document
.all
[id
];
366 x
.innerHTML
= content
;
368 // alert("ID = \"" + id + "\", string = \"" + content + "\"");
371 // Called when a different template name is selected.
372 function newTemplate(sel
) {
373 if (ssChanged
&& !confirm('You have made changes that will be discarded ' +
374 'if you select a new template. Do you really want to do this?'))
376 // Restore the original template selection.
377 for (var i
= 0; i
< sel
.options
.length
; ++i
) {
378 if (sel
.options
[i
].value
== '<?php echo $tempid ?>') {
379 sel
.options
[i
].selected
= true;
384 top
.restoreSession();
385 document
.forms
[0].submit();
388 // Called when the Cancel button is clicked.
389 function doCancel() {
390 if (!ssChanged ||
confirm('You have made changes that will be discarded ' +
391 'if you close now. Click OK if you really want to exit this form.'))
393 <?php
if ($popup) { ?
>
396 top
.restoreSession();
397 location
='<?php echo $GLOBALS['form_exit_url
'] ?>';
402 // Called when the Edit Structure checkbox is clicked.
403 function editChanged() {
404 var f
= document
.forms
[0];
405 var newdisplay
= f
.form_edit_template
.checked ?
'' : 'none';
408 for (var i
= 0; i
< <?php
echo $num_virtual_rows; ?
>; ++i
) {
409 for (var j
= 0; j
< <?php
echo $num_virtual_cols; ?
>; ++j
) {
410 if (f
['cell['+i+
']['+j+
']'].value
.charAt(0) != '0') {
411 if (i
>= usedrows
) usedrows
= i +
1;
412 if (j
>= usedcols
) usedcols
= j +
1;
416 for (var i
= 0; i
< <?php
echo $num_virtual_rows; ?
>; ++i
) {
417 for (var j
= 0; j
< <?php
echo $num_virtual_cols; ?
>; ++j
) {
418 // document.getElementById('div_'+i+'_'+j).style.display = newdisplay;
419 document
.getElementById('sel_'+i+
'_'+j
).style
.display
= newdisplay
;
420 if (i
>= usedrows || j
>= usedcols
) {
421 document
.getElementById('td_'+i+
'_'+j
).style
.display
= newdisplay
;
427 // Prepare a string for use as an HTML value attribute in single quotes.
428 function escQuotes(s
) {
429 return s
.replace(/'/g, "'");
432 // Parse static text to evaluate possible functions.
433 function genStatic(s) {
437 while ((i = s.indexOf('%day
(')) >= 0) {
438 var s1 = s.substring(0, i);
440 var j = s.indexOf(')', i);
442 var dayinc = parseInt(s.substring(i,j));
443 var mydate = new Date(parseInt(startDate.substring(0,4)),
444 parseInt(startDate.substring(5,7))-1, parseInt(startDate.substring(8)));
445 mydate.setTime(1000 * 60 * 60 * 24 * dayinc + mydate.getTime());
446 var year = mydate.getYear(); if (year < 1900) year += 1900;
447 s = s1 + year + '-' +
448 ('' + (mydate.getMonth() + 101)).substring(1) + '-' +
449 ('' + (mydate.getDate() + 100)).substring(1) +
453 // Parse "%sel(first,second,third,...,default)".
454 while ((i = s.indexOf('%sel
(')) >= 0) {
455 var s1 = s.substring(0, i);
457 var j = s.indexOf(')', i);
459 var x = s.substring(0,j);
460 var k = x.lastIndexOf(',');
462 var dflt = s.substring(k+1, j);
463 x = "<select class='selgen
' onchange='newsel(this
)'>";
464 while ((k = s.indexOf(',', i)) > i) {
466 var elem = s.substring(i,k);
467 x += "<option value='" + elem + "'";
468 if (elem == dflt) x += " selected";
469 x += ">" + elem + "</option>";
473 s = s1 + x + s.substring(j + 1);
474 break; // only one %sel allowed
477 // Parse "%ptp(default)".
478 while ((i = s.indexOf('%ptp
(')) >= 0) {
479 var s1 = s.substring(0, i);
481 var j = s.indexOf(')', i);
483 var dflt = s.substring(i, j);
484 x = "<select class='selgen
' onchange='newptp(this
)'>";
485 x += "<option value=''>-- Select --</option>";
487 foreach ($bcodes['Phys
']['Physiotherapy Procedures
'] as $key => $value) {
488 echo " x += \"<option value='$key'\";\n";
489 echo " if (dflt == '$key') x += ' selected
';\n";
490 echo " x += '>$value</option
>';\n";
494 s = s1 + x + s.substring(j + 1);
495 break; // only one %ptp allowed
501 // Called when a cell type selector in the spreadsheet is clicked.
502 function newType(i,j) {
504 var f = document.forms[0];
505 var typeval = f['cell
['+i+']['+j+']'].value;
506 var thevalue = typeval.substring(1);
507 var thetype = document.getElementById('sel_
'+i+'_
'+j).value;
508 var s = "<input type='hidden
' name='cell
[" + i + "][" + j + "]' " +
509 "value='" + thetype + escQuotes(thevalue) + "' />";
511 if (thetype == '1') {
512 s += genStatic(thevalue);
514 else if (thetype == '2') {
515 s += "<input type='checkbox
' value='1' onclick='cbClick(this
," + i + "," + j + ")'";
516 if (thevalue) s += " checked";
519 else if (thetype == '3') {
520 s += "<input type='text
' onchange='textChange(this
," + i + "," + j + ")'" +
521 " class='intext
' value='" + escQuotes(thevalue) + "' size='12' />";
523 else if (thetype == '4') {
524 s += "<textarea rows='3' cols='25' wrap='virtual
' class='intext
' " +
525 "onchange='longChange(this
," + i + "," + j + ")'>" +
526 escQuotes(thevalue) + "</textarea>";
528 setBlockContent('vis_
' + i + '_
' + j, s);
531 // Called when a checkbox in the spreadsheet is clicked.
532 function cbClick(elem,i,j) {
534 var f = document.forms[0];
535 var cell = f['cell
['+i+']['+j+']'];
536 cell.value = '2' + (elem.checked ? '1' : '');
539 // Called when a text value in the spreadsheet is changed.
540 function textChange(elem,i,j) {
542 var f = document.forms[0];
543 var cell = f['cell
['+i+']['+j+']'];
544 cell.value = '3' + elem.value;
547 // Called when a textarea value in the spreadsheet is changed.
548 function longChange(elem,i,j) {
550 var f = document.forms[0];
551 var cell = f['cell
['+i+']['+j+']'];
552 cell.value = '4' + elem.value;
555 // Helper function to get the value element of a table cell given any
556 // other element within that cell.
557 function getHidden(sel) {
558 var p = sel.parentNode;
559 while (p.tagName != 'TD
') {
560 if (!p.parentNode || p.parentNode == p) {
561 alert("JavaScript error, cannot find TD element");
566 // Get the <input type=hidden> element within this table cell.
567 var f = document.forms[0];
568 var s = p.id.substring(3);
569 var uix = s.indexOf('_
');
570 var i = s.substring(0, uix);
571 var j = s.substring(uix+1);
572 return f['cell
[' + i + '][' + j + ']'];
575 // Called when a user-defined select list has a new selection.
576 // This rewrites the function definition for the select list.
577 function newsel(sel) {
578 var inelem = getHidden(sel);
579 var s = inelem.value;
580 var i = s.indexOf('%sel
(');
581 var j = s.indexOf(')', i);
582 var x = s.substring(0, j);
583 var k = x.lastIndexOf(',');
584 inelem.value = s.substring(0, k+1) + sel.value + s.substring(j);
587 // Called when a physiotherapy select list has a new selection.
588 // This rewrites the function definition for the select list.
589 function newptp(sel) {
590 var inelem = getHidden(sel);
591 var s = inelem.value;
592 var i = s.indexOf('%ptp
(') + 5;
593 var j = s.indexOf(')', i);
594 inelem.value = s.substring(0, i) + sel.value + s.substring(j);
597 $(document).ready(function() {
598 $('.datepicker
').datetimepicker({
599 <?php $datetimepicker_timepicker = false; ?>
600 <?php $datetimepicker_showseconds = false; ?>
601 <?php $datetimepicker_formatInput = false; ?>
602 <?php require($GLOBALS['srcdir
'] . '/js
/xl
/jquery
-datetimepicker
-2-5-4.js
.php
'); ?>
603 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
611 <body class="body_top">
612 <form method="post" action="<?php echo "$rootdir/forms/$spreadsheet_form_name/new.php?id=$formid&thisenc=$thisenc";
616 onsubmit="return top.restoreSession()">
619 <table border='0' cellpadding='5' cellspacing='0' style='margin
:8pt
'>
620 <tr bgcolor='#ddddff'>
622 <?php
xl('Start Date', 'e'); ?
>:
623 <input type
='text' class='datepicker' name
='form_start_date' id
='form_start_date'
624 size
='10' value
='<?php echo $start_date; ?>'
626 <?php
echo ($formid && $start_date) ?
'disabled ' : ''; ?
>/>
628 <?php
xl('Template:', 'e') ?
>
629 <select name
='form_template' onchange
='newTemplate(this)'<?php
echo ($formid) ?
' disabled' : ''; ?
>>
630 <option value
='0'>-- Select
--</option
>
632 while ($trow = sqlFetchArray($tres)) {
633 echo " <option value='" . $trow['id'] . "'";
634 if ($tempid && $tempid == $trow['id'] ||
635 $formid && $template_name == $trow['value']) {
639 echo ">" . $trow['value'] . "</option>\n";
644 <input type
='checkbox' name
='form_edit_template'
645 onclick
='editChanged()'
646 title
='<?php xl("If you want to change data types, or add rows or columns", "e") ?>' />
647 <?php
xl('Edit Structure', 'e') ?
>
648 <?php
if ($formid) { ?
>
650 <input type
='checkbox' name
='form_completed'
651 title
='<?php xl("If all data for all columns are complete for this form", "e") ?>'
652 <?php
echo ($form_completed) ?
'checked ' : ''; ?
>/>
653 <?php
xl('Completed', 'e') ?
>
659 <table border
='1' cellpadding
='2' cellspacing
='0' class='sstable'>
662 $drow = sqlFetchArray($dres);
665 $typeprompts = array('unused','static','checkbox','text');
667 for ($i = 0; $i < $num_virtual_rows; ++
$i) {
669 for ($j = 0; $j < $num_virtual_cols; ++
$j) {
670 // Match up with the database for cell type and value.
674 while ($drow && $drow['rownbr'] < $i) {
675 $drow = sqlFetchArray($dres);
678 while ($drow && $drow['rownbr'] == $i && $drow['colnbr'] < $j) {
679 $drow = sqlFetchArray($dres);
682 if ($drow && $drow['rownbr'] == $i && $drow['colnbr'] == $j) {
683 $celltype = $drow['datatype'];
684 $cellvalue = real2form($drow['value']);
685 $cellstatic = addslashes($drow['value']);
689 echo " <td id='td_${i}_${j}' valign='top'";
690 if ($i >= $num_used_rows ||
$j >= $num_used_cols) {
691 echo " style='display:none'";
696 /*****************************************************************
697 echo "<span id='div_${i}_${j}' ";
698 echo "style='float:right;cursor:pointer;display:none' ";
699 echo "onclick='newType($i,$j)'>[";
700 echo $typeprompts[$celltype];
702 *****************************************************************/
703 echo "<div class='seldiv'>";
704 echo "<select id='sel_${i}_${j}' class='seltype' style='display:none' " .
705 "onchange='newType($i,$j)'>";
706 foreach ($celltypes as $key => $value) {
707 echo "<option value='$key'";
708 if ($key == $celltype) {
712 echo ">$value</option>";
717 /****************************************************************/
719 echo "<span id='vis_${i}_${j}'>"; // new //
721 echo "<input type='hidden' name='cell[$i][$j]' value='$celltype$cellvalue' />";
722 if ($celltype == '1') {
723 // So we don't have to write a PHP version of genStatic():
724 echo "<script language='JavaScript'>document.write(genStatic('$cellstatic'));</script>";
725 } else if ($celltype == '2') {
726 echo "<input type='checkbox' value='1' onclick='cbClick(this,$i,$j)'";
732 } else if ($celltype == '3') {
733 echo "<input type='text' class='intext' onchange='textChange(this,$i,$j)'";
734 echo " value='$cellvalue'";
735 echo " size='12' />";
736 } else if ($celltype == '4') {
737 echo "<textarea rows='3' cols='25' wrap='virtual' class='intext' " .
738 "onchange='longChange(this,$i,$j)'>";
743 echo "</span>"; // new //
754 <input type
='submit' name
='bn_save_form' value
='Save Form' />
755 <?php
if (!$formid) { ?
>
757 <input type
='submit' name
='bn_save_template' value
='Save as Template:' />
759 <input type
='text' name
='form_new_template_name' value
='<?php echo $template_name ?>' />
761 <input type
='submit' name
='bn_delete_template' value
='Delete Template' />
764 <input type
='button' value
='Cancel' onclick
="doCancel()" />
769 <script language
='JavaScript'>
772 echo " alert('$alertmsg');\n";