Improvements in problem lists for MU2.
[openemr.git] / interface / super / edit_list.php
blob73def14e3144983a49ae6e0f0c57daa902add5eb
1 <?php
2 // Copyright (C) 2007-2011 Rod Roark <rod@sunsetsystems.com>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 require_once("../globals.php");
10 require_once("$srcdir/acl.inc");
11 require_once("$srcdir/formdata.inc.php");
12 require_once("../../custom/code_types.inc.php");
14 $list_id = empty($_REQUEST['list_id']) ? 'language' : $_REQUEST['list_id'];
16 // Check authorization.
17 $thisauth = acl_check('admin', 'super');
18 if (!$thisauth) die(xl('Not authorized'));
20 // If we are saving, then save.
22 if ($_POST['formaction']=='save' && $list_id) {
23 $opt = $_POST['opt'];
24 if ($list_id == 'feesheet') {
25 // special case for the feesheet list
26 sqlStatement("DELETE FROM fee_sheet_options");
27 for ($lino = 1; isset($opt["$lino"]['category']); ++$lino) {
28 $iter = $opt["$lino"];
29 $category = formTrim($iter['category']);
30 $option = formTrim($iter['option']);
31 $codes = formTrim($iter['codes']);
32 if (strlen($category) > 0 && strlen($option) > 0) {
33 sqlInsert("INSERT INTO fee_sheet_options ( " .
34 "fs_category, fs_option, fs_codes " .
35 ") VALUES ( " .
36 "'$category', " .
37 "'$option', " .
38 "'$codes' " .
39 ")");
43 else if ($list_id == 'code_types') {
44 // special case for code types
45 sqlStatement("DELETE FROM code_types");
46 for ($lino = 1; isset($opt["$lino"]['ct_key']); ++$lino) {
47 $iter = $opt["$lino"];
48 $ct_key = formTrim($iter['ct_key']);
49 $ct_id = formTrim($iter['ct_id']) + 0;
50 $ct_seq = formTrim($iter['ct_seq']) + 0;
51 $ct_mod = formTrim($iter['ct_mod']) + 0;
52 $ct_just = formTrim($iter['ct_just']);
53 $ct_mask = formTrim($iter['ct_mask']);
54 $ct_fee = empty($iter['ct_fee' ]) ? 0 : 1;
55 $ct_rel = empty($iter['ct_rel' ]) ? 0 : 1;
56 $ct_nofs = empty($iter['ct_nofs']) ? 0 : 1;
57 $ct_diag = empty($iter['ct_diag']) ? 0 : 1;
58 $ct_active = empty($iter['ct_active' ]) ? 0 : 1;
59 $ct_label = formTrim($iter['ct_label']);
60 $ct_external = formTrim($iter['ct_external']) + 0;
61 $ct_claim = empty($iter['ct_claim']) ? 0 : 1;
62 $ct_proc = empty($iter['ct_proc']) ? 0 : 1;
63 $ct_term = empty($iter['ct_term']) ? 0 : 1;
64 $ct_problem = empty($iter['ct_problem']) ? 0 : 1;
65 if (strlen($ct_key) > 0 && $ct_id > 0) {
66 sqlInsert("INSERT INTO code_types ( " .
67 "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 " .
68 ") VALUES ( " .
69 "'$ct_key' , " .
70 "'$ct_id' , " .
71 "'$ct_seq' , " .
72 "'$ct_mod' , " .
73 "'$ct_just', " .
74 "'$ct_mask', " .
75 "'$ct_fee' , " .
76 "'$ct_rel' , " .
77 "'$ct_nofs', " .
78 "'$ct_diag', " .
79 "'$ct_active', " .
80 "'$ct_label', " .
81 "'$ct_external', " .
82 "'$ct_claim', " .
83 "'$ct_proc', " .
84 "'$ct_term', " .
85 "'$ct_problem' " .
86 ")");
90 else {
91 // all other lists
93 // erase lists options and recreate them from the submitted form data
94 sqlStatement("DELETE FROM list_options WHERE list_id = '$list_id'");
95 for ($lino = 1; isset($opt["$lino"]['id']); ++$lino) {
96 $iter = $opt["$lino"];
97 $value = empty($iter['value']) ? 0 : (formTrim($iter['value']) + 0);
98 $id = formTrim($iter['id']);
99 if (strlen($id) > 0) {
101 // Special processing for the immunizations list
102 // Map the entered cvx codes into the immunizations table cvx_code
103 sqlStatement ("UPDATE `immunizations` " .
104 "SET `cvx_code`='".$value."' " .
105 "WHERE `immunization_id`='".$id."'");
107 // Force List Based Form names to start with LBF.
108 if ($list_id == 'lbfnames' && substr($id,0,3) != 'LBF')
109 $id = "LBF$id";
110 sqlInsert("INSERT INTO list_options ( " .
111 "list_id, option_id, title, seq, is_default, option_value, mapping, notes, codes " .
112 ") VALUES ( " .
113 "'$list_id', " .
114 "'" . $id . "', " .
115 "'" . formTrim($iter['title']) . "', " .
116 "'" . formTrim($iter['seq']) . "', " .
117 "'" . formTrim($iter['default']) . "', " .
118 "'" . $value . "', " .
119 "'" . formTrim($iter['mapping']) . "', " .
120 "'" . formTrim($iter['notes']) . "', " .
121 "'" . formTrim($iter['codes']) . "' " .
122 ")");
127 else if ($_POST['formaction']=='addlist') {
128 // make a new list ID from the new list name
129 $newlistID = $_POST['newlistname'];
130 $newlistID = preg_replace("/\W/", "_", $newlistID);
132 // determine the position of this new list
133 $row = sqlQuery("SELECT max(seq) as maxseq FROM list_options WHERE list_id= 'lists'");
135 // add the new list to the list-of-lists
136 sqlInsert("INSERT INTO list_options ( " .
137 "list_id, option_id, title, seq, is_default, option_value " .
138 ") VALUES ( " .
139 "'lists',". // the master list-of-lists
140 "'".$newlistID."',".
141 "'".$_POST['newlistname']."', ".
142 "'".($row['maxseq']+1)."',".
143 "'1', '0')"
146 else if ($_POST['formaction']=='deletelist') {
147 // delete the lists options
148 sqlStatement("DELETE FROM list_options WHERE list_id = '".$_POST['list_id']."'");
149 // delete the list from the master list-of-lists
150 sqlStatement("DELETE FROM list_options WHERE list_id = 'lists' and option_id='".$_POST['list_id']."'");
153 $opt_line_no = 0;
155 // Given a string of multiple instances of code_type|code|selector,
156 // make a description for each.
157 // @TODO Instead should use a function from custom/code_types.inc.php and need to remove casing functions
158 function getCodeDescriptions($codes) {
159 global $code_types;
160 $arrcodes = explode('~', $codes);
161 $s = '';
162 foreach ($arrcodes as $codestring) {
163 if ($codestring === '') continue;
164 $arrcode = explode('|', $codestring);
165 $code_type = $arrcode[0];
166 $code = $arrcode[1];
167 $selector = $arrcode[2];
168 $desc = '';
169 if ($code_type == 'PROD') {
170 $row = sqlQuery("SELECT name FROM drugs WHERE drug_id = '$code' ");
171 $desc = "$code:$selector " . $row['name'];
173 else {
174 $row = sqlQuery("SELECT code_text FROM codes WHERE " .
175 "code_type = '" . $code_types[$code_type]['id'] . "' AND " .
176 "code = '$code' ORDER BY modifier LIMIT 1");
177 $desc = "$code_type:$code " . ucfirst(strtolower($row['code_text']));
179 $desc = str_replace('~', ' ', $desc);
180 if ($s) $s .= '~';
181 $s .= $desc;
183 return $s;
186 // Write one option line to the form.
188 function writeOptionLine($option_id, $title, $seq, $default, $value, $mapping='', $notes='', $codes='') {
189 global $opt_line_no, $list_id;
190 ++$opt_line_no;
191 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
192 $checked = $default ? " checked" : "";
194 echo " <tr bgcolor='$bgcolor'>\n";
196 echo " <td align='center' class='optcell'>";
197 echo "<input type='text' name='opt[$opt_line_no][id]' value='" .
198 htmlspecialchars($option_id, ENT_QUOTES) . "' size='12' maxlength='63' class='optin' />";
199 echo "</td>\n";
201 echo " <td align='center' class='optcell'>";
202 echo "<input type='text' name='opt[$opt_line_no][title]' value='" .
203 htmlspecialchars($title, ENT_QUOTES) . "' size='20' maxlength='63' class='optin' />";
204 echo "</td>\n";
206 // if not english and translating lists then show the translation
207 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
208 echo " <td align='center' class='translation'>" . (htmlspecialchars( xl($title), ENT_QUOTES)) . "</td>\n";
211 echo " <td align='center' class='optcell'>";
212 echo "<input type='text' name='opt[$opt_line_no][seq]' value='" .
213 htmlspecialchars($seq, ENT_QUOTES) . "' size='4' maxlength='10' class='optin' />";
214 echo "</td>\n";
216 echo " <td align='center' class='optcell'>";
217 echo "<input type='checkbox' name='opt[$opt_line_no][default]' value='1' " .
218 "onclick='defClicked($opt_line_no)' class='optin'$checked />";
219 echo "</td>\n";
221 // Tax rates, contraceptive methods and LBF names have an additional attribute.
223 if ($list_id == 'taxrate' || $list_id == 'contrameth' || $list_id == 'lbfnames') {
224 echo " <td align='center' class='optcell'>";
225 echo "<input type='text' name='opt[$opt_line_no][value]' value='" .
226 htmlspecialchars($value, ENT_QUOTES) . "' size='8' maxlength='15' class='optin' />";
227 echo "</td>\n";
230 // Adjustment reasons use option_value as a reason category. This is
231 // needed to distinguish between adjustments that change the invoice
232 // balance and those that just shift responsibility of payment or
233 // are used as comments.
235 else if ($list_id == 'adjreason') {
236 echo " <td align='center' class='optcell'>";
237 echo "<select name='opt[$opt_line_no][value]' class='optin'>";
238 foreach (array(
239 1 => xl('Charge adjustment'),
240 2 => xl('Coinsurance'),
241 3 => xl('Deductible'),
242 4 => xl('Other pt resp'),
243 5 => xl('Comment'),
244 ) as $key => $desc) {
245 echo "<option value='$key'";
246 if ($key == $value) echo " selected";
247 echo ">" . htmlspecialchars($desc) . "</option>";
249 echo "</select>";
250 echo "</td>\n";
253 // Address book categories use option_value to flag category as a
254 // person-centric vs company-centric vs indifferent.
256 else if ($list_id == 'abook_type') {
257 echo " <td align='center' class='optcell'>";
258 echo "<select name='opt[$opt_line_no][value]' class='optin'>";
259 foreach (array(
260 1 => xl('Unassigned'),
261 2 => xl('Person'),
262 3 => xl('Company'),
263 ) as $key => $desc) {
264 echo "<option value='$key'";
265 if ($key == $value) echo " selected";
266 echo ">" . htmlspecialchars($desc) . "</option>";
268 echo "</select>";
269 echo "</td>\n";
272 // Immunization categories use option_value to map list items
273 // to CVX codes.
275 else if ($list_id == 'immunizations') {
276 echo " <td align='center' class='optcell'>";
277 echo "<input type='text' size='10' name='opt[$opt_line_no][value]' " .
278 "value='" . htmlspecialchars($value,ENT_QUOTES) . "' onclick='sel_cvxcode(this)' " .
279 "title='" . htmlspecialchars( xl('Click to select or change CVX code'), ENT_QUOTES) . "'/>";
280 echo "</td>\n";
283 // IPPF includes the ability to map each list item to a "master" identifier.
284 // Sports teams use this for some extra info for fitness levels.
286 if ($GLOBALS['ippf_specific'] || $list_id == 'fitness') {
287 echo " <td align='center' class='optcell'>";
288 echo "<input type='text' name='opt[$opt_line_no][mapping]' value='" .
289 htmlspecialchars($mapping, ENT_QUOTES) . "' size='12' maxlength='15' class='optin' />";
290 echo "</td>\n";
293 echo " <td align='center' class='optcell'>";
294 echo "<input type='text' name='opt[$opt_line_no][notes]' value='" .
295 htmlspecialchars($notes, ENT_QUOTES) . "' size='25' maxlength='255' class='optin' />";
296 echo "</td>\n";
298 echo " <td align='center' class='optcell'>";
299 echo "<input type='text' name='opt[$opt_line_no][codes]' title='" .
300 xla('Clinical Term Code(s)') ."' value='" .
301 htmlspecialchars($codes, ENT_QUOTES) . "' onclick='select_clin_term_code(this)' size='25' maxlength='255' class='optin' />";
302 echo "</td>\n";
304 echo " </tr>\n";
307 // Write a form line as above but for the special case of the Fee Sheet.
309 function writeFSLine($category, $option, $codes) {
310 global $opt_line_no;
312 ++$opt_line_no;
313 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
315 $descs = getCodeDescriptions($codes);
317 echo " <tr bgcolor='$bgcolor'>\n";
319 echo " <td align='center' class='optcell'>";
320 echo "<input type='text' name='opt[$opt_line_no][category]' value='" .
321 htmlspecialchars($category, ENT_QUOTES) . "' size='20' maxlength='63' class='optin' />";
322 echo "</td>\n";
324 echo " <td align='center' class='optcell'>";
325 echo "<input type='text' name='opt[$opt_line_no][option]' value='" .
326 htmlspecialchars($option, ENT_QUOTES) . "' size='20' maxlength='63' class='optin' />";
327 echo "</td>\n";
329 echo " <td align='left' class='optcell'>";
330 echo " <div id='codelist_$opt_line_no'>";
331 if (strlen($descs)) {
332 $arrdescs = explode('~', $descs);
333 $i = 0;
334 foreach ($arrdescs as $desc) {
335 echo "<a href='' onclick='return delete_code($opt_line_no,$i)' title='" . xl('Delete') . "'>";
336 echo "[x]&nbsp;</a>$desc<br />";
337 ++$i;
340 echo "</div>";
341 echo "<a href='' onclick='return select_code($opt_line_no)'>";
342 echo "[" . xl('Add') . "]</a>";
344 echo "<input type='hidden' name='opt[$opt_line_no][codes]' value='" .
345 htmlspecialchars($codes, ENT_QUOTES) . "' />";
346 echo "<input type='hidden' name='opt[$opt_line_no][descs]' value='" .
347 htmlspecialchars($descs, ENT_QUOTES) . "' />";
348 echo "</td>\n";
350 echo " </tr>\n";
353 // Helper functions for writeCTLine():
355 function ctGenCell($opt_line_no, $ct_array, $name, $size, $maxlength, $title='') {
356 $value = isset($ct_array[$name]) ? $ct_array[$name] : '';
357 $s = " <td align='center' class='optcell'";
358 if ($title) $s .= " title='" . addslashes($title) . "'";
359 $s .= ">";
360 $s .= "<input type='text' name='opt[$opt_line_no][$name]' value='";
361 $s .= htmlspecialchars($value, ENT_QUOTES);
362 $s .= "' size='$size' maxlength='$maxlength' class='optin' />";
363 $s .= "</td>\n";
364 return $s;
367 function ctGenCbox($opt_line_no, $ct_array, $name, $title='') {
368 $checked = empty($ct_array[$name]) ? '' : 'checked ';
369 $s = " <td align='center' class='optcell'";
370 if ($title) $s .= " title='" . addslashes($title) . "'";
371 $s .= ">";
372 $s .= "<input type='checkbox' name='opt[$opt_line_no][$name]' value='1' ";
373 $s .= "$checked/>";
374 $s .= "</td>\n";
375 return $s;
378 // Write a form line as above but for the special case of Code Types.
380 function writeCTLine($ct_array) {
381 global $opt_line_no,$cd_external_options;
383 ++$opt_line_no;
384 $bgcolor = "#" . (($opt_line_no & 1) ? "ddddff" : "ffdddd");
386 echo " <tr bgcolor='$bgcolor'>\n";
388 echo ctGenCBox($opt_line_no, $ct_array, 'ct_active',
389 xl('Is this code type active?'));
390 echo ctGenCell($opt_line_no, $ct_array, 'ct_key' , 6, 15,
391 xl('Unique human-readable identifier for this type'));
392 echo ctGenCell($opt_line_no, $ct_array, 'ct_id' , 2, 11,
393 xl('Unique numeric identifier for this type'));
394 echo ctGenCell($opt_line_no, $ct_array, 'ct_label' , 6, 30,
395 xl('Label for this type'));
396 echo ctGenCell($opt_line_no, $ct_array, 'ct_seq' , 2, 3,
397 xl('Numeric display order'));
398 echo ctGenCell($opt_line_no, $ct_array, 'ct_mod' , 1, 2,
399 xl('Length of modifier, 0 if none'));
400 echo ctGenCell($opt_line_no, $ct_array, 'ct_just', 4, 15,
401 xl('If billing justification is used enter the name of the diagnosis code type.'));
402 echo ctGenCell($opt_line_no, $ct_array, 'ct_mask', 6, 9,
403 xl('Specifies formatting for codes. # = digit, @ = alpha, * = any character. Empty if not used.'));
404 echo ctGenCBox($opt_line_no, $ct_array, 'ct_claim',
405 xl('Is this code type used in claims?'));
406 echo ctGenCBox($opt_line_no, $ct_array, 'ct_fee',
407 xl('Are fees charged for this type?'));
408 echo ctGenCBox($opt_line_no, $ct_array, 'ct_rel',
409 xl('Does this type allow related codes?'));
410 echo ctGenCBox($opt_line_no, $ct_array, 'ct_nofs',
411 xl('Is this type hidden in the fee sheet?'));
412 echo ctGenCBox($opt_line_no, $ct_array, 'ct_proc',
413 xl('Is this a procedure/service type?'));
414 echo ctGenCBox($opt_line_no, $ct_array, 'ct_diag',
415 xl('Is this a diagnosis type?'));
416 echo ctGenCBox($opt_line_no, $ct_array, 'ct_term',
417 xl('Is this a Clinical Term code type?'));
418 echo ctGenCBox($opt_line_no, $ct_array, 'ct_problem',
419 xl('Is this a Medical Problem code type?'));
420 // Show the external code types selector
421 $value_ct_external = isset($ct_array['ct_external']) ? $ct_array['ct_external'] : '';
422 echo " <td title='" . xla('Is this using external sql tables? If it is, then choose the format.') . "' align='center' class='optcell'>";
423 echo "<select name='opt[$opt_line_no][ct_external]' class='optin'>";
424 foreach ( $cd_external_options as $key => $desc) {
425 echo "<option value='" . attr($key) . "'";
426 if ($key == $value_ct_external) echo " selected";
427 echo ">" . text($desc) . "</option>";
429 echo "</select>";
430 echo "</td>\n";
431 echo " </tr>\n";
434 <html>
436 <head>
437 <?php html_header_show();?>
439 <!-- supporting javascript code -->
440 <script type="text/javascript" src="<?php echo $GLOBALS['webroot'] ?>/library/js/jquery.js"></script>
442 <link rel="stylesheet" href='<?php echo $css_header ?>' type='text/css'>
443 <title><?php xl('List Editor','e'); ?></title>
445 <style>
446 tr.head { font-size:10pt; background-color:#cccccc; text-align:center; }
447 tr.detail { font-size:10pt; }
448 td { font-size:10pt; }
449 input { font-size:10pt; }
450 a, a:visited, a:hover { color:#0000cc; }
451 .optcell { }
452 .optin { background-color:transparent; }
453 .help { cursor:help; }
454 .translation { color:green; }
455 </style>
457 <script type="text/javascript" src="../../library/dialog.js"></script>
459 <script language="JavaScript">
461 var current_lino = 0;
463 // Helper function to set the contents of a div.
464 // This is for Fee Sheet administration.
465 function setDivContent(id, content) {
466 if (document.getElementById) {
467 var x = document.getElementById(id);
468 x.innerHTML = '';
469 x.innerHTML = content;
471 else if (document.all) {
472 var x = document.all[id];
473 x.innerHTML = content;
477 // Given a line number, redisplay its descriptive list of codes.
478 // This is for Fee Sheet administration.
479 function displayCodes(lino) {
480 var f = document.forms[0];
481 var s = '';
482 var descs = f['opt[' + lino + '][descs]'].value;
483 if (descs.length) {
484 var arrdescs = descs.split('~');
485 for (var i = 0; i < arrdescs.length; ++i) {
486 s += "<a href='' onclick='return delete_code(" + lino + "," + i + ")' title='<?php xl('Delete','e'); ?>'>";
487 s += "[x]&nbsp;</a>" + arrdescs[i] + "<br />";
490 setDivContent('codelist_' + lino, s);
493 // Helper function to remove a Fee Sheet code.
494 function dc_substring(s, i) {
495 var r = '';
496 var j = s.indexOf('~', i);
497 if (j < 0) { // deleting last segment
498 if (i > 0) r = s.substring(0, i-1); // omits trailing ~
500 else { // not last segment
501 r = s.substring(0, i) + s.substring(j + 1);
503 return r;
506 // Remove a generated Fee Sheet code.
507 function delete_code(lino, seqno) {
508 var f = document.forms[0];
509 var celem = f['opt[' + lino + '][codes]'];
510 var delem = f['opt[' + lino + '][descs]'];
511 var ci = 0;
512 var di = 0;
513 for (var i = 0; i < seqno; ++i) {
514 ci = celem.value.indexOf('~', ci) + 1;
515 di = delem.value.indexOf('~', di) + 1;
517 celem.value = dc_substring(celem.value, ci);
518 delem.value = dc_substring(delem.value, di);
519 displayCodes(lino);
520 return false;
523 // This invokes the find-code popup.
524 // For Fee Sheet administration.
525 function select_code(lino) {
526 current_lino = lino;
527 dlgopen('../patient_file/encounter/find_code_popup.php', '_blank', 700, 400);
528 return false;
531 // This invokes the find-code popup.
532 // For CVX/immunization code administration.
533 function sel_cvxcode(e) {
534 current_sel_name = e.name;
535 dlgopen('../patient_file/encounter/find_code_popup.php?codetype=CVX', '_blank', 500, 400);
538 // This invokes the find-code popup.
539 // For CVX/immunization code administration.
540 function select_clin_term_code(e) {
541 current_sel_clin_term = e.name;
542 dlgopen('../patient_file/encounter/find_code_popup.php?codetype=<?php echo attr(collect_codetypes("clinical_term","csv")) ?>', '_blank', 500, 400);
545 // This is for callback by the find-code popup.
546 function set_related(codetype, code, selector, codedesc) {
547 if (typeof(current_sel_name) == 'undefined' && typeof(current_sel_clin_term) == 'undefined')
549 // Coming from Fee Sheet edit
550 var f = document.forms[0];
551 var celem = f['opt[' + current_lino + '][codes]'];
552 var delem = f['opt[' + current_lino + '][descs]'];
553 var i = 0;
554 while ((i = codedesc.indexOf('~')) >= 0) {
555 codedesc = codedesc.substring(0, i) + ' ' + codedesc.substring(i+1);
557 if (code) {
558 if (celem.value) {
559 celem.value += '~';
560 delem.value += '~';
562 celem.value += codetype + '|' + code + '|' + selector;
563 if (codetype == 'PROD') delem.value += code + ':' + selector + ' ' + codedesc;
564 else delem.value += codetype + ':' + code + ' ' + codedesc;
565 } else {
566 celem.value = '';
567 delem.value = '';
569 displayCodes(current_lino);
571 else if (typeof(current_sel_name) == 'undefined') {
572 // Coming from the Clinical Terms Code(s) edit
573 var f = document.forms[0][current_sel_clin_term];
574 var s = f.value;
575 if (code) {
576 if (s.length > 0) s += ';';
577 s += codetype + ':' + code;
579 else {
580 s = '';
582 f.value = s;
584 else {
585 // Coming from Immunizations edit
586 var f = document.forms[0][current_sel_name];
587 var s = f.value;
588 if (code) {
589 s = code;
591 else {
592 s = '0';
594 f.value = s;
598 // Called when a "default" checkbox is clicked. Clears all the others.
599 function defClicked(lino) {
600 var f = document.forms[0];
601 for (var i = 1; f['opt[' + i + '][default]']; ++i) {
602 if (i != lino) f['opt[' + i + '][default]'].checked = false;
606 // Form validation and submission.
607 // This needs more validation.
608 function mysubmit() {
609 var f = document.forms[0];
610 if (f.list_id.value == 'code_types') {
611 for (var i = 1; f['opt[' + i + '][ct_key]'].value; ++i) {
612 var ikey = 'opt[' + i + ']';
613 for (var j = i+1; f['opt[' + j + '][ct_key]'].value; ++j) {
614 var jkey = 'opt[' + j + ']';
615 if (f[ikey+'[ct_key]'].value == f[jkey+'[ct_key]'].value) {
616 alert('<?php echo xl('Error: duplicated name on line') ?>' + ' ' + j);
617 return;
619 if (parseInt(f[ikey+'[ct_id]'].value) == parseInt(f[jkey+'[ct_id]'].value)) {
620 alert('<?php echo xl('Error: duplicated ID on line') ?>' + ' ' + j);
621 return;
626 f.submit();
629 </script>
631 </head>
633 <body class="body_top">
635 <form method='post' name='theform' id='theform' action='edit_list.php'>
636 <input type="hidden" name="formaction" id="formaction">
638 <p><b><?php xl('Edit list','e'); ?>:</b>&nbsp;
639 <select name='list_id' id="list_id">
640 <?php
642 // List order depends on language translation options.
643 $lang_id = empty($_SESSION['language_choice']) ? '1' : $_SESSION['language_choice'];
645 if (($lang_id == '1' && !empty($GLOBALS['skip_english_translation'])) ||
646 !$GLOBALS['translate_lists'])
648 $res = sqlStatement("SELECT option_id, title FROM list_options WHERE " .
649 "list_id = 'lists' ORDER BY title, seq");
651 else {
652 // Use and sort by the translated list name.
653 $res = sqlStatement("SELECT lo.option_id, " .
654 "IF(LENGTH(ld.definition),ld.definition,lo.title) AS title " .
655 "FROM list_options AS lo " .
656 "LEFT JOIN lang_constants AS lc ON lc.constant_name = lo.title " .
657 "LEFT JOIN lang_definitions AS ld ON ld.cons_id = lc.cons_id AND " .
658 "ld.lang_id = '$lang_id' " .
659 "WHERE lo.list_id = 'lists' " .
660 "ORDER BY IF(LENGTH(ld.definition),ld.definition,lo.title), lo.seq");
663 while ($row = sqlFetchArray($res)) {
664 $key = $row['option_id'];
665 echo "<option value='$key'";
666 if ($key == $list_id) echo " selected";
667 echo ">" . $row['title'] . "</option>\n";
671 </select>
672 <input type="button" id="<?php echo $list_id; ?>" class="deletelist" value=<?php xl('Delete List','e','\'','\''); ?>>
673 <input type="button" id="newlist" class="newlist" value=<?php xl('New List','e','\'','\''); ?>>
674 </p>
676 <center>
678 <table cellpadding='2' cellspacing='0'>
679 <tr class='head'>
680 <?php if ($list_id == 'feesheet') { ?>
681 <td><b><?php xl('Group' ,'e'); ?></b></td>
682 <td><b><?php xl('Option' ,'e'); ?></b></td>
683 <td><b><?php xl('Generates','e'); ?></b></td>
684 <?php } else if ($list_id == 'code_types') { ?>
685 <td><b><?php xl('Active' ,'e'); ?></b></td>
686 <td><b><?php xl('Key' ,'e'); ?></b></td>
687 <td><b><?php xl('ID' ,'e'); ?></b></td>
688 <td><b><?php xl('Label' ,'e'); ?></b></td>
689 <td><b><?php xl('Seq' ,'e'); ?></b></td>
690 <td><b><?php xl('ModLength' ,'e'); ?></b></td>
691 <td><b><?php xl('Justify' ,'e'); ?></b></td>
692 <td><b><?php xl('Mask' ,'e'); ?></b></td>
693 <td><b><?php xl('Claims' ,'e'); ?></b></td>
694 <td><b><?php xl('Fees' ,'e'); ?></b></td>
695 <td><b><?php xl('Relations' ,'e'); ?></b></td>
696 <td><b><?php xl('Hide' ,'e'); ?></b></td>
697 <td><b><?php xl('Procedure' ,'e'); ?></b></td>
698 <td><b><?php xl('Diagnosis' ,'e'); ?></b></td>
699 <td><b><?php xl('Clinical Term','e'); ?></b></td>
700 <td><b><?php xl('Medical Problem' ,'e'); ?></b></td>
701 <td><b><?php xl('External' ,'e'); ?></b></td>
702 <?php } else { ?>
703 <td title=<?php xl('Click to edit','e','\'','\''); ?>><b><?php xl('ID','e'); ?></b></td>
704 <td><b><?php xl('Title' ,'e'); ?></b></td>
705 <?php //show translation column if not english and the translation lists flag is set
706 if ($GLOBALS['translate_lists'] && $_SESSION['language_choice'] > 1) {
707 echo "<td><b>".xl('Translation')."</b><span class='help' title='".xl('The translated Title that will appear in current language')."'> (?)</span></td>";
708 } ?>
709 <td><b><?php xl('Order' ,'e'); ?></b></td>
710 <td><b><?php xl('Default','e'); ?></b></td>
711 <?php if ($list_id == 'taxrate') { ?>
712 <td><b><?php xl('Rate' ,'e'); ?></b></td>
713 <?php } else if ($list_id == 'contrameth') { ?>
714 <td><b><?php xl('Effectiveness','e'); ?></b></td>
715 <?php } else if ($list_id == 'lbfnames') { ?>
716 <td title='<?php xl('Number of past history columns','e'); ?>'><b><?php xl('Repeats','e'); ?></b></td>
717 <?php } else if ($list_id == 'fitness') { ?>
718 <td><b><?php xl('Color:Abbr','e'); ?></b></td>
719 <?php } else if ($list_id == 'adjreason' || $list_id == 'abook_type') { ?>
720 <td><b><?php xl('Type','e'); ?></b></td>
721 <?php } else if ($list_id == 'immunizations') { ?>
722 <td><b>&nbsp;&nbsp;&nbsp;&nbsp;<?php xl('CVX Code Mapping','e'); ?></b></td>
723 <?php } if ($GLOBALS['ippf_specific']) { ?>
724 <td><b><?php xl('Global ID','e'); ?></b></td>
725 <?php } ?>
726 <td><b><?php xl('Notes','e'); ?></b></td>
727 <td><b><?php xl('Code(s)','e'); ?></b></td>
728 <?php } // end not fee sheet ?>
729 </tr>
731 <?php
732 // Get the selected list's elements.
733 if ($list_id) {
734 if ($list_id == 'feesheet') {
735 $res = sqlStatement("SELECT * FROM fee_sheet_options " .
736 "ORDER BY fs_category, fs_option");
737 while ($row = sqlFetchArray($res)) {
738 writeFSLine($row['fs_category'], $row['fs_option'], $row['fs_codes']);
740 for ($i = 0; $i < 3; ++$i) {
741 writeFSLine('', '', '');
744 else if ($list_id == 'code_types') {
745 $res = sqlStatement("SELECT * FROM code_types " .
746 "ORDER BY ct_seq, ct_key");
747 while ($row = sqlFetchArray($res)) {
748 writeCTLine($row);
750 for ($i = 0; $i < 3; ++$i) {
751 writeCTLine(array());
754 else {
755 $res = sqlStatement("SELECT * FROM list_options WHERE " .
756 "list_id = '$list_id' ORDER BY seq,title");
757 while ($row = sqlFetchArray($res)) {
758 writeOptionLine($row['option_id'], $row['title'], $row['seq'],
759 $row['is_default'], $row['option_value'], $row['mapping'],
760 $row['notes'],$row['codes']);
762 for ($i = 0; $i < 3; ++$i) {
763 writeOptionLine('', '', '', '', 0);
769 </table>
772 <input type='button' name='form_save' id='form_save' value='<?php xl('Save','e'); ?>' />
773 </p>
774 </center>
776 </form>
778 <!-- template DIV that appears when user chooses to make a new list -->
779 <div id="newlistdetail" style="border: 1px solid black; padding: 3px; display: none; visibility: hidden; background-color: lightgrey;">
780 <?php xl('List Name','e'); ?>: <input type="textbox" size="20" maxlength="30" name="newlistname" id="newlistname">
781 <br>
782 <input type="button" class="savenewlist" value=<?php xl('Save New List','e','\'','\''); ?>>
783 <input type="button" class="cancelnewlist" value=<?php xl('Cancel','e','\'','\''); ?>>
784 </div>
785 </body>
786 <script language="javascript">
787 // jQuery stuff to make the page a little easier to use
789 $(document).ready(function(){
790 $("#form_save").click(function() { SaveChanges(); });
791 $("#list_id").change(function() { $('#theform').submit(); });
793 $(".newlist").click(function() { NewList(this); });
794 $(".savenewlist").click(function() { SaveNewList(this); });
795 $(".deletelist").click(function() { DeleteList(this); });
796 $(".cancelnewlist").click(function() { CancelNewList(this); });
798 var SaveChanges = function() {
799 $("#formaction").val("save");
800 // $('#theform').submit();
801 mysubmit();
804 // show the DIV to create a new list
805 var NewList = function(btnObj) {
806 // show the field details DIV
807 $('#newlistdetail').css('visibility', 'visible');
808 $('#newlistdetail').css('display', 'block');
809 $(btnObj).parent().append($("#newlistdetail"));
810 $('#newlistdetail > #newlistname').focus();
812 // save the new list
813 var SaveNewList = function() {
814 // the list name can only have letters, numbers, spaces and underscores
815 // AND it cannot start with a number
816 if ($("#newlistname").val().match(/^\d+/)) {
817 alert("<?php xl('List names cannot start with numbers.','e'); ?>");
818 return false;
820 var validname = $("#newlistname").val().replace(/[^A-za-z0-9 -]/g, "_"); // match any non-word characters and replace them
821 if (validname != $("#newlistname").val()) {
822 if (! confirm("<?php xl('Your list name has been changed to meet naming requirements.','e','','\n') . xl('Please compare the new name','e','',', \''); ?>"+validname+"<?php xl('with the old name','e','\' ',', \''); ?>"+$("#newlistname").val()+"<?php xl('Do you wish to continue with the new name?','e','\'.\n',''); ?>"))
824 return false;
827 $("#newlistname").val(validname);
829 // submit the form to add a new field to a specific group
830 $("#formaction").val("addlist");
831 $("#theform").submit();
833 // actually delete an entire list from the database
834 var DeleteList = function(btnObj) {
835 var listid = $(btnObj).attr("id");
836 if (confirm("<?php xl('WARNING','e','',' - ') . xl('This action cannot be undone.','e','','\n') . xl('Are you sure you wish to delete the entire list','e',' ','('); ?>"+listid+")?")) {
837 // submit the form to add a new field to a specific group
838 $("#formaction").val("deletelist");
839 $("#deletelistname").val(listid);
840 $("#theform").submit();
844 // just hide the new list DIV
845 var CancelNewList = function(btnObj) {
846 // hide the list details DIV
847 $('#newlistdetail').css('visibility', 'hidden');
848 $('#newlistdetail').css('display', 'none');
849 // reset the new group values to a default
850 $('#newlistdetail > #newlistname').val("");
854 </script>
856 </html>