This commit adds central configuration functionality for use of addons in OpenEMR. The pending orders report is included to illustrate use of insert-features.inc file to replace current calendar with jquery-ui-datepicker.
This approach is useful when existing codebase lacks any standard framework and code does not use objects/classes. The approach tries to group various PHP file elements as a feature. Scripts invoke specific features which then insert related code. With some reorganization, even OpenEMR code can be packaged into ‘features’.
We also use a completely separate directory to identify external add-on packages. This allows for easy testing of version upgrades without need to link or modify the calling programs.
This concept can be improved and expanded significantly.
Select2 is a great addon that can be used in several places by offering standard text phrases as typing accelerator. In case anyone is interested, check Text_Fragments fiddle’s use of static options. When used with Ajax/JSON support, this is useful in ICD and CPT code selections.
However, you don’t need Select2 to do autocomplete.
There are tons of jquery examples on how to do autocomplete. Its not really that difficult. It does not take much coding to add autocomplete functionality to any input box. There are many areas in OpenEMR that would benefit from this functionality.
I’ve already successfully implemented an autocomplete functionality to my current project (demographics improvements). I will be submitting some of my code by early Jan, hopefully.
If no one adds auto complete functionality to other areas of OpenEMR, such as entering ICD-9 codes, I will probably work on this sometime next year.
Also, if used, Select2 and/or any autocomplete functionality, would probably not be an “add-on”. It should be put in the library folder and just included in webpages that would use the functionality.
David, Our design requirement is to track individual fragments in a single field so each fragment can be reused in different order. For example if a patient makes appointment for Flu Shot and follow up, we track that as 2 reasons (fragments) that can be reused individually but saved in a single field after some formatting.
If your approach works without overhead of any add-ons, it would be a great feature.
In the meanwhile, since Select2 code is from another project, we put it in a separate directory for better visibility. The commit mentioned at the start of this topic makes it easy to change base location per your preference - all without affecting calling code.
Basic type ahead/search autocomplete is in use in OpenEMR in the payments
posting module that ZH contributed and in the dynamic_finder that Rod
added. Be careful not to re-re-re-re invent the wheel please.
–Tony
Tony McCormick, CTO
Medical Information Integration, LLC
David, Our design requirement is to track individual fragments in a single
field so each fragment can be reused in different order. For example if a
patient makes appointment for Flu Shot and follow up, we track that as 2
reasons (fragments) that can be reused individually but saved in a single
field after some formatting.
If your approach works without overhead of any add-ons, it would be a
great feature.
In the meanwhile, since Select2 code is from another project, we put it in
a separate directory for better visibility. The commit mentioned at the
start of this topic makes it easy to change base location per your
preference - all without affecting calling code.
Although the purpose of this topic is not autocomplete, using it as an example if there is a library/object that can reliably add that functionality on demand, we are not able to locate it. We do not use billing but based on your pointer, cursory check seems to indicate a highly custom solution addressing a specific requirement. Use of widely used and well documented addons lets our developers focus on business logic than details of presentation layer.
Even if ZH had used this or another addon, we would not be aware of it under current structure / documentation. Commit posted in this topic addressed that basic problem. We use a centralized approach to managing these addons and their interdependence. The insert_features script provides an abstraction layer for rest of code to invoke ‘features’ and the script makes requirements available. This approach has worked for us well but obviously others may have better solutions in use. We were hoping to get that feedback. Based on responses so far, that has not worked well…
Regarding auto-complete, wouldn’t get to stuck on a centralized function, since this is generally rather lightweight. Note several places now have separate mechanisms to do this (with minimal overhead):
My main issue with the add-on feature interface is that it will likely get bypassed as newer versions of these packages come out. For example if several scripts were built in a certain version of jquery, however, then newer scripts needed a more recent version, then would be stuck (either would need to update the jquery for all older scripts and test/debug them or would go towards path of least resistance and bypass the mechanism).
That being said, though, do like the idea of creating some sort of framework to make it easier to create scripts in addition to bringing in all the dependencies, which your frameworks does. Is there any way to make the versions separate or does that defeat the purpose of it? Also, to bring this into the codebase, best thing to do would be do convert a current script to use it fully (and not bring in date_picker, since that would likely need to be modded to support internationalization).
All addons are in openemr/addon/project/product directory for easy visibility and to keep standard release unaffected by our customization. (If someone wants, they could potentially set base directory to ‘library’ or whatever.)
Contents of this directory are as provided by the project. Since jquery.com releases code with version, it will be downloaded as jquery-1.10.2.min.js. Since unzipped code for bootstrap does not include version, it will unzipped without version.
Calling script just invokes the feature (e.g. line 80 in commit) as -
<?php insert_feature('jquery-ui-datepicker'); ?>.
Since datepicker requires jquery, the insert_features script line 88 invokes jquery as :
insert_feature(‘jquery-min’);
Since we wanted to control current version manually, at line 82 actual file name is constructed by calling:
insert_script("$basedir/jquery",’-1.10.2.min.js’);
4. As you notice, to test a new version (e.g. 2.0.3) we would change line 82 in central script and test the calling routines without any change. In cases where version is not part of the standard released files, we rename entire directory as version number and install the latest version.
5. If we find the new version breaks the functionality,
a. we reset line 82 until scripts are made compatible OR
b. If the problem is localized, we change a specific calling script to pass optional version specification.
6. We can also use this approach for openemr features e.g. calling script can check if inventory is in use and insert_feature(‘inventory’) which will pull in inventory specific library files.
Although the explanation makes it sound complex, it is extremely simple to maintain. Hope this also answers your question regarding making versions separate - that versions are specified as exception otherwise latest version will be invoked.
Datepicker’s i18N code is available here. It is also a great use case for insert_features. To implement this, add a single line after line 91 in insert_features as :
insert_script("$basedir/…/i18n/",‘jquery.ui.datepicker-’.$_SESSION[‘language_choice’].‘js’);
If language_choices do not match, it may need an static array map or a list.
This seems to work fine when one group is working on code, but the real weakness seems to lie in hard-coding most recent jquery (and other js libraries that are versioned), since we can’t expect a developer whom makes a simple change or a simple script that requires a newer version of the js library to test all other scripts (could literally be hundreds at one point) and be responsible for localizing problems and creating exceptions. On a big picture sense, it seems that the framework may be yet another layer that may potentially cause confusion especially if it just gets bypassed. Am curious what other developers think?
Regarding translations, OpenEMR doesn’t yet have ability to pick scripts based on choices like that. This would require optimization(ie. planning and coding) along with maintenance. Also, then the control of the translation would no longer be within OpenEMR itself (ie. the Administration->Other->Language). The solution for the current date picker (and the Patients->Patients stuff) was the following mechanism:
(include a php script that translates using the openemr translation engine)
(additionally, can also set local settings (date etc.) )
Note getting correct date setting done correctly is also not a simple issue: http://sourceforge.net/p/openemr/discussion/202506/thread/7f38b864
As stated in earlier notes, this is an abstraction layer – not sure of what you mean by ‘yet another layer’. Selecting component files has some logic/analysis/tesing. Result of that can be hard-coded (less upgrade/change flexibility and more developer control) or a program can do it (more flexibility less control). Integration issues become increasing complex as number of components increase – e.g. in LBF, some of new jquery features cannot be used since one control uses version 1.3.2 (hardcoded) and invoking multiple jquery js breaks some functionality.
While developer has option of inserting specific jquery version (like they do currently) and limit impact, it defeats the intent. The commit reflects our struggle with common approaches to overcome hardcoded versions – have tried ‘current-linked’ location as well as accepting specific, minimum and maximum versions as parameters and put logic to resolve developer’s wishes. Each such option however is invitation for either code bloat or future mess but it can be done.
Regarding i18N, wouldn’t it be better to let generic terms such month, day names be translated and vetted by a larger user base?
Regarding date format issue, commit shows use of standard datepicker functionality :
Hide existing date field (e.g. date_begin).
Add a new text field (e.g. dt2_date_begin) with datepicker class.
In jquery specify the dt2_date_begin to have format specified in globals AND alternate field as original (date_begin).
Drawback of datepicker is since time is not a standard option, you have to rely on one of the community contributed plugins. Alternatively until time gets added by jquery.com, use datepicker if no time is needed (most cases) and use existing code where date+time is needed in a single field.
Was hoping to get more thoughts by other developers on this, especially insert_feature/script() stuff. Still seems like in the long-term, developers will bypass this mechanism and/or the insert_feature() switch loop will get convoluted. Just my opinion, curious if others have an opinion here.
For translations, note almost all of the datepicker constants are already in the OpenEMR translation engine. If we were to look long term, don’t you see an issue with a user that would like to translate something to their liking (perhaps a locale/dialect form of the month of February) and would then need to modify or create their own translation i18n code files for every single js module that is brought in the future (vs. simply modifying it one time in Administration->Other->Language)?
My feelings on this are mixed. A standard way to include js and CSS is a good idea in the hypothetical, but I agree with you about it getting convoluted or ignored. The versioning stuff fits MD suport’s development process, but I don’t know that it really works with the rest of the codebase.
Since earlier posts, we have generically used Select2 to show top 20 matches in several high usage scenarios and time savings are dramatic. Four forms that showed best results were:
Patient search - User types ** jo do 60 ** as the list narrows for all john doe with DoB 1960.
Issues - Title, codes, referral. Code selection is now inline with pattern matching across all code types.
Issue-encounter multi-select - No need to use two hands (tablet users find it impossible) to select multiple issues
Appointment reasons - Front desk can now enter detailed reason with 3-4 keystrokes. Also less spelling mistakes.
Next task for us are
Speed up tests selection in procedure order data entry.
Filter messages based on content since messages are part of our workflow.
Development efforts:
After initial design effort, as long other js version changes in the script do not create problems, developers are now able to add the select2 feature to a textbox in about 15-30 minutes.
This is not a push for one approach over other. Our developers like Select2 so that is our library of choice. We just hope the official code base implements a standard, flexible approach relatively quickly as this is baseline expectation of all users.