make sure pt payments show on statement as pt paid (#4008)
[openemr.git] / library / options.inc.php
blob94717563453080cf53ab34f1edefe3f214176ab3
1 <?php
3 // Copyright (C) 2007-2019 Rod Roark <rod@sunsetsystems.com>
4 // Copyright © 2010 by Andrew Moore <amoore@cpan.org>
5 // Copyright © 2010 by "Boyd Stephen Smith Jr." <bss@iguanasuicide.net>
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // Functions for managing the lists and layouts
14 // Note: there are translation wrappers for the lists and layout labels
15 // at library/translation.inc.php. The functions are titled
16 // xl_list_label() and xl_layout_label() and are controlled by the
17 // $GLOBALS['translate_lists'] and $GLOBALS['translate_layout']
18 // flags in globals.php
20 // Documentation for layout_options.edit_options:
22 // A = Age as years or "xx month(s)"
23 // B = Gestational age as "xx week(s) y day(s)"
24 // C = Capitalize first letter of each word (text fields)
25 // D = Check for duplicates in New Patient form
26 // G = Graphable (for numeric fields in forms supporting historical data)
27 // H = Read-only field copied from static history (this is obsolete)
28 // J = Jump to Next Row
29 // K = Prepend Blank Row
30 // L = Lab Order ("ord_lab") types only (address book)
31 // M = Radio Group Master (currently for radio buttons only)
32 // m = Radio Group Member (currently for radio buttons only)
33 // N = Show in New Patient form
34 // O = Procedure Order ("ord_*") types only (address book)
35 // P = Default to previous value when current value is not yet set
36 // R = Distributor types only (address book)
37 // T = Use description as default Text
38 // U = Capitalize all letters (text fields)
39 // V = Vendor types only (address book)
40 // 0 = Read Only - the input element's "disabled" property is set
41 // 1 = Write Once (not editable when not empty) (text fields)
42 // 2 = Show descriptions instead of codes for billing code input
44 require_once("user.inc");
45 require_once("patient.inc");
46 require_once("lists.inc");
47 require_once(dirname(dirname(__FILE__)) . "/custom/code_types.inc.php");
49 use OpenEMR\Common\Acl\AclExtended;
50 use OpenEMR\Common\Acl\AclMain;
51 use OpenEMR\Services\FacilityService;
53 $facilityService = new FacilityService();
55 $date_init = "";
56 $membership_group_number = 0;
58 function get_pharmacies()
60 return sqlStatement("SELECT d.id, d.name, a.line1, a.city, " .
61 "p.area_code, p.prefix, p.number FROM pharmacies AS d " .
62 "LEFT OUTER JOIN addresses AS a ON a.foreign_id = d.id " .
63 "LEFT OUTER JOIN phone_numbers AS p ON p.foreign_id = d.id " .
64 "AND p.type = 2 " .
65 "ORDER BY state, city, name, area_code, prefix, number");
68 function optionalAge($frow, $date, &$asof, $description = '')
70 $asof = '';
71 if (empty($date)) {
72 return '';
75 $edit_options = $frow['edit_options'] ?? null;
77 $date = substr($date, 0, 10);
78 if (isOption($edit_options, 'A') !== false) {
79 $format = 0;
80 } elseif (isOption($edit_options, 'B') !== false) {
81 $format = 3;
82 } else {
83 return '';
86 if (isOption($frow['form_id'], 'LBF') === 0) {
87 $tmp = sqlQuery(
88 "SELECT date FROM form_encounter WHERE " .
89 "pid = ? AND encounter = ? ORDER BY id DESC LIMIT 1",
90 array($GLOBALS['pid'], $GLOBALS['encounter'])
92 if (!empty($tmp['date'])) {
93 $asof = substr($tmp['date'], 0, 10);
96 if ($description === '') {
97 $prefix = ($format ? xl('Gest age') : xl('Age')) . ' ';
98 } else {
99 $prefix = $description . ' ';
101 return $prefix . oeFormatAge($date, $asof, $format);
104 // Function to generate a drop-list.
106 function generate_select_list(
107 $tag_name,
108 $list_id,
109 $currvalue,
110 $title,
111 $empty_name = ' ',
112 $class = '',
113 $onchange = '',
114 $tag_id = '',
115 $custom_attributes = null,
116 $multiple = false,
117 $backup_list = ''
119 $s = '';
121 $tag_name_esc = attr($tag_name);
123 if ($multiple) {
124 $tag_name_esc = $tag_name_esc . "[]";
127 $s .= "<select name='$tag_name_esc'";
129 if ($multiple) {
130 $s .= " multiple='multiple'";
133 $tag_id_esc = attr($tag_name);
135 if ($tag_id != '') {
136 $tag_id_esc = attr($tag_id);
139 $s .= " id='$tag_id_esc'";
141 if (!empty($class)) {
142 $class_esc = attr($class);
143 $s .= " class='form-control $class_esc'";
144 } else {
145 $s .= " class='form-control'";
148 if ($onchange) {
149 $s .= " onchange='$onchange'";
152 if ($custom_attributes != null && is_array($custom_attributes)) {
153 foreach ($custom_attributes as $attr => $val) {
154 if (isset($custom_attributes [$attr])) {
155 $s .= " " . attr($attr) . "='" . attr($val) . "'";
160 $selectTitle = attr($title);
161 $s .= " title='$selectTitle'>";
162 $selectEmptyName = xlt($empty_name);
163 if ($empty_name) {
164 $s .= "<option value=''>" . $selectEmptyName . "</option>";
167 // List order depends on language translation options.
168 // (Note we do not need to worry about the list order in the algorithm
169 // after the below code block since that is where searches for exceptions
170 // are done which include inactive items or items from a backup
171 // list; note these will always be shown at the bottom of the list no matter the
172 // chosen order.)
173 $lang_id = empty($_SESSION['language_choice']) ? '1' : $_SESSION['language_choice'];
174 // sort by title
175 if (!$GLOBALS['translate_lists']) {
176 // do not translate
177 if ($GLOBALS['gb_how_sort_list'] == '0') {
178 // order by seq
179 $order_by_sql = "seq, title";
180 } else { //$GLOBALS['gb_how_sort_list'] == '1'
181 // order by title
182 $order_by_sql = "title, seq";
185 $lres = sqlStatement("SELECT * FROM list_options WHERE list_id = ? AND activity=1 ORDER BY " . $order_by_sql, array($list_id));
186 } else {
187 // do translate
188 if ($GLOBALS['gb_how_sort_list'] == '0') {
189 // order by seq
190 $order_by_sql = "lo.seq, IF(LENGTH(ld.definition),ld.definition,lo.title)";
191 } else { //$GLOBALS['gb_how_sort_list'] == '1'
192 // order by title
193 $order_by_sql = "IF(LENGTH(ld.definition),ld.definition,lo.title), lo.seq";
196 $lres = sqlStatement("SELECT lo.option_id, lo.is_default, " .
197 "IF(LENGTH(ld.definition),ld.definition,lo.title) AS title " .
198 "FROM list_options AS lo " .
199 "LEFT JOIN lang_constants AS lc ON lc.constant_name = lo.title " .
200 "LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND " .
201 "ld.lang_id = ? " .
202 "WHERE lo.list_id = ? AND lo.activity=1 " .
203 "ORDER BY " . $order_by_sql, array($lang_id, $list_id));
206 $got_selected = false;
208 while ($lrow = sqlFetchArray($lres)) {
209 $selectedValues = explode("|", $currvalue);
211 $optionValue = attr($lrow ['option_id']);
212 $s .= "<option value='$optionValue'";
214 if ((strlen($currvalue) == 0 && $lrow ['is_default']) || (strlen($currvalue) > 0 && in_array($lrow ['option_id'], $selectedValues))) {
215 $s .= " selected";
216 $got_selected = true;
219 // Already has been translated above (if applicable), so do not need to use
220 // the xl_list_label() function here
221 $optionLabel = text($lrow ['title']);
222 $s .= ">$optionLabel</option>\n";
226 To show the inactive item in the list if the value is saved to database
228 if (!$got_selected && strlen($currvalue) > 0) {
229 $lres_inactive = sqlStatement("SELECT * FROM list_options " .
230 "WHERE list_id = ? AND activity = 0 AND option_id = ? ORDER BY seq, title", array($list_id, $currvalue));
231 $lrow_inactive = sqlFetchArray($lres_inactive);
232 if ($lrow_inactive['option_id']) {
233 $optionValue = htmlspecialchars($lrow_inactive['option_id'], ENT_QUOTES);
234 $s .= "<option value='$optionValue' selected>" . htmlspecialchars(xl_list_label($lrow_inactive['title']), ENT_NOQUOTES) . "</option>\n";
235 $got_selected = true;
239 if (!$got_selected && strlen($currvalue) > 0 && !$multiple) {
240 $list_id = $backup_list;
241 $lrow = sqlQuery("SELECT title FROM list_options WHERE list_id = ? AND option_id = ?", array($list_id,$currvalue));
243 if ($lrow > 0 && !empty($backup_list)) {
244 $selected = text(xl_list_label($lrow ['title']));
245 $s .= "<option value='$currescaped' selected> $selected </option>";
246 $s .= "</select>";
247 } else {
248 $s .= "<option value='$currescaped' selected>* $currescaped *</option>";
249 $s .= "</select>";
250 $fontTitle = xlt('Please choose a valid selection from the list.');
251 $fontText = xlt('Fix this');
252 $s .= " <span class='text-danger' title='$fontTitle'>$fontText!</span>";
254 } elseif (!$got_selected && strlen($currvalue) > 0 && $multiple) {
255 //if not found in main list, display all selected values that exist in backup list
256 $list_id = $backup_list;
258 $got_selected_backup = false;
259 if (!empty($backup_list)) {
260 $lres_backup = sqlStatement("SELECT * FROM list_options WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
261 while ($lrow_backup = sqlFetchArray($lres_backup)) {
262 $selectedValues = explode("|", $currvalue);
264 $optionValue = attr($lrow_backup['option_id']);
266 if (in_array($lrow_backup ['option_id'], $selectedValues)) {
267 $s .= "<option value='$optionValue'";
268 $s .= " selected";
269 $optionLabel = text(xl_list_label($lrow_backup ['title']));
270 $s .= ">$optionLabel</option>\n";
271 $got_selected_backup = true;
276 if (!$got_selected_backup) {
277 $selectedValues = explode("|", $currvalue);
278 foreach ($selectedValues as $selectedValue) {
279 $s .= "<option value='" . attr($selectedValue) . "'";
280 $s .= " selected";
281 $s .= ">* " . text($selectedValue) . " *</option>\n";
284 $s .= "</select>";
285 $fontTitle = xlt('Please choose a valid selection from the list.');
286 $fontText = xlt('Fix this');
287 $s .= " <span class='text-danger' title='$fontTitle'>$fontText!</span>";
289 } else {
290 $s .= "</select>";
293 return $s;
296 // Parsing for data type 31, static text.
297 function parse_static_text($frow)
299 $tmp = $frow['description'];
300 // Translate if it does not look like HTML.
301 if (substr($tmp, 0, 1) != '<') {
302 $tmp = nl2br(xl_layout_label($tmp));
304 $s = '';
305 if ($frow['source'] == 'D' || $frow['source'] == 'H') {
306 // Source is demographics or history. This case supports value substitution.
307 while (preg_match('/^(.*?)\{(\w+)\}(.*)$/', $tmp, $matches)) {
308 $s .= $matches[1];
309 $tmprow = $frow;
310 $tmprow['field_id'] = $matches[2];
311 $s .= lbf_current_value($tmprow, 0, 0);
312 $tmp = $matches[3];
315 $s .= $tmp;
316 return $s;
319 // $frow is a row from the layout_options table.
320 // $currvalue is the current value, if any, of the associated item.
322 function generate_form_field($frow, $currvalue)
324 global $rootdir, $date_init, $ISSUE_TYPES, $code_types, $membership_group_number;
326 $currescaped = htmlspecialchars($currvalue, ENT_QUOTES);
328 $data_type = $frow['data_type'];
329 $field_id = $frow['field_id'];
330 $list_id = $frow['list_id'] ?? null;
331 $backup_list = $frow['list_backup_id'] ?? null;
332 $edit_options = $frow['edit_options'] ?? null;
333 $form_id = $frow['form_id'] ?? null;
335 // Get if we want a smaller form field
336 $smallform = $frow['smallform'] ?? null;
338 if ($smallform === 'true') {
339 $smallform = ' form-control-sm';
342 // escaped variables to use in html
343 $field_id_esc = htmlspecialchars($field_id, ENT_QUOTES);
344 $list_id_esc = htmlspecialchars($list_id, ENT_QUOTES);
346 // Added 5-09 by BM - Translate description if applicable
347 $description = (isset($frow['description']) ? htmlspecialchars(xl_layout_label($frow['description']), ENT_QUOTES) : '');
349 // Support edit option T which assigns the (possibly very long) description as
350 // the default value.
351 if (isOption($edit_options, 'T') !== false) {
352 if (strlen($currescaped) == 0) {
353 $currescaped = $description;
356 // Description used in this way is not suitable as a title.
357 $description = '';
360 // added 5-2009 by BM to allow modification of the 'empty' text title field.
361 // Can pass $frow['empty_title'] with this variable, otherwise
362 // will default to 'Unassigned'.
363 // modified 6-2009 by BM to allow complete skipping of the 'empty' text title
364 // if make $frow['empty_title'] equal to 'SKIP'
365 $showEmpty = true;
366 if (isset($frow['empty_title'])) {
367 if ($frow['empty_title'] == "SKIP") {
368 //do not display an 'empty' choice
369 $showEmpty = false;
370 $empty_title = "Unassigned";
371 } else {
372 $empty_title = $frow['empty_title'];
374 } else {
375 $empty_title = "Unassigned";
378 $disabled = isOption($edit_options, '0') === false ? '' : 'disabled';
380 $lbfchange = (
381 strpos($form_id, 'LBF') === 0 ||
382 strpos($form_id, 'LBT') === 0 ||
383 $form_id == 'DEM' ||
384 $form_id == 'HIS'
385 ) ? "checkSkipConditions();" : "";
386 $lbfonchange = $lbfchange ? "onchange='$lbfchange'" : "";
388 // generic single-selection list or single-selection list with search or Race and Ethnicity.
389 // These data types support backup lists.
390 if ($data_type == 1 || $data_type == 33 || $data_type == 43) {
391 echo generate_select_list(
392 "form_$field_id",
393 $list_id,
394 $currvalue,
395 $description,
396 ($showEmpty ? $empty_title : ''),
397 (($data_type == 43) ? "select-dropdown" : $smallform),
398 $lbfchange,
400 ($disabled ? array('disabled' => 'disabled') : null),
401 false,
402 $backup_list
404 } elseif ($data_type == 2) { // simple text field
405 $fldlength = htmlspecialchars($frow['fld_length'], ENT_QUOTES);
406 $maxlength = $frow['max_length'];
407 $string_maxlength = "";
408 // if max_length is set to zero, then do not set a maxlength
409 if ($maxlength) {
410 $string_maxlength = "maxlength='" . attr($maxlength) . "'";
413 echo "<input type='text'" .
414 " class='form-control$smallform'" .
415 " name='form_$field_id_esc'" .
416 " id='form_$field_id_esc'" .
417 " size='$fldlength'" .
418 " $string_maxlength" .
419 " title='$description'" .
420 " value='$currescaped'";
421 $tmp = $lbfchange;
422 if (isOption($edit_options, 'C') !== false) {
423 $tmp .= "capitalizeMe(this);";
424 } elseif (isOption($edit_options, 'U') !== false) {
425 $tmp .= "this.value = this.value.toUpperCase();";
428 if ($tmp) {
429 echo " onchange='$tmp'";
432 $tmp = htmlspecialchars($GLOBALS['gbl_mask_patient_id'], ENT_QUOTES);
433 // If mask is for use at save time, treat as no mask.
434 if (strpos($tmp, '^') !== false) {
435 $tmp = '';
437 if ($field_id == 'pubpid' && strlen($tmp) > 0) {
438 echo " onkeyup='maskkeyup(this,\"$tmp\")'";
439 echo " onblur='maskblur(this,\"$tmp\")'";
442 if (isOption($edit_options, '1') !== false && strlen($currescaped) > 0) {
443 echo " readonly";
446 if ($disabled) {
447 echo ' disabled';
450 echo " />";
451 } elseif ($data_type == 3) { // long or multi-line text field
452 $textCols = htmlspecialchars($frow['fld_length'], ENT_QUOTES);
453 $textRows = htmlspecialchars($frow['fld_rows'], ENT_QUOTES);
454 echo "<textarea" .
455 " name='form_$field_id_esc'" .
456 " class='form-control$smallform'" .
457 " id='form_$field_id_esc'" .
458 " title='$description'" .
459 " cols='$textCols'" .
460 " rows='$textRows' $lbfonchange $disabled" .
461 ">" . $currescaped . "</textarea>";
462 } elseif ($data_type == 4) { // date
463 $age_asof_date = ''; // optionalAge() sets this
464 $age_format = isOption($edit_options, 'A') === false ? 3 : 0;
465 $agestr = optionalAge($frow, $currvalue, $age_asof_date, $description);
466 if ($agestr) {
467 echo "<table class='table'><tr><td class='text'>";
470 $onchange_string = '';
471 if (!$disabled && $agestr) {
472 $onchange_string = "onchange=\"if (typeof(updateAgeString) == 'function') " .
473 "updateAgeString('$field_id','$age_asof_date', $age_format, '$description')\"";
475 if ($data_type == 4) {
476 $modtmp = isOption($edit_options, 'F') === false ? 0 : 1;
477 $datetimepickerclass = $frow['validation'] === 'past_date' ? '-past' : ( $frow['validation'] === 'future_date' ? '-future' : '' );
478 if (!$modtmp) {
479 $dateValue = oeFormatShortDate(substr($currescaped, 0, 10));
480 echo "<input type='text' size='10' class='datepicker$datetimepickerclass form-control$smallform' name='form_$field_id_esc' id='form_$field_id_esc'" . " value='" . attr($dateValue) . "'";
481 } else {
482 $dateValue = oeFormatDateTime(substr($currescaped, 0, 20), 0);
483 echo "<input type='text' size='20' class='datetimepicker$datetimepickerclass form-control$smallform' name='form_$field_id_esc' id='form_$field_id_esc'" . " value='" . attr($dateValue) . "'";
486 if (!$agestr) {
487 echo " title='$description'";
490 // help chrome users avoid autocomplete interfere with datepicker widget display
491 if ($frow['field_id'] == 'DOB') {
492 echo " autocomplete='off' $onchange_string $lbfonchange $disabled />";
493 } else {
494 echo " $onchange_string $lbfonchange $disabled />";
497 // Optional display of age or gestational age.
498 if ($agestr) {
499 echo "</td></tr><tr><td id='span_$field_id' class='text'>" . text($agestr) . "</td></tr></table>";
501 } elseif ($data_type == 10) { // provider list, local providers only
502 $ures = sqlStatement("SELECT id, fname, lname, specialty FROM users " .
503 "WHERE active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
504 "AND authorized = 1 " .
505 "ORDER BY lname, fname");
506 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' title='$description' $lbfonchange $disabled class='form-control$smallform'>";
507 echo "<option value=''>" . xlt($empty_title) . "</option>";
508 $got_selected = false;
509 while ($urow = sqlFetchArray($ures)) {
510 $uname = text($urow['fname'] . ' ' . $urow['lname']);
511 $optionId = attr($urow['id']);
512 echo "<option value='$optionId'";
513 if ($urow['id'] == $currvalue) {
514 echo " selected";
515 $got_selected = true;
518 echo ">$uname</option>";
521 if (!$got_selected && $currvalue) {
522 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
523 echo "</select>";
524 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
525 } else {
526 echo "</select>";
528 } elseif ($data_type == 11) { // provider list, including address book entries with an NPI number
529 $ures = sqlStatement("SELECT id, fname, lname, specialty FROM users " .
530 "WHERE active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
531 "AND ( authorized = 1 OR ( username = '' AND npi != '' ) ) " .
532 "ORDER BY lname, fname");
533 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' title='$description' class='form-control$smallform'";
534 echo " $lbfonchange $disabled>";
535 echo "<option value=''>" . xlt('Unassigned') . "</option>";
536 $got_selected = false;
537 while ($urow = sqlFetchArray($ures)) {
538 $uname = text($urow['fname'] . ' ' . $urow['lname']);
539 $optionId = attr($urow['id']);
540 echo "<option value='$optionId'";
541 if ($urow['id'] == $currvalue) {
542 echo " selected";
543 $got_selected = true;
546 echo ">$uname</option>";
549 if (!$got_selected && $currvalue) {
550 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
551 echo "</select>";
552 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
553 } else {
554 echo "</select>";
556 } elseif ($data_type == 12) { // pharmacy list
557 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' title='$description' class='form-control$smallform'";
558 echo " $lbfonchange $disabled>";
559 echo "<option value='0'></option>";
560 $pres = get_pharmacies();
561 $got_selected = false;
562 $zone = '';
563 while ($prow = sqlFetchArray($pres)) {
564 if ($zone != strtolower(trim($prow['city']))) {
565 if ($zone != '') {
566 echo "</optgroup>";
568 $zone = strtolower(trim($prow['city']));
569 echo "<optgroup label='" . attr($prow['city']) . "'>";
571 $key = $prow['id'];
572 $optionValue = htmlspecialchars($key, ENT_QUOTES);
573 $optionLabel = htmlspecialchars($prow['name'] . ' ' . $prow['area_code'] . '-' .
574 $prow['prefix'] . '-' . $prow['number'] . ' / ' .
575 $prow['line1'] . ' / ' . $prow['city'], ENT_NOQUOTES);
576 echo "<option value='$optionValue'";
577 if ($currvalue == $key) {
578 echo " selected";
579 $got_selected = true;
582 echo ">$optionLabel</option>";
585 if (!$got_selected && $currvalue) {
586 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
587 echo "</select>";
588 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
589 } else {
590 echo "</select>";
592 } elseif ($data_type == 13) { // squads
593 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' title='$description' class='form-control$smallform'";
594 echo " $lbfonchange $disabled>";
595 echo "<option value=''>&nbsp;</option>";
596 $squads = AclExtended::aclGetSquads();
597 if ($squads) {
598 foreach ($squads as $key => $value) {
599 $optionValue = htmlspecialchars($key, ENT_QUOTES);
600 $optionLabel = htmlspecialchars($value[3], ENT_NOQUOTES);
601 echo "<option value='$optionValue'";
602 if ($currvalue == $key) {
603 echo " selected";
606 echo ">$optionLabel</option>\n";
610 echo "</select>";
611 } elseif ($data_type == 14) {
612 // Address book, preferring organization name if it exists and is not in
613 // parentheses, and excluding local users who are not providers.
614 // Supports "referred to" practitioners and facilities.
615 // Alternatively the letter L in edit_options means that abook_type
616 // must be "ord_lab", indicating types used with the procedure
617 // lab ordering system.
618 // Alternatively the letter O in edit_options means that abook_type
619 // must begin with "ord_", indicating types used with the procedure
620 // ordering system.
621 // Alternatively the letter V in edit_options means that abook_type
622 // must be "vendor", indicating the Vendor type.
623 // Alternatively the letter R in edit_options means that abook_type
624 // must be "dist", indicating the Distributor type.
626 if (isOption($edit_options, 'L') !== false) {
627 $tmp = "abook_type = 'ord_lab'";
628 } elseif (isOption($edit_options, 'O') !== false) {
629 $tmp = "abook_type LIKE 'ord\\_%'";
630 } elseif (isOption($edit_options, 'V') !== false) {
631 $tmp = "abook_type LIKE 'vendor%'";
632 } elseif (isOption($edit_options, 'R') !== false) {
633 $tmp = "abook_type LIKE 'dist'";
634 } else {
635 $tmp = "( username = '' OR authorized = 1 )";
638 $ures = sqlStatement("SELECT id, fname, lname, organization, username FROM users " .
639 "WHERE active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
640 "AND $tmp " .
641 "ORDER BY organization, lname, fname");
642 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' title='$description' class='form-control$smallform'";
643 echo " $lbfonchange $disabled>";
644 echo "<option value=''>" . htmlspecialchars(xl('Unassigned'), ENT_NOQUOTES) . "</option>";
645 while ($urow = sqlFetchArray($ures)) {
646 $uname = $urow['organization'];
647 if (empty($uname) || substr($uname, 0, 1) == '(') {
648 $uname = $urow['lname'];
649 if ($urow['fname']) {
650 $uname .= ", " . $urow['fname'];
654 $optionValue = htmlspecialchars($urow['id'], ENT_QUOTES);
655 $optionLabel = htmlspecialchars($uname, ENT_NOQUOTES);
656 echo "<option value='$optionValue'";
657 // Failure to translate Local and External is not an error here;
658 // they are only used as internal flags and must not be translated!
659 $title = $urow['username'] ? 'Local' : 'External';
660 $optionTitle = htmlspecialchars($title, ENT_QUOTES);
661 echo " title='$optionTitle'";
662 if ($urow['id'] == $currvalue) {
663 echo " selected";
666 echo ">$optionLabel</option>";
669 echo "</select>";
670 } elseif ($data_type == 15) { // A billing code. If description matches an existing code type then that type is used.
671 $codetype = '';
672 if (!empty($frow['description']) && isset($code_types[$frow['description']])) {
673 $codetype = $frow['description'];
675 $fldlength = attr($frow['fld_length']);
676 $maxlength = $frow['max_length'];
677 $string_maxlength = "";
678 // if max_length is set to zero, then do not set a maxlength
679 if ($maxlength) {
680 $string_maxlength = "maxlength='" . attr($maxlength) . "'";
684 if (isOption($edit_options, '2') !== false && substr($form_id, 0, 3) == 'LBF') {
685 // Option "2" generates a hidden input for the codes, and a matching visible field
686 // displaying their descriptions. First step is computing the description string.
687 $currdescstring = '';
688 if (!empty($currvalue)) {
689 $relcodes = explode(';', $currvalue);
690 foreach ($relcodes as $codestring) {
691 if ($codestring === '') {
692 continue;
695 $code_text = lookup_code_descriptions($codestring);
696 if ($currdescstring !== '') {
697 $currdescstring .= '; ';
700 if (!empty($code_text)) {
701 $currdescstring .= $code_text;
702 } else {
703 $currdescstring .= $codestring;
708 $currdescstring = attr($currdescstring);
710 echo "<input type='text'" .
711 " name='form_$field_id_esc'" .
712 " id='form_related_code'" .
713 " size='$fldlength'" .
714 " value='$currescaped'" .
715 " style='display:none'" .
716 " $lbfonchange readonly $disabled />";
717 // Extra readonly input field for optional display of code description(s).
718 echo "<input type='text'" .
719 " name='form_$field_id_esc" . "__desc'" .
720 " size='$fldlength'" .
721 " title='$description'" .
722 " value='$currdescstring'";
723 if (!$disabled) {
724 echo " onclick='sel_related(this," . attr_js($codetype) . ")'";
727 echo "class='form-control$smallform'";
728 echo " readonly $disabled />";
729 } else {
730 echo "<input type='text'" .
731 " name='form_$field_id_esc'" .
732 " id='form_related_code'" .
733 " size='$fldlength'" .
734 " $string_maxlength" .
735 " title='$description'" .
736 " value='$currescaped'";
737 if (!$disabled) {
738 echo " onclick='sel_related(this," . attr_js($codetype) . ")'";
741 echo "class='form-control$smallform'";
742 echo " $lbfonchange readonly $disabled />";
744 } elseif ($data_type == 16) { // insurance company list
745 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' class='form-control$smallform' title='$description'>";
746 echo "<option value='0'></option>";
747 $insprovs = getInsuranceProviders();
748 $got_selected = false;
749 foreach ($insprovs as $key => $ipname) {
750 $optionValue = htmlspecialchars($key, ENT_QUOTES);
751 $optionLabel = htmlspecialchars($ipname, ENT_NOQUOTES);
752 echo "<option value='$optionValue'";
753 if ($currvalue == $key) {
754 echo " selected";
755 $got_selected = true;
758 echo ">$optionLabel</option>";
761 if (!$got_selected && $currvalue) {
762 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
763 echo "</select>";
764 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
765 } else {
766 echo "</select>";
768 } elseif ($data_type == 17) { // issue types
769 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' class='form-control$smallform' title='$description'>";
770 echo "<option value='0'></option>";
771 $got_selected = false;
772 foreach ($ISSUE_TYPES as $key => $value) {
773 $optionValue = htmlspecialchars($key, ENT_QUOTES);
774 $optionLabel = htmlspecialchars($value[1], ENT_NOQUOTES);
775 echo "<option value='$optionValue'";
776 if ($currvalue == $key) {
777 echo " selected";
778 $got_selected = true;
781 echo ">$optionLabel</option>";
784 if (!$got_selected && strlen($currvalue) > 0) {
785 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
786 echo "</select>";
787 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
788 } else {
789 echo "</select>";
791 } elseif ($data_type == 18) { // Visit categories.
792 $cres = sqlStatement("SELECT pc_catid, pc_catname " .
793 "FROM openemr_postcalendar_categories ORDER BY pc_catname");
794 echo "<select name='form_$field_id_esc' id='form_$field_id_esc' class='form-control$smallform' title='$description'" . " $lbfonchange $disabled>";
795 echo "<option value=''>" . xlt($empty_title) . "</option>";
796 $got_selected = false;
797 while ($crow = sqlFetchArray($cres)) {
798 $catid = $crow['pc_catid'];
799 if (($catid < 9 && $catid != 5) || $catid == 11) {
800 continue;
803 echo "<option value='" . attr($catid) . "'";
804 if ($catid == $currvalue) {
805 echo " selected";
806 $got_selected = true;
809 echo ">" . text(xl_appt_category($crow['pc_catname'])) . "</option>";
812 if (!$got_selected && $currvalue) {
813 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
814 echo "</select>";
815 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
816 } else {
817 echo "</select>";
819 } elseif ($data_type == 21) { // a set of labeled checkboxes
820 // If no list then it's a single checkbox and its value is "Yes" or empty.
821 if (!$list_id) {
822 echo "<input type='checkbox' name='form_{$field_id_esc}' " .
823 "id='form_{$field_id_esc}' value='Yes' $lbfonchange";
824 if ($currvalue) {
825 echo " checked";
827 echo " $disabled />";
828 } else {
829 // In this special case, fld_length is the number of columns generated.
830 $cols = max(1, $frow['fld_length']);
831 $avalue = explode('|', $currvalue);
832 $lres = sqlStatement("SELECT * FROM list_options " .
833 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
834 echo "<table class='w-100' cellpadding='0' cellspacing='0' title='" . attr($description) . "'>";
835 $tdpct = (int) (100 / $cols);
836 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
837 $option_id = $lrow['option_id'];
838 $option_id_esc = htmlspecialchars($option_id, ENT_QUOTES);
839 // if ($count) echo "<br />";
840 if ($count % $cols == 0) {
841 if ($count) {
842 echo "</tr>";
844 echo "<tr>";
846 echo "<td width='" . attr($tdpct) . "%' nowrap>";
847 echo "<input type='checkbox' name='form_{$field_id_esc}[$option_id_esc]'" .
848 "id='form_{$field_id_esc}[$option_id_esc]' class='form-check-inline' value='1' $lbfonchange";
849 if (in_array($option_id, $avalue)) {
850 echo " checked";
852 // Added 5-09 by BM - Translate label if applicable
853 echo " $disabled />" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES);
854 echo "</td>";
856 if ($count) {
857 echo "</tr>";
858 if ($count > $cols) {
859 // Add some space after multiple rows of checkboxes.
860 $cols = htmlspecialchars($cols, ENT_QUOTES);
861 echo "<tr><td colspan='$cols' style='height:0.7rem'></td></tr>";
864 echo "</table>";
866 } elseif ($data_type == 22) { // a set of labeled text input fields
867 $tmp = explode('|', $currvalue);
868 $avalue = array();
869 foreach ($tmp as $value) {
870 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
871 $avalue[$matches[1]] = $matches[2];
875 $lres = sqlStatement("SELECT * FROM list_options " .
876 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
877 echo "<table class='table'>";
878 while ($lrow = sqlFetchArray($lres)) {
879 $option_id = $lrow['option_id'];
880 $option_id_esc = htmlspecialchars($option_id, ENT_QUOTES);
881 $maxlength = $frow['max_length'];
882 $string_maxlength = "";
883 // if max_length is set to zero, then do not set a maxlength
884 if ($maxlength) {
885 $string_maxlength = "maxlength='" . attr($maxlength) . "'";
888 $fldlength = empty($frow['fld_length']) ? 20 : $frow['fld_length'];
890 // Added 5-09 by BM - Translate label if applicable
891 echo "<tr><td>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
892 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
893 $optionValue = htmlspecialchars($avalue[$option_id], ENT_QUOTES);
894 echo "<td><input type='text'" .
895 " name='form_{$field_id_esc}[$option_id_esc]'" .
896 " id='form_{$field_id_esc}[$option_id_esc]'" .
897 " size='$fldlength'" .
898 " class='form-control$smallform'" .
899 " $string_maxlength" .
900 " value='$optionValue'";
901 echo " $lbfonchange $disabled /></td></tr>";
904 echo "</table>";
905 } elseif ($data_type == 23) { // a set of exam results; 3 radio buttons and a text field:
906 $tmp = explode('|', $currvalue);
907 $avalue = array();
908 foreach ($tmp as $value) {
909 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
910 $avalue[$matches[1]] = $matches[2];
914 $maxlength = $frow['max_length'];
915 $string_maxlength = "";
916 // if max_length is set to zero, then do not set a maxlength
917 if ($maxlength) {
918 $string_maxlength = "maxlength='" . attr($maxlength) . "'";
921 $fldlength = empty($frow['fld_length']) ? 20 : $frow['fld_length'];
922 $lres = sqlStatement("SELECT * FROM list_options " .
923 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
924 echo "<table class='table'>";
925 echo "<tr><td>&nbsp;</td><td class='font-weight-bold'>" .
926 htmlspecialchars(xl('N/A'), ENT_NOQUOTES) .
927 "&nbsp;</td><td class='font-weight-bold'>" .
928 htmlspecialchars(xl('Nor'), ENT_NOQUOTES) . "&nbsp;</td>" .
929 "<td class='font-weight-bold'>" .
930 htmlspecialchars(xl('Abn'), ENT_NOQUOTES) . "&nbsp;</td><td class='font-weight-bold'>" .
931 htmlspecialchars(xl('Date/Notes'), ENT_NOQUOTES) . "</td></tr>";
932 while ($lrow = sqlFetchArray($lres)) {
933 $option_id = $lrow['option_id'];
934 $option_id_esc = htmlspecialchars($option_id, ENT_QUOTES);
935 $restype = substr(($avalue[$option_id] ?? ''), 0, 1);
936 $resnote = substr(($avalue[$option_id] ?? ''), 2);
938 // Added 5-09 by BM - Translate label if applicable
939 echo "<tr><td>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
941 for ($i = 0; $i < 3; ++$i) {
942 $inputValue = htmlspecialchars($i, ENT_QUOTES);
943 echo "<td><input type='radio'" .
944 " name='radio_{$field_id_esc}[$option_id_esc]'" .
945 " id='radio_{$field_id_esc}[$option_id_esc]'" .
946 " value='$inputValue' $lbfonchange";
947 if ($restype === "$i") {
948 echo " checked";
951 echo " $disabled /></td>";
954 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
955 $resnote = htmlspecialchars($resnote, ENT_QUOTES);
956 echo "<td><input type='text'" .
957 " name='form_{$field_id_esc}[$option_id_esc]'" .
958 " id='form_{$field_id_esc}[$option_id_esc]'" .
959 " size='$fldlength'" .
960 " class='form-control'" .
961 " $string_maxlength" .
962 " value='$resnote' $disabled /></td>";
963 echo "</tr>";
966 echo "</table>";
967 } elseif ($data_type == 24) { // the list of active allergies for the current patient
968 // this is read-only!
969 $query = "SELECT title, comments FROM lists WHERE " .
970 "pid = ? AND type = 'allergy' AND enddate IS NULL " .
971 "ORDER BY begdate";
972 // echo "<!-- $query -->\n"; // debugging
973 $lres = sqlStatement($query, array($GLOBALS['pid']));
974 $count = 0;
975 while ($lrow = sqlFetchArray($lres)) {
976 if ($count++) {
977 echo "<br />";
980 echo htmlspecialchars($lrow['title'], ENT_NOQUOTES);
981 if ($lrow['comments']) {
982 echo ' (' . htmlspecialchars($lrow['comments'], ENT_NOQUOTES) . ')';
985 } elseif ($data_type == 25) { // a set of labeled checkboxes, each with a text field:
986 $tmp = explode('|', $currvalue);
987 $avalue = array();
988 foreach ($tmp as $value) {
989 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
990 $avalue[$matches[1]] = $matches[2];
994 $maxlength = $frow['max_length'];
995 $string_maxlength = "";
996 // if max_length is set to zero, then do not set a maxlength
997 if ($maxlength) {
998 $string_maxlength = "maxlength='" . attr($maxlength) . "'";
1001 $fldlength = empty($frow['fld_length']) ? 20 : $frow['fld_length'];
1002 $lres = sqlStatement("SELECT * FROM list_options " .
1003 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1004 echo "<table class='table'>";
1005 while ($lrow = sqlFetchArray($lres)) {
1006 $option_id = $lrow['option_id'];
1007 $option_id_esc = htmlspecialchars($option_id, ENT_QUOTES);
1008 $restype = substr($avalue[$option_id], 0, 1);
1009 $resnote = substr($avalue[$option_id], 2);
1011 // Added 5-09 by BM - Translate label if applicable
1012 echo "<tr><td>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
1014 $option_id = htmlspecialchars($option_id, ENT_QUOTES);
1015 echo "<td><input type='checkbox' name='check_{$field_id_esc}[$option_id_esc]'" .
1016 " id='check_{$field_id_esc}[$option_id_esc]' class='form-check-inline' value='1' $lbfonchange";
1017 if ($restype) {
1018 echo " checked";
1021 echo " $disabled />&nbsp;</td>";
1022 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
1023 $resnote = htmlspecialchars($resnote, ENT_QUOTES);
1024 echo "<td><input type='text'" .
1025 " name='form_{$field_id_esc}[$option_id_esc]'" .
1026 " id='form_{$field_id_esc}[$option_id_esc]'" .
1027 " size='$fldlength'" .
1028 " class='form-control$smallform' " .
1029 " $string_maxlength" .
1030 " value='$resnote' $disabled /></td>";
1031 echo "</tr>";
1034 echo "</table>";
1035 } elseif ($data_type == 26) { // single-selection list with ability to add to it
1036 echo "<div class='input-group'>";
1037 echo generate_select_list(
1038 "form_$field_id",
1039 $list_id,
1040 $currvalue,
1041 $description,
1042 ($showEmpty ? $empty_title : ''),
1043 'addtolistclass_' . $list_id . $smallform,
1044 $lbfchange,
1046 ($disabled ? array('disabled' => 'disabled') : null),
1047 false,
1048 $backup_list
1050 // show the add button if user has access to correct list
1051 $inputValue = htmlspecialchars(xl('Add'), ENT_QUOTES);
1052 $outputAddButton = "<div class='input-group-append'><input type='button' class='btn btn-primary addtolist' id='addtolistid_" . $list_id_esc . "' fieldid='form_" .
1053 $field_id_esc . "' value='$inputValue' $disabled /></div>";
1054 if (AclExtended::acoExist('lists', $list_id)) {
1055 // a specific aco exist for this list, so ensure access
1056 if (AclMain::aclCheckCore('lists', $list_id)) {
1057 echo $outputAddButton;
1059 } else {
1060 // no specific aco exist for this list, so check for access to 'default' list
1061 if (AclMain::aclCheckCore('lists', 'default')) {
1062 echo $outputAddButton;
1065 echo "</div>";
1066 } elseif ($data_type == 27) { // a set of labeled radio buttons
1067 // In this special case, fld_length is the number of columns generated.
1068 $cols = max(1, $frow['fld_length']);
1069 // Support for edit option M.
1070 if (isOption($edit_options, 'M')) {
1071 ++$membership_group_number;
1074 $lres = sqlStatement("SELECT * FROM list_options " .
1075 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1076 echo "<table class='table w-100'>";
1077 $tdpct = (int) (100 / $cols);
1078 $got_selected = false;
1079 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
1080 $option_id = $lrow['option_id'];
1081 $option_id_esc = htmlspecialchars($option_id, ENT_QUOTES);
1082 if ($count % $cols == 0) {
1083 if ($count) {
1084 echo "</tr>";
1086 echo "<tr>";
1088 echo "<td width='" . attr($tdpct) . "%'>";
1089 echo "<input type='radio' name='form_{$field_id_esc}' id='form_{$field_id_esc}[$option_id_esc]'" .
1090 " value='$option_id_esc' $lbfonchange";
1091 // Support for edit options M and m.
1092 if (isOption($edit_options, 'M')) {
1093 echo " class='form-check-inline'";
1094 echo " onclick='checkGroupMembers(this, $membership_group_number);'";
1095 } elseif (isOption($edit_options, 'm')) {
1096 echo " class='form-check-inline lbf_memgroup_$membership_group_number'";
1097 } else {
1098 echo " class='form-check-inline'";
1101 if (
1102 (strlen($currvalue) == 0 && $lrow['is_default']) ||
1103 (strlen($currvalue) > 0 && $option_id == $currvalue)
1105 echo " checked";
1106 $got_selected = true;
1108 echo " $disabled />" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES);
1109 echo "</td>";
1112 if ($count) {
1113 echo "</tr>";
1114 if ($count > $cols) {
1115 // Add some space after multiple rows of radio buttons.
1116 $cols = htmlspecialchars($cols, ENT_QUOTES);
1117 echo "<tr><td colspan='$cols' style='height: 0.7rem'></td></tr>";
1121 echo "</table>";
1122 if (!$got_selected && strlen($currvalue) > 0) {
1123 $fontTitle = htmlspecialchars(xl('Please choose a valid selection.'), ENT_QUOTES);
1124 $fontText = htmlspecialchars(xl('Fix this'), ENT_NOQUOTES);
1125 echo "$currescaped <span class='text-danger' title='$fontTitle'>$fontText!</span>";
1127 } elseif ($data_type == 28 || $data_type == 32) { // special case for history of lifestyle status; 3 radio buttons
1128 // and a date text field:
1129 // VicarePlus :: A selection list box for smoking status:
1130 $tmp = explode('|', $currvalue);
1131 switch (count($tmp)) {
1132 case "4":
1133 $resnote = $tmp[0];
1134 $restype = $tmp[1];
1135 $resdate = oeFormatShortDate($tmp[2]);
1136 $reslist = $tmp[3];
1137 break;
1138 case "3":
1139 $resnote = $tmp[0];
1140 $restype = $tmp[1];
1141 $resdate = oeFormatShortDate($tmp[2]);
1142 $reslist = '';
1143 break;
1144 case "2":
1145 $resnote = $tmp[0];
1146 $restype = $tmp[1];
1147 $resdate = "";
1148 $reslist = '';
1149 break;
1150 case "1":
1151 $resnote = $tmp[0];
1152 $resdate = $restype = "";
1153 $reslist = '';
1154 break;
1155 default:
1156 $restype = $resdate = $resnote = "";
1157 $reslist = '';
1158 break;
1161 $maxlength = $frow['max_length'];
1162 $string_maxlength = "";
1163 // if max_length is set to zero, then do not set a maxlength
1164 if ($maxlength) {
1165 $string_maxlength = "maxlength='" . attr($maxlength) . "'";
1168 $fldlength = empty($frow['fld_length']) ? 20 : $frow['fld_length'];
1170 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
1171 $resnote = htmlspecialchars($resnote, ENT_QUOTES);
1172 $resdate = htmlspecialchars($resdate, ENT_QUOTES);
1173 echo "<table class='table'>";
1174 echo "<tr>";
1175 if ($data_type == 28) {
1176 // input text
1177 echo "<td><input type='text' class='form-control'" .
1178 " name='form_$field_id_esc'" .
1179 " id='form_$field_id_esc'" .
1180 " size='$fldlength'" .
1181 " class='form-control$smallform'" .
1182 " $string_maxlength" .
1183 " value='$resnote' $disabled />&nbsp;</td>";
1184 echo "<td class='font-weight-bold'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" .
1185 "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" .
1186 htmlspecialchars(xl('Status'), ENT_NOQUOTES) . ":&nbsp;&nbsp;</td>";
1187 } elseif ($data_type == 32) {
1188 // input text
1189 echo "<tr><td><input type='text'" .
1190 " name='form_text_$field_id_esc'" .
1191 " id='form_text_$field_id_esc'" .
1192 " size='$fldlength'" .
1193 " class='form-control$smallform'" .
1194 " $string_maxlength" .
1195 " value='$resnote' $disabled />&nbsp;</td></tr>";
1196 echo "<td>";
1197 //Selection list for smoking status
1198 $onchange = 'radioChange(this.options[this.selectedIndex].value)';//VicarePlus :: The javascript function for selection list.
1199 echo generate_select_list(
1200 "form_$field_id",
1201 $list_id,
1202 $reslist,
1203 $description,
1204 ($showEmpty ? $empty_title : ''),
1205 $smallform,
1206 $onchange,
1208 ($disabled ? array('disabled' => 'disabled') : null)
1210 echo "</td>";
1211 echo "<td class='font-weight-bold'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . xlt('Status') . ":&nbsp;&nbsp;</td>";
1214 // current
1215 echo "<td class='text'><input type='radio'" .
1216 " name='radio_{$field_id_esc}'" .
1217 " id='radio_{$field_id_esc}[current]'" .
1218 " class='form-check-inline'" .
1219 " value='current" . $field_id_esc . "' $lbfonchange";
1220 if ($restype == "current" . $field_id) {
1221 echo " checked";
1224 if ($data_type == 32) {
1225 echo " onClick='smoking_statusClicked(this)'";
1228 echo " />" . xlt('Current') . "&nbsp;</td>";
1229 // quit
1230 echo "<td class='text'><input type='radio'" .
1231 " name='radio_{$field_id_esc}'" .
1232 " id='radio_{$field_id_esc}[quit]'" .
1233 " class='form-check-inline'" .
1234 " value='quit" . $field_id_esc . "' $lbfonchange";
1235 if ($restype == "quit" . $field_id) {
1236 echo " checked";
1239 if ($data_type == 32) {
1240 echo " onClick='smoking_statusClicked(this)'";
1243 echo " $disabled />" . xlt('Quit') . "&nbsp;</td>";
1244 // quit date
1245 echo "<td class='text'><input type='text' size='6' class='form-control datepicker' name='date_$field_id_esc' id='date_$field_id_esc'" .
1246 " value='$resdate'" .
1247 " title='$description'" .
1248 " $disabled />";
1249 echo "&nbsp;</td>";
1250 // never
1251 echo "<td class='text'><input type='radio'" .
1252 " name='radio_{$field_id_esc}'" .
1253 " class='form-check-inline'" .
1254 " id='radio_{$field_id_esc}[never]'" .
1255 " value='never" . $field_id_esc . "' $lbfonchange";
1256 if ($restype == "never" . $field_id) {
1257 echo " checked";
1260 if ($data_type == 32) {
1261 echo " onClick='smoking_statusClicked(this)'";
1264 echo " />" . xlt('Never') . "&nbsp;</td>";
1265 // Not Applicable
1266 echo "<td class='text'><input type='radio'" .
1267 " class='form-check-inline' " .
1268 " name='radio_{$field_id}'" .
1269 " id='radio_{$field_id}[not_applicable]'" .
1270 " value='not_applicable" . $field_id . "' $lbfonchange";
1271 if ($restype == "not_applicable" . $field_id) {
1272 echo " checked";
1275 if ($data_type == 32) {
1276 echo " onClick='smoking_statusClicked(this)'";
1279 echo " $disabled />" . xlt('N/A') . "&nbsp;</td>";
1281 //Added on 5-jun-2k14 (regarding 'Smoking Status - display SNOMED code description')
1282 echo "<td class='text'><div id='smoke_code'></div></td>";
1283 echo "</tr>";
1284 echo "</table>";
1285 } elseif ($data_type == 31) { // static text. read-only, of course.
1286 echo parse_static_text($frow);
1287 } elseif ($data_type == 34) {
1288 // $data_type == 33
1289 // Race and Ethnicity. After added support for backup lists, this is now the same as datatype 1; so have migrated it there.
1290 // $data_type == 33
1292 $arr = explode("|*|*|*|", $currvalue);
1293 echo "<a href='../../../library/custom_template/custom_template.php?type=form_{$field_id}&contextName=" . htmlspecialchars($list_id_esc, ENT_QUOTES) . "' class='iframe_medium text-body text-decoration-none'>";
1294 echo "<div id='form_{$field_id}_div' class='text-area' style='min-width: 133px'>" . $arr[0] . "</div>";
1295 echo "<div style='display: none'><textarea name='form_{$field_id}' id='form_{$field_id}' class='form-control$smallform' style='display: none' $lbfonchange $disabled>" . $currvalue . "</textarea></div>";
1296 echo "</a>";
1297 } elseif ($data_type == 35) { //facilities drop-down list
1298 if (empty($currvalue)) {
1299 $currvalue = 0;
1302 dropdown_facility(
1303 $selected = $currvalue,
1304 $name = "form_$field_id_esc",
1305 $allow_unspecified = true,
1306 $allow_allfacilities = false,
1307 $disabled,
1308 $lbfchange
1310 } elseif ($data_type == 36) { //multiple select, supports backup list
1311 echo generate_select_list(
1312 "form_$field_id",
1313 $list_id,
1314 $currvalue,
1315 $description,
1316 $showEmpty ? $empty_title : '',
1317 $smallform,
1318 $lbfchange,
1320 null,
1321 true,
1322 $backup_list
1324 } elseif ($data_type == 40) { // Canvas and related elements for browser-side image drawing.
1325 // Note you must invoke lbf_canvas_head() (below) to use this field type in a form.
1326 // Unlike other field types, width and height are in pixels.
1327 $canWidth = intval($frow['fld_length']);
1328 $canHeight = intval($frow['fld_rows']);
1329 if (empty($currvalue)) {
1330 if (preg_match('/\\bimage=([a-zA-Z0-9._-]*)/', $frow['description'], $matches)) {
1331 // If defined this is the filename of the default starting image.
1332 $currvalue = $GLOBALS['web_root'] . '/sites/' . $_SESSION['site_id'] . '/images/' . $matches[1];
1336 $mywidth = 50 + ($canWidth > 250 ? $canWidth : 250);
1337 $myheight = 31 + ($canHeight > 261 ? $canHeight : 261);
1338 echo "<div id='form_$field_id_esc' style='width:$mywidth; height:$myheight;'></div>";
1339 // Hidden form field exists to send updated data to the server at submit time.
1340 echo "<input type='hidden' name='form_$field_id_esc' value='' />";
1341 // Hidden image exists to support initialization of the canvas.
1342 echo "<img src='" . attr($currvalue) . "' id='form_{$field_id_esc}_img' style='display:none'>";
1343 // $date_init is a misnomer but it's the place for browser-side setup logic.
1344 $date_init .= " lbfCanvasSetup('form_$field_id_esc', $canWidth, $canHeight);\n";
1345 } elseif ($data_type == 41 || $data_type == 42) {
1346 $datatype = 'patient-signature';
1347 $cpid = $GLOBALS['pid'];
1348 $cuser = $_SESSION['authUserID'];
1349 if ($data_type == 42) {
1350 $datatype = 'admin-signature';
1352 echo "<input type='hidden' id='form_$field_id_esc' name='form_$field_id_esc' value='' />\n";
1353 echo "<img class='signature' id='form_{$field_id_esc}_img' title='$description'
1354 data-pid='$cpid' data-user='$cuser' data-type='$datatype'
1355 data-action='fetch_signature' alt='Get Signature' src='" . attr($currvalue) . "'>\n";
1356 } elseif ($data_type == 44) { //multiple select facility
1357 if (empty($currvalue)) {
1358 $currvalue = 0;
1361 dropdown_facility(
1362 $selected = $currvalue,
1363 $name = "form_$field_id_esc",
1364 $allow_unspecified = false,
1365 $allow_allfacilities = false,
1366 $disabled,
1367 $lbfchange,
1368 true
1370 } elseif ($data_type == 45) { // Multiple provider list, local providers only
1371 $ures = sqlStatement("SELECT id, fname, lname, specialty FROM users " .
1372 "WHERE active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
1373 "AND authorized = 1 ORDER BY lname, fname");
1374 echo "<select name='form_$field_id_esc" . "[]'" . " id='form_$field_id_esc' title='$description' $lbfonchange $disabled class='form-control$smallform select-dropdown' multiple='multiple'>";
1375 $got_selected = false;
1376 while ($urow = sqlFetchArray($ures)) {
1377 $uname = text($urow['fname'] . ' ' . $urow['lname']);
1378 $optionId = attr($urow['id']);
1379 echo "<option value='$optionId'";
1380 $selectedValues = explode("|", $currvalue);
1382 if (in_array($optionId, $selectedValues)) {
1383 echo " selected";
1384 $got_selected = true;
1387 echo ">$uname</option>";
1390 if (!$got_selected && $currvalue) {
1391 echo "<option value='" . attr($currvalue) . "' selected>* " . text($currvalue) . " *</option>";
1392 echo "</select>";
1393 echo " <span class='text-danger' title='" . xla('Please choose a valid selection from the list.') . "'>" . xlt('Fix this') . "!</span>";
1394 } else {
1395 echo "</select>";
1400 function generate_print_field($frow, $currvalue)
1402 global $rootdir, $date_init, $ISSUE_TYPES;
1404 $currescaped = htmlspecialchars($currvalue, ENT_QUOTES);
1406 $data_type = $frow['data_type'];
1407 $field_id = $frow['field_id'];
1408 $list_id = $frow['list_id'];
1409 $fld_length = $frow['fld_length'];
1410 $backup_list = $frow['list_backup_id'];
1412 $description = htmlspecialchars(xl_layout_label($frow['description']), ENT_QUOTES);
1414 // Can pass $frow['empty_title'] with this variable, otherwise
1415 // will default to 'Unassigned'.
1416 // If it is 'SKIP' then an empty text title is completely skipped.
1417 $showEmpty = true;
1418 if (isset($frow['empty_title'])) {
1419 if ($frow['empty_title'] == "SKIP") {
1420 //do not display an 'empty' choice
1421 $showEmpty = false;
1422 $empty_title = "Unassigned";
1423 } else {
1424 $empty_title = $frow['empty_title'];
1426 } else {
1427 $empty_title = "Unassigned";
1430 // generic single-selection list
1431 // Supports backup lists.
1432 if (false && ($data_type == 1 || $data_type == 26 || $data_type == 33 || $data_type == 43)) {
1433 if (empty($fld_length)) {
1434 if ($list_id == 'titles') {
1435 $fld_length = 3;
1436 } else {
1437 $fld_length = 10;
1441 $tmp = '';
1442 if ($currvalue) {
1443 $lrow = sqlQuery("SELECT title FROM list_options " .
1444 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($list_id,$currvalue));
1445 $tmp = xl_list_label($lrow['title']);
1446 if ($lrow == 0 && !empty($backup_list)) {
1447 // since primary list did not map, try to map to backup list
1448 $lrow = sqlQuery("SELECT title FROM list_options " .
1449 "WHERE list_id = ? AND option_id = ?", array($backup_list,$currvalue));
1450 $tmp = xl_list_label($lrow['title']);
1453 if (empty($tmp)) {
1454 $tmp = "($currvalue)";
1458 /*****************************************************************
1459 echo "<input type='text'" .
1460 " size='$fld_length'" .
1461 " value='$tmp'" .
1462 " class='under'" .
1463 " />";
1464 *****************************************************************/
1465 if ($tmp === '') {
1466 $tmp = '&nbsp;';
1467 } else {
1468 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1471 echo $tmp;
1472 } elseif ($data_type == 2 || $data_type == 15) { // simple text field
1473 /*****************************************************************
1474 echo "<input type='text'" .
1475 " size='$fld_length'" .
1476 " value='$currescaped'" .
1477 " class='under'" .
1478 " />";
1479 *****************************************************************/
1480 if ($currescaped === '') {
1481 $currescaped = '&nbsp;';
1484 echo $currescaped;
1485 } elseif ($data_type == 3) { // long or multi-line text field
1486 $fldlength = htmlspecialchars($fld_length, ENT_QUOTES);
1487 $maxlength = htmlspecialchars($frow['fld_rows'], ENT_QUOTES);
1488 echo "<textarea" .
1489 " class='form-control' " .
1490 " cols='$fldlength'" .
1491 " rows='$maxlength'>" .
1492 $currescaped . "</textarea>";
1493 } elseif ($data_type == 4) { // date
1494 $age_asof_date = '';
1495 $agestr = optionalAge($frow, $currvalue, $age_asof_date, $description);
1496 if ($currvalue === '') {
1497 echo '&nbsp;';
1498 } else {
1499 $modtmp = isOption($frow['edit_options'], 'F') === false ? 0 : 1;
1500 if (!$modtmp) {
1501 echo text(oeFormatShortDate($currvalue));
1502 } else {
1503 echo text(oeFormatDateTime($currvalue));
1505 if ($agestr) {
1506 echo "&nbsp;(" . text($agestr) . ")";
1509 } elseif ($data_type == 10 || $data_type == 11) { // provider list
1510 $tmp = '';
1511 if ($currvalue) {
1512 $urow = sqlQuery("SELECT fname, lname, specialty FROM users " .
1513 "WHERE id = ?", array($currvalue));
1514 $tmp = ucwords($urow['fname'] . " " . $urow['lname']);
1515 if (empty($tmp)) {
1516 $tmp = "($currvalue)";
1520 /*****************************************************************
1521 echo "<input type='text'" .
1522 " size='$fld_length'" .
1523 " value='$tmp'" .
1524 " class='under'" .
1525 " />";
1526 *****************************************************************/
1527 if ($tmp === '') {
1528 $tmp = '&nbsp;';
1529 } else {
1530 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1533 echo $tmp;
1534 } elseif ($data_type == 12) { // pharmacy list
1535 $tmp = '';
1536 if ($currvalue) {
1537 $pres = get_pharmacies();
1538 while ($prow = sqlFetchArray($pres)) {
1539 $key = $prow['id'];
1540 if ($currvalue == $key) {
1541 $tmp = $prow['name'] . ' ' . $prow['area_code'] . '-' .
1542 $prow['prefix'] . '-' . $prow['number'] . ' / ' .
1543 $prow['line1'] . ' / ' . $prow['city'];
1547 if (empty($tmp)) {
1548 $tmp = "($currvalue)";
1552 /*****************************************************************
1553 echo "<input type='text'" .
1554 " size='$fld_length'" .
1555 " value='$tmp'" .
1556 " class='under'" .
1557 " />";
1558 *****************************************************************/
1559 if ($tmp === '') {
1560 $tmp = '&nbsp;';
1561 } else {
1562 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1565 echo $tmp;
1566 } elseif ($data_type == 13) { // squads
1567 $tmp = '';
1568 if ($currvalue) {
1569 $squads = AclExtended::aclGetSquads();
1570 if ($squads) {
1571 foreach ($squads as $key => $value) {
1572 if ($currvalue == $key) {
1573 $tmp = $value[3];
1578 if (empty($tmp)) {
1579 $tmp = "($currvalue)";
1583 /*****************************************************************
1584 echo "<input type='text'" .
1585 " size='$fld_length'" .
1586 " value='$tmp'" .
1587 " class='under'" .
1588 " />";
1589 *****************************************************************/
1590 if ($tmp === '') {
1591 $tmp = '&nbsp;';
1592 } else {
1593 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1596 echo $tmp;
1597 } elseif ($data_type == 14) { // Address book.
1598 $tmp = '';
1599 if ($currvalue) {
1600 $urow = sqlQuery("SELECT fname, lname, specialty FROM users " .
1601 "WHERE id = ?", array($currvalue));
1602 $uname = $urow['lname'];
1603 if ($urow['fname']) {
1604 $uname .= ", " . $urow['fname'];
1607 $tmp = $uname;
1608 if (empty($tmp)) {
1609 $tmp = "($currvalue)";
1613 /*****************************************************************
1614 echo "<input type='text'" .
1615 " size='$fld_length'" .
1616 " value='$tmp'" .
1617 " class='under'" .
1618 " />";
1619 *****************************************************************/
1620 if ($tmp === '') {
1621 $tmp = '&nbsp;';
1622 } else {
1623 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1626 echo $tmp;
1627 } elseif ($data_type == 16) { // insurance company list
1628 $tmp = '';
1629 if ($currvalue) {
1630 $insprovs = getInsuranceProviders();
1631 foreach ($insprovs as $key => $ipname) {
1632 if ($currvalue == $key) {
1633 $tmp = $ipname;
1637 if (empty($tmp)) {
1638 $tmp = "($currvalue)";
1642 if ($tmp === '') {
1643 $tmp = '&nbsp;';
1644 } else {
1645 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1648 echo $tmp;
1649 } elseif ($data_type == 17) { // issue types
1650 $tmp = '';
1651 if ($currvalue) {
1652 foreach ($ISSUE_TYPES as $key => $value) {
1653 if ($currvalue == $key) {
1654 $tmp = $value[1];
1658 if (empty($tmp)) {
1659 $tmp = "($currvalue)";
1663 if ($tmp === '') {
1664 $tmp = '&nbsp;';
1665 } else {
1666 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1669 echo $tmp;
1670 } elseif ($data_type == 18) { // Visit categories.
1671 $tmp = '';
1672 if ($currvalue) {
1673 $crow = sqlQuery(
1674 "SELECT pc_catid, pc_catname " .
1675 "FROM openemr_postcalendar_categories WHERE pc_catid = ?",
1676 array($currvalue)
1678 $tmp = xl_appt_category($crow['pc_catname']);
1679 if (empty($tmp)) {
1680 $tmp = "($currvalue)";
1684 if ($tmp === '') {
1685 $tmp = '&nbsp;';
1686 } else {
1687 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
1690 echo $tmp;
1691 } elseif ($data_type == 21) { // a single checkbox or set of labeled checkboxes
1692 if (!$list_id) {
1693 echo "<input type='checkbox'";
1694 if ($currvalue) {
1695 echo " checked";
1697 echo " />";
1698 } else {
1699 // In this special case, fld_length is the number of columns generated.
1700 $cols = max(1, $fld_length);
1701 $avalue = explode('|', $currvalue);
1702 $lres = sqlStatement("SELECT * FROM list_options " .
1703 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1704 echo "<table class='w-100' cellpadding='0' cellspacing='0'>";
1705 $tdpct = (int) (100 / $cols);
1706 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
1707 $option_id = $lrow['option_id'];
1708 if ($count % $cols == 0) {
1709 if ($count) {
1710 echo "</tr>";
1713 echo "<tr>";
1715 echo "<td width='" . attr($tdpct) . "%' nowrap>";
1716 echo "<input type='checkbox'";
1717 if (in_array($option_id, $avalue)) {
1718 echo " checked";
1720 echo ">" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES);
1721 echo "</td>";
1723 if ($count) {
1724 echo "</tr>";
1725 if ($count > $cols) {
1726 // Add some space after multiple rows of checkboxes.
1727 $cols = htmlspecialchars($cols, ENT_QUOTES);
1728 echo "<tr><td colspan='$cols' style='height:0.7em'></td></tr>";
1731 echo "</table>";
1733 } elseif ($data_type == 22) { // a set of labeled text input fields
1734 $tmp = explode('|', $currvalue);
1735 $avalue = array();
1736 foreach ($tmp as $value) {
1737 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
1738 $avalue[$matches[1]] = $matches[2];
1742 $lres = sqlStatement("SELECT * FROM list_options " .
1743 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1744 echo "<table class='table'>";
1745 while ($lrow = sqlFetchArray($lres)) {
1746 $option_id = $lrow['option_id'];
1747 $fldlength = empty($fld_length) ? 20 : $fld_length;
1748 echo "<tr><td>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
1749 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
1750 $inputValue = htmlspecialchars($avalue[$option_id], ENT_QUOTES);
1751 echo "<td><input type='text'" .
1752 " class='form-control' " .
1753 " size='$fldlength'" .
1754 " value='$inputValue'" .
1755 " class='under'" .
1756 " /></td></tr>";
1759 echo "</table>";
1760 } elseif ($data_type == 23) { // a set of exam results; 3 radio buttons and a text field:
1761 $tmp = explode('|', $currvalue);
1762 $avalue = array();
1763 foreach ($tmp as $value) {
1764 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
1765 $avalue[$matches[1]] = $matches[2];
1769 $fldlength = empty($fld_length) ? 20 : $fld_length;
1770 $lres = sqlStatement("SELECT * FROM list_options " .
1771 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1772 echo "<table class='table'>";
1773 echo "<tr><td>&nbsp;</td><td class='font-weight-bold'>" .
1774 htmlspecialchars(xl('N/A'), ENT_NOQUOTES) .
1775 "&nbsp;</td><td class='font-weight-bold'>" .
1776 htmlspecialchars(xl('Nor'), ENT_NOQUOTES) . "&nbsp;</td>" .
1777 "<td class='font-weight-bold'>" .
1778 htmlspecialchars(xl('Abn'), ENT_NOQUOTES) . "&nbsp;</td><td class='font-weight-bold'>" .
1779 htmlspecialchars(xl('Date/Notes'), ENT_NOQUOTES) . "</td></tr>";
1780 while ($lrow = sqlFetchArray($lres)) {
1781 $option_id = $lrow['option_id'];
1782 $restype = substr($avalue[$option_id], 0, 1);
1783 $resnote = substr($avalue[$option_id], 2);
1784 echo "<tr><td>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
1785 for ($i = 0; $i < 3; ++$i) {
1786 echo "<td><input type='radio'";
1787 if ($restype === "$i") {
1788 echo " checked";
1791 echo " /></td>";
1794 $resnote = htmlspecialchars($resnote, ENT_QUOTES);
1795 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
1796 echo "<td><input type='text'" .
1797 " size='$fldlength'" .
1798 " value='$resnote'" .
1799 " class='under form-control' /></td>" .
1800 "</tr>";
1803 echo "</table>";
1804 } elseif ($data_type == 24) { // the list of active allergies for the current patient
1805 // this is read-only!
1806 $query = "SELECT title, comments FROM lists WHERE " .
1807 "pid = ? AND type = 'allergy' AND enddate IS NULL " .
1808 "ORDER BY begdate";
1809 $lres = sqlStatement($query, array($GLOBALS['pid']));
1810 $count = 0;
1811 while ($lrow = sqlFetchArray($lres)) {
1812 if ($count++) {
1813 echo "<br />";
1816 echo htmlspecialchars($lrow['title'], ENT_QUOTES);
1817 if ($lrow['comments']) {
1818 echo htmlspecialchars(' (' . $lrow['comments'] . ')', ENT_QUOTES);
1821 } elseif ($data_type == 25) { // a set of labeled checkboxes, each with a text field:
1822 $tmp = explode('|', $currvalue);
1823 $avalue = array();
1824 foreach ($tmp as $value) {
1825 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
1826 $avalue[$matches[1]] = $matches[2];
1830 $fldlength = empty($fld_length) ? 20 : $fld_length;
1831 $lres = sqlStatement("SELECT * FROM list_options " .
1832 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1833 echo "<table class='table'>";
1834 while ($lrow = sqlFetchArray($lres)) {
1835 $option_id = $lrow['option_id'];
1836 $restype = substr($avalue[$option_id], 0, 1);
1837 $resnote = substr($avalue[$option_id], 2);
1838 echo "<tr><td>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
1839 echo "<td><input type='checkbox'";
1840 if ($restype) {
1841 echo " checked";
1844 echo " />&nbsp;</td>";
1845 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
1846 $resnote = htmlspecialchars($resnote, ENT_QUOTES);
1847 echo "<td><input type='text'" .
1848 " size='$fldlength'" .
1849 " class='form-control' " .
1850 " value='$resnote'" .
1851 " class='under'" .
1852 " /></td>" .
1853 "</tr>";
1856 echo "</table>";
1857 } elseif ($data_type == 27 || $data_type == 1 || $data_type == 26 || $data_type == 33) {
1858 // a set of labeled radio buttons
1859 // In this special case, fld_length is the number of columns generated.
1860 $cols = max(1, $frow['fld_length']);
1861 $lres = sqlStatement("SELECT * FROM list_options " .
1862 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
1863 echo "<table class='w-100' cellpadding='0' cellspacing='0'>";
1864 $tdpct = (int) (100 / $cols);
1865 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
1866 $option_id = $lrow['option_id'];
1867 if ($count % $cols == 0) {
1868 if ($count) {
1869 echo "</tr>";
1872 echo "<tr>";
1874 echo "<td width='" . attr($tdpct) . "%' nowrap>";
1875 echo "<input type='radio'";
1876 if (strlen($currvalue) > 0 && $option_id == $currvalue) {
1877 // Do not use defaults for these printable forms.
1878 echo " checked";
1881 echo ">" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES);
1882 echo "</td>";
1885 if ($count) {
1886 echo "</tr>";
1887 if ($count > $cols) {
1888 // Add some space after multiple rows of radio buttons.
1889 $cols = htmlspecialchars($cols, ENT_QUOTES);
1890 echo "<tr><td colspan='$cols' style='height:0.7em'></td></tr>";
1894 echo "</table>";
1895 } elseif ($data_type == 28 || $data_type == 32) { // special case for history of lifestyle status; 3 radio buttons and a date text field:
1896 $tmp = explode('|', $currvalue);
1897 switch (count($tmp)) {
1898 case "4":
1899 $resnote = $tmp[0];
1900 $restype = $tmp[1];
1901 $resdate = oeFormatShortDate($tmp[2]) ;
1902 $reslist = $tmp[3];
1903 break;
1904 case "3":
1905 $resnote = $tmp[0];
1906 $restype = $tmp[1];
1907 $resdate = oeFormatShortDate($tmp[2]);
1908 $reslist = '';
1909 break;
1910 case "2":
1911 $resnote = $tmp[0];
1912 $restype = $tmp[1];
1913 $resdate = "";
1914 $reslist = '';
1915 break;
1916 case "1":
1917 $resnote = $tmp[0];
1918 $resdate = $restype = "";
1919 $reslist = '';
1920 break;
1921 default:
1922 $restype = $resdate = $resnote = "";
1923 $reslist = '';
1924 break;
1927 $fldlength = empty($frow['fld_length']) ? 20 : $frow['fld_length'];
1928 echo "<table class='table'>";
1929 echo "<tr>";
1930 $fldlength = htmlspecialchars($fldlength, ENT_QUOTES);
1931 $resnote = htmlspecialchars($resnote, ENT_QUOTES);
1932 $resdate = htmlspecialchars($resdate, ENT_QUOTES);
1933 if ($data_type == 28) {
1934 echo "<td><input type='text'" .
1935 " size='$fldlength'" .
1936 " class='under'" .
1937 " value='$resnote' /></td>";
1938 echo "<td class='font-weight-bold'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" .
1939 "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" .
1940 htmlspecialchars(xl('Status'), ENT_NOQUOTES) . ":&nbsp;</td>";
1941 } elseif ($data_type == 32) {
1942 echo "<tr><td><input type='text'" .
1943 " size='$fldlength'" .
1944 " class='under form-control'" .
1945 " value='$resnote' /></td></tr>";
1946 $fldlength = 30;
1947 $smoking_status_title = generate_display_field(array('data_type' => '1','list_id' => $list_id), $reslist);
1948 echo "<td><input type='text'" .
1949 " size='$fldlength'" .
1950 " class='under form-control'" .
1951 " value='$smoking_status_title' /></td>";
1952 echo "<td class='font-weight-bold'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" . htmlspecialchars(xl('Status'), ENT_NOQUOTES) . ":&nbsp;&nbsp;</td>";
1955 echo "<td><input type='radio' class='form-check-inline'";
1956 if ($restype == "current" . $field_id) {
1957 echo " checked";
1960 echo "/>" . htmlspecialchars(xl('Current'), ENT_NOQUOTES) . "&nbsp;</td>";
1962 echo "<td><input type='radio' class='form-check-inline'";
1963 if ($restype == "current" . $field_id) {
1964 echo " checked";
1967 echo "/>" . htmlspecialchars(xl('Quit'), ENT_NOQUOTES) . "&nbsp;</td>";
1969 echo "<td><input type='text' size='6'" .
1970 " value='$resdate'" .
1971 " class='under form-control'" .
1972 " /></td>";
1974 echo "<td><input type='radio' class='form-check-inline'";
1975 if ($restype == "current" . $field_id) {
1976 echo " checked";
1979 echo " />" . htmlspecialchars(xl('Never'), ENT_NOQUOTES) . "</td>";
1981 echo "<td><input type='radio' class='form-check-inline'";
1982 if ($restype == "not_applicable" . $field_id) {
1983 echo " checked";
1986 echo " />" . htmlspecialchars(xl('N/A'), ENT_NOQUOTES) . "&nbsp;</td>";
1987 echo "</tr>";
1988 echo "</table>";
1989 } elseif ($data_type == 31) { // static text. read-only, of course.
1990 echo parse_static_text($frow);
1991 } elseif ($data_type == 34) {
1992 echo "<a href='../../../library/custom_template/custom_template.php?type=form_{$field_id}&contextName=" . htmlspecialchars($list_id_esc, ENT_QUOTES) . "' class='iframe_medium text-body text-decoration-none'>";
1993 echo "<div id='form_{$field_id}_div' class='text-area'></div>";
1994 echo "<div style='display: none'><textarea name='form_{$field_id}' class='form-control' id='form_{$field_id}' style='display: none'></textarea></div>";
1995 echo "</a>";
1996 } elseif ($data_type == 35) { //facilities drop-down list
1997 // In this special case, fld_length is the number of columns generated.
1998 $cols = max(1, $frow['fld_length']);
1999 $lres = sqlStatement("SELECT id, name FROM facility ORDER BY name");
2000 echo "<table class='w-100' cellpadding='0' cellspacing='0'>";
2001 $tdpct = (int) (100 / $cols);
2002 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
2003 $option_id = $lrow['id'];
2004 if ($count % $cols == 0) {
2005 if ($count) {
2006 echo "</tr>";
2008 echo "<tr>";
2010 echo "<td width='" . attr($tdpct) . "%'>";
2011 echo "<input type='radio'";
2012 if (strlen($currvalue) > 0 && $option_id == $currvalue) {
2013 // Do not use defaults for these printable forms.
2014 echo " checked";
2016 echo ">" . htmlspecialchars($lrow['name']);
2017 echo "</td>";
2019 if ($count) {
2020 echo "</tr>";
2021 if ($count > $cols) {
2022 // Add some space after multiple rows of radio buttons.
2023 echo "<tr><td colspan='$cols' style='height:0.7em'></td></tr>";
2026 echo "</table>";
2027 } elseif ($data_type == 36) { //Multi-select. Supports backup lists.
2028 if (empty($fld_length)) {
2029 if ($list_id == 'titles') {
2030 $fld_length = 3;
2031 } else {
2032 $fld_length = 10;
2036 $tmp = '';
2038 $values_array = explode("|", $currvalue);
2040 $i = 0;
2041 foreach ($values_array as $value) {
2042 if ($value) {
2043 $lrow = sqlQuery("SELECT title FROM list_options " .
2044 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($list_id,$value));
2045 $tmp = xl_list_label($lrow['title']);
2046 if ($lrow == 0 && !empty($backup_list)) {
2047 // since primary list did not map, try to map to backup list
2048 $lrow = sqlQuery("SELECT title FROM list_options " .
2049 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($backup_list,$currvalue));
2050 $tmp = xl_list_label($lrow['title']);
2053 if (empty($tmp)) {
2054 $tmp = "($value)";
2058 if ($tmp === '') {
2059 $tmp = '&nbsp;';
2060 } else {
2061 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
2064 if ($i != 0 && $tmp != '&nbsp;') {
2065 echo ",";
2068 echo $tmp;
2069 $i++;
2071 } elseif ($data_type == 40) { // Image from canvas drawing
2072 if ($currvalue) {
2073 echo "<img src='" . attr($currvalue) . "'>";
2075 } elseif ($data_type == 41 || $data_type == 42) {
2076 if ($currvalue) {
2077 echo "<img class='w-auto' style='height: 70px;' src='" . attr($currvalue) . "'>";
2079 } elseif ($data_type == 44 || $data_type == 45) {
2080 $tmp = '';
2082 $values_array = explode("|", $currvalue);
2084 $i = 0;
2085 foreach ($values_array as $value) {
2086 if ($value) {
2087 if ($data_type == 44) {
2088 $lrow = sqlQuery("SELECT name as name FROM facility WHERE id = ?", array($value));
2090 if ($data_type == 45) {
2091 $lrow = sqlQuery("SELECT CONCAT(fname,' ',lname) as name FROM users WHERE id = ?", array($value));
2093 $tmp = $lrow['name'];
2096 if ($tmp === '') {
2097 $tmp = '&nbsp;';
2098 } else {
2099 $tmp = htmlspecialchars($tmp, ENT_QUOTES);
2102 if ($i != 0 && $tmp != '&nbsp;') {
2103 echo ",";
2106 echo $tmp;
2107 $i++;
2113 * @param $list_id
2114 * @param bool $translate
2115 * @return array
2117 * Generate a key-value array containing each row of the specified list,
2118 * with the option ID as the index, and the title as the element
2120 * Pass in the list_id to specify this list.
2122 * Use the translate flag to run the title element through the translator
2124 function generate_list_map($list_id, $translate = false)
2126 $result = sqlStatement("SELECT option_id, title FROM list_options WHERE list_id = ?", [$list_id]);
2127 $map = [];
2128 while ($row = sqlFetchArray($result)) {
2129 if ($translate === true) {
2130 $title = xl_list_label($row['title']);
2131 } else {
2132 $title = $row['title'];
2134 $map[$row['option_id']] = $title;
2137 return $map;
2140 function generate_display_field($frow, $currvalue)
2142 global $ISSUE_TYPES, $facilityService;
2144 $data_type = $frow['data_type'];
2145 $field_id = isset($frow['field_id']) ? $frow['field_id'] : null;
2146 $list_id = $frow['list_id'];
2147 $backup_list = isset($frow['list_backup_id']) ? $frow['list_backup_id'] : null;
2149 $s = '';
2151 // generic selection list or the generic selection list with add on the fly
2152 // feature
2153 if ($data_type == 1 || $data_type == 26 || $data_type == 33 || $data_type == 43) {
2154 $lrow = sqlQuery("SELECT title FROM list_options " .
2155 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($list_id,$currvalue));
2156 $s = htmlspecialchars(xl_list_label($lrow['title'] ?? ''), ENT_NOQUOTES);
2157 //if there is no matching value in the corresponding lists check backup list
2158 // only supported in data types 1,26,33,43
2159 if ($lrow == 0 && !empty($backup_list) && ($data_type == 1 || $data_type == 26 || $data_type == 33 || $data_type == 43)) {
2160 $lrow = sqlQuery("SELECT title FROM list_options " .
2161 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($backup_list,$currvalue));
2162 $s = htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES);
2164 // If match is not found in main and backup lists, return the key with exclamation mark
2165 if ($s == '') {
2166 $s = nl2br(text(xl_list_label($currvalue))) .
2167 '<span> <i class="fa fas fa-exclamation-circle ml-1"></i></span>';
2169 } elseif ($data_type == 2) { // simple text field
2170 $s = nl2br(htmlspecialchars($currvalue, ENT_NOQUOTES));
2171 } elseif ($data_type == 3) { // long or multi-line text field
2172 $s = nl2br(htmlspecialchars($currvalue, ENT_NOQUOTES));
2173 } elseif ($data_type == 4) { // date
2174 $asof = ''; //not used here, but set to prevent a php warning when call optionalAge
2175 $s = '';
2176 $description = (isset($frow['description']) ? htmlspecialchars(xl_layout_label($frow['description']), ENT_QUOTES) : '');
2177 $age_asof_date = '';
2178 $agestr = optionalAge($frow, $currvalue, $age_asof_date, $description);
2179 if ($currvalue === '') {
2180 $s .= '&nbsp;';
2181 } else {
2182 $modtmp = isOption($frow['edit_options'], 'F') === false ? 0 : 1;
2183 if (!$modtmp) {
2184 $s .= text(oeFormatShortDate($currvalue));
2185 } else {
2186 $s .= text(oeFormatDateTime($currvalue));
2188 if ($agestr) {
2189 $s .= "&nbsp;(" . text($agestr) . ")";
2192 } elseif ($data_type == 10 || $data_type == 11) { // provider
2193 $urow = sqlQuery("SELECT fname, lname, specialty FROM users " .
2194 "WHERE id = ?", array($currvalue));
2195 $s = text(ucwords(($urow['fname'] ?? '') . " " . ($urow['lname'] ?? '')));
2196 } elseif ($data_type == 12) { // pharmacy list
2197 $pres = get_pharmacies();
2198 while ($prow = sqlFetchArray($pres)) {
2199 $key = $prow['id'];
2200 if ($currvalue == $key) {
2201 $s .= htmlspecialchars($prow['name'] . ' ' . $prow['area_code'] . '-' .
2202 $prow['prefix'] . '-' . $prow['number'] . ' / ' .
2203 $prow['line1'] . ' / ' . $prow['city'], ENT_NOQUOTES);
2206 } elseif ($data_type == 13) { // squads
2207 $squads = AclExtended::aclGetSquads();
2208 if ($squads) {
2209 foreach ($squads as $key => $value) {
2210 if ($currvalue == $key) {
2211 $s .= htmlspecialchars($value[3], ENT_NOQUOTES);
2215 } elseif ($data_type == 14) { // address book
2216 $urow = sqlQuery("SELECT fname, lname, specialty, organization FROM users " .
2217 "WHERE id = ?", array($currvalue));
2218 //ViSolve: To display the Organization Name if it exist. Else it will display the user name.
2219 if ($urow['organization'] != "") {
2220 $uname = $urow['organization'];
2221 } else {
2222 $uname = $urow['lname'];
2223 if ($urow['fname']) {
2224 $uname .= ", " . $urow['fname'];
2228 $s = htmlspecialchars($uname, ENT_NOQUOTES);
2229 } elseif ($data_type == 15) { // billing code
2230 $s = '';
2231 if (!empty($currvalue)) {
2232 $relcodes = explode(';', $currvalue);
2233 foreach ($relcodes as $codestring) {
2234 if ($codestring === '') {
2235 continue;
2237 $tmp = lookup_code_descriptions($codestring);
2238 if ($s !== '') {
2239 $s .= '; ';
2241 if (!empty($tmp)) {
2242 $s .= text($tmp);
2243 } else {
2244 $s .= text($codestring) . ' (' . xlt('not found') . ')';
2248 } elseif ($data_type == 16) { // insurance company list
2249 $insprovs = getInsuranceProviders();
2250 foreach ($insprovs as $key => $ipname) {
2251 if ($currvalue == $key) {
2252 $s .= htmlspecialchars($ipname, ENT_NOQUOTES);
2255 } elseif ($data_type == 17) { // issue types
2256 foreach ($ISSUE_TYPES as $key => $value) {
2257 if ($currvalue == $key) {
2258 $s .= htmlspecialchars($value[1], ENT_NOQUOTES);
2261 } elseif ($data_type == 18) { // visit category
2262 $crow = sqlQuery(
2263 "SELECT pc_catid, pc_catname " .
2264 "FROM openemr_postcalendar_categories WHERE pc_catid = ?",
2265 array($currvalue)
2267 $s = htmlspecialchars($crow['pc_catname'], ENT_NOQUOTES);
2268 } elseif ($data_type == 21) { // a single checkbox or set of labeled checkboxes
2269 if (!$list_id) {
2270 $s .= $currvalue ? '[ x ]' : '[ &nbsp;&nbsp; ]';
2271 } else {
2272 // In this special case, fld_length is the number of columns generated.
2273 $cols = max(1, $frow['fld_length']);
2274 $avalue = explode('|', $currvalue);
2275 $lres = sqlStatement("SELECT * FROM list_options " .
2276 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2277 $s .= "<table cellspacing='0' cellpadding='0'>";
2278 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
2279 $option_id = $lrow['option_id'];
2280 $option_id_esc = text($option_id);
2281 if ($count % $cols == 0) {
2282 if ($count) {
2283 $s .= "</tr>";
2285 $s .= "<tr>";
2287 $s .= "<td nowrap>";
2288 $checked = in_array($option_id, $avalue);
2289 $s .= $checked ? '[ x ]' : '[ &nbsp;&nbsp; ]';
2290 $s .= '&nbsp;' . text(xl_list_label($lrow['title'])) . '&nbsp;&nbsp;';
2291 $s .= "</td>";
2293 if ($count) {
2294 $s .= "</tr>";
2296 $s .= "</table>";
2298 } elseif ($data_type == 22) { // a set of labeled text input fields
2299 $tmp = explode('|', $currvalue);
2300 $avalue = array();
2301 foreach ($tmp as $value) {
2302 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
2303 $avalue[$matches[1]] = $matches[2];
2307 $lres = sqlStatement("SELECT * FROM list_options " .
2308 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2309 $s .= "<table class='table'>";
2310 while ($lrow = sqlFetchArray($lres)) {
2311 $option_id = $lrow['option_id'];
2312 if (empty($avalue[$option_id])) {
2313 continue;
2316 // Added 5-09 by BM - Translate label if applicable
2317 $s .= "<tr><td class='font-weight-bold align-top'>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . ":&nbsp;</td>";
2319 $s .= "<td class='text align-top'>" . htmlspecialchars($avalue[$option_id], ENT_NOQUOTES) . "</td></tr>";
2322 $s .= "</table>";
2323 } elseif ($data_type == 23) { // a set of exam results; 3 radio buttons and a text field:
2324 $tmp = explode('|', $currvalue);
2325 $avalue = array();
2326 foreach ($tmp as $value) {
2327 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
2328 $avalue[$matches[1]] = $matches[2];
2332 $lres = sqlStatement("SELECT * FROM list_options " .
2333 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2334 $s .= "<table class='table'>";
2335 while ($lrow = sqlFetchArray($lres)) {
2336 $option_id = $lrow['option_id'];
2337 $restype = substr(($avalue[$option_id] ?? ''), 0, 1);
2338 $resnote = substr(($avalue[$option_id] ?? ''), 2);
2339 if (empty($restype) && empty($resnote)) {
2340 continue;
2343 // Added 5-09 by BM - Translate label if applicable
2344 $s .= "<tr><td class='font-weight-bold align-top'>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
2346 $restype = ($restype == '1') ? xl('Normal') : (($restype == '2') ? xl('Abnormal') : xl('N/A'));
2347 // $s .= "<td class='text align-top'>$restype</td></tr>";
2348 // $s .= "<td class='text align-top'>$resnote</td></tr>";
2349 $s .= "<td class='text align-top'>" . htmlspecialchars($restype, ENT_NOQUOTES) . "&nbsp;</td>";
2350 $s .= "<td class='text align-top'>" . htmlspecialchars($resnote, ENT_NOQUOTES) . "</td>";
2351 $s .= "</tr>";
2354 $s .= "</table>";
2355 } elseif ($data_type == 24) { // the list of active allergies for the current patient
2356 $query = "SELECT title, comments FROM lists WHERE " .
2357 "pid = ? AND type = 'allergy' AND enddate IS NULL " .
2358 "ORDER BY begdate";
2359 // echo "<!-- $query -->\n"; // debugging
2360 $lres = sqlStatement($query, array($GLOBALS['pid']));
2361 $count = 0;
2362 while ($lrow = sqlFetchArray($lres)) {
2363 if ($count++) {
2364 $s .= "<br />";
2367 $s .= htmlspecialchars($lrow['title'], ENT_NOQUOTES);
2368 if ($lrow['comments']) {
2369 $s .= ' (' . htmlspecialchars($lrow['comments'], ENT_NOQUOTES) . ')';
2372 } elseif ($data_type == 25) { // a set of labeled checkboxes, each with a text field:
2373 $tmp = explode('|', $currvalue);
2374 $avalue = array();
2375 foreach ($tmp as $value) {
2376 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
2377 $avalue[$matches[1]] = $matches[2];
2381 $lres = sqlStatement("SELECT * FROM list_options " .
2382 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2383 $s .= "<table class='table'>";
2384 while ($lrow = sqlFetchArray($lres)) {
2385 $option_id = $lrow['option_id'];
2386 $restype = substr($avalue[$option_id], 0, 1);
2387 $resnote = substr($avalue[$option_id], 2);
2388 if (empty($restype) && empty($resnote)) {
2389 continue;
2392 // Added 5-09 by BM - Translate label if applicable
2393 $s .= "<tr><td class='font-weight-bold align-top'>" . htmlspecialchars(xl_list_label($lrow['title']), ENT_NOQUOTES) . "&nbsp;</td>";
2395 $restype = $restype ? xl('Yes') : xl('No');
2396 $s .= "<td class='text align-top'>" . htmlspecialchars($restype, ENT_NOQUOTES) . "&nbsp;</td>";
2397 $s .= "<td class='text align-top'>" . htmlspecialchars($resnote, ENT_NOQUOTES) . "</td>";
2398 $s .= "</tr>";
2401 $s .= "</table>";
2402 } elseif ($data_type == 27) { // a set of labeled radio buttons
2403 // In this special case, fld_length is the number of columns generated.
2404 $cols = max(1, $frow['fld_length']);
2405 $lres = sqlStatement("SELECT * FROM list_options " .
2406 "WHERE list_id = ? ORDER BY seq, title", array($list_id));
2407 $s .= "<table cellspacing='0' cellpadding='0'>";
2408 for ($count = 0; $lrow = sqlFetchArray($lres); ++$count) {
2409 $option_id = $lrow['option_id'];
2410 $option_id_esc = text($option_id);
2411 if ($count % $cols == 0) {
2412 if ($count) {
2413 $s .= "</tr>";
2415 $s .= "<tr>";
2417 $s .= "<td nowrap>";
2418 $checked = ((strlen($currvalue) == 0 && $lrow['is_default']) ||
2419 (strlen($currvalue) > 0 && $option_id == $currvalue));
2420 $s .= $checked ? '[ x ]' : '[ &nbsp;&nbsp; ]';
2421 $s .= '&nbsp;' . text(xl_list_label($lrow['title'])) . '&nbsp;&nbsp;';
2422 $s .= "</td>";
2424 if ($count) {
2425 $s .= "</tr>";
2427 $s .= "</table>";
2428 } elseif ($data_type == 28 || $data_type == 32) { // special case for history of lifestyle status; 3 radio buttons
2429 // and a date text field:
2430 // VicarePlus :: A selection list for smoking status.
2431 $tmp = explode('|', $currvalue);
2432 switch (count($tmp)) {
2433 case "4":
2434 $resnote = $tmp[0];
2435 $restype = $tmp[1];
2436 $resdate = oeFormatShortDate($tmp[2]);
2437 $reslist = $tmp[3];
2438 break;
2439 case "3":
2440 $resnote = $tmp[0];
2441 $restype = $tmp[1];
2442 $resdate = oeFormatShortDate($tmp[2]);
2443 $reslist = '';
2444 break;
2445 case "2":
2446 $resnote = $tmp[0];
2447 $restype = $tmp[1];
2448 $resdate = "";
2449 $reslist = '';
2450 break;
2451 case "1":
2452 $resnote = $tmp[0];
2453 $resdate = $restype = "";
2454 $reslist = '';
2455 break;
2456 default:
2457 $restype = $resdate = $resnote = "";
2458 $reslist = '';
2459 break;
2462 $s .= "<table class='table'>";
2464 $s .= "<tr>";
2465 $res = "";
2466 if ($restype == "current" . $field_id) {
2467 $res = xl('Current');
2470 if ($restype == "quit" . $field_id) {
2471 $res = xl('Quit');
2474 if ($restype == "never" . $field_id) {
2475 $res = xl('Never');
2478 if ($restype == "not_applicable" . $field_id) {
2479 $res = xl('N/A');
2482 // $s .= "<td class='text align-top'>$restype</td></tr>";
2483 // $s .= "<td class='text align-top'>$resnote</td></tr>";
2484 if ($data_type == 28) {
2485 if (!empty($resnote)) {
2486 $s .= "<td class='text align-top'>" . htmlspecialchars($resnote, ENT_NOQUOTES) . "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td>";
2488 } elseif ($data_type == 32) { //VicarePlus :: Tobacco field has a listbox, text box, date field and 3 radio buttons.
2489 // changes on 5-jun-2k14 (regarding 'Smoking Status - display SNOMED code description')
2490 $smoke_codes = getSmokeCodes();
2491 if (!empty($reslist)) {
2492 if ($smoke_codes[$reslist] != "") {
2493 $code_desc = "( " . $smoke_codes[$reslist] . " )";
2496 $s .= "<td class='text align-top'>" . generate_display_field(array('data_type' => '1','list_id' => $list_id), $reslist) . "&nbsp;" . text($code_desc) . "&nbsp;&nbsp;&nbsp;&nbsp;</td>";
2499 if (!empty($resnote)) {
2500 $s .= "<td class='text align-top'>" . htmlspecialchars($resnote, ENT_NOQUOTES) . "&nbsp;&nbsp;</td>";
2504 if (!empty($res)) {
2505 $s .= "<td class='text align-top'><strong>" . htmlspecialchars(xl('Status'), ENT_NOQUOTES) . "</strong>:&nbsp;" . htmlspecialchars($res, ENT_NOQUOTES) . "&nbsp;</td>";
2508 if ($restype == "quit" . $field_id) {
2509 $s .= "<td class='text align-top'>" . htmlspecialchars($resdate, ENT_NOQUOTES) . "&nbsp;</td>";
2512 $s .= "</tr>";
2513 $s .= "</table>";
2514 } elseif ($data_type == 31) { // static text. read-only, of course.
2515 $s .= parse_static_text($frow);
2516 } elseif ($data_type == 34) {
2517 $arr = explode("|*|*|*|", $currvalue);
2518 for ($i = 0; $i < sizeof($arr); $i++) {
2519 $s .= $arr[$i];
2521 } elseif ($data_type == 35) { // facility
2522 $urow = $facilityService->getById($currvalue);
2523 $s = htmlspecialchars($urow['name'], ENT_NOQUOTES);
2524 } elseif ($data_type == 36) { // Multi select. Supports backup lists
2525 $values_array = explode("|", $currvalue);
2526 $i = 0;
2527 foreach ($values_array as $value) {
2528 $lrow = sqlQuery("SELECT title FROM list_options " .
2529 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($list_id,$value));
2530 if ($lrow == 0 && !empty($backup_list)) {
2531 //use back up list
2532 $lrow = sqlQuery("SELECT title FROM list_options " .
2533 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($backup_list,$value));
2536 $title = $lrow['title'] ?? '';
2537 if ($i > 0) {
2538 $s = $s . ", " . text(xl_list_label($title));
2539 } else {
2540 $s = text(xl_list_label($title));
2543 $i++;
2545 } elseif ($data_type == 40) { // Image from canvas drawing
2546 if ($currvalue) {
2547 $s .= "<img src='" . attr($currvalue) . "'>";
2549 } elseif ($data_type == 41 || $data_type == 42) {
2550 if ($currvalue) {
2551 $s .= "<img class='w-auto' style='height: 70px;' src='" . attr($currvalue) . "'>";
2553 } elseif ($data_type == 44 || $data_type == 45) { // Multiple select facility and provider
2554 $values_array = explode("|", $currvalue);
2555 $i = 0;
2556 foreach ($values_array as $value) {
2557 if ($data_type == 44) {
2558 $lrow = sqlQuery("SELECT name as name FROM facility WHERE id = ?", array($value));
2560 if ($data_type == 45) {
2561 $lrow = sqlQuery("SELECT CONCAT(fname,' ',lname) as name FROM users WHERE id = ?", array($value));
2563 if ($i > 0) {
2564 $s = $s . ", " . htmlspecialchars($lrow['name'], ENT_NOQUOTES);
2565 } else {
2566 $s = text($lrow['name'] ?? '');
2568 $i++;
2572 return $s;
2575 // Generate plain text versions of selected LBF field types.
2576 // Currently used by interface/patient_file/download_template.php and interface/main/finder/dynamic_finder_ajax.php.
2577 // More field types might need to be supported here in the future.
2579 function generate_plaintext_field($frow, $currvalue)
2581 global $ISSUE_TYPES;
2583 $data_type = $frow['data_type'];
2584 $field_id = isset($frow['field_id']) ? $frow['field_id'] : null;
2585 $list_id = $frow['list_id'];
2586 $backup_list = $frow['backup_list'] ?? null;
2587 $edit_options = $frow['edit_options'] ?? null;
2588 $s = '';
2590 // generic selection list or the generic selection list with add on the fly
2591 // feature, or radio buttons
2592 // Supports backup lists (for datatypes 1,26,33,43)
2593 if ($data_type == 1 || $data_type == 26 || $data_type == 27 || $data_type == 33 || $data_type == 43) {
2594 $lrow = sqlQuery(
2595 "SELECT title FROM list_options " .
2596 "WHERE list_id = ? AND option_id = ? AND activity = 1",
2597 array($list_id, $currvalue)
2599 $s = xl_list_label($lrow['title']);
2600 //if there is no matching value in the corresponding lists check backup list
2601 // only supported in data types 1,26,33,43
2602 if ($lrow == 0 && !empty($backup_list) && ($data_type == 1 || $data_type == 26 || $data_type == 33 || $data_type == 43)) {
2603 $lrow = sqlQuery("SELECT title FROM list_options " .
2604 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($backup_list, $currvalue));
2605 $s = xl_list_label($lrow['title']);
2607 } elseif ($data_type == 2 || $data_type == 3 || $data_type == 15) { // simple or long text field
2608 $s = $currvalue;
2609 } elseif ($data_type == 4) { // date
2610 $modtmp = isOption($edit_options, 'F') === false ? 0 : 1;
2611 if (!$modtmp) {
2612 $s = text(oeFormatShortDate($currvalue));
2613 } else {
2614 $s = text(oeFormatDateTime($currvalue));
2616 $description = (isset($frow['description']) ? htmlspecialchars(xl_layout_label($frow['description']), ENT_QUOTES) : '');
2617 $age_asof_date = '';
2618 // Optional display of age or gestational age.
2619 $tmp = optionalAge($frow, $currvalue, $age_asof_date, $description);
2620 if ($tmp) {
2621 $s .= ' ' . $tmp;
2623 } elseif ($data_type == 10 || $data_type == 11) { // provider
2624 $urow = sqlQuery("SELECT fname, lname, specialty FROM users " .
2625 "WHERE id = ?", array($currvalue));
2626 $s = ucwords($urow['fname'] . " " . $urow['lname']);
2627 } elseif ($data_type == 12) { // pharmacy list
2628 $pres = get_pharmacies();
2629 while ($prow = sqlFetchArray($pres)) {
2630 $key = $prow['id'];
2631 if ($currvalue == $key) {
2632 $s .= $prow['name'] . ' ' . $prow['area_code'] . '-' .
2633 $prow['prefix'] . '-' . $prow['number'] . ' / ' .
2634 $prow['line1'] . ' / ' . $prow['city'];
2637 } elseif ($data_type == 14) { // address book
2638 $urow = sqlQuery("SELECT fname, lname, specialty FROM users " .
2639 "WHERE id = ?", array($currvalue));
2640 $uname = $urow['lname'];
2641 if ($urow['fname']) {
2642 $uname .= ", " . $urow['fname'];
2645 $s = $uname;
2646 } elseif ($data_type == 16) { // insurance company list
2647 $insprovs = getInsuranceProviders();
2648 foreach ($insprovs as $key => $ipname) {
2649 if ($currvalue == $key) {
2650 $s .= $ipname;
2653 } elseif ($data_type == 17) { // issue type
2654 foreach ($ISSUE_TYPES as $key => $value) {
2655 if ($currvalue == $key) {
2656 $s .= $value[1];
2659 } elseif ($data_type == 18) { // visit category
2660 $crow = sqlQuery(
2661 "SELECT pc_catid, pc_catname " .
2662 "FROM openemr_postcalendar_categories WHERE pc_catid = ?",
2663 array($currvalue)
2665 $s = $crow['pc_catname'];
2666 } elseif ($data_type == 21) { // a set of labeled checkboxes
2667 if (!$list_id) {
2668 $s .= $currvalue ? xlt('Yes') : xlt('No');
2669 } else {
2670 $avalue = explode('|', $currvalue);
2671 $lres = sqlStatement("SELECT * FROM list_options " .
2672 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2673 $count = 0;
2674 while ($lrow = sqlFetchArray($lres)) {
2675 $option_id = $lrow['option_id'];
2676 if (in_array($option_id, $avalue)) {
2677 if ($count++) {
2678 $s .= "; ";
2680 $s .= xl_list_label($lrow['title']);
2684 } elseif ($data_type == 22) { // a set of labeled text input fields
2685 $tmp = explode('|', $currvalue);
2686 $avalue = array();
2687 foreach ($tmp as $value) {
2688 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
2689 $avalue[$matches[1]] = $matches[2];
2693 $lres = sqlStatement("SELECT * FROM list_options " .
2694 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2695 while ($lrow = sqlFetchArray($lres)) {
2696 $option_id = $lrow['option_id'];
2697 if (empty($avalue[$option_id])) {
2698 continue;
2701 if ($s !== '') {
2702 $s .= '; ';
2705 $s .= xl_list_label($lrow['title']) . ': ';
2706 $s .= $avalue[$option_id];
2708 } elseif ($data_type == 23) { // A set of exam results; 3 radio buttons and a text field.
2709 // This shows abnormal results only.
2710 $tmp = explode('|', $currvalue);
2711 $avalue = array();
2712 foreach ($tmp as $value) {
2713 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
2714 $avalue[$matches[1]] = $matches[2];
2718 $lres = sqlStatement("SELECT * FROM list_options " .
2719 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2720 while ($lrow = sqlFetchArray($lres)) {
2721 $option_id = $lrow['option_id'];
2722 $restype = substr($avalue[$option_id], 0, 1);
2723 $resnote = substr($avalue[$option_id], 2);
2724 if (empty($restype) && empty($resnote)) {
2725 continue;
2728 if ($restype != '2') {
2729 continue; // show abnormal results only
2732 if ($s !== '') {
2733 $s .= '; ';
2736 $s .= xl_list_label($lrow['title']);
2737 if (!empty($resnote)) {
2738 $s .= ': ' . $resnote;
2741 } elseif ($data_type == 24) { // the list of active allergies for the current patient
2742 $query = "SELECT title, comments FROM lists WHERE " .
2743 "pid = ? AND type = 'allergy' AND enddate IS NULL " .
2744 "ORDER BY begdate";
2745 $lres = sqlStatement($query, array($GLOBALS['pid']));
2746 $count = 0;
2747 while ($lrow = sqlFetchArray($lres)) {
2748 if ($count++) {
2749 $s .= "; ";
2752 $s .= $lrow['title'];
2753 if ($lrow['comments']) {
2754 $s .= ' (' . $lrow['comments'] . ')';
2757 } elseif ($data_type == 25) { // a set of labeled checkboxes, each with a text field:
2758 $tmp = explode('|', $currvalue);
2759 $avalue = array();
2760 foreach ($tmp as $value) {
2761 if (preg_match('/^([^:]+):(.*)$/', $value, $matches)) {
2762 $avalue[$matches[1]] = $matches[2];
2766 $lres = sqlStatement("SELECT * FROM list_options " .
2767 "WHERE list_id = ? AND activity = 1 ORDER BY seq, title", array($list_id));
2768 while ($lrow = sqlFetchArray($lres)) {
2769 $option_id = $lrow['option_id'];
2770 $restype = substr($avalue[$option_id], 0, 1);
2771 $resnote = substr($avalue[$option_id], 2);
2772 if (empty($restype) && empty($resnote)) {
2773 continue;
2776 if ($s !== '') {
2777 $s .= '; ';
2780 $s .= xl_list_label($lrow['title']);
2781 $restype = $restype ? xl('Yes') : xl('No');
2782 $s .= $restype;
2783 if ($resnote) {
2784 $s .= ' ' . $resnote;
2787 } elseif ($data_type == 28 || $data_type == 32) { // special case for history of lifestyle status; 3 radio buttons and a date text field:
2788 // VicarePlus :: A selection list for smoking status.
2789 $tmp = explode('|', $currvalue);
2790 $resnote = count($tmp) > 0 ? $tmp[0] : '';
2791 $restype = count($tmp) > 1 ? $tmp[1] : '';
2792 $resdate = count($tmp) > 2 ? oeFormatShortDate($tmp[2]) : '';
2793 $reslist = count($tmp) > 3 ? $tmp[3] : '';
2794 $res = "";
2795 if ($restype == "current" . $field_id) {
2796 $res = xl('Current');
2799 if ($restype == "quit" . $field_id) {
2800 $res = xl('Quit');
2803 if ($restype == "never" . $field_id) {
2804 $res = xl('Never');
2807 if ($restype == "not_applicable" . $field_id) {
2808 $res = xl('N/A');
2811 if ($data_type == 28) {
2812 if (!empty($resnote)) {
2813 $s .= $resnote;
2815 } elseif ($data_type == 32) { // Tobacco field has a listbox, text box, date field and 3 radio buttons.
2816 if (!empty($reslist)) {
2817 $s .= generate_plaintext_field(array('data_type' => '1','list_id' => $list_id), $reslist);
2820 if (!empty($resnote)) {
2821 $s .= ' ' . $resnote;
2825 if (!empty($res)) {
2826 if ($s !== '') {
2827 $s .= ' ';
2830 $s .= xl('Status') . ' ' . $res;
2833 if ($restype == "quit" . $field_id) {
2834 if ($s !== '') {
2835 $s .= ' ';
2838 $s .= $resdate;
2840 } elseif ($data_type == 35) { // Facility, so facility can be listed in plain-text, as in patient finder column
2841 $facilityService = new FacilityService();
2842 $facility = $facilityService->getById($currvalue);
2843 $s = $facility['name'];
2844 } elseif ($data_type == 36) { // Multi select. Supports backup lists
2845 $values_array = explode("|", $currvalue);
2847 $i = 0;
2848 foreach ($values_array as $value) {
2849 $lrow = sqlQuery("SELECT title FROM list_options " .
2850 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($list_id,$value));
2852 if ($lrow == 0 && !empty($backup_list)) {
2853 //use back up list
2854 $lrow = sqlQuery("SELECT title FROM list_options " .
2855 "WHERE list_id = ? AND option_id = ? AND activity = 1", array($backup_list,$value));
2858 if ($i > 0) {
2859 $s = $s . ", " . xl_list_label($lrow['title']);
2860 } else {
2861 $s = xl_list_label($lrow['title']);
2864 $i++;
2866 } elseif ($data_type == 44 || $data_type == 45) {
2867 $values_array = explode("|", $currvalue);
2869 $i = 0;
2870 foreach ($values_array as $value) {
2871 if ($data_type == 44) {
2872 $lrow = sqlQuery("SELECT name as name FROM facility WHERE id = ?", array($value));
2874 if ($data_type == 45) {
2875 $lrow = sqlQuery("SELECT CONCAT(fname,' ',lname) as name FROM users WHERE id = ?", array($value));
2878 if ($i > 0) {
2879 $s = $s . ", " . $lrow['name'];
2880 } else {
2881 $s = $lrow['name'];
2884 $i++;
2888 return $s;
2891 $CPR = 4; // cells per row of generic data
2892 $last_group = '';
2893 $cell_count = 0;
2894 $item_count = 0;
2896 function disp_end_cell()
2898 global $item_count, $cell_count;
2899 if ($item_count > 0) {
2900 echo "</td>";
2901 $item_count = 0;
2905 function disp_end_row()
2907 global $cell_count, $CPR;
2908 disp_end_cell();
2909 if ($cell_count > 0) {
2910 for (; $cell_count < $CPR; ++$cell_count) {
2911 echo "<td></td>";
2914 echo "</tr>\n";
2915 $cell_count = 0;
2919 function disp_end_group()
2921 global $last_group;
2922 if (strlen($last_group) > 0) {
2923 disp_end_row();
2927 // Accumulate action conditions into a JSON expression for the browser side.
2928 function accumActionConditions($field_id, &$condition_str, &$condarr)
2930 $conditions = empty($condarr) ? array() : unserialize($condarr, ['allowed_classes' => false]);
2931 $action = 'skip';
2932 foreach ($conditions as $key => $condition) {
2933 if ($key === 'action') {
2934 // If specified this should be the first array item.
2935 if ($condition) {
2936 $action = $condition;
2938 continue;
2940 if (empty($condition['id'])) {
2941 continue;
2943 $andor = empty($condition['andor']) ? '' : $condition['andor'];
2944 if ($condition_str) {
2945 $condition_str .= ",\n";
2947 $condition_str .= "{" .
2948 "target:" . js_escape($field_id) . ", " .
2949 "action:" . js_escape($action) . ", " .
2950 "id:" . js_escape($condition['id']) . ", " .
2951 "itemid:" . js_escape($condition['itemid']) . ", " .
2952 "operator:" . js_escape($condition['operator']) . ", " .
2953 "value:" . js_escape($condition['value']) . ", " .
2954 "andor:" . js_escape($andor) . "}";
2958 // This checks if the given field with the given value should have an action applied.
2959 // Originally the only action was skip, but now you can also set the field to a specified value.
2960 // It somewhat mirrors the checkSkipConditions function in options.js.php.
2961 // If you use this for multiple layouts in the same script, you should
2962 // clear $sk_layout_items before each layout.
2963 function isSkipped(&$frow, $currvalue)
2965 global $sk_layout_items;
2967 // Accumulate an array of the encountered fields and their values.
2968 // It is assumed that fields appear before they are tested by another field.
2969 // TBD: Bad assumption?
2970 $field_id = $frow['field_id'];
2971 if (!is_array($sk_layout_items)) {
2972 $sk_layout_items = array();
2974 $sk_layout_items[$field_id] = array('row' => $frow, 'value' => $currvalue);
2976 if (empty($frow['conditions'])) {
2977 return false;
2980 $skiprows = unserialize($frow['conditions'], ['allowed_classes' => false]);
2981 $prevandor = '';
2982 $prevcond = false;
2983 $datatype = $frow['data_type'];
2984 $action = 'skip'; // default action if none specified
2986 foreach ($skiprows as $key => $skiprow) {
2987 // id referenced field id
2988 // itemid referenced array key if applicable
2989 // operator "eq", "ne", "se" or "ns"
2990 // value if eq or ne, some string to compare with
2991 // andor "and", "or" or empty
2993 if ($key === 'action') {
2994 // Action value is a string. It can be "skip", or "value=" followed by a value.
2995 $action = $skiprow;
2996 continue;
2999 if (empty($skiprow['id'])) {
3000 continue;
3003 $id = $skiprow['id'];
3004 if (!isset($sk_layout_items[$id])) {
3005 error_log("Function isSkipped() cannot find skip source field '" . errorLogEscape($id) . "'.");
3006 continue;
3008 $itemid = $skiprow['itemid'];
3009 $operator = $skiprow['operator'];
3010 $skipval = $skiprow['value'];
3011 $srcvalue = $sk_layout_items[$id]['value'];
3012 $src_datatype = $sk_layout_items[$id]['row']['data_type'];
3013 $src_list_id = $sk_layout_items[$id]['row']['list_id'];
3015 // Some data types use itemid and we have to dig for their value.
3016 if ($src_datatype == 21 && $src_list_id) { // array of checkboxes
3017 $tmp = explode('|', $srcvalue);
3018 $srcvalue = in_array($itemid, $tmp);
3019 } elseif ($src_datatype == 22 || $src_datatype == 23 || $src_datatype == 25) {
3020 $tmp = explode('|', $srcvalue);
3021 $srcvalue = '';
3022 foreach ($tmp as $tmp2) {
3023 if (strpos($tmp2, "$itemid:") === 0) {
3024 if ($datatype == 22) {
3025 $srcvalue = substr($tmp2, strlen($itemid) + 1);
3026 } else {
3027 $srcvalue = substr($tmp2, strlen($itemid) + 1, 1);
3033 // Compute the result of the test for this condition row.
3034 // PHP's looseness with variable type conversion helps us here.
3035 $condition = false;
3036 if ($operator == 'eq') {
3037 $condition = $srcvalue == $skipval;
3038 } elseif ($operator == 'ne') {
3039 $condition = $srcvalue != $skipval;
3040 } elseif ($operator == 'se') {
3041 $condition = $srcvalue == true;
3042 } elseif ($operator == 'ns') {
3043 $condition = $srcvalue != true;
3044 } else {
3045 error_log("Unknown skip operator '" . errorLogEscape($operator) . "' for field '" . errorLogEscape($field_id) . "'.");
3048 // Logic to accumulate multiple conditions for the same target.
3049 if ($prevandor == 'and') {
3050 $condition = $condition && $prevcond;
3051 } elseif ($prevandor == 'or') {
3052 $condition = $condition || $prevcond;
3054 $prevandor = $skiprow['andor'];
3055 $prevcond = $condition;
3057 return $prevcond ? $action : '';
3060 // Load array of names of the given layout and its groups.
3061 function getLayoutProperties($formtype, &$grparr, $sel = "grp_title")
3063 if ($sel != '*' && strpos($sel, 'grp_group_id') === false) {
3064 $sel = "grp_group_id, $sel";
3066 $gres = sqlStatement("SELECT $sel FROM layout_group_properties WHERE grp_form_id = ? " .
3067 "ORDER BY grp_group_id", array($formtype));
3068 while ($grow = sqlFetchArray($gres)) {
3069 $grparr[$grow['grp_group_id']] = $grow;
3073 function display_layout_rows($formtype, $result1, $result2 = '')
3075 global $item_count, $cell_count, $last_group, $CPR;
3077 $grparr = array();
3078 getLayoutProperties($formtype, $grparr, '*');
3080 $TOPCPR = empty($grparr['']['grp_columns']) ? 4 : $grparr['']['grp_columns'];
3082 $fres = sqlStatement("SELECT * FROM layout_options " .
3083 "WHERE form_id = ? AND uor > 0 " .
3084 "ORDER BY group_id, seq", array($formtype));
3086 while ($frow = sqlFetchArray($fres)) {
3087 $this_group = $frow['group_id'];
3088 $titlecols = $frow['titlecols'];
3089 $datacols = $frow['datacols'];
3090 $data_type = $frow['data_type'];
3091 $field_id = $frow['field_id'];
3092 $list_id = $frow['list_id'];
3093 $currvalue = '';
3094 $jump_new_row = isOption($frow['edit_options'], 'J');
3095 $prepend_blank_row = isOption($frow['edit_options'], 'K');
3097 $CPR = empty($grparr[$this_group]['grp_columns']) ? $TOPCPR : $grparr[$this_group]['grp_columns'];
3099 if ($formtype == 'DEM') {
3100 if (strpos($field_id, 'em_') === 0) {
3101 // Skip employer related fields, if it's disabled.
3102 if ($GLOBALS['omit_employers']) {
3103 continue;
3106 $tmp = substr($field_id, 3);
3107 if (isset($result2[$tmp])) {
3108 $currvalue = $result2[$tmp];
3110 } else {
3111 if (isset($result1[$field_id])) {
3112 $currvalue = $result1[$field_id];
3115 } else {
3116 if (isset($result1[$field_id])) {
3117 $currvalue = $result1[$field_id];
3121 // Handle a data category (group) change.
3122 if (strcmp($this_group, $last_group) != 0) {
3123 $group_name = $grparr[$this_group]['grp_title'];
3124 // totally skip generating the employer category, if it's disabled.
3125 if ($group_name === 'Employer' && $GLOBALS['omit_employers']) {
3126 continue;
3129 disp_end_group();
3130 $last_group = $this_group;
3133 // filter out all the empty field data from the patient report.
3134 if (!empty($currvalue) && !($currvalue == '0000-00-00 00:00:00')) {
3135 // Handle starting of a new row.
3136 if (($titlecols > 0 && $cell_count >= $CPR) || $cell_count == 0 || $prepend_blank_row || $jump_new_row) {
3137 disp_end_row();
3138 if ($prepend_blank_row) {
3139 echo "<tr><td class='label' colspan='" . ($CPR + 1) . "'>&nbsp;</td></tr>\n";
3141 echo "<tr>";
3142 if ($group_name) {
3143 echo "<td class='groupname'>";
3144 echo text(xl_layout_label($group_name));
3145 $group_name = '';
3146 } else {
3147 echo "<td class='align-top'>&nbsp;";
3150 echo "</td>";
3153 if ($item_count == 0 && $titlecols == 0) {
3154 $titlecols = 1;
3157 // Handle starting of a new label cell.
3158 if ($titlecols > 0) {
3159 disp_end_cell();
3160 //echo "<td class='label_custom align-top' colspan='$titlecols'";
3161 $titlecols_esc = htmlspecialchars($titlecols, ENT_QUOTES);
3162 echo "<td class='label_custom' colspan='$titlecols_esc' ";
3163 //if ($cell_count == 2) echo " style='padding-left:10pt'";
3164 echo ">";
3165 $cell_count += $titlecols;
3168 ++$item_count;
3170 // Added 5-09 by BM - Translate label if applicable
3171 if ($frow['title']) {
3172 $tmp = xl_layout_label($frow['title']);
3173 echo text($tmp);
3174 // Append colon only if label does not end with punctuation.
3175 if (strpos('?!.,:-=', substr($tmp, -1, 1)) === false) {
3176 echo ':';
3178 } else {
3179 echo "&nbsp;";
3182 // Handle starting of a new data cell.
3183 if ($datacols > 0) {
3184 disp_end_cell();
3185 //echo "<td class='text data align-top' colspan='$datacols'";
3186 $datacols_esc = htmlspecialchars($datacols, ENT_QUOTES);
3187 echo "<td class='text data' colspan='$datacols_esc'";
3188 //if ($cell_count > 0) echo " style='padding-left:5pt'";
3189 echo ">";
3190 $cell_count += $datacols;
3193 ++$item_count;
3194 echo generate_display_field($frow, $currvalue);
3198 disp_end_group();
3201 function display_layout_tabs($formtype, $result1, $result2 = '')
3203 global $item_count, $cell_count, $last_group, $CPR;
3205 $grparr = array();
3206 getLayoutProperties($formtype, $grparr);
3208 $fres = sqlStatement("SELECT distinct group_id FROM layout_options " .
3209 "WHERE form_id = ? AND uor > 0 " .
3210 "ORDER BY group_id", array($formtype));
3212 $first = true;
3213 while ($frow = sqlFetchArray($fres)) {
3214 $this_group = $frow['group_id'];
3215 // $group_name = substr($this_group, 1);
3216 $group_name = $grparr[$this_group]['grp_title'];
3217 if ($group_name === 'Employer' && $GLOBALS['omit_employers']) {
3218 continue;
3221 <li <?php echo $first ? 'class="current"' : '' ?>>
3222 <a href="#" id="header_tab_<?php echo attr($group_name); ?>">
3223 <?php echo text(xl_layout_label($group_name)); ?></a>
3224 </li>
3225 <?php
3226 $first = false;
3230 function display_layout_tabs_data($formtype, $result1, $result2 = '')
3232 global $item_count, $cell_count, $last_group, $CPR;
3234 $grparr = array();
3235 getLayoutProperties($formtype, $grparr, '*');
3237 $TOPCPR = empty($grparr['']['grp_columns']) ? 4 : $grparr['']['grp_columns'];
3239 $fres = sqlStatement("SELECT distinct group_id FROM layout_options " .
3240 "WHERE form_id = ? AND uor > 0 " .
3241 "ORDER BY group_id", array($formtype));
3243 $first = true;
3244 while ($frow = sqlFetchArray($fres)) {
3245 $this_group = isset($frow['group_id']) ? $frow['group_id'] : "" ;
3247 if ($grparr[$this_group]['grp_columns'] === 'Employer' && $GLOBALS['omit_employers']) {
3248 continue;
3250 $CPR = empty($grparr[$this_group]['grp_columns']) ? $TOPCPR : $grparr[$this_group]['grp_columns'];
3251 $subtitle = empty($grparr[$this_group]['grp_subtitle']) ? '' : xl_layout_label($grparr[$this_group]['grp_subtitle']);
3253 $group_fields_query = sqlStatement("SELECT * FROM layout_options " .
3254 "WHERE form_id = ? AND uor > 0 AND group_id = ? " .
3255 "ORDER BY seq", array($formtype, $this_group));
3258 <div class="tab <?php echo $first ? 'current' : '' ?>">
3259 <table class='table table-borderless'>
3261 <?php
3262 while ($group_fields = sqlFetchArray($group_fields_query)) {
3263 $titlecols = $group_fields['titlecols'];
3264 $datacols = $group_fields['datacols'];
3265 $data_type = $group_fields['data_type'];
3266 $field_id = $group_fields['field_id'];
3267 $list_id = $group_fields['list_id'];
3268 $currvalue = '';
3269 $edit_options = $group_fields['edit_options'];
3270 $jump_new_row = isOption($edit_options, 'J');
3271 $prepend_blank_row = isOption($edit_options, 'K');
3273 if ($formtype == 'DEM') {
3274 if (strpos($field_id, 'em_') === 0) {
3275 // Skip employer related fields, if it's disabled.
3276 if ($GLOBALS['omit_employers']) {
3277 continue;
3280 $tmp = substr($field_id, 3);
3281 if (isset($result2[$tmp])) {
3282 $currvalue = $result2[$tmp];
3284 } else {
3285 if (isset($result1[$field_id])) {
3286 $currvalue = $result1[$field_id];
3289 } else {
3290 if (isset($result1[$field_id])) {
3291 $currvalue = $result1[$field_id];
3295 // Skip this field if action conditions call for that.
3296 // Note this also accumulates info for subsequent skip tests.
3297 $skip_this_field = isSkipped($group_fields, $currvalue) == 'skip';
3299 // Skip this field if its do-not-print option is set.
3300 if (isOption($edit_options, 'X') !== false) {
3301 $skip_this_field = true;
3304 // Handle a data category (group) change.
3305 if (strcmp($this_group, $last_group) != 0) {
3306 $group_name = $grparr[$this_group]['grp_title'];
3307 // totally skip generating the employer category, if it's disabled.
3308 if ($group_name === 'Employer' && $GLOBALS['omit_employers']) {
3309 continue;
3311 $last_group = $this_group;
3314 // Handle starting of a new row.
3315 if (($titlecols > 0 && $cell_count >= $CPR) || $cell_count == 0 || $prepend_blank_row || $jump_new_row) {
3316 disp_end_row();
3317 if ($subtitle) {
3318 // Group subtitle exists and is not displayed yet.
3319 echo "<tr><td class='label' style='background-color: var(--gray300); padding: 4px' colspan='$CPR'>" . text($subtitle) . "</td></tr>\n";
3320 echo "<tr><td class='label' style='height: 5px' colspan='$CPR'></td></tr>\n";
3321 $subtitle = '';
3323 if ($prepend_blank_row) {
3324 echo "<tr><td class='label' colspan='$CPR'>&nbsp;</td></tr>\n";
3326 echo "<tr>";
3329 if ($item_count == 0 && $titlecols == 0) {
3330 $titlecols = 1;
3333 // Handle starting of a new label cell.
3334 if ($titlecols > 0) {
3335 disp_end_cell();
3336 $titlecols_esc = htmlspecialchars($titlecols, ENT_QUOTES);
3337 $field_id_label = 'label_' . $group_fields['field_id'];
3338 echo "<td class='label_custom' colspan='$titlecols_esc' id='" . attr($field_id_label) . "'";
3339 echo ">";
3340 $cell_count += $titlecols;
3343 ++$item_count;
3345 $field_id_label = 'label_' . $group_fields['field_id'];
3346 echo "<span id='" . attr($field_id_label) . "'>";
3347 if ($skip_this_field) {
3348 // No label because skipping
3349 } elseif ($group_fields['title']) {
3350 $tmp = xl_layout_label($group_fields['title']);
3351 echo text($tmp);
3352 // Append colon only if label does not end with punctuation.
3353 if (strpos('?!.,:-=', substr($tmp, -1, 1)) === false) {
3354 echo ':';
3356 } else {
3357 echo "&nbsp;";
3359 echo "</span>";
3361 // Handle starting of a new data cell.
3362 if ($datacols > 0) {
3363 disp_end_cell();
3364 $datacols_esc = htmlspecialchars($datacols, ENT_QUOTES);
3365 $field_id = 'text_' . $group_fields['field_id'];
3366 echo "<td class='text data' colspan='$datacols_esc' id='" . attr($field_id) . "' data-value='" . attr($currvalue) . "'";
3367 if (!$skip_this_field && $data_type == 3) {
3368 // Textarea gets a light grey border.
3369 echo " style='border: 1px solid var(--gray400)'";
3371 echo ">";
3372 $cell_count += $datacols;
3373 } else {
3374 $field_id = 'text_' . $group_fields['field_id'];
3375 echo "<span id='" . attr($field_id) . "' style='display: none'>" . text($currvalue) . "</span>";
3378 ++$item_count;
3379 if (!$skip_this_field) {
3380 echo generate_display_field($group_fields, $currvalue);
3384 disp_end_row();
3387 </table>
3388 </div>
3390 <?php
3392 $first = false;
3396 function display_layout_tabs_data_editable($formtype, $result1, $result2 = '')
3398 global $item_count, $cell_count, $last_group, $CPR,$condition_str;
3400 $grparr = array();
3401 getLayoutProperties($formtype, $grparr, '*');
3403 $TOPCPR = empty($grparr['']['grp_columns']) ? 4 : $grparr['']['grp_columns'];
3405 $fres = sqlStatement("SELECT distinct group_id FROM layout_options " .
3406 "WHERE form_id = ? AND uor > 0 " .
3407 "ORDER BY group_id", array($formtype));
3409 $first = true;
3410 $condition_str = '';
3412 while ($frow = sqlFetchArray($fres)) {
3413 $this_group = $frow['group_id'];
3414 $group_name = $grparr[$this_group]['grp_title'];
3415 $group_name_esc = text($group_name);
3417 if ($grparr[$this_group]['grp_title'] === 'Employer' && $GLOBALS['omit_employers']) {
3418 continue;
3420 $CPR = empty($grparr[$this_group]['grp_columns']) ? $TOPCPR : $grparr[$this_group]['grp_columns'];
3421 $subtitle = empty($grparr[$this_group]['grp_subtitle']) ? '' : xl_layout_label($grparr[$this_group]['grp_subtitle']);
3423 $group_fields_query = sqlStatement("SELECT * FROM layout_options " .
3424 "WHERE form_id = ? AND uor > 0 AND group_id = ? " .
3425 "ORDER BY seq", array($formtype, $this_group));
3428 <div class="table-responsive tab <?php echo $first ? 'current' : '' ?>" id="tab_<?php echo str_replace(' ', '_', $group_name_esc)?>" >
3429 <table class='table table-borderless'>
3431 <?php
3432 while ($group_fields = sqlFetchArray($group_fields_query)) {
3433 $titlecols = $group_fields['titlecols'];
3434 $datacols = $group_fields['datacols'];
3435 $data_type = $group_fields['data_type'];
3436 $field_id = $group_fields['field_id'];
3437 $list_id = $group_fields['list_id'];
3438 $backup_list = $group_fields['list_backup_id'];
3439 $currvalue = '';
3440 $action = 'skip';
3441 $jump_new_row = isOption($group_fields['edit_options'], 'J');
3442 $prepend_blank_row = isOption($group_fields['edit_options'], 'K');
3444 // Accumulate action conditions into a JSON expression for the browser side.
3445 accumActionConditions($field_id, $condition_str, $group_fields['conditions']);
3447 if ($formtype == 'DEM') {
3448 if (strpos($field_id, 'em_') === 0) {
3449 // Skip employer related fields, if it's disabled.
3450 if ($GLOBALS['omit_employers']) {
3451 continue;
3454 $tmp = substr($field_id, 3);
3455 if (isset($result2[$tmp])) {
3456 $currvalue = $result2[$tmp];
3458 } else {
3459 if (isset($result1[$field_id])) {
3460 $currvalue = $result1[$field_id];
3463 } else {
3464 if (isset($result1[$field_id])) {
3465 $currvalue = $result1[$field_id];
3469 // Handle a data category (group) change.
3470 if (strcmp($this_group, $last_group) != 0) {
3471 // totally skip generating the employer category, if it's disabled.
3472 if ($group_name === 'Employer' && $GLOBALS['omit_employers']) {
3473 continue;
3476 $last_group = $this_group;
3479 // Handle starting of a new row.
3480 if (($titlecols > 0 && $cell_count >= $CPR) || $cell_count == 0 || $prepend_blank_row || $jump_new_row) {
3481 disp_end_row();
3482 if ($subtitle) {
3483 // Group subtitle exists and is not displayed yet.
3484 echo "<tr><td class='label' style='background-color: var(--gray300); padding: 4px' colspan='$CPR'>" . text($subtitle) . "</td></tr>\n";
3485 echo "<tr><td class='label' style='height: 5px' colspan='$CPR'></td></tr>\n";
3486 $subtitle = '';
3488 if ($prepend_blank_row) {
3489 echo "<tr><td class='label' colspan='$CPR'>&nbsp;</td></tr>\n";
3491 echo "<tr>";
3494 if ($item_count == 0 && $titlecols == 0) {
3495 $titlecols = 1;
3498 // Handle starting of a new label cell.
3499 if ($titlecols > 0) {
3500 disp_end_cell();
3501 $titlecols_esc = htmlspecialchars($titlecols, ENT_QUOTES);
3502 $field_id_label = 'label_' . $group_fields['field_id'];
3503 echo "<td class='label_custom' colspan='$titlecols_esc'";
3504 // This ID is used by skip conditions.
3505 echo " id='label_id_" . attr($field_id) . "'";
3506 echo ">";
3507 $cell_count += $titlecols;
3510 ++$item_count;
3512 if ($group_fields['title']) {
3513 $tmp = xl_layout_label($group_fields['title']);
3514 echo text($tmp);
3515 // Append colon only if label does not end with punctuation.
3516 if (strpos('?!.,:-=', substr($tmp, -1, 1)) === false) {
3517 echo ':';
3519 } else {
3520 echo "&nbsp;";
3523 // Handle starting of a new data cell.
3524 if ($datacols > 0) {
3525 disp_end_cell();
3526 $datacols_esc = htmlspecialchars($datacols, ENT_QUOTES);
3527 $field_id = 'text_' . $group_fields['field_id'];
3528 echo "<td class='text data' colspan='$datacols_esc'";
3529 // This ID is used by action conditions.
3530 echo " id='value_id_" . attr($field_id) . "'";
3531 echo ">";
3532 $cell_count += $datacols;
3535 ++$item_count;
3537 echo generate_form_field($group_fields, $currvalue);
3541 </table>
3542 </div>
3544 <?php
3546 $first = false;
3550 // From the currently posted HTML form, this gets the value of the
3551 // field corresponding to the provided layout_options table row.
3553 function get_layout_form_value($frow, $prefix = 'form_')
3555 $maxlength = empty($frow['max_length']) ? 0 : intval($frow['max_length']);
3556 $data_type = $frow['data_type'];
3557 $field_id = $frow['field_id'];
3558 $value = '';
3559 if (isset($_POST["$prefix$field_id"])) {
3560 if ($data_type == 4) {
3561 $modtmp = isOption($frow['edit_options'], 'F') === false ? 0 : 1;
3562 if (!$modtmp) {
3563 $value = DateToYYYYMMDD($_POST["$prefix$field_id"]);
3564 } else {
3565 $value = DateTimeToYYYYMMDDHHMMSS($_POST["$prefix$field_id"]);
3567 } elseif ($data_type == 21) {
3568 if (!$frow['list_id']) {
3569 if (!empty($_POST["form_$field_id"])) {
3570 $value = xlt('Yes');
3572 } else {
3573 // $_POST["$prefix$field_id"] is an array of checkboxes and its keys
3574 // must be concatenated into a |-separated string.
3575 foreach ($_POST["$prefix$field_id"] as $key => $val) {
3576 if (strlen($value)) {
3577 $value .= '|';
3579 $value .= $key;
3582 } elseif ($data_type == 22) {
3583 // $_POST["$prefix$field_id"] is an array of text fields to be imploded
3584 // into "key:value|key:value|...".
3585 foreach ($_POST["$prefix$field_id"] as $key => $val) {
3586 $val = str_replace('|', ' ', $val);
3587 if (strlen($value)) {
3588 $value .= '|';
3591 $value .= "$key:$val";
3593 } elseif ($data_type == 23) {
3594 // $_POST["$prefix$field_id"] is an array of text fields with companion
3595 // radio buttons to be imploded into "key:n:notes|key:n:notes|...".
3596 foreach ($_POST["$prefix$field_id"] as $key => $val) {
3597 $restype = $_POST["radio_{$field_id}"][$key];
3598 if (empty($restype)) {
3599 $restype = '0';
3602 $val = str_replace('|', ' ', $val);
3603 if (strlen($value)) {
3604 $value .= '|';
3607 $value .= "$key:$restype:$val";
3609 } elseif ($data_type == 25) {
3610 // $_POST["$prefix$field_id"] is an array of text fields with companion
3611 // checkboxes to be imploded into "key:n:notes|key:n:notes|...".
3612 foreach ($_POST["$prefix$field_id"] as $key => $val) {
3613 $restype = empty($_POST["check_{$field_id}"][$key]) ? '0' : '1';
3614 $val = str_replace('|', ' ', $val);
3615 if (strlen($value)) {
3616 $value .= '|';
3619 $value .= "$key:$restype:$val";
3621 } elseif ($data_type == 28 || $data_type == 32) {
3622 // $_POST["$prefix$field_id"] is an date text fields with companion
3623 // radio buttons to be imploded into "notes|type|date".
3624 $restype = $_POST["radio_{$field_id}"] ?? '';
3625 if (empty($restype)) {
3626 $restype = '0';
3629 $resdate = DateToYYYYMMDD(str_replace('|', ' ', $_POST["date_$field_id"]));
3630 $resnote = str_replace('|', ' ', $_POST["$prefix$field_id"]);
3631 if ($data_type == 32) {
3632 //VicarePlus :: Smoking status data is imploded into "note|type|date|list".
3633 $reslist = str_replace('|', ' ', $_POST["$prefix$field_id"]);
3634 $res_text_note = str_replace('|', ' ', $_POST["{$prefix}text_$field_id"]);
3635 $value = "$res_text_note|$restype|$resdate|$reslist";
3636 } else {
3637 $value = "$resnote|$restype|$resdate";
3639 } elseif ($data_type == 36 || $data_type == 44 || $data_type == 45) {
3640 $value_array = $_POST["form_$field_id"];
3641 $i = 0;
3642 foreach ($value_array as $key => $valueofkey) {
3643 if ($i == 0) {
3644 $value = $valueofkey;
3645 } else {
3646 $value = $value . "|" . $valueofkey;
3649 $i++;
3651 } else {
3652 $value = $_POST["$prefix$field_id"];
3656 // Better to die than to silently truncate data!
3657 if ($maxlength && $maxlength != 0 && strlen($value) > $maxlength) {
3658 die(htmlspecialchars(xl('ERROR: Field') . " '$field_id' " . xl('is too long'), ENT_NOQUOTES) .
3659 ":<br />&nbsp;<br />" . htmlspecialchars($value, ENT_NOQUOTES));
3662 return trim($value);
3665 // Generate JavaScript validation logic for the required fields.
3667 function generate_layout_validation($form_id)
3669 $fres = sqlStatement("SELECT * FROM layout_options " .
3670 "WHERE form_id = ? AND uor > 0 AND field_id != '' " .
3671 "ORDER BY group_id, seq", array($form_id));
3673 while ($frow = sqlFetchArray($fres)) {
3674 $data_type = $frow['data_type'];
3675 $field_id = $frow['field_id'];
3676 $fldtitle = $frow['title'];
3677 if (!$fldtitle) {
3678 $fldtitle = $frow['description'];
3681 $fldname = attr("form_$field_id");
3683 if ($data_type == 40) {
3684 $fldid = "form_" . $field_id;
3685 // Move canvas image data to its hidden form field so the server will get it.
3686 echo
3687 " var canfld = f[" . js_escape($fldid) . "];\n" .
3688 " if (canfld) canfld.value = lbfCanvasGetData(" . js_escape($fldid) . ");\n";
3689 continue;
3691 if ($data_type == 41 || $data_type == 42) {
3692 $fldid = "form_" . $field_id;
3693 // Move canvas image data to its hidden form field so the server will get it.
3694 echo " lbfSetSignature(" . js_escape($fldid) . ");\n";
3695 continue;
3697 if ($frow['uor'] < 2) {
3698 continue;
3701 echo " if (f.$fldname && !f.$fldname.disabled) {\n";
3702 switch ($data_type) {
3703 case 1:
3704 case 11:
3705 case 12:
3706 case 13:
3707 case 14:
3708 case 26:
3709 echo
3710 " if (f.$fldname.selectedIndex <= 0) {\n" .
3711 " alert(" . xlj('Please choose a value for') . " + " .
3712 "\":\\n\" + " . js_escape(xl_layout_label($fldtitle)) . ");\n" .
3713 " if (f.$fldname.focus) f.$fldname.focus();\n" .
3714 " return false;\n" .
3715 " }\n";
3716 break;
3717 case 33:
3718 echo
3719 " if (f.$fldname.selectedIndex <= 0) {\n" .
3720 " if (f.$fldname.focus) f.$fldname.focus();\n" .
3721 " errMsgs[errMsgs.length] = " . js_escape(xl_layout_label($fldtitle)) . "; \n" .
3722 " }\n";
3723 break;
3724 case 27: // radio buttons
3725 echo
3726 " var i = 0;\n" .
3727 " for (; i < f.$fldname.length; ++i) if (f.{$fldname}[i].checked) break;\n" .
3728 " if (i >= f.$fldname.length) {\n" .
3729 " alert(" . xlj('Please choose a value for') . " + " .
3730 "\":\\n\" + " . js_escape(xl_layout_label($fldtitle)) . ");\n" .
3731 " return false;\n" .
3732 " }\n";
3733 break;
3734 case 2:
3735 case 3:
3736 case 4:
3737 case 15:
3738 echo
3739 " if (trimlen(f.$fldname.value) == 0) {\n" .
3740 " if (f.$fldname.focus) f.$fldname.focus();\n" .
3741 " $('#" . $fldname . "').parents('div.tab').each( function(){ var tabHeader = $('#header_' + $(this).attr('id') ); tabHeader.css('color','var(--danger)'); } ); " .
3742 " $('#" . $fldname . "').attr('style','background: var(--danger)'); \n" .
3743 " errMsgs[errMsgs.length] = " . js_escape(xl_layout_label($fldtitle)) . "; \n" .
3744 " } else { " .
3745 " $('#" . $fldname . "').attr('style',''); " .
3746 " $('#" . $fldname . "').parents('div.tab').each( function(){ var tabHeader = $('#header_' + $(this).attr('id') ); tabHeader.css('color',''); } ); " .
3747 " } \n";
3748 break;
3749 case 36: // multi select
3750 echo
3751 " var multi_select=f['$fldname" . "[]']; \n " .
3752 " var multi_choice_made=false; \n" .
3753 " for (var options_index=0; options_index < multi_select.length; options_index++) { " .
3754 " multi_choice_made=multi_choice_made || multi_select.options[options_index].selected; \n" .
3755 " } \n" .
3756 " if(!multi_choice_made)
3757 errMsgs[errMsgs.length] = " . js_escape(xl_layout_label($fldtitle)) . "; \n" .
3759 break;
3761 echo " }\n";
3766 * DROPDOWN FOR FACILITIES
3768 * build a dropdown with all facilities
3770 * @param string $selected - name of the currently selected facility
3771 * use '0' for "unspecified facility"
3772 * use '' for "All facilities" (the default)
3773 * @param string $name - the name/id for select form (defaults to "form_facility")
3774 * @param boolean $allow_unspecified - include an option for "unspecified" facility
3775 * defaults to true
3776 * @return void - just echo the html encoded string
3778 * Note: This should become a data-type at some point, according to Brady
3780 function dropdown_facility(
3781 $selected = '',
3782 $name = 'form_facility',
3783 $allow_unspecified = true,
3784 $allow_allfacilities = true,
3785 $disabled = '',
3786 $onchange = '',
3787 $multiple = false
3790 global $facilityService;
3792 $have_selected = false;
3793 $fres = $facilityService->getAllFacility();
3794 $id = $name;
3796 if ($multiple) {
3797 $name = $name . "[]";
3799 echo " <select class='form-control";
3800 if ($multiple) {
3801 echo " select-dropdown";
3803 echo "' name='" . attr($name) . "' id='" . attr($id) . "'";
3804 if ($onchange) {
3805 echo " onchange='$onchange'";
3808 if ($multiple) {
3809 echo " multiple='multiple'";
3812 echo " $disabled>\n";
3814 if ($allow_allfacilities) {
3815 $option_value = '';
3816 $option_selected_attr = '';
3817 if ($selected == '') {
3818 $option_selected_attr = ' selected="selected"';
3819 $have_selected = true;
3822 $option_content = '-- ' . xl('All Facilities') . ' --';
3823 echo " <option value='" . attr($option_value) . "' $option_selected_attr>" . text($option_content) . "</option>\n";
3824 } elseif ($allow_unspecified) {
3825 $option_value = '0';
3826 $option_selected_attr = '';
3827 if ($selected == '0') {
3828 $option_selected_attr = ' selected="selected"';
3829 $have_selected = true;
3832 $option_content = '-- ' . xl('Unspecified') . ' --';
3833 echo " <option value='" . attr($option_value) . "' $option_selected_attr>" . text($option_content) . "</option>\n";
3836 foreach ($fres as $frow) {
3837 $facility_id = $frow['id'];
3838 $option_value = $facility_id;
3839 $option_selected_attr = '';
3840 if ($multiple) {
3841 $selectedValues = explode("|", $selected);
3843 if (in_array($facility_id, $selectedValues)) {
3844 $option_selected_attr = ' selected="selected"';
3845 $have_selected = true;
3847 } else {
3848 if ($selected == $facility_id) {
3849 $option_selected_attr = ' selected="selected"';
3850 $have_selected = true;
3854 $option_content = $frow['name'];
3855 echo " <option value='" . attr($option_value) . "' $option_selected_attr>" . text($option_content) . "</option>\n";
3858 if ($allow_unspecified && $allow_allfacilities) {
3859 $option_value = '0';
3860 $option_selected_attr = '';
3861 if ($selected == '0') {
3862 $option_selected_attr = ' selected="selected"';
3863 $have_selected = true;
3866 $option_content = '-- ' . xl('Unspecified') . ' --';
3867 echo " <option value='" . attr($option_value) . "' $option_selected_attr>" . text($option_content) . "</option>\n";
3870 if (!$have_selected && !$multiple) {
3871 $option_value = $selected;
3872 $option_label = '(' . xl('Do not change') . ')';
3873 $option_content = xl('Missing or Invalid');
3874 echo " <option value='" . attr($option_value) . "' label='" . attr($option_label) . "' selected='selected'>" . text($option_content) . "</option>\n";
3877 echo " </select>\n";
3880 // Expand Collapse Widget
3881 // This forms the header and functionality component of the widget. The information that is displayed
3882 // then follows this function followed by a closing div tag
3884 // $title is the title of the section (already translated)
3885 // $label is identifier used in the tag id's and sql columns
3886 // $buttonLabel is the button label text (already translated)
3887 // $buttonLink is the button link information
3888 // $buttonClass is any additional needed class elements for the button tag
3889 // $linkMethod is the button link method ('javascript' vs 'html')
3890 // $bodyClass is to set class(es) of the body
3891 // $auth is a flag to decide whether to show the button
3892 // $fixedWidth is to flag whether width is fixed
3893 // $forceExpandAlways is a flag to force the widget to always be expanded
3895 // TODO: Convert to accordion
3896 function expand_collapse_widget($title, $label, $buttonLabel, $buttonLink, $buttonClass, $linkMethod, $bodyClass, $auth, $fixedWidth, $forceExpandAlways = false)
3898 if ($fixedWidth) {
3899 echo "<div class='section-header'>";
3900 } else {
3901 echo "<div class='section-header-dynamic'>";
3904 echo "<table><tr>";
3905 if ($auth) {
3906 // show button, since authorized
3907 // first prepare class string
3908 if ($buttonClass) {
3909 $class_string = "btn btn-primary btn-sm " . $buttonClass;
3910 } else {
3911 $class_string = "btn btn-primary btn-sm";
3914 // next, create the link
3915 if ($linkMethod == "javascript") {
3916 echo "<td><a class='" . attr($class_string) . "' href='javascript:;' onclick='" . $buttonLink . "'";
3917 } else {
3918 echo "<td><a class='" . attr($class_string) . "' href='" . $buttonLink . "'";
3919 if (!isset($_SESSION['patient_portal_onsite_two'])) {
3920 // prevent an error from occuring when calling the function from the patient portal
3921 echo " onclick='top.restoreSession()'";
3925 echo "><span>" .
3926 text($buttonLabel) . "</span></a></td>";
3929 if ($forceExpandAlways) {
3930 // Special case to force the widget to always be expanded
3931 echo "<td><span class='text font-weight-bold'>" . text($title) . "</span>";
3932 $indicatorTag = "style='display: none'";
3935 $indicatorTag = isset($indicatorTag) ? $indicatorTag : "";
3936 echo "<td><a " . $indicatorTag . " href='javascript:;' class='small' onclick='toggleIndicator(this," .
3937 attr_js($label . "_ps_expand") . ")'><span class='text font-weight-bold'>";
3938 echo text($title) . "</span>";
3940 if (isset($_SESSION['patient_portal_onsite_two'])) {
3941 // collapse all entries in the patient portal
3942 $text = xl('expand');
3943 } elseif (getUserSetting($label . "_ps_expand")) {
3944 $text = xl('collapse');
3945 } else {
3946 $text = xl('expand');
3949 echo " (<span class='indicator'>" . text($text) .
3950 "</span>)</a></td>";
3951 echo "</tr></table>";
3952 echo "</div>";
3953 if ($forceExpandAlways) {
3954 // Special case to force the widget to always be expanded
3955 $styling = "";
3956 } elseif (isset($_SESSION['patient_portal_onsite_two'])) {
3957 // collapse all entries in the patient portal
3958 $styling = "style='display: none'";
3959 } elseif (getUserSetting($label . "_ps_expand")) {
3960 $styling = "";
3961 } else {
3962 $styling = "style='display: none'";
3965 if ($bodyClass) {
3966 $styling .= " class='" . attr($bodyClass) . "'";
3969 //next, create the first div tag to hold the information
3970 // note the code that calls this function will then place the ending div tag after the data
3971 echo "<div id='" . attr($label) . "_ps_expand' " . $styling . ">";
3974 //billing_facility fuction will give the dropdown list which contain billing faciliies.
3975 function billing_facility($name, $select)
3977 global $facilityService;
3979 $fres = $facilityService->getAllBillingLocations();
3980 echo " <select id='" . htmlspecialchars($name, ENT_QUOTES) . "' class='form-control' name='" . htmlspecialchars($name, ENT_QUOTES) . "'>";
3981 foreach ($fres as $facrow) {
3982 $selected = ( $facrow['id'] == $select ) ? 'selected="selected"' : '' ;
3983 echo "<option value=" . htmlspecialchars($facrow['id'], ENT_QUOTES) . " $selected>" . htmlspecialchars($facrow['name'], ENT_QUOTES) . "</option>";
3986 echo "</select>";
3989 // Generic function to get the translated title value for a particular list option.
3991 function getListItemTitle($list, $option)
3993 $row = sqlQuery("SELECT title FROM list_options WHERE " .
3994 "list_id = ? AND option_id = ? AND activity = 1", array($list, $option));
3995 if (empty($row['title'])) {
3996 return $option;
3999 return xl_list_label($row['title']);
4002 //function to get the translated title value in Patient Transactions
4003 function getLayoutTitle($list, $option)
4005 $row = sqlQuery("SELECT grp_title FROM layout_group_properties " .
4006 "WHERE grp_mapping = ? AND grp_form_id = ? ", array($list, $option));
4008 if (empty($row['grp_title'])) {
4009 return $option;
4011 return xl_list_label($row['grp_title']);
4013 //Added on 5-jun-2k14 (regarding get the smoking code descriptions)
4014 function getSmokeCodes()
4016 $smoking_codes_arr = array();
4017 $smoking_codes = sqlStatement("SELECT option_id,codes FROM list_options WHERE list_id='smoking_status' AND activity = 1");
4018 while ($codes_row = sqlFetchArray($smoking_codes)) {
4019 $smoking_codes_arr[$codes_row['option_id']] = $codes_row['codes'];
4022 return $smoking_codes_arr;
4025 // Get the current value for a layout based form field.
4026 // Depending on options this might come from lbf_data, patient_data,
4027 // form_encounter, shared_attributes or elsewhere.
4028 // Returns FALSE if the field ID is invalid (layout error).
4030 function lbf_current_value($frow, $formid, $encounter)
4032 global $pid;
4033 $formname = $frow['form_id'];
4034 $field_id = $frow['field_id'];
4035 $source = $frow['source'];
4036 $currvalue = '';
4037 $deffname = $formname . '_default_' . $field_id;
4038 if ($source == 'D' || $source == 'H') {
4039 // Get from patient_data, employer_data or history_data.
4040 if ($source == 'H') {
4041 $table = 'history_data';
4042 $orderby = 'ORDER BY date DESC LIMIT 1';
4043 } elseif (strpos($field_id, 'em_') === 0) {
4044 $field_id = substr($field_id, 3);
4045 $table = 'employer_data';
4046 $orderby = 'ORDER BY date DESC LIMIT 1';
4047 } else {
4048 $table = 'patient_data';
4049 $orderby = '';
4052 // It is an error if the field does not exist, but don't crash.
4053 $tmp = sqlQuery("SHOW COLUMNS FROM " . escape_table_name($table) . " WHERE Field = ?", array($field_id));
4054 if (empty($tmp)) {
4055 return '*?*';
4058 $pdrow = sqlQuery("SELECT `$field_id` AS field_value FROM " . escape_table_name($table) . " WHERE pid = ? $orderby", array($pid));
4059 if (isset($pdrow)) {
4060 $currvalue = $pdrow['field_value'];
4062 } elseif ($source == 'E') {
4063 $sarow = false;
4064 if ($encounter) {
4065 // Get value from shared_attributes of the current encounter.
4066 $sarow = sqlQuery(
4067 "SELECT field_value FROM shared_attributes WHERE " .
4068 "pid = ? AND encounter = ? AND field_id = ?",
4069 array($pid, $encounter, $field_id)
4071 if (!empty($sarow)) {
4072 $currvalue = $sarow['field_value'];
4074 } elseif ($formid) {
4075 // Get from shared_attributes of the encounter that this form is linked to.
4076 // Note the importance of having an index on forms.form_id.
4077 $sarow = sqlQuery(
4078 "SELECT sa.field_value " .
4079 "FROM forms AS f, shared_attributes AS sa WHERE " .
4080 "f.form_id = ? AND f.formdir = ? AND f.deleted = 0 AND " .
4081 "sa.pid = f.pid AND sa.encounter = f.encounter AND sa.field_id = ?",
4082 array($formid, $formname, $field_id)
4084 if (!empty($sarow)) {
4085 $currvalue = $sarow['field_value'];
4087 } else {
4088 // New form and encounter not available, this should not happen.
4090 if (empty($sarow) && !$formid) {
4091 // New form, see if there is a custom default from a plugin.
4092 if (function_exists($deffname)) {
4093 $currvalue = call_user_func($deffname);
4096 } elseif ($source == 'V') {
4097 if ($encounter) {
4098 // Get value from the current encounter's form_encounter.
4099 $ferow = sqlQuery(
4100 "SELECT * FROM form_encounter WHERE " .
4101 "pid = ? AND encounter = ?",
4102 array($pid, $encounter)
4104 if (isset($ferow[$field_id])) {
4105 $currvalue = $ferow[$field_id];
4107 } elseif ($formid) {
4108 // Get value from the form_encounter that this form is linked to.
4109 $ferow = sqlQuery(
4110 "SELECT fe.* " .
4111 "FROM forms AS f, form_encounter AS fe WHERE " .
4112 "f.form_id = ? AND f.formdir = ? AND f.deleted = 0 AND " .
4113 "fe.pid = f.pid AND fe.encounter = f.encounter",
4114 array($formid, $formname)
4116 if (isset($ferow[$field_id])) {
4117 $currvalue = $ferow[$field_id];
4119 } else {
4120 // New form and encounter not available, this should not happen.
4122 } elseif ($formid) {
4123 // This is a normal form field.
4124 $ldrow = sqlQuery("SELECT field_value FROM lbf_data WHERE " .
4125 "form_id = ? AND field_id = ?", array($formid, $field_id));
4126 if (!empty($ldrow)) {
4127 $currvalue = $ldrow['field_value'];
4129 } else {
4130 // New form, see if there is a custom default from a plugin.
4131 if (function_exists($deffname)) {
4132 $currvalue = call_user_func($deffname);
4136 return $currvalue;
4139 function signer_head()
4141 return <<<EOD
4142 <link href="{$GLOBALS['web_root']}/portal/sign/css/signer_modal.css?v={$GLOBALS['v_js_includes']}" rel="stylesheet"/>
4143 <script src="{$GLOBALS['web_root']}/portal/sign/assets/signature_pad.umd.js?v={$GLOBALS['v_js_includes']}"></script>
4144 <script src="{$GLOBALS['web_root']}/portal/sign/assets/signer_api.js?v={$GLOBALS['v_js_includes']}"></script>
4145 EOD;
4148 // This returns stuff that needs to go into the <head> section of a caller using
4149 // the drawable image field type in a form.
4150 // A TRUE argument makes the widget controls smaller.
4152 function lbf_canvas_head($small = true)
4154 $s = <<<EOD
4155 <link href="{$GLOBALS['assets_static_relative']}/literallycanvas/css/literallycanvas.css" rel="stylesheet" />
4156 <script src="{$GLOBALS['assets_static_relative']}/react/build/react-with-addons.min.js"></script>
4157 <script src="{$GLOBALS['assets_static_relative']}/react/build/react-dom.min.js"></script>
4158 <script src="{$GLOBALS['assets_static_relative']}/literallycanvas/js/literallycanvas.min.js"></script>
4159 EOD;
4160 if ($small) {
4161 $s .= <<<EOD
4162 <style>
4163 /* Custom LiterallyCanvas styling.
4164 * This makes the widget 25% less tall and adjusts some other things accordingly.
4166 .literally {
4167 min-height: 100%;
4168 min-width: 300px; /* Was 400, unspecified */
4170 .literally .lc-picker .toolbar-button {
4171 width: 20px;
4172 height: 20px;
4173 line-height: 20px; /* Was 26, 26, 26 */
4175 .literally .color-well {
4176 font-size: 8px;
4177 width: 49px; /* Was 10, 60 */
4179 .literally .color-well-color-container {
4180 width: 21px;
4181 height: 21px; /* Was 28, 28 */
4183 .literally .lc-picker {
4184 width: 50px; /* Was 61 */
4186 .literally .lc-drawing.with-gui {
4187 left: 50px; /* Was 61 */
4189 .literally .lc-options {
4190 left: 50px; /* Was 61 */
4192 .literally .color-picker-popup {
4193 left: 49px;
4194 bottom: 0px; /* Was 60, 31 */
4196 </style>
4197 EOD;
4200 return $s;
4204 * Test if modifier($test) is in array of options for data type.
4206 * @param json array $options ["G","P","T"], ["G"] or could be legacy string with form "GPT", "G", "012"
4207 * @param string $test
4208 * @return boolean
4210 function isOption($options, $test)
4212 if (empty($options) || !isset($test) || $options == "null") {
4213 return false; // why bother?
4215 if (strpos($options, ',') === false) { // not json array of modifiers.
4216 // could be string of char's or single element of json ["RO"] or "TP" or "P" e.t.c.
4217 json_decode($options, true); // test if options json. json_last_error() will return JSON_ERROR_SYNTAX if not.
4218 // if of form ["RO"] (single modifier) means not legacy so continue on.
4219 if (is_string($options) && (json_last_error() !== JSON_ERROR_NONE)) { // nope, it's string.
4220 $t = str_split(trim($options)); // very good chance it's legacy modifier string.
4221 $options = json_encode($t); // make it json array to convert from legacy to new modifier json schema.
4225 $options = json_decode($options, true); // all should now be json
4227 return !is_null($options) && in_array($test, $options, true) ? true : false; // finally the truth!