...
Prior to OpenMRS version 1.8, the search widgets were written with dojo which involved writing a separate javascript file where you would have to extended the parent OpenmrsSearch for each Openmrs Object if it were to be searchable in the webapp. The widgets would fetch all hits in one ajax query which would take a while to return all the hits in case there are many making the widgets slow. In 1.8, this was changed by introducing a single and more generic search widget written with jquery, the widget is expected to be faster from a user's stand point in that it fetches just the exact amount number of results to display on the first page and then continue to query the server for the rest in the background while updating the table until all results are returned. The reason behind this is that it should take way less time to display the first N results to display on the first page rather waiting for all the matching hits to be returned in one call in case there are many. The objective is to increase the perceived speed from a user's point of view since they get some results returned back results for the first page in a nick of time even if it isn't all.
...
objectList: Maps to the actual list of hits
notification: Maps to an form of informative or error message you wish to display for the user about the results
searchAgain: Maps to the phrase against which to search againstagain, when this key is included with a value, the search widget machinery will discard the current results and re run the search against the new specified phrase, a use case for this is if there are no matches to what the user originally entered and you wish to send them back results based on a shorter phrase
Next thing is to initialize the widget and there are 2 ways to do it, the one used above is the one which delegates to a helper function that takes in 4 arguments5 arguments, in the case above, the first argument is the id of the element inside which the widget should be embedded, the rest of them are configuration properties that are explained below under the 'widget properties' section. Below is the other way of how to initialize the widget:
Code Block |
---|
$j(document).ready(function() { $j("#elementId").openmrsSearch({ searchLabel:'<spring:message code="General.search"/>', searchPlaceholder: '<spring:message code="Encounter.search.placeholder" javaScriptEscape="true"/>', searchHandler: doSearchHandler, selectionHandler: doSelectionHandler, fieldsAndHeaders: [ {fieldName:"personName", header:"Patient Name}, {fieldName:"encounterType", header:"Encounter Type}, {fieldName:"formName", header:"Encounter Form}, {fieldName:"providerName", header:"Encounter Provider}, {fieldName:"location", header:"Encounter Location}, {fieldName:"encounterDateString", header:"Encounter Date} ] }); }); |
...
The implementation of the server side logic should call the API methods that return the count and the appropriate search method that supports paging for the given domain object, in this case they would be EncounterService.getCountOfEncounters(String, boolean) and EncounterService.getEncounters(String, Integer, Integer, boolean). In the DAO layer, it's highly recommended that these methods use the same criteria object and the difference should be that the one that gets the count sets a row count projection while the other should return the actual objects matching the criteria. This implies that the total number of hits fetched when the search is done should always match the value returned by the get Count method otherwise the scripts in the widgets will fail with the assumption that there is either more hits to fetch or some will get left out. For an example implementation of the methods in the DAO layer, you can look at HibernateEncounterDAO.getCountOfEncounters(String, boolean) and HibernateEncounterDAO.getEncounters(String, Integer, Integer, boolean).
Widget properties
- minLength: int (default: 1) The minimum number of characters required to trigger a search, this is ignored if 'doSearchWhenEmpty' is set to true
- searchLabel: string (default: omsgs.searchLabel) The text to be used as the label for the search textbox
- includeVoidedLabel: string (default: omsgs.includeVoided) The text to be used as the label for the 'includeVoided' checkbox
- showIncludeVoided: bool (default: false) - Specifies whether the 'includeVoided' checkbox and label should be displayed
- includeVerboseLabel: string (default: omsgs.includeVerbose) The text to be used as the label for the 'includeVerbose' checkbox
- showIncludeVerbose: bool (default: false) Specifies whether the 'includeVerbose' checkbox and label should be displayed
- searchHandler: function(text, resultHandler, options) (default:null) The function to be called to fetch search results from the server
- resultsHandler: function(results) (default:null) The function to be called
- selectionHandler: function(index, rowData
- fieldsAndHeaders: Array of fieldNames and column header maps
- displayLength: int (default: 10)
- columnWidths: an array of column widths, the length of the array should be equal to the number of columns, should be of the same length as the number of columns
- columnRenderers: array of fnRender(s) for each column, should be of the same length as the number of columns, set a value of null for columns with no renderers
- columnVisibility: array of bVisible values for each column, true/false are the only possible values in the array and should be of the same length as the number of columns
- initialData: (default: null) The initial data to be displayed e.g if it is an encounter search, it should be an encounter list
- searchPhrase: string The phrase to be set in the search box so that a search is triggered on page load to display initial items
- doSearchWhenEmpty: string (default:false): If it is set to true, it lists all items initially and filters them with the given search phrase.
- verboseHandler: function to be called to return the text to display as verbose output