4 * Administration Lists Module.
7 * @link http://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @author Robert Down <robertdown@live.com>
11 * @author Jerry Padgett <sjpadgett@gmail.com>
12 * @copyright Copyright (c) 2007-2022 Rod Roark <rod@sunsetsystems.com>
13 * @copyright Copyright (c) 2017-2018 Brady Miller <brady.g.miller@gmail.com>
14 * @copyright Copyright (c) 2022-2023 Robert Down <robertdown@live.com>
15 * @copyright Copyright (c) 2017-2023 Jerry Padgett <sjpadgett@gmail.com>
16 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
19 require_once("../globals.php");
20 require_once("$srcdir/lists.inc.php");
21 require_once("../../custom/code_types.inc.php");
22 require_once("$srcdir/options.inc.php");
24 use OpenEMR\Common\Acl\AclExtended
;
25 use OpenEMR\Common\Acl\AclMain
;
26 use OpenEMR\Common\Csrf\CsrfUtils
;
27 use OpenEMR\Common\Logging\EventAuditLogger
;
28 use OpenEMR\Common\Twig\TwigContainer
;
29 use OpenEMR\Core\Header
;
32 if (!CsrfUtils
::verifyCsrfToken($_POST["csrf_token_form"])) {
33 CsrfUtils
::csrfNotVerified();
37 // Below allows the list to default to the first item on the list
38 // when list_id is blank.
40 if (empty($_REQUEST['list_id'] ??
null) && empty($_REQUEST['list_id_container'] ??
null)) {
41 $list_id = 'language';
42 $blank_list_id = true;
44 $list_id = $_REQUEST['list_id'];
47 // Check authorization.
48 $thisauth = AclMain
::aclCheckCore('admin', 'super');
50 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("List Editor")]);
54 // Compute a current checksum of the data from the database for the given list.
56 function listChecksum($list_id)
58 if ($list_id == 'feesheet') {
60 "SELECT BIT_XOR(CRC32(CONCAT_WS(',', " .
61 "fs_category, fs_option, fs_codes" .
62 "))) AS checksum FROM fee_sheet_options"
64 } elseif ($list_id == 'code_types') {
66 "SELECT BIT_XOR(CRC32(CONCAT_WS(',', " .
67 "ct_key, ct_id, ct_seq, ct_mod, ct_just, ct_mask, ct_fee, ct_rel, ct_nofs, ct_diag" .
68 "))) AS checksum FROM code_types"
72 "SELECT BIT_XOR(CRC32(CONCAT_WS(',', " .
73 "list_id, option_id, title, seq, is_default, option_value, mapping, notes" .
74 "))) AS checksum FROM list_options WHERE " .
79 return (0 +
$row['checksum']);
84 if (isset($_POST['form_checksum']) && $_POST['formaction'] == 'save') {
85 if ($_POST['form_checksum'] != listChecksum($list_id)) {
86 $alertmsg = xl('Save rejected because someone else has changed this list. Please try again.');
90 //Limit variables for filter
91 $records_per_page = 40;
92 $list_from = ( isset($_REQUEST["list_from"]) ?
intval($_REQUEST["list_from"]) : 1 );
93 $list_to = ( isset($_REQUEST["list_to"]) ?
intval($_REQUEST["list_to"]) : 0);
95 // If we are saving, then save.
97 if ((($_POST['formaction'] ??
'') == 'save') && $list_id && $alertmsg == '') {
99 if ($list_id == 'feesheet') {
100 // special case for the feesheet list
101 sqlStatement("DELETE FROM fee_sheet_options");
102 for ($lino = 1; isset($opt["$lino"]['category']); ++
$lino) {
103 $iter = $opt["$lino"];
104 $category = trim($iter['category']);
105 $option = trim($iter['option']);
106 $codes = trim($iter['codes']);
107 if (strlen($category) > 0 && strlen($option) > 0) {
108 sqlStatement("INSERT INTO fee_sheet_options ( " .
109 "fs_category, fs_option, fs_codes " .
110 ") VALUES ( ?,?,? )", array($category, $option, $codes));
113 } elseif ($list_id == 'code_types') {
114 // special case for code types
115 sqlStatement("DELETE FROM code_types");
116 for ($lino = 1; isset($opt["$lino"]['ct_key']); ++
$lino) {
117 $iter = $opt["$lino"];
118 $ct_key = trim($iter['ct_key']);
119 $ct_id = (int)trim($iter['ct_id']);
120 $ct_seq = (int)trim($iter['ct_seq']);
121 $ct_mod = (int)trim($iter['ct_mod']);
122 $ct_just = trim($iter['ct_just']);
123 $ct_mask = trim($iter['ct_mask']);
124 $ct_fee = empty($iter['ct_fee']) ?
0 : 1;
125 $ct_rel = empty($iter['ct_rel']) ?
0 : 1;
126 $ct_nofs = empty($iter['ct_nofs']) ?
0 : 1;
127 $ct_diag = empty($iter['ct_diag']) ?
0 : 1;
128 $ct_active = empty($iter['ct_active']) ?
0 : 1;
129 $ct_label = trim($iter['ct_label']);
130 $ct_external = (int)trim($iter['ct_external']);
131 $ct_claim = empty($iter['ct_claim']) ?
0 : 1;
132 $ct_proc = empty($iter['ct_proc']) ?
0 : 1;
133 $ct_term = empty($iter['ct_term']) ?
0 : 1;
134 $ct_problem = empty($iter['ct_problem']) ?
0 : 1;
135 $ct_drug = empty($iter['ct_drug']) ?
0 : 1;
136 if (strlen($ct_key) > 0 && $ct_id > 0) {
138 "INSERT INTO code_types ( " .
139 "ct_key, ct_id, ct_seq, ct_mod, ct_just, ct_mask, ct_fee, ct_rel, ct_nofs, ct_diag, ct_active, ct_label, ct_external, ct_claim, ct_proc, ct_term, ct_problem, ct_drug " .
140 ") VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
164 } elseif ($list_id == 'issue_types') {
165 // special case for issue_types
166 sqlStatement("DELETE FROM issue_types");
167 for ($lino = 1; isset($opt["$lino"]['category']); ++
$lino) {
168 $iter = $opt["$lino"];
169 $it_category = trim($iter['category']);
170 $it_type = trim($iter['type']);
171 if ((strlen($it_category) > 0) && (strlen($it_type) > 0)) {
172 sqlStatement("INSERT INTO issue_types (" .
173 "`active`,`category`,`ordering`, `type`, `plural`, `singular`, `abbreviation`, `style`, " .
174 "`force_show`, `aco_spec`) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", array(
175 trim($iter['active']),
177 trim($iter['ordering']),
179 trim($iter['plural']),
180 trim($iter['singular']),
181 trim($iter['abbreviation']),
182 trim($iter['style']),
183 trim($iter['force_show']),
184 trim($iter['aco_spec']),
191 // collect the option toggle if using the 'immunizations' list
192 if ($list_id == 'immunizations') {
193 $ok_map_cvx_codes = isset($_POST['ok_map_cvx_codes']) ?
$_POST['ok_map_cvx_codes'] : 0;
196 for ($lino = 1; isset($opt["$lino"]['id']); ++
$lino) {
197 $iter = $opt["$lino"];
198 $value = empty($iter['value']) ?
0 : (trim($iter['value']));
199 $id = trim($iter['id']);
200 $real_id = trim($iter['real_id']);
202 if (strlen($real_id) > 0 ||
strlen($id) > 0) {
203 // Special processing for the immunizations list
204 // Map the entered cvx codes into the immunizations table cvx_code
205 // Ensure the following conditions are met to do this:
206 // $list_id == 'immunizations'
207 // $value is an integer and greater than 0
208 // $id is set, not empty and not equal to 0
209 // (note that all these filters are important. Not allowing $id
210 // of zero here is extremely important; never remove this conditional
211 // or you risk corrupting your current immunizations database entries)
212 // $ok_map_cvx_codes is equal to 1
214 $list_id == 'immunizations' &&
220 $ok_map_cvx_codes == 1
222 sqlStatement("UPDATE `immunizations` " .
223 "SET `cvx_code`= ? " .
224 "WHERE `immunization_id`= ? ", array($value, $id));
227 // Force List Based Form names to start with LBF.
228 if ($list_id == 'lbfnames' && substr($id, 0, 3) != 'LBF') {
230 $real_id = "LBF$real_id";
233 // Force Transaction Form names to start with LBT.
234 if ($list_id == 'transactions' && substr($id, 0, 3) != 'LBT') {
236 $real_id = "LBT$real_id";
239 if ($list_id == 'apptstat' ||
$list_id == 'groupstat') {
240 $notes = trim($iter['apptstat_color']) . '|' . trim($iter['apptstat_timealert']);
242 $notes = trim($iter['notes'] ??
'');
245 if (preg_match("/Eye_QP_/", $list_id)) {
246 if (preg_match("/^[BLR]/", $id)) {
247 $stuff = explode("_", $id)[0];
248 $iter['mapping'] = substr($stuff, 1);
249 $iter['subtype'] = substr($stuff, 0, 1);
251 $stuff = explode("_", $id)[0];
252 $iter['mapping'] = substr($stuff, 2);
253 $iter['subtype'] = substr($stuff, 0, 2);
257 // Delete the list item
258 sqlStatement("DELETE FROM list_options WHERE list_id = ? AND option_id = ?", array($list_id, $real_id));
259 if (strlen($id) <= 0 && strlen(trim($iter['title'])) <= 0 && empty($id) && empty($iter['title'])) {
262 // Insert the list item
264 "INSERT INTO list_options ( " .
265 "list_id, option_id, title, seq, is_default, option_value, mapping, notes, codes, toggle_setting_1, toggle_setting_2, activity, subtype " .
266 ") VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
270 trim($iter['title']),
272 trim($iter['default'] ??
0),
274 trim($iter['mapping'] ??
''),
276 trim($iter['codes']),
277 trim($iter['toggle_setting_1'] ??
0),
278 trim($iter['toggle_setting_2'] ??
0),
279 trim($iter['activity'] ??
0),
280 trim($iter['subtype'] ??
'')
286 EventAuditLogger
::instance()->newEvent(
288 $_SESSION['authUser'],
289 $_SESSION['authProvider'],
293 } elseif (!empty($_POST['formaction']) && ($_POST['formaction'] == 'addlist')) {
294 // make a new list ID from the new list name
295 $newlistID = $_POST['newlistname'];
296 $newlistID = preg_replace("/\W/", "_", $newlistID);
298 // determine the position of this new list
299 $row = sqlQuery("SELECT max(seq) AS maxseq FROM list_options WHERE list_id= 'lists'");
300 $dup_cnt = sqlQuery("SELECT count(seq) as validate FROM list_options WHERE list_id= 'lists' AND option_id = ?", array($newlistID))['validate'];
301 if ((int)$dup_cnt === 0) {
302 // add the new list to the list-of-lists
303 sqlStatement("INSERT INTO list_options ( " .
304 "list_id, option_id, title, seq, is_default, option_value " .
305 ") VALUES ( 'lists', ?, ?, ?, '1', '0')", array($newlistID, $_POST['newlistname'], ($row['maxseq'] +
1)));
306 $list_id = $newlistID;
308 // send error and continue.
309 echo "<script>let error=" . js_escape(xlt("The new list") . " [" . $_POST['newlistname'] . "] " . xlt("already exists! Please try again.")) . ";</script>";
311 EventAuditLogger
::instance()->newEvent(
313 $_SESSION['authUser'],
314 $_SESSION['authProvider'],
318 } elseif (!empty($_POST['formaction']) && ($_POST['formaction'] == 'deletelist')) {
319 // delete the lists options
320 sqlStatement("DELETE FROM list_options WHERE list_id = ?", array($_POST['list_id']));
321 // delete the list from the master list-of-lists
322 sqlStatement("DELETE FROM list_options WHERE list_id = 'lists' AND option_id=?", array($_POST['list_id']));
323 EventAuditLogger
::instance()->newEvent(
325 $_SESSION['authUser'],
326 $_SESSION['authProvider'],
328 "List = " . $_POST['list_id']
334 // Given a string of multiple instances of code_type|code|selector,
335 // make a description for each.
336 // @TODO Instead should use a function from custom/code_types.inc.php and need to remove casing functions
337 function getCodeDescriptions($codes)
340 $arrcodes = explode('~', $codes);
342 foreach ($arrcodes as $codestring) {
343 if ($codestring === '') {
346 $arrcode = explode('|', $codestring);
347 $code_type = $arrcode[0];
348 // test for code with a modifier.
350 if (stripos($arrcode[1], ':') !== false) {
351 $tmp = explode(':', $arrcode[1]);
352 if (!empty($tmp[0] ??
null)) {
353 $code = $tmp[0] ??
'';
354 $modifier = $tmp[1] ??
'';
355 $modifier .= ($tmp[2] ??
'') ?
":" . $tmp[2] : '';
356 $modifier .= ($tmp[3] ??
'') ?
":" . $tmp[3] : '';
357 $modifier .= ($tmp[4] ??
'') ?
":" . $tmp[4] : '';
362 $selector = $arrcode[2];
363 if ($code_type == 'PROD') {
364 $row = sqlQuery("SELECT name FROM drugs WHERE drug_id = ?", array($code));
365 $desc = "$code:$selector " . $row['name'];
367 $row = sqlQuery("SELECT code_text FROM codes WHERE " .
368 "code_type = ? AND " .
369 "code = ? ORDER BY modifier LIMIT 1", array($code_types[$code_type]['id'], $code ));
370 $desc = "$code_type:$code " . ucfirst(strtolower($row['code_text'] ??
''));
372 $desc = str_replace('~', ' ', $desc);
373 if (!empty($modifier ??
'')) {
374 $desc .= " " . xlt("Modifier") . ": " . $modifier;
384 // Write one option line to the form.
386 function writeOptionLine($option_id, $title, $seq, $default, $value, $mapping = '', $notes = '', $codes = '', $tog1 = '', $tog2 = '', $active = '1', $subtype = '')
388 global $opt_line_no, $list_id;
390 $bgcolor = "#" . (($opt_line_no & 1) ?
"ddddff" : "ffdddd");
391 $checked = $default ?
" checked" : "";
392 $checked_tog1 = $tog1 ?
" checked" : "";
393 $checked_tog2 = $tog2 ?
" checked" : "";
394 $checked_active = $active ?
" checked" : "";
399 //New line for hidden input, for update items
400 echo "<input type='hidden' name='opt[" . attr($opt_line_no) . "][real_id]' value='" .
401 attr($option_id) . "' size='12' maxlength='127' class='optin form-control form-control-sm' />";
402 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][id]' value='" .
403 attr($option_id) . "' size='12' maxlength='127' class='optin form-control form-control-sm' />";
406 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][title]' value='" .
407 attr($title) . "' size='20' maxlength='127' class='optin form-control form-control-sm'>";
410 // if not english and translating lists then show the translation
411 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
412 echo " <td align='center' class='translation'>" . xlt($title) . "</td>\n";
415 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][seq]' value='" .
416 attr($seq) . "' size='4' maxlength='10' class='optin form-control form-control-sm' />";
420 echo "<input type='checkbox' name='opt[" . attr($opt_line_no) . "][default]' value='1' " .
421 "onclick='defClicked(" . attr($opt_line_no) . ")' class='optin'$checked />";
424 if (preg_match('/Eye_QP_/', $list_id)) {
426 echo "<select name='opt[" . attr($opt_line_no) . "][activity]' class='optin'>";
433 echo "<option value='" . attr($key) . "'";
434 if ($key == $active) {
437 echo ">" . text($desc) . "</option>";
443 echo "<input type='checkbox' name='opt[" . attr($opt_line_no) . "][activity]' value='1' " . " class='optin'$checked_active />";
446 // Tax rates, contraceptive methods and LBF names have an additional attribute.
448 if ($list_id == 'taxrate' ||
$list_id == 'contrameth' ||
$list_id == 'lbfnames' ||
$list_id == 'transactions') {
450 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][value]' value='" .
451 attr($value) . "' size='8' maxlength='15' class='optin' />";
453 } elseif ($list_id == 'adjreason') {
454 // Adjustment reasons use option_value as a reason category. This is
455 // needed to distinguish between adjustments that change the invoice
456 // balance and those that just shift responsibility of payment or
457 // are used as comments.
459 echo "<select name='opt[" . attr($opt_line_no) . "][value]' class='optin'>";
462 1 => xl('Charge adjustment'),
463 2 => xl('Coinsurance'),
464 3 => xl('Deductible'),
465 4 => xl('Other pt resp'),
469 echo "<option value='" . attr($key) . "'";
470 if ($key == $value) {
473 echo ">" . text($desc) . "</option>";
477 } elseif ($list_id == 'warehouse') {
479 // Build a drop-down list of facilities.
480 $query = "SELECT id, name FROM facility ORDER BY name";
481 $fres = sqlStatement($query);
482 echo "<select name='opt[" . attr($opt_line_no) . "][value]' class='optin'>";
483 echo " <option value='0'>-- " . xlt('Unassigned') . " --\n";
484 while ($frow = sqlFetchArray($fres)) {
485 $facid = $frow['id'];
486 echo " <option value='" . attr($facid) . "'";
487 if ($facid == $value) {
490 echo ">" . text($frow['name']) . "\n";
494 } elseif ($list_id == 'abook_type') { // Address book categories use option_value to flag category as a
495 // person-centric vs company-centric vs indifferent.
497 echo "<select name='opt[" . attr($opt_line_no) . "][value]' class='optin'>";
500 1 => xl('Unassigned'),
505 echo "<option value='" . attr($key) . "'";
506 if ($key == $value) {
509 echo ">" . text($desc) . "</option>";
513 } elseif ($list_id == 'immunizations') { // Immunization categories use option_value to map list items to CVX codes.
515 echo "<input type='text' size='10' name='opt[" . attr($opt_line_no) . "][value]' " .
516 "value='" . attr($value) . "' onclick='sel_cvxcode(this)' " .
517 "title='" . xla('Click to select or change CVX code') . "'/>";
519 } elseif ($list_id == 'ptlistcols') {
521 echo generate_select_list("opt[$opt_line_no][toggle_setting_1]", 'Sort_Direction', $tog1, 'Sort Direction', null, 'option');
525 if ($list_id == 'apptstat' ||
$list_id == 'groupstat') {
526 list($apptstat_color, $apptstat_timealert) = explode("|", $notes);
528 echo "<input type='text' class='jscolor' name='opt[" . attr($opt_line_no) . "][apptstat_color]' value='" .
529 attr($apptstat_color) . "' size='6' maxlength='6' class='optin' />";
532 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][apptstat_timealert]' value='" .
533 attr($apptstat_timealert) . "' size='2' maxlength='2' class='optin' />";
536 echo "<input type='checkbox' name='opt[" . attr($opt_line_no) . "][toggle_setting_1]' value='1' " .
537 "onclick='defClicked(" . attr($opt_line_no) . ")' class='optin'$checked_tog1 />";
540 echo "<input type='checkbox' name='opt[" . attr($opt_line_no) . "][toggle_setting_2]' value='1' " .
541 "onclick='defClicked(" . attr($opt_line_no) . ")' class='optin'$checked_tog2 />";
544 // IPPF includes the ability to map each list item to a "master" identifier.
545 // Sports teams use this for some extra info for fitness levels.
546 if ($GLOBALS['ippf_specific'] ||
$list_id == 'fitness') {
548 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][mapping]' value='" .
549 attr($mapping) . "' size='12' maxlength='15' class='optin' />";
553 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][notes]' value='" .
554 attr($notes) . "' size='25' maxlength='255' class='optin form-control form-control-sm' ";
560 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][codes]' title='" .
561 xla('Code(s)') . "' value='" .
562 attr($codes) . "' onclick='select_clin_term_code(this)' size='25' maxlength='255' class='optin form-control form-control-sm' />";
565 if (preg_match('/_issue_list$/', $list_id)) {
567 echo generate_select_list("opt[$opt_line_no][subtype]", 'issue_subtypes', $subtype, 'Subtype', ' ', 'optin');
570 if (preg_match('/Eye_QP_/', $list_id)) {
571 echo "<input type='hidden' name='opt[" . attr($opt_line_no) . "][subtype]' value='" . attr($subtype) . "' />";
572 echo "<input type='hidden' name='opt[" . attr($opt_line_no) . "][mapping]' value='" . attr($mapping) . "' />";
577 // Write a form line as above but for the special case of the Fee Sheet.
579 function writeFSLine($category, $option, $codes)
584 $bgcolor = "#" . (($opt_line_no & 1) ?
"ddddff" : "ffdddd");
586 $descs = getCodeDescriptions($codes);
591 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][category]' value='" .
592 attr($category) . "' size='20' maxlength='63' class='optin' />";
596 echo "<input type='text' name='opt[" . attr($opt_line_no) . "][option]' value='" .
597 attr($option) . "' size='20' maxlength='63' class='optin' />";
600 echo " <td align='left' class='optcell'>";
601 echo " <div id='codelist_" . attr($opt_line_no) . "'>";
602 if (strlen($descs)) {
603 $arrdescs = explode('~', $descs);
605 foreach ($arrdescs as $desc) {
606 echo "<a href='' onclick='return delete_code(" . attr($opt_line_no) . ",$i)' title='" . xla('Delete') . "'>";
607 echo "[x] </a>" . text($desc) . "<br />";
612 echo "<a href='' onclick='return select_code(" . attr($opt_line_no) . ")'>";
613 echo "[" . xlt('Add') . "]</a>";
615 echo "<input type='hidden' name='opt[" . attr($opt_line_no) . "][codes]' value='" .
616 attr($codes) . "' />";
617 echo "<input type='hidden' name='opt[" . attr($opt_line_no) . "][descs]' value='" .
618 attr($descs) . "' />";
626 * Helper functions for writeITLine() and writeCTLine().
628 function ctGenCell($opt_line_no, $data_array, $name, $size, $maxlength, $title = '')
630 $value = isset($data_array[$name]) ?
$data_array[$name] : '';
633 $s .= " title='" . attr($title) . "'";
636 $s .= "<input type='text' name='opt[" . attr($opt_line_no) . "][" . attr($name) . "]' value='";
638 $s .= "' size='" . attr($size) . "' maxlength='" . attr($maxlength) . "' class='optin' />";
643 function ctGenCbox($opt_line_no, $data_array, $name, $title = '')
645 $checked = empty($data_array[$name]) ?
'' : 'checked ';
648 $s .= " title='" . attr($title) . "'";
651 $s .= "<input type='checkbox' name='opt[" . attr($opt_line_no) . "][" . attr($name) . "]' value='1' ";
657 function ctSelector($opt_line_no, $data_array, $name, $option_array, $title = '')
659 $value = isset($data_array[$name]) ?
$data_array[$name] : '';
660 $s = " <td title='" . attr($title) . "'>";
661 $s .= "<select name='opt[" . attr($opt_line_no) . "][" . attr($name) . "]' class='optin'>";
662 foreach ($option_array as $key => $desc) {
663 $s .= "<option value='" . attr($key) . "'";
664 if ($key == $value) {
667 $s .= ">" . text($desc) . "</option>";
674 // Write a form line as above but for the special case of Code Types.
676 function writeCTLine($ct_array)
678 global $opt_line_no, $ct_external_options;
681 $bgcolor = "#" . (($opt_line_no & 1) ?
"ddddff" : "ffdddd");
689 xl('Is this code type active?')
697 xl('Unique human-readable identifier for this type')
705 xl('Unique numeric identifier for this type')
713 xl('Label for this type')
715 // if not english and translating lists then show the translation
716 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
717 echo " <td align='center' class='translation'>" . xlt($ct_array['ct_label']) . "</td>\n";
725 xl('Numeric display order')
733 xl('Length of modifier, 0 if none')
741 xl('If billing justification is used enter the name of the diagnosis code type.')
749 xl('Specifies formatting for codes. # = digit, @ = alpha, * = any character. Empty if not used.')
755 xl('Is this code type used in claims?')
761 xl('Are fees charged for this type?')
767 xl('Does this type allow related codes?')
773 xl('Is this type hidden in the fee sheet?')
779 xl('Is this a procedure/service type?')
785 xl('Is this a diagnosis type?')
791 xl('Is this a Clinical Term code type?')
797 xl('Is this a Medical Problem code type?')
803 xl('Is this a Medication type?')
809 $ct_external_options,
810 xl('Is this using external sql tables? If it is, then choose the format.')
816 * Special case of Issue Types
818 function writeITLine($it_array)
820 global $opt_line_no, $ISSUE_TYPE_CATEGORIES, $ISSUE_TYPE_STYLES;
822 $bgcolor = "#" . (($opt_line_no & 1) ?
"ddddff" : "ffdddd");
824 echo ctSelector($opt_line_no, $it_array, 'category', $ISSUE_TYPE_CATEGORIES, xl('OpenEMR Application Category'));
825 echo ctGenCBox($opt_line_no, $it_array, 'active', xl('Is this active?'));
826 echo ctGenCell($opt_line_no, $it_array, 'ordering', 4, 10, xl('Order{{Sequence}}'));
827 echo ctGenCell($opt_line_no, $it_array, 'type', 15, 75, xl('Issue Type'));
828 echo ctGenCell($opt_line_no, $it_array, 'plural', 15, 75, xl('Plural'));
829 // if not english and translating lists then show the translation
830 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
831 echo " <td align='center' class='translation'>" . xlt($it_array['plural']) . "</td>\n";
833 echo ctGenCell($opt_line_no, $it_array, 'singular', 15, 75, xl('Singular'));
834 // if not english and translating lists then show the translation
835 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
836 echo " <td align='center' class='translation'>" . xlt($it_array['singular']) . "</td>\n";
838 echo ctGenCell($opt_line_no, $it_array, 'abbreviation', 5, 10, xl('Abbreviation'));
839 // if not english and translating lists then show the translation
840 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
841 echo " <td align='center' class='translation'>" . xlt($it_array['abbreviation']) . "</td>\n";
843 echo ctSelector($opt_line_no, $it_array, 'style', $ISSUE_TYPE_STYLES, xl('Standard; Simplified: only title, start date, comments and an Active checkbox;no diagnosis, occurrence, end date, referred-by or sports fields. ; Football Injury'));
844 echo ctGenCBox($opt_line_no, $it_array, 'force_show', xl('Show this category on the patient summary screen even if no issues have been entered for this category.'));
847 echo "<select name='opt[" . attr($opt_line_no) . "][aco_spec]' class='optin'>";
848 echo "<option value=''></option>";
849 echo AclExtended
::genAcoHtmlOptions($it_array['aco_spec']);
860 <?php
echo Header
::setupHeader(['select2', 'jscolor']); ?
>
861 <title
><?php
echo xlt('List Editor'); ?
></title
>
864 background
-color
: transparent
;
872 color
: var(--success
);
874 #theform input[type=text],
881 $
(".select-dropdown").select2({
883 <?php
require($GLOBALS['srcdir'] . '/js/xl/select2.js.php'); ?
>
885 if (typeof error
!== 'undefined') {
891 $
(document
).on('select2:open', () => {
892 document
.querySelector('.select2-search__field').focus();
894 // Keeping track of code picker requests.
895 var current_lino
= 0;
896 var current_sel_name
= '';
897 var current_sel_clin_term
= '';
899 // Helper function to set the contents of a div.
900 // This is for Fee Sheet administration.
901 function setDivContent(id
, content
) {
902 if (document
.getElementById
) {
903 var x
= document
.getElementById(id
);
905 x
.innerHTML
= content
;
907 else if (document
.all
) {
908 var x
= document
.all
[id
];
909 x
.innerHTML
= content
;
913 // Given a line number, redisplay its descriptive list of codes.
914 // This is for Fee Sheet administration.
915 function displayCodes(lino
) {
916 var f
= document
.forms
[0];
918 var descs
= f
['opt[' + lino +
'][descs]'].value
;
920 var arrdescs
= descs
.split('~');
921 for (var i
= 0; i
< arrdescs
.length
; ++i
) {
922 s +
= "<a href='' onclick='return delete_code(" + lino +
"," + i +
")' title='<?php echo xla('Delete'); ?>'>";
923 s +
= "[x] </a>" + arrdescs
[i
] +
"<br />";
926 setDivContent('codelist_' + lino
, s
);
929 // Helper function to remove a Fee Sheet code.
930 function dc_substring(s
, i
) {
932 var j
= s
.indexOf('~', i
);
933 if (j
< 0) { // deleting last segment
934 if (i
> 0) r
= s
.substring(0, i
- 1); // omits trailing ~
936 else { // not last segment
937 r
= s
.substring(0, i
) + s
.substring(j +
1);
942 // Remove a generated Fee Sheet code.
943 function delete_code(lino
, seqno
) {
944 var f
= document
.forms
[0];
945 var celem
= f
['opt[' + lino +
'][codes]'];
946 var delem
= f
['opt[' + lino +
'][descs]'];
949 for (var i
= 0; i
< seqno
; ++i
) {
950 ci
= celem
.value
.indexOf('~', ci
) +
1;
951 di
= delem
.value
.indexOf('~', di
) +
1;
953 celem
.value
= dc_substring(celem
.value
, ci
);
954 delem
.value
= dc_substring(delem
.value
, di
);
959 // This invokes the find-code popup.
960 // For Fee Sheet administration.
961 function select_code(lino
) {
962 current_sel_name
= '';
963 current_sel_clin_term
= '';
965 dlgopen('../patient_file/encounter/find_code_dynamic.php', '_blank', 900, 600);
969 // This invokes the find-code popup.
970 // For CVX/immunization code administration.
971 function sel_cvxcode(e
) {
972 current_sel_clin_term
= '';
973 current_sel_name
= e
.name
;
974 dlgopen('../patient_file/encounter/find_code_dynamic.php?codetype=CVX', '_blank', 900, 600);
977 // This invokes the find-code popup.
978 function select_clin_term_code(e
) {
979 current_sel_name
= '';
980 current_sel_clin_term
= e
.name
;
981 dlgopen('../patient_file/encounter/find_code_dynamic.php', '_blank', 900, 600);
984 // This is for callback by the find-code popup.
985 function set_related(codetype
, code
, selector
, codedesc
, modifier
= '') {
986 var f
= document
.forms
[0];
987 if (current_sel_clin_term
) {
988 // Coming from the Clinical Terms Code(s) edit
989 var e
= f
[current_sel_clin_term
];
995 s +
= codetype +
':' + code
;
1002 else if (current_sel_name
) {
1003 // Coming from Immunizations edit
1004 var e
= f
[current_sel_name
];
1015 // Coming from Fee Sheet edit
1016 var celem
= f
['opt[' + current_lino +
'][codes]'];
1017 var delem
= f
['opt[' + current_lino +
'][descs]'];
1019 while ((i
= codedesc
.indexOf('~')) >= 0) {
1020 codedesc
= codedesc
.substring(0, i
) +
' ' + codedesc
.substring(i+
1);
1024 code
= code +
':' + modifier
;
1030 celem
.value +
= codetype +
'|' + code +
'|' + selector
;
1031 if (codetype
== 'PROD') {
1032 delem
.value +
= code +
':' + selector +
' ' + codedesc
;
1034 delem
.value +
= codetype +
':' + code +
' ' + codedesc
;
1040 displayCodes(current_lino
);
1044 // This is for callback by the find-code popup.
1045 // Deletes the specified codetype:code from the currently selected list.
1046 function del_related(s
) {
1047 var f
= document
.forms
[0];
1048 if (current_sel_clin_term
) {
1049 // Coming from the Clinical Terms Code(s) edit
1050 my_del_related(s
, f
[current_sel_clin_term
], false);
1052 else if (current_sel_name
) {
1053 // Coming from Immunizations edit
1054 f
[current_sel_name
].value
= '0';
1057 // Coming from Fee Sheet edit
1058 f
['opt[' + current_lino +
'][codes]'].value
= '';
1059 f
['opt[' + current_lino +
'][descs]'].value
= '';
1060 displayCodes(current_lino
);
1064 // This is for callback by the find-code popup.
1065 // Returns the array of currently selected codes with each element in codetype:code format.
1066 function get_related() {
1067 var f
= document
.forms
[0];
1068 if (current_sel_clin_term
) {
1069 return f
[current_sel_clin_term
].value
.split(';');
1074 // Called when a "default" checkbox is clicked. Clears all the others.
1075 function defClicked(lino
) {
1076 var f
= document
.forms
[0];
1077 for (var i
= 1; f
['opt[' + i +
'][default]']; ++i
) {
1078 if (i
!= lino
) f
['opt[' + i +
'][default]'].checked
= false;
1082 // Form validation and submission.
1083 // This needs more validation.
1084 function mysubmit() {
1085 var f
= document
.forms
[0];
1086 if (f
.list_id
.value
== 'code_types') {
1087 for (var i
= 1; f
['opt[' + i +
'][ct_key]'].value
; ++i
) {
1088 var ikey
= 'opt[' + i +
']';
1089 for (var j
= i +
1; f
['opt[' + j +
'][ct_key]'].value
; ++j
) {
1090 var jkey
= 'opt[' + j +
']';
1091 if (f
[ikey +
'[ct_key]'].value
== f
[jkey +
'[ct_key]'].value
) {
1092 alert(<?php
echo xlj('Error: duplicated name on line') ?
> +
' ' + j
);
1095 if (parseInt(f
[ikey +
'[ct_id]'].value
) == parseInt(f
[jkey +
'[ct_id]'].value
)) {
1096 alert(<?php
echo xlj('Error: duplicated ID on line') ?
> +
' ' + j
);
1102 else if (f
['opt[1][id]']) {
1103 // Check for duplicate IDs.
1104 for (var i
= 1; f
['opt[' + i +
'][id]']; ++i
) {
1105 var ikey
= 'opt[' + i +
'][id]';
1106 if (f
[ikey
].value
== '') continue;
1107 for (var j
= i+
1; f
['opt[' + j +
'][id]']; ++j
) {
1108 var jkey
= 'opt[' + j +
'][id]';
1109 if (f
[ikey
].value
.toUpperCase() == f
[jkey
].value
.toUpperCase()) {
1110 alert(<?php
echo xlj('Error: duplicated ID') ?
> +
': ' + f
[jkey
].value
);
1111 f
[jkey
].scrollIntoView();
1122 // This is invoked when a new list is chosen.
1123 // Disables all buttons and actions so certain bad things cannot happen.
1124 function listSelected() {
1125 var f
= document
.forms
[0];
1126 // For jQuery 1.6 and later, change ".attr" to ".prop".
1127 $
(":button").attr("disabled", true);
1128 f
.formaction
.value
= '';
1136 <body
class="body_top">
1137 <form method
='post' name
='theform' id
='theform' action
='edit_list.php'>
1138 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
1139 <input type
="hidden" id
="list_from" name
="list_from" value
="<?php echo attr($list_from);?>"/>
1140 <input type
="hidden" id
="list_to" name
="list_to" value
="<?php echo attr($list_to);?>"/>
1141 <nav
class="navbar navbar-light bg-light navbar-expand-md fixed-top">
1142 <div
class="container-fluid">
1143 <button
class="navbar-toggler" type
="button" data
-toggle
="collapse" data
-target
="#navbar-list" aria
-controls
="navbar-list" aria
-expanded
="false" aria
-label
="Toggle navigation"><span
class="navbar-toggler-icon"></span
></button
>
1144 <a
class="navbar-brand" href
="#"><?php
echo xlt('Manage Lists'); ?
></a
>
1146 <!-- Collect the nav links
, forms
, and other content
for toggling
-->
1147 <div
class="collapse navbar-collapse" id
="navbar-list">
1148 <ul
class="nav navbar-nav">
1149 <li
class="nav-item"><a
class="nav-link" href
="#" data
-toggle
="modal" data
-target
="#modal-new-list"><i
class="fa fa-plus"></i
> 
;<?php
echo xlt('New List'); ?
></a
></li
>
1150 <li
class="nav-item"><a
class="nav-link deletelist" href
="#" id
="<?php echo attr($list_id); ?>"><i
class="fa fa-trash"></i
> 
;<?php
echo xlt('Delete List'); ?
></a
></li
>
1152 <input type
="hidden" name
="formaction" id
="formaction" />
1153 <div
class="form-inline my-2 my-lg-0 navbar-left">
1154 <select name
='list_id' class="form-control select-dropdown" id
="list_id">
1157 * Keep proper list name (otherwise list name changes according to
1158 * the options shown on the screen).
1160 $list_id_container = $_GET["list_id_container"] ??
null;
1161 if (isset($_GET["list_id_container"]) && strlen($list_id_container) > 0) {
1162 $list_id = $list_id_container;
1165 // List order depends on language translation options.
1166 $lang_id = empty($_SESSION['language_choice']) ?
'1' : $_SESSION['language_choice'];
1168 if (!$GLOBALS['translate_lists']) {
1169 $res = sqlStatement("SELECT option_id, title FROM list_options WHERE " .
1170 "list_id = 'lists' ORDER BY title, seq");
1172 // Use and sort by the translated list name.
1173 $res = sqlStatement(
1174 "SELECT lo.option_id, " .
1175 "COALESCE((SELECT ld.definition FROM lang_constants AS lc, lang_definitions AS ld " .
1176 "WHERE lc.constant_name = lo.title AND ld.cons_id = lc.cons_id AND ld.lang_id = ? " .
1177 "AND ld.definition IS NOT NULL AND ld.definition != '' LIMIT 1), lo.title) AS title " .
1178 "FROM list_options AS lo " .
1179 "WHERE lo.list_id = 'lists' AND lo.edit_options = 1 " .
1180 "ORDER BY title, lo.seq",
1185 while ($row = sqlFetchArray($res)) {
1186 // This allows the list to default to the first item on the list
1187 // when the list_id request parameter is blank.
1188 if (($blank_list_id) && ($list_id == 'language')) {
1189 $list_id = $row['option_id'];
1190 $blank_list_id = false;
1193 $key = $row['option_id'];
1194 echo "<option value='" . attr($key) . "'";
1195 if ($key == $list_id) {
1198 echo ">" . text($row['title']) . "</option>\n";
1208 var queryParams
= getQueryStringAsObject();
1209 var list_from
= parseInt($
("#list-from").val());
1210 var list_to
= parseInt($
("#list-to").val());
1211 var list_id_container
= $
("#list_id").val();
1213 if( list_from
> list_to
){
1214 alert(<?php
echo xlj("Please enter a enter valid range"); ?
>);
1217 if( list_from
>= 0 ){
1218 queryParams
['list_from'] = list_from
;
1222 queryParams
['list_to'] = list_to
;
1224 if( list_id_container
.length
> 0 ){
1225 queryParams
['list_id_container'] = list_id_container
;
1227 var urlParts
= document
.URL
.split('?');
1228 var newUrl
= urlParts
[0] +
'?' + $
.param(queryParams
);
1229 window
.location
.replace(newUrl
);
1233 $urlFrom = ($list_from > 0 ?
$list_from : 1);
1234 $urlTo = ($list_to > 0 ?
$list_to : $records_per_page);
1236 <div
class="blck-filter float-left w-auto my-2 my-lg-0" style
="display: none;">
1237 <div id
="input-type-from" class="float-left"><?php
echo xlt("From"); ?
> 
;<input autocomplete
="off" id
="list-from" value
="<?php echo attr($urlFrom);?>" style
="margin-right: 10px; width: 40px;">
1238 <?php
echo xlt("To{{Range}}"); ?
> 
;<input autocomplete
="off" id
="list-to" value
="<?php echo attr($urlTo); ?>" style
=" margin-right: 10px; width: 40px;">
1240 <div
class="float-left"><input type
="button" value
="<?php echo xla('Show records'); ?>" onclick
="lister()"></div
>
1243 <div
class="float-left ml-2 my-2 my-lg-0" id
="total-record"></div
>
1244 </div
><!-- /.navbar
-collapse
-->
1248 <table
class="table table-striped table-sm" style
="margin-top: 55px;">
1251 <?php
if ($list_id == 'feesheet') : ?
>
1252 <th
><?php
echo xlt('Group'); ?
></th
>
1253 <th
><?php
echo xlt('Option'); ?
></th
>
1254 <th
><?php
echo xlt('Generates'); ?
></th
>
1255 <?php
elseif ($list_id == 'code_types') : ?
>
1256 <th
><?php
echo xlt('Active{{Code}}'); ?
></th
>
1257 <th
><?php
echo xlt('Key'); ?
></th
>
1258 <th
><?php
echo xlt('ID'); ?
></th
>
1259 <th
><?php
echo xlt('Label'); ?
></th
>
1260 <?php
//show translation column if not english and the translation lists flag is set
1261 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
1262 echo "<th class='font-weight-bold'>" . xlt('Translation') . "<span class='help' title='" . xla('The translated Title that will appear in current language') . "'> (?)</span></th>";
1264 <th
><?php
echo xlt('Seq'); ?
></th
>
1265 <th
><?php
echo xlt('ModLength'); ?
></th
>
1266 <th
><?php
echo xlt('Justify'); ?
></th
>
1267 <th
><?php
echo xlt('Mask'); ?
></th
>
1268 <th
><?php
echo xlt('Claims'); ?
></th
>
1269 <th
><?php
echo xlt('Fees'); ?
></th
>
1270 <th
><?php
echo xlt('Relations'); ?
></th
>
1271 <th
><?php
echo xlt('Hide'); ?
></th
>
1272 <th
><?php
echo xlt('Procedure'); ?
></th
>
1273 <th
><?php
echo xlt('Diagnosis'); ?
></th
>
1274 <th
><?php
echo xlt('Clinical Term'); ?
></th
>
1275 <th
><?php
echo xlt('Medical Problem'); ?
></th
>
1276 <th
><?php
echo xlt('Drug'); ?
></th
>
1277 <th
><?php
echo xlt('External'); ?
></th
>
1278 <?php
elseif ($list_id == 'apptstat' ||
$list_id == 'groupstat') : ?
>
1279 <th
><?php
echo xlt('ID'); ?
></th
>
1280 <th
><?php
echo xlt('Title'); ?
></th
>
1281 <th
><?php
echo xlt('Order{{Sequence}}'); ?
></th
>
1282 <th
><?php
echo xlt('Default'); ?
></th
>
1283 <th
><?php
echo xlt('Active{{Appointment}}'); ?
></th
>
1284 <th
><?php
echo xlt('Color'); ?
></th
>
1285 <th
><?php
echo xlt('Alert Time'); ?
></th
>
1286 <th
><?php
echo xlt('Check In'); ?
> 
; 
; 
; 
;</th
>
1287 <th
><?php
echo xlt('Check Out'); ?
></th
>
1288 <th
><?php
echo xlt('Code(s)'); ?
></th
>
1289 <?php
elseif ($list_id == 'issue_types') : ?
>
1290 <th
><?php
echo xlt('OpenEMR Application Category'); ?
></th
>
1291 <th
><?php
echo xlt('Active{{Issue}}'); ?
></th
>
1292 <th
><?php
echo xlt('Order{{Sequence}}'); ?
></th
>
1293 <th
><?php
echo xlt('Type'); ?
></th
>
1294 <th
><?php
echo xlt('Plural'); ?
></th
>
1295 <?php
//show translation column if not english and the translation lists flag is set
1296 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
1297 echo "<th>" . xlt('Translation') . "<span class='help' title='" . xla('The translated Title that will appear in current language') . "'> (?)</span></th>";
1299 <th
><?php
echo xlt('Singular'); ?
></th
>
1300 <?php
//show translation column if not english and the translation lists flag is set
1301 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
1302 echo "<th>" . xlt('Translation') . "<span class='help' title='" . xla('The translated Title that will appear in current language') . "'> (?)</span></th>";
1304 <th
><?php
echo xlt('Mini'); ?
></th
>
1305 <?php
//show translation column if not english and the translation lists flag is set
1306 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
1307 echo "<th>" . xlt('Translation') . "<span class='help' title='" . xla('The translated Title that will appear in current language') . "'> (?)</span></th>";
1309 <th
><?php
echo xlt('Style'); ?
></th
>
1310 <th
><?php
echo xlt('Force Show'); ?
></th
>
1311 <th
><?php
echo xlt('Access Control'); ?
></th
>
1313 <th title
='<?php echo xla('Click to edit
'); ?>'><?php
echo xlt('ID'); ?
></th
>
1314 <th
><?php
echo xlt('Title'); ?
></th
>
1315 <?php
//show translation column if not english and the translation lists flag is set
1316 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
1317 echo "<th>" . xlt('Translation') . "<span class='help' title='" . xla('The translated Title that will appear in current language') . "'> (?)</span></th>";
1319 <th
><?php
echo xlt('Order{{Sequence}}'); ?
></th
>
1320 <th
><?php
echo xlt('Default'); ?
></th
>
1321 <th
><?php
echo xlt('Active'); ?
></th
>
1322 <?php
if ($list_id == 'taxrate') { ?
>
1323 <th
><?php
echo xlt('Rate'); ?
></th
>
1324 <?php
} elseif ($list_id == 'contrameth') { ?
>
1325 <th
><?php
echo xlt('Effectiveness'); ?
></th
>
1326 <?php
} elseif ($list_id == 'lbfnames' ||
$list_id == 'transactions') { ?
>
1327 <th title
='<?php echo xla('Number of past history columns
'); ?>'><?php
echo xlt('Repeats'); ?
></th
>
1328 <?php
} elseif ($list_id == 'fitness') { ?
>
1329 <th
><?php
echo xlt('Color:Abbr'); ?
></th
>
1330 <?php
} elseif ($list_id == 'adjreason' ||
$list_id == 'abook_type') { ?
>
1331 <th
><?php
echo xlt('Type'); ?
></th
>
1332 <?php
} elseif ($list_id == 'warehouse') { ?
>
1333 <th
><?php
echo xlt('Facility'); ?
></th
>
1334 <?php
} elseif ($list_id == 'immunizations') { ?
>
1335 <th
> 
; 
; 
; 
;<?php
echo xlt('CVX Code Mapping'); ?
></th
>
1336 <?php
} elseif ($list_id == 'ptlistcols') { ?
>
1337 <th
> 
; 
; 
; 
;<?php
echo xlt('Default Sort Direction'); ?
></th
>
1339 if ($GLOBALS['ippf_specific']) { ?
>
1340 <th
><?php
echo xlt('Global ID'); ?
></th
>
1343 if ($list_id == 'language') {
1344 echo xlt('ISO 639 Code');
1345 } elseif ($list_id == 'personal_relationship' ||
$list_id == 'religious_affiliation' ||
$list_id == 'ethnicity' ||
$list_id == 'race' ||
$list_id == 'drug_route') {
1346 echo xlt('HL7-V3 Concept Code');
1347 } elseif ($list_id == 'Immunization_Completion_Status') {
1348 echo xlt('Treatment Completion Status');
1349 } elseif ($list_id == 'race') {
1350 echo xlt('CDC Code');
1351 } elseif ($list_id == 'Immunization_Manufacturer') {
1352 echo xlt('MVX Code');
1353 } elseif ($list_id == 'marital') {
1354 echo xlt('Marital Status');
1355 } elseif ($list_id == 'county') {
1356 echo xlt('INCITS Code'); //International Committee for Information Technology Standards
1357 } elseif ($list_id == 'immunization_registry_status' ||
$list_id == 'imm_vac_eligibility_results') {
1358 echo xlt('IIS Code');
1359 } elseif ($list_id == 'publicity_code') {
1360 echo xlt('CDC Code');
1361 } elseif ($list_id == 'immunization_refusal_reason' ||
$list_id == 'immunization_informationsource') {
1362 echo xlt('CDC-NIP Code');
1363 } elseif ($list_id == 'next_of_kin_relationship' ||
$list_id == 'immunization_administered_site') {
1364 echo xlt('HL7 Code');
1365 } elseif ($list_id == 'immunization_observation') {
1366 echo xlt('LOINC Code');
1367 } elseif ($list_id == 'page_validation') {
1368 echo xlt('Page Validation');
1369 } elseif ($list_id == 'lbfnames') {
1370 echo xlt('Attributes');
1371 } elseif ($list_id == "external_patient_education") {
1372 echo xlt('External URL');
1373 } elseif ($list_id == "default_open_tabs") {
1379 <th
><?php
echo xlt('Code(s)'); ?
></th
>
1381 if (preg_match('/_issue_list$/', $list_id)) { ?
>
1382 <th
><?php
echo xlt('Subtype'); ?
></th
>
1385 endif; // end not fee sheet ?>
1390 // Get the selected list's elements.
1392 $sql_limits = 'ASC LIMIT 0, ' . escape_limit($records_per_page);
1394 if ($list_from > 0) {
1398 $sql_limits = " ASC LIMIT " . escape_limit($list_from) . (intval($list_to) > 0 ?
", " . escape_limit($list_to - $list_from) : "");
1401 if ($list_id == 'feesheet') {
1402 $res = sqlStatement("SELECT count(*) as total_rows FROM fee_sheet_options ORDER BY fs_category, fs_option");
1403 $total_rows = sqlFetchArray($res)["total_rows"];
1405 $res = sqlStatement("SELECT * FROM fee_sheet_options " .
1406 "ORDER BY fs_category, fs_option " . $sql_limits);
1407 while ($row = sqlFetchArray($res)) {
1408 writeFSLine($row['fs_category'], $row['fs_option'], $row['fs_codes']);
1410 for ($i = 0; $i < 3; ++
$i) {
1411 writeFSLine('', '', '');
1413 } elseif ($list_id == 'code_types') {
1414 $res = sqlStatement("SELECT count(*) as total_rows FROM code_types ORDER BY ct_seq, ct_key");
1415 $total_rows = sqlFetchArray($res)["total_rows"];
1417 $res = sqlStatement("SELECT * FROM code_types " .
1418 "ORDER BY ct_seq, ct_key " . $sql_limits);
1419 while ($row = sqlFetchArray($res)) {
1422 for ($i = 0; $i < 3; ++
$i) {
1423 writeCTLine(array());
1425 } elseif ($list_id == 'issue_types') {
1426 $res = sqlStatement("SELECT count(*) as total_rows FROM issue_types ORDER BY category, ordering");
1427 $total_rows = sqlFetchArray($res)["total_rows"];
1429 $res = sqlStatement("SELECT * FROM issue_types " .
1430 "ORDER BY category, ordering " . $sql_limits);
1431 while ($row = sqlFetchArray($res)) {
1434 for ($i = 0; $i < 3; ++
$i) {
1435 writeITLine(array());
1438 $res = sqlStatement("SELECT count(*) as total_rows
1439 FROM list_options AS lo
1440 RIGHT JOIN list_options as lo2 on lo2.option_id = lo.list_id AND lo2.list_id = 'lists' AND lo2.edit_options = 1
1441 WHERE lo.list_id = ? AND lo.edit_options = 1", array($list_id));
1442 $total_rows = sqlFetchArray($res)["total_rows"];
1445 $res = sqlStatement("SELECT lo.*
1446 FROM list_options AS lo
1447 RIGHT JOIN list_options as lo2 on lo2.option_id = lo.list_id AND lo2.list_id = 'lists' AND lo2.edit_options = 1
1448 WHERE lo.list_id = ? AND lo.edit_options = 1
1449 ORDER BY seq,title " . $sql_limits, array($list_id));
1451 while ($row = sqlFetchArray($res)) {
1457 $row['option_value'],
1461 $row['toggle_setting_1'],
1462 $row['toggle_setting_2'],
1467 for ($i = 0; $i < 3; ++
$i) {
1468 writeOptionLine('', '', '', '', 0);
1476 <?php
if ($list_id == 'immunizations') { ?
>
1477 <p
> <?php
echo xlt('Is it ok to map these CVX codes to already existent immunizations?') ?
>
1478 <input type
='checkbox' name
='ok_map_cvx_codes' id
='ok_map_cvx_codes' value
='1'/>
1480 <?php
} // end if($list_id == 'immunizations') ?>
1483 <button type
="submit" name
='form_save' id
='form_save' class="btn btn-secondary btn-save"><?php
echo xlt('Save'); ?
></button
>
1486 <input type
='hidden' name
='form_checksum' value
='<?php echo listChecksum($list_id); ?>' />
1490 <div
class="modal fade" id
="modal-new-list" tabindex
="-1" role
="dialog">
1491 <div
class="modal-dialog" role
="document">
1492 <div
class="modal-content">
1493 <form action
="edit_list.php" method
="post" class="form">
1494 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
1495 <div
class="modal-header">
1496 <h4
class="modal-title"><?php
echo xlt('New List'); ?
></h4
>
1497 <button type
="button" class="close" data
-dismiss
="modal" aria
-label
="<?php echo xla('Close'); ?>"><i
class="fa fa-times" aria
-hidden
="true"></i
></button
>
1499 <div
class="modal-body">
1500 <label
for="newlistname" class="control-label"><?php
echo xlt('List Name'); ?
></label
>
1501 <input type
="text" size
="20" class="form-control" maxlength
="100" name
="newlistname" id
="newlistname" />
1502 <input type
="hidden" name
="formaction" value
="addlist">
1505 <div
class="modal-footer text-right">
1506 <button type
="submit" class="btn btn-secondary btn-save"><?php
echo xlt('Save'); ?
></button
>
1507 <button type
="button" class="btn btn-link btn-cancel" data
-dismiss
="modal"><?php
echo xlt('Cancel'); ?
></button
>
1510 </div
><!-- /.modal
-content
-->
1511 </div
><!-- /.modal
-dialog
-->
1512 </div
><!-- /.modal
#modal-new-list -->
1515 // jQuery stuff to make the page a little easier to use
1518 $
("#form_save").click(function (e
) {
1522 $
("#list_id").change(function () {
1523 $
("#list_from").val(1);
1524 $
("#list_to").val('');
1526 $
('#theform').submit();
1529 $
(".newlist").click(function () {
1532 $
(".savenewlist").click(function () {
1535 $
(".deletelist").click(function () {
1539 var totalRecords
= '<?php echo attr($res->_numOfRows);?>';
1540 var totalRecordDiv
= $
('#total-record');
1541 if( totalRecordDiv
){
1542 totalRecordDiv
.text("<?php echo xlt("Showing items
"); ?>: <?php echo ( $list_to > 0 ? attr($list_from + 1) . " - " . attr($list_to) : attr($res->_numOfRows) );?> of <?php echo attr($total_rows);?>");
1545 var queryParams
= getQueryStringAsObject();
1546 var listIdCont
= null;
1547 if (typeof queryParams
['list_id_container'] !== 'undefined') {
1548 listIdCont
= queryParams
['list_id_container'];
1552 if( totalRecords
>= <?php
echo attr($records_per_page);?
> || listIdCont
!= null || $
("#list_to").val() > 0) {
1553 $
(".blck-filter").show();
1556 //prevent Enter button press on filter
1557 $
('.blck-filter').on('keyup keypress', function(e
)
1559 var keyCode
= e
.keyCode || e
.which
;
1566 var SaveChanges
= function () {
1567 $
("#formaction").val("save");
1568 // $('#theform').submit();
1572 // show the DIV to create a new list
1573 var NewList
= function (btnObj
) {
1574 // show the field details DIV
1575 $
('#newlistdetail').css('visibility', 'visible');
1576 $
('#newlistdetail').css('display', 'block');
1577 $
(btnObj
).parent().append($
("#newlistdetail"));
1578 $
('#newlistdetail > #newlistname').focus();
1580 // save the new list
1581 var SaveNewList
= function () {
1582 // the list name can only have letters, numbers, spaces and underscores
1583 // AND it cannot start with a number
1584 if ($
("#newlistname").val().match(/^\d+
/)) {
1585 alert(<?php
echo xlj('List names cannot start with numbers.'); ?
>);
1588 var validname
= $
("#newlistname").val().replace(/[^A
-za
-z0
-9 -]/g
, "_"); // match any non-word characters and replace them
1589 if (validname
!= $
("#newlistname").val()) {
1590 if (!confirm(<?php
echo xlj('Your list name has been changed to meet naming requirements.'); ?
> +
'\n' +
<?php
echo xlj('Please compare the new name'); ?
> +
', \'' + validname +
'\' ' +
<?php
echo xlj('with the old name'); ?
> +
', \'' + $
("#newlistname").val() +
'\'.\n' +
<?php
echo xlj('Do you wish to continue with the new name?'); ?
>)) {
1594 $
("#newlistname").val(validname
);
1596 // submit the form to add a new field to a specific group
1597 $
("#formaction").val("addlist");
1598 $
("#theform").submit();
1600 // actually delete an entire list from the database
1601 var DeleteList
= function (btnObj
) {
1602 var listid
= $
(btnObj
).attr("id");
1603 if (confirm(<?php
echo xlj('WARNING'); ?
> +
' - ' +
<?php
echo xlj('This action cannot be undone.'); ?
> +
'\n' +
<?php
echo xlj('Are you sure you wish to delete the entire list'); ?
> +
'(' + listid +
")?")) {
1604 // submit the form to add a new field to a specific group
1605 $
("#formaction").val("deletelist");
1606 $
("#deletelistname").val(listid
);
1607 $
("#theform").submit();
1612 function getQueryStringAsObject() {
1613 var paramsString
= document
.URL
.split('?');
1614 var paramsFull
= (paramsString
.length
> 1) ? paramsString
[1].split('&') : [];
1615 var listIdCont
= null;
1618 for (var i
= 0; i
< paramsFull
.length
; i++
) {
1619 queryParameter
= paramsFull
[i
].split('=');
1620 resObject
[queryParameter
[0]] = queryParameter
[1];
1627 echo " alert(" . js_escape($alertmsg) . ");\n";